IndexConsole.tsx 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910
  1. import { View, Text, Image, PageContainer } from '@tarojs/components'
  2. import './IndexConsole.scss'
  3. import { useTranslation } from 'react-i18next'
  4. import { useDispatch, useSelector } from 'react-redux';
  5. import { endFast, endSleep, startFast, startSleep, uploadLocalPushInfo } from "../actions/TrackTimeActions";
  6. import { jumpPage } from '../hooks/Common';
  7. import { useContext, useEffect, useRef, useState } from 'react';
  8. import ConsolePicker from './ConsolePicker';
  9. import LimitPickers from '@/components/input/LimitPickers';
  10. import LimitTimeoutPickers from '@/components/input/LimitTimeoutPickers';
  11. import { getColor, getTimePickerTitle } from '../hooks/Console';
  12. import { rpxToPx, vibrate } from '@/utils/tools';
  13. import { TimeFormatter } from '@/utils/time_format';
  14. import Modal from '@/components/layout/Modal.weapp';
  15. import Taro, { useDidShow } from '@tarojs/taro';
  16. import { wxPubFollow } from '@/services/permission';
  17. import { setWXFollow } from '@/store/permission';
  18. import CircadianDetailPopup from './CircadianDetailPopup';
  19. import showAlert from '@/components/basic/Alert';
  20. import CheckAccess from './CheckAccess';
  21. let useNavigation;
  22. let Linking;
  23. let JPush, checkNotification;
  24. if (process.env.TARO_ENV == 'rn') {
  25. useNavigation = require("@react-navigation/native").useNavigation
  26. Linking = require('react-native').Linking;
  27. JPush = require('jpush-react-native').default;
  28. checkNotification = require('@/utils/native_permission_check').checkNotification;
  29. }
  30. let operateType = ''
  31. let min = 0
  32. let max = 0
  33. let defaultTimestamp = 0
  34. let isTimeout = false
  35. let stageIndex = 0
  36. let nativePushListener = null
  37. export default function IndexConsole(props: { record: any, count: number }) {
  38. const user = useSelector((state: any) => state.user);
  39. const { status } = props.record.current_record;
  40. const currentRecord = props.record.current_record;
  41. const { t } = useTranslation()
  42. const [fastDuration, setFastDuration] = useState<number>(0);
  43. const [sleepDuration, setSleepDuration] = useState<number>(0);
  44. const [expand, setExpand] = useState(false);
  45. const permission = useSelector((state: any) => state.permission);
  46. const common = useSelector((state: any) => state.common);
  47. const [firstEnter, setFirstEnter] = useState(true);
  48. const [showTimePicker, setShowTimePicker] = useState(false);
  49. const dayMilliSeconds = 24 * 3600 * 1000;
  50. const [btnDisable, setBtnDisable] = useState(false)
  51. const [showStageModal, setShowStageModal] = useState(false)
  52. const dispatch = useDispatch();
  53. const limitPickerRef = useRef(null)
  54. let navigation;
  55. if (useNavigation) {
  56. navigation = useNavigation()
  57. }
  58. useDidShow(() => {
  59. if (process.env.TARO_ENV == 'weapp') {
  60. wxPubFollow({ force_refresh: true }).then(res => {
  61. dispatch(setWXFollow((res as any).wx_pub_followed));
  62. })
  63. }
  64. })
  65. useEffect(() => {
  66. if (process.env.TARO_ENV == 'rn') {
  67. // console.error('current status',status)
  68. if (Taro.getSystemInfoSync().platform == 'ios') {
  69. var Jto = require('react-native').NativeModules.NativeBridge;
  70. var NativeAppEventEmitter = require('react-native').NativeAppEventEmitter;
  71. Jto.getNotificationAuthStatus()
  72. if (nativePushListener){
  73. (nativePushListener as any).remove()
  74. }
  75. nativePushListener = NativeAppEventEmitter.addListener('notificationReceive', (data) => {
  76. console.log('notification receive action', data)
  77. const { category_id, action_id,id } = data
  78. uploadLocalPushInfo({
  79. messageId:id
  80. })
  81. console.log(props.record)
  82. switch (action_id) {
  83. case 'START_TIMER_NOW':
  84. {
  85. if (category_id == 'REMINDER_FS_START_FAST'){
  86. operateType = 'startFast'
  87. }
  88. else {
  89. operateType = 'startSleep'
  90. }
  91. global.set_time = new Date().getTime()
  92. pickerConfirm(new Date().getTime())
  93. }
  94. break;
  95. case 'PICK_EARLIER_START':
  96. {
  97. if (category_id == 'REMINDER_FS_START_FAST'){
  98. tapStartFast(null)
  99. }
  100. else {
  101. tapStartSleep(null)
  102. }
  103. }
  104. break;
  105. case 'END_TIMER_NOW':
  106. {
  107. if (category_id == 'REMINDER_FS_END_FAST'){
  108. operateType = 'endFast'
  109. }
  110. else {
  111. operateType = 'endSleep'
  112. }
  113. global.set_time = new Date().getTime()
  114. pickerConfirm(new Date().getTime())
  115. }
  116. break;
  117. case 'PICK_EARLIER_END':
  118. {
  119. if (category_id == 'REMINDER_FS_END_FAST'){
  120. tapEndFast(null)
  121. }
  122. else {
  123. tapEndSleep(null)
  124. }
  125. }
  126. break;
  127. case 'SKIP':
  128. break;
  129. }
  130. })
  131. }
  132. }
  133. }, [props.record])
  134. useEffect(() => {
  135. if (currentRecord.fast) {
  136. var fastCount = currentRecord.fast.target_end_time - currentRecord.fast.target_start_time
  137. setFastDuration(fastCount)
  138. }
  139. if (currentRecord.sleep) {
  140. var sleepCount = currentRecord.sleep.target_end_time - currentRecord.sleep.target_start_time
  141. setSleepDuration(sleepCount)
  142. }
  143. if (props.record.current_record.status == 'WAIT_FOR_START') {
  144. setExpand(false)
  145. }
  146. }, [props.record])
  147. function tapStartFast(e) {
  148. if (process.env.TARO_ENV == 'weapp') {
  149. e.stopPropagation()
  150. }
  151. if (!user.isLogin) {
  152. jumpPage('/pages/account/ChooseAuth', 'ChooseAuth', navigation)
  153. return
  154. }
  155. operateType = 'startFast'
  156. global.pauseIndexTimer = true
  157. global.set_time = new Date().getTime()
  158. defaultTimestamp = new Date().getTime()
  159. min = defaultTimestamp - 6 * 24 * 3600 * 1000
  160. max = defaultTimestamp
  161. isTimeout = false
  162. setShowTimePicker(true)
  163. // showPicker()
  164. }
  165. function tapStartSleep(e) {
  166. if (process.env.TARO_ENV == 'weapp') {
  167. e.stopPropagation()
  168. }
  169. if (!user.isLogin) {
  170. jumpPage('/pages/account/ChooseAuth', 'ChooseAuth')
  171. return
  172. }
  173. if (status != 'ONGOING1' && props.record.scenario.name == 'FAST_SLEEP') {
  174. if (status == 'WAIT_FOR_START') {
  175. Taro.showToast({
  176. title: t('feature.track_time_duration.console.lock_fast_tip'),
  177. icon: 'none'
  178. })
  179. }
  180. vibrate()
  181. return;
  182. }
  183. operateType = 'startSleep'
  184. global.pauseIndexTimer = true
  185. global.set_time = new Date().getTime()
  186. isTimeout = false
  187. if (props.record.scenario.name == 'SLEEP') {
  188. defaultTimestamp = new Date().getTime()
  189. min = defaultTimestamp - 6 * dayMilliSeconds
  190. max = defaultTimestamp
  191. }
  192. else {
  193. //todolist
  194. var now = new Date().getTime()
  195. var last_check_time = props.record.current_record.last_real_check_time
  196. if (now - last_check_time >= dayMilliSeconds) {
  197. //ongoing1 严重超时单独处理
  198. // var schedule_start_time = props.record.current_record.sleep.target_start_time
  199. // defaultTimestamp = Math.min(now, schedule_start_time)
  200. // min = Math.max(last_check_time, schedule_start_time - 3 * dayMillionSeconds)
  201. // max = Math.min(now, schedule_start_time + 3 * dayMillionSeconds)
  202. defaultTimestamp = now
  203. min = Math.max(last_check_time, defaultTimestamp - 6 * dayMilliSeconds)
  204. max = defaultTimestamp
  205. }
  206. else {
  207. defaultTimestamp = now
  208. min = Math.max(last_check_time, defaultTimestamp - 6 * dayMilliSeconds)
  209. max = defaultTimestamp
  210. }
  211. }
  212. setShowTimePicker(true)
  213. // showPicker()
  214. }
  215. function tapEndSleep(e) {
  216. if (process.env.TARO_ENV == 'weapp') {
  217. e.stopPropagation()
  218. }
  219. if (!user.isLogin) {
  220. jumpPage('/pages/account/ChooseAuth', 'ChooseAuth')
  221. return
  222. }
  223. if (status != 'ONGOING2' && status != 'ONGOING') {
  224. Taro.showToast({
  225. title: t('feature.track_time_duration.console.lock_sleep_tip'),
  226. icon: 'none'
  227. })
  228. vibrate()
  229. return;
  230. }
  231. operateType = 'endSleep'
  232. global.pauseIndexTimer = true
  233. global.set_time = new Date().getTime()
  234. var real_start_time = props.record.current_record.sleep.real_start_time
  235. var last_check_time = props.record.current_record.last_real_check_time
  236. var now = new Date().getTime()
  237. if (now - real_start_time >= dayMilliSeconds) {
  238. //严重超时
  239. isTimeout = true
  240. // defaultTimestamp = Math.min(props.record.current_record.sleep.target_end_time, now)
  241. // min = Math.max(last_check_time, defaultTimestamp - 3 * dayMillionSeconds)
  242. // max = Math.min(now, defaultTimestamp + 3 * dayMillionSeconds)
  243. defaultTimestamp = now
  244. min = Math.max(last_check_time, defaultTimestamp - 6 * dayMilliSeconds)
  245. max = defaultTimestamp
  246. }
  247. else {
  248. isTimeout = false
  249. defaultTimestamp = now
  250. min = Math.max(last_check_time, defaultTimestamp - 6 * dayMilliSeconds)
  251. max = defaultTimestamp
  252. }
  253. setShowTimePicker(true)
  254. // if (last_check_time + 24 * 3600 * 1000 <= new Date().getTime()) {
  255. // setShowTimePicker(true)
  256. // return
  257. // }
  258. // showPicker()
  259. }
  260. function tapEndFast(e) {
  261. if (process.env.TARO_ENV == 'weapp') {
  262. e.stopPropagation()
  263. }
  264. if (!user.isLogin) {
  265. jumpPage('/pages/account/ChooseAuth', 'ChooseAuth')
  266. return
  267. }
  268. debugger
  269. if (status == 'WAIT_FOR_START') {
  270. Taro.showToast({
  271. title: t('feature.track_time_duration.console.lock_fast_tip'),
  272. icon: 'none'
  273. })
  274. vibrate()
  275. return;
  276. }
  277. operateType = 'endFast'
  278. global.pauseIndexTimer = true
  279. global.set_time = new Date().getTime()
  280. var real_start_time = props.record.current_record.fast.real_start_time
  281. var last_check_time = props.record.current_record.last_real_check_time
  282. var now = new Date().getTime()
  283. if (now - real_start_time >= dayMilliSeconds) {
  284. //严重超时
  285. isTimeout = true
  286. // defaultTimestamp = Math.min(props.record.current_record.fast.target_end_time, now)
  287. // min = Math.max(last_check_time, defaultTimestamp - 3 * dayMillionSeconds)
  288. // max = Math.min(now, defaultTimestamp + 3 * dayMillionSeconds)
  289. // debugger
  290. defaultTimestamp = now
  291. min = Math.max(last_check_time, defaultTimestamp - 6 * dayMilliSeconds)
  292. max = defaultTimestamp
  293. }
  294. else {
  295. isTimeout = false
  296. defaultTimestamp = now
  297. min = Math.max(last_check_time, defaultTimestamp - 6 * dayMilliSeconds)
  298. max = defaultTimestamp
  299. }
  300. setShowTimePicker(true)
  301. // if (last_check_time + 24 * 3600 * 1000 <= new Date().getTime() ||
  302. // props.record.current_record.fast.real_check_time + 24 * 3600 * 1000 <= new Date().getTime()) {
  303. // setShowTimePicker(true)
  304. // return
  305. // }
  306. // showPicker()
  307. }
  308. function layoutContent() {
  309. var limit = global.set_time - 7 * 3600 * 1000 * 24;
  310. global.limit = limit
  311. if (currentRecord.last_real_check_time) {
  312. limit = currentRecord.last_real_check_time
  313. global.limit = limit
  314. //当set_time秒数<=latest_record_time秒数时,最小限制时间戳需+1分钟
  315. if (new Date(global.set_time).getSeconds() <= new Date(currentRecord.last_real_check_time).getSeconds() && global.set_time - currentRecord.last_real_check_time > 60000) {
  316. limit = limit + 60 * 1000
  317. }
  318. }
  319. var title = getTimePickerTitle(currentRecord, t, operateType == 'endFast')
  320. var color = getColor(currentRecord, operateType == 'endFast')
  321. var duration = 0
  322. if (operateType == 'startFast' && currentRecord.fast) {
  323. duration = currentRecord.fast.target_end_time - currentRecord.fast.target_start_time
  324. }
  325. if (operateType == 'startSleep' && currentRecord.sleep) {
  326. duration = currentRecord.sleep.target_end_time - currentRecord.sleep.target_start_time
  327. }
  328. var endTimestamp = 0
  329. if (operateType == 'endFast') {
  330. endTimestamp = currentRecord.fast.target_end_time
  331. }
  332. else if (operateType == 'endSleep') {
  333. endTimestamp = currentRecord.sleep.target_end_time
  334. }
  335. return <View className="modal_content">
  336. <LimitPickers ref={limitPickerRef} limit={limit} limitDay={7}
  337. themeColor={color}
  338. title={title}
  339. showEndTime={true}
  340. isFast={operateType == 'startFast' || operateType == 'endFast'}
  341. isEnd={operateType == 'endFast' || operateType == 'endSleep'}
  342. endTimestamp={endTimestamp}
  343. // showEndTime={operateType == 'startFast' || operateType == 'startSleep'}
  344. duration={duration}
  345. onCancel={hidePicker} onChange={(e) => {
  346. pickerConfirm(e)
  347. global.pauseIndexTimer = false
  348. // hidePicker()
  349. }} />
  350. </View>
  351. }
  352. function timePickerContent() {
  353. var title = getTimePickerTitle(currentRecord, t, operateType == 'endFast')
  354. var color = getColor(currentRecord, operateType == 'endFast')
  355. // var limit = props.record.current_record.last_real_check_time
  356. // var targetTime = props.record.current_record.fast.target_end_time
  357. // if (props.record.current_record.status == 'ONGOING3') {
  358. // limit = 0
  359. // targetTime = props.record.current_record.sleep.real_end_time + 60 * 1000
  360. // }
  361. var endTimestamp = 0
  362. if (operateType == 'endFast') {
  363. endTimestamp = currentRecord.fast.target_end_time
  364. }
  365. else if (operateType == 'endSleep') {
  366. endTimestamp = currentRecord.sleep.target_end_time
  367. }
  368. var duration = 0
  369. if (operateType == 'startFast' && currentRecord.fast) {
  370. duration = currentRecord.fast.target_end_time - currentRecord.fast.target_start_time
  371. }
  372. if (operateType == 'startSleep' && currentRecord.sleep) {
  373. duration = currentRecord.sleep.target_end_time - currentRecord.sleep.target_start_time
  374. }
  375. return <View className="modal_content">
  376. <ConsolePicker ref={limitPickerRef}
  377. themeColor={color}
  378. title={title}
  379. onCancel={hidePicker}
  380. min={min}
  381. max={max}
  382. current={defaultTimestamp}
  383. duration={duration}
  384. endTimestamp={endTimestamp}
  385. isFast={operateType == 'startFast' || operateType == 'endFast'}
  386. isEnd={operateType == 'endFast' || operateType == 'endSleep'}
  387. isTimeout={isTimeout}
  388. onChange={(e) => {
  389. pickerConfirm(e)
  390. global.pauseIndexTimer = false
  391. }}
  392. />
  393. {/* <LimitTimeoutPickers ref={limitPickerRef} limit={limit} limitDay={7}
  394. themeColor={color}
  395. title={title}
  396. isFast={operateType == 'endFast'}
  397. endTimestamp={endTimestamp}
  398. time={operateType == 'endFast' ? new Date(targetTime).getTime() :
  399. new Date(props.record.current_record.sleep.target_end_time).getTime()
  400. }
  401. onCancel={hidePicker} onChange={(e) => {
  402. pickerConfirm(e)
  403. global.pauseIndexTimer = false
  404. }} /> */}
  405. </View>
  406. }
  407. function showPicker() {
  408. // global.scenario = 'FAST_SLEEP'
  409. if (global.testInfotimer) {
  410. return
  411. }
  412. global.pauseIndexTimer = true
  413. global.set_time = new Date().getTime()
  414. updateNodeInfo()
  415. if (!global.isDebug) {
  416. return
  417. }
  418. // global.testInfotimer = setInterval(() => {
  419. // updateNodeInfo()
  420. // }, 1000)
  421. }
  422. function updateNodeInfo() {
  423. var node = layoutContent()
  424. global.showIndexModal(true, node, null);
  425. }
  426. function hidePicker() {
  427. var node = layoutContent()
  428. global.showIndexModal(false, node, null);
  429. setShowTimePicker(false)
  430. setBtnDisable(false)
  431. global.pauseIndexTimer = false
  432. }
  433. function followWxPub() {
  434. const resource = common.resources.filter((item: any) => {
  435. return item.code == 'follow_wx_pub'
  436. })
  437. jumpPage('/pages/common/H5?title=fast16cc 关注服务号&url=' + resource[0].url)
  438. }
  439. function pickerConfirm(t1: number) {
  440. debugger
  441. if (btnDisable) {
  442. return
  443. }
  444. setBtnDisable(true)
  445. // hidePicker()
  446. var date = new Date(t1)
  447. var setDate = new Date(global.set_time);
  448. date.setMilliseconds(setDate.getMilliseconds());
  449. date.setSeconds(setDate.getSeconds());
  450. t1 = date.getTime();
  451. // if (process.env.TARO_ENV=='rn'){
  452. // debugger
  453. // JPush.isNotificationEnabled((res)=>{
  454. // console.log(res)
  455. // debugger
  456. // })
  457. // }
  458. switch (operateType) {
  459. case 'startFast':
  460. startFast(t1, fastDuration).then(res => {
  461. global.indexPageRefresh()
  462. setFirstEnter(false)
  463. hidePicker()
  464. setBtnDisable(false)
  465. refreshDayNight()
  466. if (process.env.TARO_ENV == 'weapp') {
  467. debugger
  468. if (permission.wxPubFollow) {
  469. showAlert({
  470. title: t('feature.track_time_duration.reminders.fast_end_title'),
  471. content:
  472. t('feature.track_time_duration.reminders.enable_post_fast_content',
  473. { date: TimeFormatter.dateDescription(t1 + fastDuration, true), time: TimeFormatter.timeDescription(t1 + fastDuration) }
  474. ),
  475. showCancel: false,
  476. confirmText: t('feature.track_time_duration.reminders.ok')
  477. })
  478. }
  479. else {
  480. showAlert({
  481. title: t('feature.track_time_duration.reminders.fast_end_title'),
  482. content: t('feature.track_time_duration.reminders.post_fast_content',
  483. { date: TimeFormatter.dateDescription(t1 + fastDuration, true), time: TimeFormatter.timeDescription(t1 + fastDuration) }
  484. ),
  485. showCancel: true,
  486. cancelText: t('feature.track_time_duration.reminders.later'),
  487. confirmText: t('feature.track_time_duration.reminders.open'),
  488. confirm: () => { followWxPub() }
  489. })
  490. }
  491. }
  492. else {
  493. JPush.isNotificationEnabled((res) => {
  494. if (res) {
  495. showAlert({
  496. title: t('feature.track_time_duration.reminders.fast_end_title'),
  497. content:
  498. t('feature.track_time_duration.reminders.enable_post_fast_content',
  499. { date: TimeFormatter.dateDescription(t1 + fastDuration, true), time: TimeFormatter.timeDescription(t1 + fastDuration) }
  500. ),
  501. showCancel: false,
  502. confirmText: t('feature.track_time_duration.reminders.ok')
  503. })
  504. }
  505. else {
  506. showAlert({
  507. title: t('feature.track_time_duration.reminders.fast_end_title'),
  508. content: t('feature.track_time_duration.reminders.post_fast_content',
  509. { date: TimeFormatter.dateDescription(t1 + fastDuration, true), time: TimeFormatter.timeDescription(t1 + fastDuration) }
  510. ),
  511. showCancel: true,
  512. cancelText: t('feature.track_time_duration.reminders.later'),
  513. confirmText: t('feature.track_time_duration.reminders.open'),
  514. confirm: () => {
  515. // Linking.openURL('app-settings:notifications')
  516. checkNotification()
  517. }
  518. })
  519. }
  520. })
  521. }
  522. }).catch(e => {
  523. setBtnDisable(false)
  524. })
  525. break
  526. case 'startSleep':
  527. startSleep(t1, sleepDuration).then(res => {
  528. global.indexPageRefresh()
  529. setFirstEnter(false)
  530. hidePicker()
  531. setBtnDisable(false)
  532. refreshDayNight()
  533. if (process.env.TARO_ENV == 'weapp') {
  534. if (permission.wxPubFollow) {
  535. showAlert({
  536. title: t('feature.track_time_duration.reminders.wake_title'),
  537. content:
  538. t('feature.track_time_duration.reminders.enable_post_sleep_content',
  539. { date: TimeFormatter.dateDescription(t1 + sleepDuration, true), time: TimeFormatter.timeDescription(t1 + sleepDuration) }),
  540. showCancel: false,
  541. confirmText: t('feature.track_time_duration.reminders.ok')
  542. })
  543. }
  544. else {
  545. showAlert({
  546. title: t('feature.track_time_duration.reminders.wake_title'),
  547. content: t('feature.track_time_duration.reminders.post_sleep_content',
  548. { date: TimeFormatter.dateDescription(t1 + sleepDuration, true), time: TimeFormatter.timeDescription(t1 + sleepDuration) }),
  549. cancelText: t('feature.track_time_duration.reminders.later'),
  550. confirmText: t('feature.track_time_duration.reminders.open'),
  551. showCancel: true,
  552. confirm: () => { followWxPub() }
  553. })
  554. }
  555. }
  556. else {
  557. JPush.isNotificationEnabled((res) => {
  558. if (res) {
  559. showAlert({
  560. title: t('feature.track_time_duration.reminders.wake_title'),
  561. content:
  562. t('feature.track_time_duration.reminders.enable_post_sleep_content',
  563. { date: TimeFormatter.dateDescription(t1 + sleepDuration, true), time: TimeFormatter.timeDescription(t1 + sleepDuration) }),
  564. showCancel: false,
  565. confirmText: t('feature.track_time_duration.reminders.ok')
  566. })
  567. }
  568. else {
  569. showAlert({
  570. title: t('feature.track_time_duration.reminders.wake_title'),
  571. content: t('feature.track_time_duration.reminders.post_sleep_content',
  572. { date: TimeFormatter.dateDescription(t1 + sleepDuration, true), time: TimeFormatter.timeDescription(t1 + sleepDuration) }),
  573. cancelText: t('feature.track_time_duration.reminders.later'),
  574. confirmText: t('feature.track_time_duration.reminders.open'),
  575. showCancel: true,
  576. confirm: () => {
  577. checkNotification()
  578. // Linking.openURL('app-settings:notifications')
  579. }
  580. })
  581. }
  582. })
  583. }
  584. }).catch((e) => {
  585. setBtnDisable(false)
  586. var picker = limitPickerRef.current;
  587. (picker as any).resetPickerData()
  588. })
  589. break
  590. case 'endSleep':
  591. endSleep(t1).then(res => {
  592. setBtnDisable(false)
  593. global.indexPageRefresh()
  594. setFirstEnter(false)
  595. hidePicker()
  596. global.refrehWeekly()
  597. global.refreshStreaks()
  598. refreshDayNight()
  599. if (props.record.current_record.scenario == 'SLEEP') {
  600. global.scrollToLatest()
  601. }
  602. }).catch((e) => {
  603. setBtnDisable(false)
  604. var picker = limitPickerRef.current;
  605. (picker as any).resetPickerData()
  606. })
  607. break
  608. case 'endFast':
  609. endFast(t1).then(res => {
  610. setBtnDisable(false)
  611. global.indexPageRefresh()
  612. setFirstEnter(false)
  613. hidePicker()
  614. global.scrollToLatest()
  615. global.refrehWeekly()
  616. global.refreshStreaks()
  617. refreshDayNight()
  618. var obj = global.checkAccess
  619. if (obj) {
  620. console.log('applw')
  621. }
  622. else {
  623. console.log('apple')
  624. }
  625. global.checkAccess((res as any).access)
  626. // checkAccessProvisional((res as any).access,showFastAlert)
  627. }).catch((e) => {
  628. setBtnDisable(false)
  629. var picker = limitPickerRef.current;
  630. (picker as any).resetPickerData()
  631. })
  632. break
  633. }
  634. }
  635. function refreshDayNight() {
  636. if (global.refreshNight) {
  637. global.refreshNight()
  638. }
  639. if (global.refreshDay) {
  640. global.refreshDay()
  641. }
  642. }
  643. function expandBtnText() {
  644. if (status == 'WAIT_FOR_START') {
  645. return t('feature.track_time_duration.console.next_steps')
  646. }
  647. else if (firstEnter) {
  648. return t('feature.track_time_duration.console.show_more')
  649. }
  650. return t('feature.track_time_duration.console.next_steps')
  651. }
  652. function modalContent() {
  653. global.set_time = new Date().getTime()
  654. return <Modal
  655. testInfo={null}
  656. dismiss={() => {
  657. hidePicker()
  658. // setShowTimeoutPicker(false)
  659. }}
  660. confirm={() => { }}>
  661. {
  662. timePickerContent()
  663. }
  664. </Modal>
  665. }
  666. function single() {
  667. if (props.record.scenario.name == 'FAST') {
  668. return <View style={{ marginTop: rpxToPx(0) }}>
  669. {
  670. status == 'WAIT_FOR_START' &&
  671. <View onClick={tapStartFast} className='console_btn'>
  672. <Text style={{ fontWeight: 'bold' }}>{t('feature.track_time_duration.common.start_fast')}</Text>
  673. </View>
  674. }
  675. {/* {
  676. status != 'WAIT_FOR_START' && <View className='btn_line' />
  677. } */}
  678. {
  679. status == 'ONGOING' && <View onClick={tapEndFast} className={status == 'ONGOING' ? 'console_btn' : 'console_btn btn_disable'}>
  680. <Text style={{ fontWeight: 'bold' }}>{t('feature.track_time_duration.common.end_fast')}</Text>
  681. </View>
  682. }
  683. {
  684. showTimePicker && modalContent()
  685. }
  686. </View>
  687. }
  688. else if (props.record.scenario.name == 'SLEEP') {
  689. return <View style={{ marginTop: rpxToPx(0) }}>
  690. {
  691. status == 'WAIT_FOR_START' &&
  692. <View onClick={tapStartSleep} className='console_btn btn_sleep'>
  693. <Text style={{ fontWeight: 'bold' }}>{t('feature.track_time_duration.common.start_sleep')}</Text>
  694. </View>
  695. }
  696. {/* {
  697. status != 'WAIT_FOR_START' && <View className='btn_line' />
  698. } */}
  699. {
  700. status == 'ONGOING' && <View onClick={tapEndSleep} className={status == 'ONGOING' ? 'console_btn btn_sleep' : 'console_btn btn_sleep btn_disable'}>
  701. <Text style={{ fontWeight: 'bold' }}>{t('feature.track_time_duration.common.end_sleep')}</Text>
  702. </View>
  703. }
  704. {
  705. showTimePicker && modalContent()
  706. }
  707. </View>
  708. }
  709. }
  710. function mixed() {
  711. return <View style={{ marginTop: rpxToPx(0) }}>
  712. {
  713. status == 'WAIT_FOR_START' ?
  714. <View onClick={tapStartFast} className='console_btn'>
  715. <Text style={{ fontWeight: 'bold', fontSize: rpxToPx(32) }}>{t('feature.track_time_duration.common.start_fast')}</Text>
  716. </View> :
  717. <View onClick={() => { tapStage(0) }} className='stage_btn'>
  718. <Text style={{ flex: 1, color: '#fff' }}>{t('feature.track_time_duration.stage.a')}</Text>
  719. {
  720. status == 'ONGOING1' ?
  721. <Text style={{ color: '#fff' }}>{TimeFormatter.countdown(currentRecord.fast.real_start_time)}</Text> :
  722. <Text style={{ color: '#fff' }}>{TimeFormatter.calculateTimeDifference(currentRecord.fast.real_start_time, currentRecord.sleep.real_start_time)}</Text>
  723. }
  724. </View>
  725. }
  726. <View className='btn_line' />
  727. {
  728. (status == 'WAIT_FOR_START' || status == 'ONGOING1') &&
  729. <View onClick={tapStartSleep} className={status == 'ONGOING1' ? 'console_btn btn_sleep' : 'console_btn btn_sleep btn_disable'}>
  730. {
  731. status != 'ONGOING1' && <Image className='lock' src={require('@assets/images/lock.png')} />
  732. }
  733. <Text style={{ fontWeight: 'bold', fontSize: rpxToPx(32) }}>{t('feature.track_time_duration.common.start_sleep')}</Text>
  734. </View>
  735. }
  736. {
  737. (status != 'WAIT_FOR_START' && status != 'ONGOING1') &&
  738. <View onClick={() => { tapStage(1) }} className='stage_btn'>
  739. <Text style={{ flex: 1, color: '#fff' }}>{t('feature.track_time_duration.stage.b')}</Text>
  740. {
  741. status == 'ONGOING2' ? <Text style={{ color: '#fff' }}>{TimeFormatter.countdown(currentRecord.sleep.real_start_time)}</Text> :
  742. <Text style={{ color: '#fff' }}>{TimeFormatter.calculateTimeDifference(currentRecord.sleep.real_start_time, currentRecord.sleep.real_end_time)}</Text>
  743. }
  744. </View>
  745. }
  746. {(expand || (status != 'WAIT_FOR_START' && status != 'ONGOING1')) && <View className='btn_line' />}
  747. {
  748. (expand || (status != 'WAIT_FOR_START' && status != 'ONGOING1')) && (status == 'WAIT_FOR_START' || status == 'ONGOING1' || status == 'ONGOING2') &&
  749. <View onClick={tapEndSleep} className={status == 'ONGOING2' ? 'console_btn btn_sleep' : 'console_btn btn_sleep btn_disable'}>
  750. {
  751. status != 'ONGOING2' && <Image className='lock' src={require('@assets/images/lock.png')} />
  752. }
  753. <Text style={{ fontWeight: 'bold', fontSize: rpxToPx(32) }}>{t('feature.track_time_duration.common.end_sleep')}</Text>
  754. </View>
  755. }
  756. {
  757. status == 'ONGOING3' &&
  758. <View onClick={() => { tapStage(2) }} className='stage_btn'>
  759. <Text style={{ flex: 1, color: '#fff' }}>{t('feature.track_time_duration.stage.c')}</Text>
  760. <Text style={{ color: '#fff' }}>{TimeFormatter.countdown(currentRecord.sleep.real_end_time)}</Text>
  761. </View>
  762. }
  763. {(expand || status == 'ONGOING3' || status == 'ONGOING') && <View className='btn_line' />}
  764. {
  765. (expand || status == 'ONGOING3' || status == 'ONGOING') &&
  766. <View onClick={tapEndFast} className={status == 'ONGOING3' ? 'console_btn' : 'console_btn btn_disable'}>
  767. {
  768. status == 'WAIT_FOR_START' && <Image className='lock' src={require('@assets/images/lock.png')} />
  769. }
  770. <Text style={{ fontWeight: 'bold', fontSize: rpxToPx(32) }}>{t('feature.track_time_duration.common.end_fast')}</Text>
  771. </View>
  772. }
  773. {
  774. (status == 'WAIT_FOR_START' || status == 'ONGOING1' || status == 'ONGOING2') &&
  775. <View>
  776. {
  777. !expand && <Text className='expand' onClick={() => { setExpand(true) }}>{expandBtnText()}</Text>
  778. }
  779. </View>
  780. }
  781. {
  782. showTimePicker && modalContent()
  783. }
  784. {
  785. showStageModal && stageContent()
  786. }
  787. </View>
  788. }
  789. function stageContent() {
  790. return <Modal
  791. testInfo={null}
  792. dismiss={() => {
  793. global.pauseIndexTimer = false
  794. setShowStageModal(false)
  795. }}
  796. confirm={() => { }}>
  797. {
  798. <CircadianDetailPopup
  799. record={currentRecord}
  800. schedule={props.record.scenario.schedule}
  801. stageIndex={stageIndex}
  802. onlyStage={true}
  803. onClose={() => { setShowStageModal(false); }} />
  804. }
  805. </Modal>
  806. }
  807. function tapStage(index) {
  808. stageIndex = index
  809. setShowStageModal(true)
  810. }
  811. return <View>
  812. {
  813. props.record.scenario.name == 'FAST_SLEEP' ? mixed() : single()
  814. }
  815. <CheckAccess record={props.record} count={props.count} />
  816. </View>
  817. }