SetSchedule.rn.tsx 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475
  1. import Buttons from "@/components/basic/Buttons";
  2. import { setPlan } from "@/services/trackTimeDuration";
  3. import { setScenario, setStep } from "@/store/scenario";
  4. import { View, Text, PageContainer, Image } from "@tarojs/components";
  5. import "./SetSchedule.scss";
  6. import Taro, { useDidShow, useReady } from "@tarojs/taro";
  7. import { useEffect, useRef, useState } from "react";
  8. import { useDispatch, useSelector } from "react-redux";
  9. import Footer from "@/components/layout/Footer";
  10. import PickerViews from "@/components/input/PickerViews";
  11. import { durationDatas, durationIndex, durationTime, pickerDurations } from "../hooks/Console";
  12. import { TimeFormatter } from "@/utils/time_format";
  13. import Modal from "@/components/layout/Modal";
  14. import TimePicker from "@/features/common/TimePicker";
  15. import { SetScheduleBtn } from "@/features/common/SpecBtns";
  16. import Layout from "@/components/layout/layout";
  17. import { NaviBarTitleShowType, TemplateType } from "@/utils/types";
  18. import { useTranslation } from "react-i18next";
  19. import { ColorType } from "@/context/themes/color";
  20. import TitleView from "./TitleView";
  21. import { jumpPage } from "../hooks/Common";
  22. import { rpxToPx, vibrate } from "@/utils/tools";
  23. import { PixelRatio } from "react-native";
  24. let useNavigation;
  25. if (process.env.TARO_ENV == 'rn') {
  26. useNavigation = require("@react-navigation/native").useNavigation
  27. }
  28. export default function Component() {
  29. const isFastFirst = true;
  30. const { t } = useTranslation()
  31. const dispatch = useDispatch();
  32. const canvasRef = useRef(null);
  33. const [scenario] = useState(useSelector((state: any) => state.scenario))
  34. // const scenario = useSelector((state: any) => state.scenario);
  35. const common = useSelector((state: any) => state.common);
  36. const [isOpen, setIsOpen] = useState(false)
  37. const [isTimeOpen, setIsTimeOpen] = useState(false)
  38. const [btnDisable, setBtnDisable] = useState(false)
  39. const pickerRef = useRef<any>(null);
  40. // const [count,setCount] = useState(0)
  41. const [beginChange, setBeginChange] = useState(true)
  42. const [operateType, setOperateType] = useState(0)
  43. const [isModalTimePicker, setIsModalTimePicker] = useState(false)
  44. let navigation;
  45. if (useNavigation) {
  46. navigation = useNavigation()
  47. }
  48. var scheduleObj: { start_time: any; end_time: any; };
  49. if (scenario.name == 'FAST') {
  50. scheduleObj = scenario.schedule.fast
  51. }
  52. else if (scenario.name == 'SLEEP') {
  53. scheduleObj = scenario.schedule.sleep
  54. }
  55. else {
  56. if (scenario.step == 'fast') {
  57. scheduleObj = scenario.schedule.fast
  58. }
  59. else {
  60. scheduleObj = scenario.schedule.sleep
  61. }
  62. }
  63. const [startTime, setStartTime] = useState(scheduleObj.start_time)
  64. const [endTime, setEndTime] = useState(scheduleObj.end_time)
  65. global.startTime = startTime
  66. global.endTime = endTime
  67. const [pickerValue, setPickerValue] = useState(durationIndex(scheduleObj.start_time, scheduleObj.end_time, common))
  68. const [hours, setHours] = useState(durationTime(scheduleObj.start_time, scheduleObj.end_time)[0])
  69. const [minutes, setMinutes] = useState(durationTime(scheduleObj.start_time, scheduleObj.end_time)[1])
  70. const [chooseStart, setChooseStart] = useState(true)
  71. const [count, setCount] = useState(0)
  72. useEffect(() => {
  73. if (global.schedule_fast && scenario.step == 'fast') {
  74. scheduleObj = global.schedule_fast
  75. }
  76. if (global.schedule_sleep && scenario.step == 'sleep') {
  77. scheduleObj = global.schedule_sleep
  78. }
  79. setStartTime(scheduleObj.start_time)
  80. setEndTime(scheduleObj.end_time)
  81. setPickerValue(durationIndex(scheduleObj.start_time, scheduleObj.end_time, common))
  82. setHours(durationTime(scheduleObj.start_time, scheduleObj.end_time)[0])
  83. setMinutes(durationTime(scheduleObj.start_time, scheduleObj.end_time)[1])
  84. }, [])
  85. useEffect(() => {
  86. if (isOpen || isTimeOpen) {
  87. global.disableCanvasGesture = true
  88. }
  89. else {
  90. global.disableCanvasGesture = false
  91. }
  92. }, [isOpen, isTimeOpen])
  93. useDidShow(() => {
  94. setCount(count + 1)
  95. })
  96. function start() {
  97. if (scenario.name == 'FAST' || scenario.name == 'SLEEP') {
  98. setBtnDisable(true)
  99. setPlan({
  100. scenario: scenario.name,
  101. schedule: scenario.name == 'FAST' ? {
  102. fast: {
  103. start_time: startTime,
  104. end_time: endTime,
  105. }
  106. } : {
  107. sleep: {
  108. start_time: startTime,
  109. end_time: endTime,
  110. }
  111. }
  112. }).then(res => {
  113. setBtnDisable(false)
  114. global.checkData()
  115. global.indexPageRefresh()
  116. if (process.env.TARO_ENV == 'weapp') {
  117. Taro.navigateBack({ delta: 3 })
  118. }
  119. else {
  120. navigation.popToTop()
  121. }
  122. }).catch(e => {
  123. setBtnDisable(false)
  124. })
  125. }
  126. else {
  127. if ((scenario.step == 'fast' && isFastFirst) || (scenario.step == 'sleep' && !isFastFirst)) {
  128. var obj = JSON.parse(JSON.stringify(scenario))
  129. if (isFastFirst) {
  130. obj.schedule.fast = {
  131. start_time: startTime,
  132. end_time: endTime,
  133. }
  134. dispatch(setStep('sleep'))
  135. dispatch(setScenario(obj))
  136. }
  137. else {
  138. obj.schedule.sleep = {
  139. start_time: startTime,
  140. end_time: endTime,
  141. }
  142. dispatch(setStep('fast'))
  143. dispatch(setScenario(obj))
  144. }
  145. saveTempCache(startTime, endTime)
  146. jumpPage('/pages/clock/SetSchedule', 'SetSchedule', navigation)
  147. }
  148. else {
  149. commit()
  150. }
  151. }
  152. }
  153. function saveTempCache(strStart, strEnd) {
  154. if (scenario.step == 'fast') {
  155. global.schedule_fast = {
  156. start_time: strStart,
  157. end_time: strEnd,
  158. }
  159. }
  160. if (scenario.step == 'sleep') {
  161. global.schedule_sleep = {
  162. start_time: strStart,
  163. end_time: strEnd,
  164. }
  165. }
  166. }
  167. function commit() {
  168. setBtnDisable(true)
  169. setPlan({
  170. scenario: scenario.name,
  171. schedule: {
  172. fast: {
  173. start_time: isFastFirst ? scenario.schedule.fast.start_time : startTime,
  174. end_time: isFastFirst ? scenario.schedule.fast.end_time : endTime,
  175. }, sleep: {
  176. start_time: !isFastFirst ? scenario.schedule.sleep.start_time : startTime,
  177. end_time: !isFastFirst ? scenario.schedule.sleep.end_time : endTime,
  178. }
  179. }
  180. }).then(res => {
  181. setBtnDisable(false)
  182. dispatch(setStep('fast'))
  183. global.checkData()
  184. if (process.env.TARO_ENV == 'weapp') {
  185. Taro.navigateBack({ delta: 4 })
  186. }
  187. else {
  188. navigation.popToTop()
  189. }
  190. }).catch(e => {
  191. setBtnDisable(false)
  192. })
  193. }
  194. function onStartTimeChange(e: string) {
  195. setIsTimeOpen(false)
  196. setBeginChange(true)
  197. setStartTime(e)
  198. setPickerValue(durationIndex(e, endTime, common))
  199. setHours(durationTime(e, endTime)[0])
  200. setMinutes(durationTime(e, endTime)[1])
  201. saveTempCache(e, endTime);
  202. if (global.updateDial)
  203. global.updateDial(e, endTime)
  204. }
  205. function onEndTimeChange(e: string) {
  206. setIsTimeOpen(false)
  207. setBeginChange(false)
  208. setEndTime(e)
  209. setPickerValue(durationIndex(startTime, e, common))
  210. setHours(durationTime(startTime, e)[0])
  211. setMinutes(durationTime(startTime, e)[1])
  212. saveTempCache(startTime, e);
  213. if (global.updateDial)
  214. global.updateDial(startTime, e)
  215. }
  216. function showPicker() {
  217. setIsOpen(true)
  218. }
  219. function durationChange(e) {
  220. var count = (e[0] + common.duration.min) * 60 + e[1] * common.duration.step
  221. var h = parseInt(count / 60)
  222. var m = count % 60
  223. setHours(h)
  224. setMinutes(m)
  225. setPickerValue(e)
  226. setIsOpen(false)
  227. if (beginChange) {
  228. var strEnd = TimeFormatter.calculateTimeByTimeRange(count, startTime, true)
  229. setEndTime(strEnd);
  230. saveTempCache(startTime, strEnd)
  231. if (global.updateDial)
  232. global.updateDial(startTime, strEnd)
  233. }
  234. else {
  235. var strStart = TimeFormatter.calculateTimeByTimeRange(count, endTime, false)
  236. setStartTime(strStart);
  237. saveTempCache(strStart, endTime)
  238. if (global.updateDial)
  239. global.updateDial(strStart, endTime)
  240. }
  241. }
  242. global.startDuration = (type) => {
  243. setOperateType(type)
  244. }
  245. global.updateDuration = (start, end) => {
  246. var startCount = parseInt(start.split(':')[0]) * 60 + parseInt(start.split(':')[1])
  247. var endCount = parseInt(end.split(':')[0]) * 60 + parseInt(end.split(':')[1])
  248. if (operateType == 1 && startCount % 30 == 0) {
  249. vibrate()
  250. }
  251. else if (operateType == 2 && endCount % 30 == 0) {
  252. vibrate()
  253. }
  254. else if (operateType == 3 && (startCount % 30 == 0 || endCount % 30 == 0)) {
  255. vibrate()
  256. }
  257. setStartTime(start)
  258. setEndTime(end)
  259. setPickerValue(durationIndex(start, end, common))
  260. setHours(durationTime(start, end)[0])
  261. setMinutes(durationTime(start, end)[1])
  262. saveTempCache(start, end)
  263. }
  264. global.endDuration = () => {
  265. setOperateType(0)
  266. }
  267. function layoutContent() {
  268. return <PickerViews ref={pickerRef}
  269. onChange={durationChange}
  270. items={durationDatas(common)}
  271. value={pickerValue} height={200}
  272. title={scenario.step == 'fast' ?
  273. t('feature.track_time_duration.dial.picker_fast_schedule_duration') :
  274. t('feature.track_time_duration.dial.picker_sleep_schedule_duration')}
  275. themeColor={scenario.step == 'fast' ? global.fastColor ? global.fastColor : ColorType.fast : global.sleepColor ? global.sleepColor : ColorType.sleep}
  276. showBtns={true} onCancel={() => { setIsOpen(false); }} />
  277. }
  278. function pickerTitle() {
  279. if (scenario.step == 'fast') {
  280. if (chooseStart) {
  281. return t('feature.track_time_duration.dial.picker_fast_schedule_start_time');
  282. }
  283. return t('feature.track_time_duration.dial.picker_fast_schedule_end_time');
  284. }
  285. else {
  286. if (chooseStart) {
  287. return t('feature.track_time_duration.dial.picker_sleep_schedule_start_time');
  288. }
  289. return t('feature.track_time_duration.dial.picker_sleep_schedule_end_time');
  290. }
  291. }
  292. function timeContent() {
  293. return <TimePicker time={chooseStart ? startTime : endTime}
  294. color={scenario.step == 'fast' ? global.fastColor ? global.fastColor : ColorType.fast : global.sleepColor ? global.sleepColor : ColorType.sleep}
  295. title={pickerTitle()}
  296. confirm={chooseStart ? onStartTimeChange : onEndTimeChange}
  297. cancel={() => { setIsTimeOpen(false) }} />
  298. }
  299. function getTargetDesc() {
  300. var count = 24*60-(hours * 60 + minutes)
  301. var leftHours = Math.floor(count/60)
  302. var leftMinutes = count%60
  303. return scenario.step == 'fast' ? t('page.set_schedule.fast_target_desc', {
  304. target_time: (hours > 0 ? hours + TimeFormatter.getHoursUnit(hours) : '') + (minutes > 0 ? minutes + TimeFormatter.getMinutesUnit(minutes) : ''),
  305. left_time: (leftHours > 0 ? leftHours + TimeFormatter.getHoursUnit(leftHours) : '') + (leftMinutes > 0 ? leftMinutes + TimeFormatter.getMinutesUnit(leftMinutes) : '')
  306. }) :
  307. t('page.set_schedule.sleep_target_desc', {
  308. target_time: (hours > 0 ? hours + TimeFormatter.getHoursUnit(hours) : '') + (minutes > 0 ? minutes + TimeFormatter.getMinutesUnit(minutes) : ''),
  309. left_time: (leftHours > 0 ? leftHours + TimeFormatter.getHoursUnit(leftHours) : '') + (leftMinutes > 0 ? leftMinutes + TimeFormatter.getMinutesUnit(leftMinutes) : '')
  310. })
  311. }
  312. function detail() {
  313. var isNextDay: boolean = parseInt(startTime.split(':')[0]) * 60 + parseInt(startTime.split(':')[1]) > parseInt(endTime.split(':')[0]) * 60 + parseInt(endTime.split(':')[1])
  314. return <View style={{ height: Taro.getSystemInfoSync().screenHeight - 200, flexDirection: 'column', display: 'flex' }}>
  315. {/* <Text className="subtitle">{t('page.set_schedule.fast_subtitle')}</Text> */}
  316. <TitleView title={scenario.step == 'fast' ? t('page.set_schedule.fast_title') : t('page.set_schedule.sleep_title')}
  317. subTitle={t('page.set_schedule.fast_subtitle')}
  318. titleColor={scenario.step == 'fast' ? global.fastColor ? global.fastColor : ColorType.fast : global.sleepColor ? global.sleepColor : ColorType.sleep}
  319. />
  320. <View style={{ color: '#fff', marginTop: rpxToPx(64) }}>
  321. <Text className="cell_header">{scenario.step == 'fast' ? t('page.set_schedule.fast_target') : t('page.set_schedule.sleep_target')}</Text>
  322. <View className="cell_full" onClick={() => { setIsModalTimePicker(false); setIsOpen(true) }}>
  323. <Text className="cell_title">{t('feature.track_time_duration.dial.duration')}</Text>
  324. <Text className="cell_value" style={{ color: scenario.step == 'fast' ? ColorType.fast : ColorType.sleep }}>{hours > 0 ? hours + TimeFormatter.getHoursUnit(hours) : ''}{minutes > 0 ? minutes + TimeFormatter.getMinutesUnit(minutes) : ''}</Text>
  325. <Image className="cell_arrow" src={require('@/assets/images/arrow3.png')} />
  326. </View>
  327. <Text className="cell_footer">{getTargetDesc()}</Text>
  328. <View style={{ height: rpxToPx(60) }} />
  329. <Text className="cell_header">{scenario.step == 'fast' ? t('page.set_schedule.fast_schedule') : t('page.set_schedule.sleep_schedule')}</Text>
  330. <View className="cell_top" onClick={() => {
  331. setIsModalTimePicker(true)
  332. setChooseStart(true)
  333. setIsTimeOpen(true)
  334. }}>
  335. <Text className="cell_title">{t('feature.track_time_duration.dial.start_time')}</Text>
  336. <Text className="cell_value" style={{ color: scenario.step == 'fast' ? ColorType.fast : ColorType.sleep }}>{startTime}</Text>
  337. <Image className="cell_arrow" src={require('@/assets/images/arrow3.png')} />
  338. <View className="cell_line" style={{ height: 1 / PixelRatio.get() }} />
  339. </View>
  340. <View className="cell_bottom" onClick={() => {
  341. setIsModalTimePicker(true)
  342. setChooseStart(false)
  343. setIsTimeOpen(true)
  344. }}>
  345. <Text className="cell_title">{t('feature.track_time_duration.dial.end_time')}</Text>
  346. {
  347. isNextDay &&
  348. <Text className="next_day">{t('page.set_schedule.next_day')}</Text>
  349. }
  350. <Text className="cell_value" style={{ color: scenario.step == 'fast' ? ColorType.fast : ColorType.sleep }}>{endTime}</Text>
  351. <Image className="cell_arrow" src={require('@/assets/images/arrow3.png')} />
  352. </View>
  353. <Text className="cell_footer">{scenario.step == 'fast' ? t('page.set_schedule.fast_schedule_desc', {
  354. start_time: startTime, end_time: endTime, the_next_day:
  355. isNextDay ? t('page.set_schedule.the_next_day') : ''
  356. }) :
  357. t('page.set_schedule.sleep_schedule_desc', {
  358. start_time: startTime, end_time: endTime, the_next_day:
  359. isNextDay ? t('page.set_schedule.the_next_day') : ''
  360. })}</Text>
  361. {/* <Text className="cell_footer">计划每日18:00开始断食,次日10:00结束断食。</Text> */}
  362. </View>
  363. <View style={{ flex: 1 }} />
  364. <Footer>
  365. <SetScheduleBtn title={(scenario.step == 'fast' && scenario.name == 'FAST_SLEEP') ? t('feature.common.btn_set_and_next') : t('feature.common.btn_set_and_done')}
  366. lowLight={operateType != 0}
  367. isFast={scenario.step == 'fast'}
  368. disable={btnDisable}
  369. onClick={() => start()} />
  370. </Footer>
  371. {
  372. (isOpen || isTimeOpen) && <PageContainer style={{ backgroundColor: '#1c1c1c' }}
  373. overlayStyle={{ backgroundColor: 'rgba(0,0,0,0.9)' }}
  374. customStyle={{ backgroundColor: '#1c1c1c' }}
  375. closeOnSlideDown={false}
  376. onAfterLeave={() => { setIsOpen(false); setIsTimeOpen(false) }}
  377. show={isOpen || isTimeOpen} round={true} overlay={true} position='bottom'
  378. >
  379. {
  380. isTimeOpen ? timeContent() : layoutContent()
  381. }
  382. </PageContainer>
  383. }
  384. {/* <PageContainer style={{ backgroundColor: '#1c1c1c' }}
  385. overlayStyle='background-color:rgba(0,0,0,0.9)'
  386. custom-style='background-color:#1c1c1c'
  387. closeOnSlideDown={false}
  388. onAfterLeave={() => { setIsOpen(false); setIsTimeOpen(false) }}
  389. show={isOpen || isTimeOpen} round={true} overlay={true} position='bottom'
  390. >
  391. {
  392. isModalTimePicker?timeContent():layoutContent()
  393. }
  394. </PageContainer> */}
  395. {/* {
  396. isOpen && <Modal children={layoutContent()} dismiss={() => setIsOpen(false)} confirm={() => {
  397. setIsOpen(false)
  398. durationChange(pickerRef.current.getConfirmData())
  399. }} />
  400. }
  401. {
  402. isTimeOpen && <Modal children={timeContent()} dismiss={() => setIsTimeOpen(false)} confirm={() => {
  403. setIsTimeOpen(false)
  404. }} />
  405. } */}
  406. </View>
  407. }
  408. return <Layout
  409. titleColor={scenario.step == 'fast' ? global.fastColor ? global.fastColor : ColorType.fast : global.sleepColor ? global.sleepColor : ColorType.sleep}
  410. title={scenario.step == 'fast' ? t('page.set_schedule.fast_title') : t('page.set_schedule.sleep_title')}
  411. titleShowStyle={NaviBarTitleShowType.scrollToShow} type={TemplateType.customHeader}>
  412. {
  413. detail()
  414. }
  415. </Layout>;
  416. }