TotalTime.tsx 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. import { View, Text, Image, PageContainer } from "@tarojs/components";
  2. import './TotalTime.scss'
  3. import { useTranslation } from "react-i18next";
  4. import { ColorType } from "@/context/themes/color";
  5. import { rpxToPx } from "@/utils/tools";
  6. import { TimeFormatter } from "@/utils/time_format";
  7. import Modal from "@/components/layout/Modal.weapp";
  8. import { useEffect, useRef, useState } from "react";
  9. import { durationDatas, durationIndex, getColor, getDurationTitle } from "../hooks/Console";
  10. import PickerViews from "@/components/input/PickerViews";
  11. import { useSelector } from "react-redux";
  12. import Taro from "@tarojs/taro";
  13. import { updateRecord } from "@/services/trackTimeDuration";
  14. export default function TotalTime(props: { record: any }) {
  15. const [showDurationPicker, setShowDurationPicker] = useState(false)
  16. const [fastPickerValue, setFastPickerValue] = useState([0, 0])
  17. const [sleepPickerValue, setSleepPickerValue] = useState([0, 0])
  18. const [showEditPicker, setShowEditPicker] = useState(false)
  19. const [count, setCount] = useState(0)
  20. const common = useSelector((state: any) => state.common);
  21. const [isFast, setIsFast] = useState(true)
  22. const durationPickerRef = useRef(null)
  23. const { t } = useTranslation()
  24. useEffect(() => {
  25. getStateDetail()
  26. setCount((pre) => pre + 1)
  27. }, [props.record])
  28. function getStateDetail() {
  29. var current_record = props.record
  30. if (current_record.fast)
  31. setFastPickerValue(durationIndex(current_record.fast.target_start_time, current_record.fast.target_end_time, common))
  32. if (current_record.sleep)
  33. setSleepPickerValue(durationIndex(current_record.sleep.target_start_time, current_record.sleep.target_end_time, common))
  34. }
  35. function sleepCompleteStatus() {
  36. if (props.record.sleep.status == "NOT_STARTED") {
  37. return t('feature.common.not_started')
  38. }
  39. else if (props.record.sleep.status == 'NOT_COMPLETED') {
  40. return t('feature.common.not_completed')
  41. }
  42. return TimeFormatter.durationFormate(props.record.sleep.real_start_time, props.record.sleep.real_end_time)
  43. }
  44. function fastGoingText() {
  45. if (props.record.status == 'WAIT_FOR_START') {
  46. return '00:00:00'
  47. }
  48. return TimeFormatter.formateTimeNow(props.record.fast.real_start_time)
  49. }
  50. function fastEndText() {
  51. if (props.record.status == 'WAIT_FOR_START') {
  52. return TimeFormatter.formateTimeDifference(new Date().getTime(), new Date().getTime() + props.record.fast.target_end_time - props.record.fast.target_start_time)
  53. }
  54. return TimeFormatter.countdown(props.record.fast.target_end_time)
  55. }
  56. function sleepGoingText() {
  57. if (props.record.status == 'WAIT_FOR_START' || props.record.status == 'ONGOING1') {
  58. return '00:00:00'
  59. }
  60. return TimeFormatter.formateTimeNow(props.record.sleep.real_start_time)
  61. }
  62. function sleepEndText() {
  63. if (props.record.status == 'WAIT_FOR_START' || props.record.status == 'ONGOING1') {
  64. return TimeFormatter.formateTimeDifference(new Date().getTime(), new Date().getTime() + props.record.sleep.target_end_time - props.record.sleep.target_start_time)
  65. }
  66. return TimeFormatter.countdown(props.record.sleep.target_end_time)
  67. }
  68. function setFastDuration(e) {
  69. setIsFast(true)
  70. if (disableChange(true)) return
  71. if (process.env.TARO_ENV == 'weapp') {
  72. e.stopPropagation()
  73. }
  74. if (props.record.status == 'WAIT_FOR_START') {
  75. setShowDurationPicker(true)
  76. }
  77. else {
  78. setShowEditPicker(true)
  79. }
  80. }
  81. function setSleepDuration(e) {
  82. setIsFast(false)
  83. if (disableChange(false)) return
  84. if (process.env.TARO_ENV == 'weapp') {
  85. e.stopPropagation()
  86. }
  87. if (props.record.status == 'WAIT_FOR_START') {
  88. Taro.showToast({
  89. title: t('feature.track_time_duration.common.start_fasting_first'),
  90. icon: 'none'
  91. })
  92. return;
  93. }
  94. if (props.record.status == 'WAIT_FOR_START' || props.record.status == 'ONGOING1') {
  95. setShowDurationPicker(true)
  96. }
  97. else {
  98. setShowEditPicker(true)
  99. }
  100. }
  101. function disableChange(isFastStatus) {
  102. if (props.record.status == 'WAIT_FOR_START') {
  103. return false;
  104. }
  105. if (isFastStatus) {
  106. if (props.record.status != 'COMPLETED')
  107. return false;
  108. return true
  109. }
  110. else {
  111. if (props.record.status == 'ONGOING3' || props.record.status == 'COMPLETED') {
  112. return true
  113. }
  114. return false;
  115. }
  116. }
  117. function fastOtherStatus() {
  118. return <View>
  119. <View className="cell_full" >
  120. <Text className="cell_title" style={{ opacity: 0.2 }}>已进行</Text>
  121. <Text className="cell_value"
  122. style={{
  123. color: props.record.status == 'WAIT_FOR_START' ?
  124. '#fff' : ColorType.fast,
  125. opacity: props.record.status == 'WAIT_FOR_START' ? 0.2 : 1
  126. }}>{fastGoingText()}</Text>
  127. </View>
  128. <View className="cell_line" style={{ height: 1 }} />
  129. <View className="cell_full" >
  130. <Text className="cell_title" style={{ opacity: 0.2 }}>{new Date().getTime() < props.record.fast.target_end_time ? '距结束' : '已超时'}</Text>
  131. <Text className="cell_value" style={{ opacity: 0.2 }}>{fastEndText()}</Text>
  132. </View>
  133. </View>
  134. }
  135. function sleepOtherStatus() {
  136. return <View>
  137. <View className="cell_full" >
  138. <Text className="cell_title" style={{ opacity: 0.2 }}>已进行</Text>
  139. <Text className="cell_value" style={{
  140. color: props.record.status == 'WAIT_FOR_START' || props.record.status == 'ONGOING1' ?
  141. '#fff' : ColorType.sleep,
  142. opacity: props.record.status == 'WAIT_FOR_START' || props.record.status == 'ONGOING1' ? 0.2 : 1
  143. }}>{sleepGoingText()}</Text>
  144. </View>
  145. <View className="cell_line" style={{ height: 1 }} />
  146. <View className="cell_full" >
  147. <Text className="cell_title" style={{ opacity: 0.2 }}>{new Date().getTime() < props.record.sleep.target_end_time ? '距结束' : '已超时'}</Text>
  148. <Text className="cell_value" style={{ opacity: 0.2 }}>{sleepEndText()}</Text>
  149. </View>
  150. </View>
  151. }
  152. function durationPickerContent() {
  153. var color = getColor(props.record)
  154. var title = getDurationTitle(props.record, t)
  155. return <View style={{ color: '#fff', backgroundColor: 'transparent' }}>
  156. <PickerViews ref={durationPickerRef}
  157. onChange={durationChange}
  158. items={durationDatas(common)}
  159. value={isFast ? fastPickerValue : sleepPickerValue}
  160. themeColor={color}
  161. title={title}
  162. showBtns={true}
  163. onCancel={() => {
  164. setShowDurationPicker(false)
  165. }} />
  166. </View>
  167. }
  168. function editPickerContent() {
  169. return <View style={{ color: '#fff', backgroundColor: 'transparent' }}>
  170. <PickerViews ref={durationPickerRef}
  171. onChange={durationChange}
  172. items={durationDatas(common)}
  173. value={isFast ? fastPickerValue : sleepPickerValue}
  174. themeColor={isFast ? ColorType.fast : ColorType.sleep}
  175. title={isFast ? t('feature.track_time_duration.action_sheet.edit_fasting_goal') :
  176. t('feature.track_time_duration.action_sheet.edit_sleeping_goal')}
  177. showBtns={true}
  178. onCancel={() => {
  179. setShowEditPicker(false)
  180. }} />
  181. </View>
  182. }
  183. function durationChange(e) {
  184. // debugger
  185. var count = (e[0] + common.duration.min) * 60 + e[1] * common.duration.step
  186. // var count = (e[0] + 1) * 60 + e[1] * 5
  187. if (showDurationPicker) {
  188. global.changeTargetDuration(count, isFast)
  189. }
  190. else {
  191. var params: any = {}
  192. if (isFast) {
  193. params = {
  194. fast: {
  195. target_duration: count * 60 * 1000
  196. }
  197. }
  198. }
  199. else {
  200. params = {
  201. sleep: {
  202. target_duration: count * 60 * 1000
  203. }
  204. }
  205. }
  206. updateRecord({
  207. ...params
  208. }, props.record.id).then(res => {
  209. global.indexPageRefresh()
  210. }).catch(e => {
  211. })
  212. }
  213. setShowDurationPicker(false)
  214. setShowEditPicker(false)
  215. }
  216. function modalContent() {
  217. if (showDurationPicker || showEditPicker) {
  218. if (process.env.TARO_ENV == 'weapp') {
  219. return <Modal
  220. testInfo={null}
  221. dismiss={() => {
  222. setShowDurationPicker(false)
  223. setShowEditPicker(false)
  224. }}
  225. confirm={() => { }}>
  226. {
  227. showDurationPicker ? durationPickerContent() : editPickerContent()
  228. }
  229. </Modal>
  230. }
  231. else if (process.env.TARO_ENV == 'rn') {
  232. return <PageContainer style={{ backgroundColor: '#1c1c1c' }}
  233. // overlayStyle='background-color:rgba(0,0,0,0.9)'
  234. // custom-style='background-color:#1c1c1c'
  235. overlayStyle={{ backgroundColor: 'rgba(0,0,0,0.9)' }}
  236. customStyle={{ backgroundColor: '#1c1c1c' }}
  237. closeOnSlideDown={false}
  238. onBeforeEnter={() => {
  239. }}
  240. onBeforeLeave={() => {
  241. }}
  242. onClick={() => { alert('b') }}
  243. onClickOverlay={() => { alert('a') }}
  244. onAfterLeave={() => { setShowDurationPicker(false); setShowEditPicker(false) }}
  245. show={showDurationPicker} round={true} overlay={true} position='bottom'
  246. >
  247. {
  248. showDurationPicker ? durationPickerContent() : editPickerContent()
  249. }
  250. </PageContainer>
  251. }
  252. }
  253. return <View />
  254. }
  255. return <View style={{ width: rpxToPx(600) }}>
  256. {
  257. props.record.fast && <View>
  258. <Text className="cell_header">断食</Text>
  259. <View className="cell_bg">
  260. {
  261. props.record.status == 'COMPLETED' ?
  262. <View className="cell_full" >
  263. <Text className="cell_title">{t('feature.track_time_duration.console.real_duration')}</Text>
  264. <Text className="cell_value" style={{ color: ColorType.fast }}>{TimeFormatter.durationFormate(props.record.fast.real_start_time, props.record.fast.real_end_time)}</Text>
  265. {/* <Image className="cell_arrow" src={require('@/assets/images/arrow3.png')} /> */}
  266. </View> :
  267. <View className="cell_full" onClick={setFastDuration}>
  268. <Text className="cell_title">{t('feature.track_time_duration.console.target')}</Text>
  269. <Text className="cell_value">{TimeFormatter.durationFormate(props.record.fast.target_start_time, props.record.fast.target_end_time)}</Text>
  270. {!disableChange(true) && <Image className="cell_arrow" src={require('@/assets/images/arrow3.png')} />}
  271. </View>
  272. }
  273. <View className="cell_line" style={{ height: 1 }} />
  274. {
  275. props.record.status == 'COMPLETED' ?
  276. <View className="cell_full" onClick={setFastDuration}>
  277. <Text className="cell_title" style={{ opacity: 0.2 }}>{t('feature.track_time_duration.console.target')}</Text>
  278. <Text className="cell_value" style={{ opacity: 0.2, color: '#fff' }}>{TimeFormatter.durationFormate(props.record.fast.target_start_time, props.record.fast.target_end_time)}</Text>
  279. {!disableChange(true) && <Image className="cell_arrow" src={require('@/assets/images/arrow3.png')} />}
  280. </View> :
  281. fastOtherStatus()
  282. }
  283. </View>
  284. </View>
  285. }
  286. {
  287. props.record.sleep && <View style={{ marginTop: 10 }}>
  288. <Text className="cell_header">睡眠</Text>
  289. <View className="cell_bg">
  290. {
  291. // props.record.status == 'COMPLETED' || props.record.status == 'ONGOING3' ?
  292. // <View className="cell_full" >
  293. // <Text className="cell_title">{t('feature.track_time_duration.console.real_duration')}</Text>
  294. // <Text className="cell_value" style={{ color: ColorType.sleep }}>{sleepCompleteStatus()}</Text>
  295. // </View> :
  296. <View className="cell_full" onClick={setSleepDuration}>
  297. <Text className="cell_title">{t('feature.track_time_duration.console.target')}</Text>
  298. <Text className="cell_value">{TimeFormatter.durationFormate(props.record.sleep.target_start_time, props.record.sleep.target_end_time)}</Text>
  299. {!disableChange(false) && <Image className="cell_arrow" src={require('@/assets/images/arrow3.png')} />}
  300. </View>
  301. }
  302. <View className="cell_line" style={{ height: 1 }} />
  303. {
  304. props.record.status == 'COMPLETED' || props.record.status == 'ONGOING3' ?
  305. // <View className="cell_full" onClick={setSleepDuration}>
  306. // <Text className="cell_title" style={{ opacity: 0.2 }}>{t('feature.track_time_duration.console.target')}</Text>
  307. // <Text className="cell_value" style={{ opacity: 0.2, color: '#fff' }}>{TimeFormatter.durationFormate(props.record.sleep.target_start_time, props.record.sleep.target_end_time)}</Text>
  308. // {!disableChange(false) && <Image className="cell_arrow" src={require('@/assets/images/arrow3.png')} />}
  309. // </View>
  310. <View className="cell_full" >
  311. <Text className="cell_title" style={{ opacity: 0.4 }}>{t('feature.track_time_duration.console.real_duration')}</Text>
  312. <Text className="cell_value" style={{ color: ColorType.sleep }}>{sleepCompleteStatus()}</Text>
  313. </View>
  314. :
  315. sleepOtherStatus()
  316. }
  317. </View>
  318. </View>
  319. }
  320. {
  321. modalContent()
  322. }
  323. </View>
  324. }