|
|
@@ -0,0 +1,231 @@
|
|
|
+import { ColorType } from "@/context/themes/color";
|
|
|
+import { TimeFormatter } from "@/utils/time_format";
|
|
|
+import { View, Text } from "@tarojs/components";
|
|
|
+import { useEffect, useState } from "react";
|
|
|
+import { ChooseScenarioBtn } from "../common/SpecBtns";
|
|
|
+import Taro from "@tarojs/taro";
|
|
|
+import { WorkoutType } from "@/utils/types";
|
|
|
+import Modal from "@/components/layout/Modal";
|
|
|
+import PickerViews from "@/components/input/PickerViews";
|
|
|
+
|
|
|
+var timer
|
|
|
+var lastStrTime
|
|
|
+export default function Component(props: { targetCount: number, type: WorkoutType }) {
|
|
|
+ const [index, setIndex] = useState(1)
|
|
|
+ const [count, setCount] = useState(0)
|
|
|
+ const [startTime, setStartTime] = useState(new Date().getTime())
|
|
|
+ const [tempTime, setTempTime] = useState(0)
|
|
|
+ // const [lastStrTime, setLastStrTime] = useState('')
|
|
|
+ const [groups, setGroups] = useState<any[]>([])
|
|
|
+ const [isDoing, setIsDoing] = useState(true)
|
|
|
+ const [showModal, setShowModal] = useState(false)
|
|
|
+
|
|
|
+ const items = [[1, 2, 3, 4, 5, 6]]
|
|
|
+ const [selIndex, setSelIndex] = useState([1])
|
|
|
+ const multiItems = [[10, 20, 30, 40], [1, 2, 3, 4, 5]]
|
|
|
+ const multiSel = [1, 1]
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ timer = setInterval(() => {
|
|
|
+ setCount((count) => count + 1)
|
|
|
+ }, 1000)
|
|
|
+ setGroups([{
|
|
|
+ index: index,
|
|
|
+ time: startTime,
|
|
|
+ type: 'start'
|
|
|
+ }])
|
|
|
+ return () => clearInterval(timer)
|
|
|
+ }, [])
|
|
|
+
|
|
|
+ function resume() {
|
|
|
+ timer = setInterval(() => {
|
|
|
+ setCount((count) => count + 1)
|
|
|
+ }, 1000)
|
|
|
+ }
|
|
|
+
|
|
|
+ function planTime() {
|
|
|
+ var minutes = props.targetCount / 60
|
|
|
+ return minutes + '分钟'
|
|
|
+ }
|
|
|
+
|
|
|
+ function durationTime() {
|
|
|
+ var str = TimeFormatter.formateTimeNow(startTime)
|
|
|
+ // setLastStrTime(str)
|
|
|
+ lastStrTime = str
|
|
|
+ return str
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ function twoTimeDuration(start, end) {
|
|
|
+ var time = Math.floor((end - start) / 1000);
|
|
|
+ const hours = Math.floor(time / 3600);
|
|
|
+ const minutes = Math.floor((time % 3600) / 60);
|
|
|
+ const seconds = Math.floor(time % 60);
|
|
|
+ var strDuration = ''
|
|
|
+ if (hours > 0) {
|
|
|
+ strDuration = `${hours}时`
|
|
|
+ }
|
|
|
+ if (minutes > 0) {
|
|
|
+ strDuration += `${minutes}分`
|
|
|
+ }
|
|
|
+ if (seconds > 0) {
|
|
|
+ strDuration += `${seconds}秒`
|
|
|
+ }
|
|
|
+ return strDuration.length == 0 ? '1秒' : strDuration
|
|
|
+ }
|
|
|
+
|
|
|
+ function finish() {
|
|
|
+ if (props.type != WorkoutType.normal) {
|
|
|
+ setTempTime(new Date().getTime())
|
|
|
+ clearInterval(timer)
|
|
|
+ setShowModal(true)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ var array = groups;
|
|
|
+ var time = new Date().getTime()
|
|
|
+ array.push({
|
|
|
+ index: index,
|
|
|
+ time: time,
|
|
|
+ type: 'end'
|
|
|
+ })
|
|
|
+ setIsDoing(false)
|
|
|
+ setStartTime(time)
|
|
|
+ setGroups(array)
|
|
|
+ }
|
|
|
+
|
|
|
+ function start() {
|
|
|
+ var array = groups;
|
|
|
+ var time = new Date().getTime()
|
|
|
+ array.push({
|
|
|
+ index: index + 1,
|
|
|
+ time: time,
|
|
|
+ type: 'start'
|
|
|
+ })
|
|
|
+ setStartTime(time)
|
|
|
+ setIndex(index + 1)
|
|
|
+ setIsDoing(true)
|
|
|
+ setGroups(array)
|
|
|
+ }
|
|
|
+
|
|
|
+ function terminal() {
|
|
|
+ Taro.showModal({
|
|
|
+ title: '提示',
|
|
|
+ content: '确认结束?',
|
|
|
+ success: function (res) {
|
|
|
+ if (res.confirm) {
|
|
|
+ var array = groups;
|
|
|
+ var time = new Date().getTime()
|
|
|
+ array.push({
|
|
|
+ index: index,
|
|
|
+ time: time,
|
|
|
+ type: 'end'
|
|
|
+ })
|
|
|
+ setIsDoing(false)
|
|
|
+ setGroups(array)
|
|
|
+
|
|
|
+ Taro.navigateTo({
|
|
|
+ url: '/pages/workout/WorkoutDetail?detail=' + JSON.stringify(array)
|
|
|
+ })
|
|
|
+ } else if (res.cancel) {
|
|
|
+ console.log('用户点击取消')
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ function numChange(e) {
|
|
|
+ setShowModal(false)
|
|
|
+ var array = groups;
|
|
|
+ array.push({
|
|
|
+ index: index,
|
|
|
+ time: tempTime,
|
|
|
+ value: e.length>0?multiItems[0][e[0]]:items[e[0]],
|
|
|
+ value2:e.length>0?multiItems[1][e[1]]:null,
|
|
|
+ type: 'end'
|
|
|
+ })
|
|
|
+ setIsDoing(false)
|
|
|
+ setStartTime(tempTime)
|
|
|
+ setGroups(array)
|
|
|
+ resume()
|
|
|
+ }
|
|
|
+
|
|
|
+ function pickerContent() {
|
|
|
+ var color = ColorType.workout
|
|
|
+ var title = '本组训练'
|
|
|
+ return <View style={{ color: '#fff', backgroundColor: 'transparent' }}>
|
|
|
+ <PickerViews
|
|
|
+ onChange={numChange}
|
|
|
+ items={props.type == WorkoutType.number ? items : multiItems}
|
|
|
+ value={props.type == WorkoutType.number ? selIndex : multiSel}
|
|
|
+ themeColor={color}
|
|
|
+ title={title}
|
|
|
+ showBtns={true}
|
|
|
+ onCancel={() => {
|
|
|
+ resume()
|
|
|
+ setShowModal(false)
|
|
|
+ }} />
|
|
|
+ </View>
|
|
|
+ }
|
|
|
+
|
|
|
+ return <View style={{ color: ColorType.workout, flexDirection: 'column', display: 'flex' }}>
|
|
|
+ <Text>平板支撑</Text>
|
|
|
+ <Text>计时训练</Text>
|
|
|
+ {
|
|
|
+ groups.length > 1 && groups.map((item, index) => {
|
|
|
+ if (index == 0) {
|
|
|
+ return <View />
|
|
|
+ }
|
|
|
+ return <View key={index} style={{ display: 'flex', flexDirection: 'row', justifyContent: 'space-between', width: '100%', color: '#fff' }}>
|
|
|
+ <Text>{item.type == 'end' ? `第${item.index}组` : '组间休息'}</Text>
|
|
|
+ {item.type == 'end' && props.type == WorkoutType.number && <Text style={{ color: ColorType.workout }}>{item.value}个</Text>}
|
|
|
+ {item.type == 'end' && props.type == WorkoutType.multi && <Text style={{ color: ColorType.workout }}>{item.value}x{item.value2}个</Text>}
|
|
|
+ <Text>{twoTimeDuration(groups[index - 1].time, item.time)}</Text>
|
|
|
+ </View>
|
|
|
+ })
|
|
|
+ }
|
|
|
+ {
|
|
|
+ isDoing && <View style={{ display: 'flex', flexDirection: 'column' }}>
|
|
|
+ <Text>第{index}组</Text>
|
|
|
+ <Text>{durationTime()}</Text>
|
|
|
+ <ChooseScenarioBtn onClick={finish} title="完成本组" background={ColorType.workout} />
|
|
|
+ </View>
|
|
|
+ }
|
|
|
+ {
|
|
|
+ !isDoing && <View style={{ display: 'flex', flexDirection: 'column' }}>
|
|
|
+ <Text>组间休息</Text>
|
|
|
+ <Text>{durationTime()}</Text>
|
|
|
+ <ChooseScenarioBtn onClick={start} title="开始下一组" background={ColorType.workout} />
|
|
|
+ </View>
|
|
|
+ }
|
|
|
+ <Text style={{ color: 'red' }} onClick={terminal}>结束训练</Text>
|
|
|
+ <View style={{ height: 50 }} />
|
|
|
+ <Text>总用时</Text>
|
|
|
+ <View style={{ display: 'flex', flexDirection: 'row', justifyContent: 'space-between', width: '100%' }}>
|
|
|
+ <View style={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
|
|
|
+ <Text>计划用时</Text>
|
|
|
+ <Text>{planTime()}</Text>
|
|
|
+ </View>
|
|
|
+ <View style={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
|
|
|
+ <Text>已进行</Text>
|
|
|
+ <Text>{groups.length > 0 && TimeFormatter.formateTimeNow(groups[0].time)}</Text>
|
|
|
+ </View>
|
|
|
+ <View style={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
|
|
|
+ <Text>{groups.length > 0 && new Date().getTime() > groups[0].time + props.targetCount * 1000 ? '已超时' : '距结束'}</Text>
|
|
|
+ <Text>{groups.length > 0 && TimeFormatter.countdown(groups[0].time + props.targetCount * 1000)}</Text>
|
|
|
+ </View>
|
|
|
+ </View>
|
|
|
+ {
|
|
|
+ showModal && <Modal dismiss={() => {
|
|
|
+ setShowModal(false)
|
|
|
+ resume()
|
|
|
+ }}>
|
|
|
+ {
|
|
|
+ pickerContent()
|
|
|
+ }
|
|
|
+ </Modal>
|
|
|
+ }
|
|
|
+
|
|
|
+ </View>
|
|
|
+}
|