CircadianDetailPopup.tsx 50 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094
  1. import { View, Text, PageContainer, Image } from '@tarojs/components'
  2. import './CircadianDetailPopup.scss'
  3. import { useEffect, useRef, useState } from 'react'
  4. import TimelineFastSleep from './TimelineFastSleep'
  5. import { RealRing } from "@/features/trackTimeDuration/components/Rings";
  6. import Rings from "./Rings";
  7. import { bigRingRadius, getBgRing, getCommon, getDot, ringWidth } from '../hooks/RingData';
  8. import { ColorType } from '@/context/themes/color';
  9. import { useTranslation } from 'react-i18next';
  10. import { TimeFormatter } from '@/utils/time_format';
  11. import { getTimezone, rpxToPx } from '@/utils/tools';
  12. import { useSelector } from 'react-redux';
  13. import { durationDatas, durationIndex, getColor, getDurationTitle } from '../hooks/Console';
  14. import Modal from '@/components/layout/Modal.weapp';
  15. import { updateRecord } from '@/services/trackTimeDuration';
  16. import PickerViews from '@/components/input/PickerViews';
  17. import Taro from '@tarojs/taro';
  18. import { IconInfo, IconMinus, IconPlus } from '@/components/basic/Icons';
  19. import showAlert from '@/components/basic/Alert';
  20. let LinearGradient
  21. if (process.env.TARO_ENV == 'rn') {
  22. LinearGradient = require('react-native-linear-gradient').default
  23. }
  24. export default function CircadianDetailPopup(props: { record: any, schedule?: any, onClose: Function, stageIndex?: number, onlyStage?: boolean }) {
  25. const [tabIndex, setTabIndex] = useState(0)
  26. const [diffTimeZone, setDiffTimeZone] = useState(false)
  27. const [multiTimeZone, setMultiTimeZone] = useState(false)
  28. const [detail, setDetail] = useState(JSON.parse(JSON.stringify(props.record)))
  29. const [showDurationPicker, setShowDurationPicker] = useState(false)
  30. const [fastPickerValue, setFastPickerValue] = useState([0, 0])
  31. const [sleepPickerValue, setSleepPickerValue] = useState([0, 0])
  32. const [showEditPicker, setShowEditPicker] = useState(false)
  33. const [schedule, setSchedule] = useState(props.schedule)
  34. const [isFast, setIsFast] = useState(true)
  35. const durationPickerRef = useRef(null)
  36. const common = useSelector((state: any) => state.common);
  37. const { t } = useTranslation()
  38. useEffect(() => {
  39. if (props.record.status == 'COMPLETED') {
  40. if ((props.record.sleep && props.record.sleep.status == 'COMPLETED') &&
  41. props.record.scenario == 'FAST_SLEEP') {
  42. setTabIndex(1)
  43. }
  44. else {
  45. setTabIndex(2)
  46. }
  47. }
  48. }, [])
  49. useEffect(() => {
  50. checkTimezone()
  51. // var current_record = props.record
  52. if (detail.fast)
  53. setFastPickerValue(durationIndex(detail.fast.target_start_time, detail.fast.target_end_time, common))
  54. if (detail.sleep)
  55. setSleepPickerValue(durationIndex(detail.sleep.target_start_time, detail.sleep.target_end_time, common))
  56. }, [detail])
  57. useEffect(() => {
  58. setDetail(JSON.parse(JSON.stringify(props.record)))
  59. }, [props.record])
  60. function checkTimezone() {
  61. var currentTZ = getTimezone()
  62. var isDiff = false;
  63. var isMulti = false;
  64. var tempTZ = '';
  65. if (props.record.fast) {
  66. if (props.record.fast.real_start_timezone && props.record.fast.real_start_timezone.gmt) {
  67. tempTZ = props.record.fast.real_start_timezone.gmt
  68. if (props.record.fast.real_start_timezone.gmt != currentTZ) {
  69. isDiff = true
  70. }
  71. }
  72. if (props.record.fast.real_end_timezone && props.record.fast.real_end_timezone.gmt) {
  73. if (tempTZ != props.record.fast.real_end_timezone.gmt) {
  74. isMulti = true
  75. }
  76. if (props.record.fast.real_end_timezone.gmt != currentTZ) {
  77. isDiff = true
  78. }
  79. }
  80. }
  81. if (props.record.sleep) {
  82. if (props.record.sleep.real_start_timezone && props.record.sleep.real_start_timezone.gmt) {
  83. if (tempTZ == '') {
  84. tempTZ = props.record.sleep.real_start_timezone.gmt
  85. }
  86. else if (tempTZ != props.record.sleep.real_start_timezone.gmt) {
  87. isMulti = true
  88. }
  89. if (props.record.sleep.real_start_timezone.gmt != currentTZ) {
  90. isDiff = true
  91. }
  92. }
  93. if (props.record.sleep.real_end_timezone && props.record.sleep.real_end_timezone.gmt) {
  94. if (tempTZ != props.record.sleep.real_end_timezone.gmt) {
  95. isMulti = true
  96. }
  97. if (props.record.sleep.real_end_timezone.gmt != currentTZ) {
  98. isDiff = true
  99. }
  100. }
  101. }
  102. setDiffTimeZone(isDiff)
  103. setMultiTimeZone(isMulti)
  104. }
  105. function getTitle() {
  106. if (props.record.status == 'COMPLETED') {
  107. var timestamp = props.record.first_real_check_time
  108. if (props.record.first_timezone) {
  109. timestamp = TimeFormatter.transferTimestamp(timestamp, props.record.first_timezone.gmt)
  110. }
  111. return TimeFormatter.getDayOfWeek(new Date(timestamp).getDay(), true)
  112. }
  113. if (props.record.status == 'WAIT_FOR_START') {
  114. return t('feature.track_time_duration.common.schedule')
  115. }
  116. return t('feature.track_time_duration.common.current_schedule')
  117. }
  118. function getSubTitle() {
  119. if (props.record.status == 'COMPLETED') {
  120. var timestamp = props.record.first_real_check_time
  121. if (props.record.first_timezone) {
  122. timestamp = TimeFormatter.transferTimestamp(timestamp, props.record.first_timezone.gmt)
  123. }
  124. return TimeFormatter.dateDescription(timestamp, true)
  125. }
  126. return ''
  127. }
  128. function getBottomText() {
  129. if (props.record.status == 'WAIT_FOR_START') {
  130. return t('feature.track_time_duration.common.im_ready')
  131. }
  132. if (props.record.status == 'COMPLETED') {
  133. return t('feature.track_time_duration.common.got_it')
  134. }
  135. return t('feature.track_time_duration.common.okay')
  136. }
  137. const startArc = (time: number) => {
  138. var date = new Date(time);
  139. var hour = date.getHours();
  140. var minute = date.getMinutes();
  141. var second = date.getSeconds();
  142. return (hour * 3600 + minute * 60 + second) / (24 * 3600) * 2 * Math.PI - Math.PI / 2.0;
  143. }
  144. function durationArc(start_time: number, end_time: number) {
  145. var duration = (end_time - start_time) / 1000;
  146. return duration / (24 * 3600) * 2 * Math.PI;
  147. }
  148. function getStageDuration(index) {
  149. var start, end;
  150. switch (index) {
  151. case 0:
  152. if (props.record.status == 'WAIT_FOR_START') {
  153. start = props.record.fast.target_start_time
  154. end = props.record.sleep.target_start_time
  155. }
  156. else if (props.record.status == 'ONGOING1') {
  157. return TimeFormatter.countdown(props.record.fast.real_start_time)
  158. }
  159. else {
  160. start = props.record.fast.real_start_time
  161. end = props.record.sleep.real_start_time
  162. }
  163. break
  164. case 1:
  165. if (props.record.status == 'WAIT_FOR_START' ||
  166. props.record.status == 'ONGOING1') {
  167. start = props.record.sleep.target_start_time
  168. end = props.record.sleep.target_end_time
  169. }
  170. else if (props.record.status == 'ONGOING2') {
  171. return TimeFormatter.countdown(props.record.sleep.real_start_time)
  172. }
  173. else {
  174. start = props.record.sleep.real_start_time
  175. end = props.record.sleep.real_end_time
  176. }
  177. break
  178. case 2:
  179. if (props.record.status == 'WAIT_FOR_START' ||
  180. props.record.status == 'ONGOING1' ||
  181. props.record.status == 'ONGOING2') {
  182. start = props.record.sleep.target_end_time
  183. end = props.record.fast.target_end_time
  184. }
  185. else if (props.record.status == 'ONGOING3') {
  186. return TimeFormatter.countdown(props.record.sleep.real_end_time)
  187. }
  188. else {
  189. start = props.record.sleep.real_end_time
  190. end = props.record.fast.real_end_time
  191. }
  192. break
  193. case 3:
  194. start = props.record.fast.real_start_time
  195. end = props.record.fast.real_end_time
  196. if (props.record.fast.status == 'NOT_COMPLETED') {
  197. return t('feature.track_time_duration.stage.not_completed')
  198. }
  199. break
  200. case 4:
  201. if (props.record.sleep.status == 'NOT_STARTED') {
  202. return t('feature.track_time_duration.stage.not_started')
  203. }
  204. else if (props.record.sleep.status == 'NOT_COMPLETED') {
  205. return t('feature.track_time_duration.stage.not_completed')
  206. }
  207. start = props.record.sleep.real_start_time
  208. end = props.record.sleep.real_end_time
  209. break;
  210. }
  211. if (start > end) {
  212. return t('feature.track_time_duration.console.no_duration_available')
  213. // return '-' + TimeFormatter.durationFormate2(start, end)
  214. }
  215. return TimeFormatter.durationFormate(start, end)
  216. // return TimeFormatter.calculateTimeDifference(start, end)
  217. }
  218. function completedOverView() {
  219. var bgRing = getBgRing()
  220. var common = getCommon(null, false)
  221. common.radius = bigRingRadius;
  222. common.lineWidth = ringWidth;
  223. var fastRing: RealRing = null
  224. if (props.record.fast) {
  225. var timestamp = TimeFormatter.transferTimestamp(props.record.fast.real_start_time, props.record.fast.real_end_timezone ? props.record.fast.real_end_timezone.gmt : '')
  226. fastRing = {
  227. color: global.fastColor ? global.fastColor : ColorType.fast,
  228. startArc: startArc(timestamp),//startArc(props.record.fast.real_start_time),
  229. durationArc: durationArc(props.record.fast.real_start_time, props.record.fast.real_end_time)
  230. }
  231. if (props.record.fast.status == 'NOT_COMPLETED') {
  232. fastRing.durationArc = 0.01
  233. }
  234. }
  235. var sleepRing: RealRing = null
  236. if (props.record.sleep && props.record.sleep.status == 'COMPLETED') {
  237. var timestamp = TimeFormatter.transferTimestamp(props.record.sleep.real_start_time,
  238. props.record.fast ? props.record.fast.real_end_timezone.gmt : props.record.sleep.real_end_timezone.gmt)
  239. sleepRing = {
  240. color: global.sleepColor ? global.sleepColor : ColorType.sleep,
  241. startArc: startArc(timestamp),//startArc(props.record.sleep.real_start_time),
  242. durationArc: durationArc(props.record.sleep.real_start_time, props.record.sleep.real_end_time)
  243. }
  244. }
  245. if (props.record.sleep && props.record.sleep.status == 'NOT_COMPLETED') {
  246. var timestamp = TimeFormatter.transferTimestamp(props.record.sleep.real_start_time,
  247. props.record.fast ? props.record.fast.real_end_timezone.gmt : props.record.sleep.real_end_timezone.gmt)
  248. sleepRing = {
  249. color: global.sleepColor ? global.sleepColor : ColorType.sleep,
  250. startArc: startArc(timestamp),//startArc(props.record.sleep.real_start_time),
  251. durationArc: 0.01
  252. }
  253. }
  254. return <View>
  255. {
  256. props.record.fast && <View className='pop_ring_bg'>
  257. <Rings common={common} bgRing={bgRing} canvasId={'pop_fast_ring'} realRing={fastRing} />
  258. <View className="pop_duration_bg">
  259. <Text className="pop_duration_title">{t('feature.track_time_duration.record_fast_sleep.item.fast')}</Text>
  260. <Text className="pop_duration_value" style={{ color: ColorType.fast }}>{getStageDuration(3)}</Text>
  261. </View>
  262. </View>
  263. }
  264. {
  265. props.record.sleep && <View className='pop_ring_bg'>
  266. <Rings common={common} bgRing={bgRing} canvasId={'pop_sleep_ring'} realRing={sleepRing} />
  267. <View className="pop_duration_bg">
  268. <Text className="pop_duration_title">{t('feature.track_time_duration.record_fast_sleep.item.sleep')}</Text>
  269. <Text className="pop_duration_value" style={{ color: ColorType.sleep }}>{getStageDuration(4)}</Text>
  270. </View>
  271. </View>
  272. }
  273. </View>
  274. }
  275. function tapDuration(isFast: boolean) {
  276. if (isFast) {
  277. setIsFast(true)
  278. global.pauseIndexTimer = true
  279. if (props.record.status == 'WAIT_FOR_START') {
  280. setShowDurationPicker(true)
  281. }
  282. else {
  283. setShowEditPicker(true)
  284. }
  285. }
  286. else {
  287. setIsFast(false)
  288. if (props.record.status == 'WAIT_FOR_START' && props.record.scenario == 'FAST_SLEEP') {
  289. Taro.showToast({
  290. title: t('feature.track_time_duration.common.start_fasting_first'),
  291. icon: 'none'
  292. })
  293. return;
  294. }
  295. global.pauseIndexTimer = true
  296. if (props.record.status == 'WAIT_FOR_START' || props.record.status == 'ONGOING1') {
  297. setShowDurationPicker(true)
  298. }
  299. else {
  300. setShowEditPicker(true)
  301. }
  302. }
  303. }
  304. function tapMinus(isFast: boolean) {
  305. if (isFast) {
  306. var fastDuration = detail.fast.target_end_time - detail.fast.target_start_time
  307. if (fastDuration == 3600000) {
  308. Taro.showToast({
  309. icon: 'none',
  310. title: 'feature.common.toast.min_value'
  311. })
  312. return
  313. }
  314. var count = fastDuration - common.duration.step * 60 * 1000
  315. count = count < 3600000 ? 3600000 : count
  316. detail.fast.target_end_time = detail.fast.target_start_time + count;
  317. setFastPickerValue(durationIndex(detail.fast.target_start_time, detail.fast.target_end_time, common))
  318. if (props.record.status == 'WAIT_FOR_START') {
  319. // var start = props.schedule.fast.start_time
  320. // var startCount = (parseInt(start.split(':')[0]) * 60 + parseInt(start.split(':')[1])) * 60 * 1000
  321. // var endCount = startCount + count
  322. // if (endCount >= 24 * 3600 * 1000) {
  323. // endCount -= 24 * 3600 * 1000
  324. // }
  325. // endCount = endCount / 60000
  326. // var endHour = Math.floor(endCount / 60)
  327. // var endMinute = endCount % 60
  328. // var endTime = TimeFormatter.padZero(endHour) + ':' + TimeFormatter.padZero(endMinute)
  329. // console.log(endTime)
  330. changeSchedule(count)
  331. }
  332. }
  333. else {
  334. if (props.record.status == 'WAIT_FOR_START' && props.record.scenario == 'FAST_SLEEP') {
  335. Taro.showToast({
  336. title: t('feature.track_time_duration.common.start_fasting_first'),
  337. icon: 'none'
  338. })
  339. return;
  340. }
  341. var sleepDuration = detail.sleep.target_end_time - detail.sleep.target_start_time
  342. if (sleepDuration == 3600000) {
  343. Taro.showToast({
  344. icon: 'none',
  345. title: 'feature.common.toast.min_value'
  346. })
  347. return
  348. }
  349. var count = sleepDuration - common.duration.step * 60 * 1000
  350. count = count < 3600000 ? 3600000 : count
  351. detail.sleep.target_end_time = detail.sleep.target_start_time + count;
  352. setSleepPickerValue(durationIndex(detail.sleep.target_start_time, detail.sleep.target_end_time, common))
  353. }
  354. setDetail(JSON.parse(JSON.stringify(detail)))
  355. }
  356. function tapPlus(isFast: boolean) {
  357. if (isFast) {
  358. var fastDuration = detail.fast.target_end_time - detail.fast.target_start_time
  359. if (fastDuration == 23 * 3600000) {
  360. Taro.showToast({
  361. icon: 'none',
  362. title: 'feature.common.toast.max_value'
  363. })
  364. return
  365. }
  366. var count = fastDuration + common.duration.step * 60 * 1000
  367. count = count > 23 * 3600000 ? 23 * 3600000 : count
  368. detail.fast.target_end_time = detail.fast.target_start_time + count;
  369. setFastPickerValue(durationIndex(detail.fast.target_start_time, detail.fast.target_end_time, common))
  370. if (props.record.status == 'WAIT_FOR_START') {
  371. changeSchedule(count)
  372. // var start = props.schedule.fast.start_time
  373. // var startCount = (parseInt(start.split(':')[0]) * 60 + parseInt(start.split(':')[1])) * 60 * 1000
  374. // var endCount = startCount + count
  375. // if (endCount >= 24 * 3600 * 1000) {
  376. // endCount -= 24 * 3600 * 1000
  377. // }
  378. // endCount = endCount / 60000
  379. // var endHour = Math.floor(endCount / 60)
  380. // var endMinute = endCount % 60
  381. // var endTime = TimeFormatter.padZero(endHour) + ':' + TimeFormatter.padZero(endMinute)
  382. // console.log(endTime)
  383. }
  384. }
  385. else {
  386. if (props.record.status == 'WAIT_FOR_START' && props.record.scenario == 'FAST_SLEEP') {
  387. Taro.showToast({
  388. title: t('feature.track_time_duration.common.start_fasting_first'),
  389. icon: 'none'
  390. })
  391. return;
  392. }
  393. var sleepDuration = detail.sleep.target_end_time - detail.sleep.target_start_time
  394. if (sleepDuration == 23 * 3600000) {
  395. Taro.showToast({
  396. icon: 'none',
  397. title: 'feature.common.toast.max_value'
  398. })
  399. return
  400. }
  401. var count = sleepDuration + common.duration.step * 60 * 1000
  402. count = count > 23 * 3600000 ? 23 * 3600000 : count
  403. detail.sleep.target_end_time = detail.sleep.target_start_time + count;
  404. setSleepPickerValue(durationIndex(detail.sleep.target_start_time, detail.sleep.target_end_time, common))
  405. }
  406. setDetail(JSON.parse(JSON.stringify(detail)))
  407. }
  408. function changeSchedule(count: number) {
  409. if (!schedule) {
  410. return
  411. }
  412. var obj = JSON.parse(JSON.stringify(schedule))
  413. var start = schedule.fast.start_time
  414. var startCount = (parseInt(start.split(':')[0]) * 60 + parseInt(start.split(':')[1])) * 60 * 1000
  415. var endCount = startCount + count
  416. if (endCount >= 24 * 3600 * 1000) {
  417. endCount -= 24 * 3600 * 1000
  418. }
  419. endCount = endCount / 60000
  420. var endHour = Math.floor(endCount / 60)
  421. var endMinute = endCount % 60
  422. var endTime = TimeFormatter.padZero(endHour) + ':' + TimeFormatter.padZero(endMinute)
  423. obj.fast.end_time = endTime
  424. setSchedule(obj)
  425. }
  426. function sleepRealDuration() {
  427. return getStageDuration(4)
  428. }
  429. function fastOverview() {
  430. if (props.record.fast.status == 'WAIT_FOR_START') {
  431. return <View className='pop_ring_bg pop_overview_bg'>
  432. <Text className='pop_duration_title'>{t('feature.track_time_duration.record_fast_sleep.item.fast')}</Text>
  433. <View onClick={() => tapDuration(true)} style={{ flexDirection: 'row', alignItems: 'center', marginTop: rpxToPx(8), display: 'flex', width: '100%' }}>
  434. <Text className='pop_duration_txt' style={{ color: ColorType.fast }}>{TimeFormatter.durationFormate(detail.fast.target_start_time, detail.fast.target_end_time)}</Text>
  435. <View onClick={(e) => {
  436. if (process.env.TARO_ENV == 'weapp') {
  437. e.stopPropagation()
  438. }
  439. tapMinus(true)
  440. }} className='minus' style={{ backgroundColor: ColorType.fast, opacity: 0.6 }}><IconMinus color='#090909' /></View>
  441. <View onClick={(e) => {
  442. if (process.env.TARO_ENV == 'weapp') {
  443. e.stopPropagation()
  444. }
  445. tapPlus(true)
  446. }} className='plus' style={{ backgroundColor: ColorType.fast }}><IconPlus color='#090909' /></View>
  447. </View>
  448. </View>
  449. }
  450. else if (props.record.status != 'COMPLETED') {
  451. return <View className='pop_ring_bg pop_overview_bg'>
  452. <Text className='pop_duration_title'>{t('feature.track_time_duration.record_fast_sleep.item.fast')}</Text>
  453. <View onClick={() => tapDuration(true)} style={{ flexDirection: 'row', alignItems: 'center', marginTop: rpxToPx(8), display: 'flex', width: '100%' }}>
  454. <Text className='pop_duration_txt'>{TimeFormatter.durationFormate(detail.fast.target_start_time, detail.fast.target_end_time)}</Text>
  455. <Image onClick={() => tapDuration(true)} className="arrow2" src={require('@/assets/images/arrow3.png')} />
  456. </View>
  457. <View style={{ marginTop: rpxToPx(20), display: 'flex', flexDirection: 'row', alignItems: 'center' }}>
  458. <View className='countdown_time_bg'>
  459. <Text className='title' style={{ color: '#fff', opacity: 0.4 }}>{t('feature.track_time_duration.console.countup')}</Text>
  460. <Text className='value' style={{ color: ColorType.fast }}>{TimeFormatter.formateTimeNow(props.record.fast.real_start_time)}</Text>
  461. </View>
  462. <View className='countdown_time_bg'>
  463. {
  464. props.record.fast.target_end_time < new Date().getTime() ? <Text className='title' style={{ color: '#fff', opacity: 0.4 }}>{t('feature.track_time_duration.console.timeout')}</Text> :
  465. <Text className='title' style={{ color: '#fff', opacity: 0.4 }}>{t('feature.track_time_duration.console.countdown_not_due')}</Text>
  466. }
  467. {
  468. props.record.fast.target_end_time < new Date().getTime() ?
  469. <Text className='value' style={{ color: ColorType.alert }}>{TimeFormatter.countdown(props.record.fast.target_end_time)}</Text> :
  470. <Text className='value' style={{ color: ColorType.fast, opacity: 0.6 }}>{TimeFormatter.countdown(props.record.fast.target_end_time)}</Text>
  471. }
  472. </View>
  473. </View>
  474. </View>
  475. }
  476. }
  477. function sleepOverview() {
  478. if (props.record.sleep.status == 'WAIT_FOR_START') {
  479. return <View className='pop_ring_bg pop_overview_bg'>
  480. <Text className='pop_duration_title'>{t('feature.track_time_duration.record_fast_sleep.item.sleep')}</Text>
  481. <View onClick={() => tapDuration(false)} style={{ flexDirection: 'row', alignItems: 'center', marginTop: rpxToPx(8), display: 'flex', width: '100%' }}>
  482. <Text className='pop_duration_txt' style={{ color: ColorType.sleep }}>{TimeFormatter.durationFormate(detail.sleep.target_start_time, detail.sleep.target_end_time)}</Text>
  483. <View onClick={(e) => {
  484. if (process.env.TARO_ENV == 'weapp') {
  485. e.stopPropagation()
  486. }
  487. tapMinus(false)
  488. }} className='minus' style={{ backgroundColor: ColorType.sleep, opacity: 0.6 }}><IconMinus color='#090909' /></View>
  489. <View onClick={(e) => {
  490. if (process.env.TARO_ENV == 'weapp') {
  491. e.stopPropagation()
  492. }
  493. tapPlus(false)
  494. }} className='plus' style={{ backgroundColor: ColorType.sleep }}><IconPlus color='#090909' /></View>
  495. </View>
  496. </View>
  497. }
  498. else if (props.record.sleep.status == 'WAIT_FOR_END') {
  499. return <View className='pop_ring_bg pop_overview_bg'>
  500. <Text className='pop_duration_title'>{t('feature.track_time_duration.record_fast_sleep.item.sleep')}</Text>
  501. <View onClick={() => tapDuration(false)} style={{ flexDirection: 'row', alignItems: 'center', marginTop: rpxToPx(8), display: 'flex', width: '100%' }}>
  502. <Text className='pop_duration_txt'>{TimeFormatter.durationFormate(detail.sleep.target_start_time, detail.sleep.target_end_time)}</Text>
  503. <Image onClick={() => tapDuration(false)} className="arrow2" src={require('@/assets/images/arrow3.png')} />
  504. </View>
  505. <View style={{ marginTop: rpxToPx(20), display: 'flex', flexDirection: 'row', alignItems: 'center' }}>
  506. <View className='countdown_time_bg'>
  507. <Text className='title'>{t('feature.track_time_duration.console.countup')}</Text>
  508. <Text className='value' style={{ color: ColorType.sleep }}>{TimeFormatter.formateTimeNow(props.record.sleep.real_start_time)}</Text>
  509. </View>
  510. <View className='countdown_time_bg'>
  511. {
  512. props.record.sleep.target_end_time < new Date().getTime() ? <Text className='title'>{t('feature.track_time_duration.console.timeout')}</Text> :
  513. <Text className='title'>{t('feature.track_time_duration.console.countdown_not_due')}</Text>
  514. }
  515. {
  516. props.record.sleep.target_end_time < new Date().getTime() ?
  517. <Text className='value' style={{ color: ColorType.alert }}>{TimeFormatter.countdown(props.record.sleep.target_end_time)}</Text> :
  518. <Text className='value' style={{ color: ColorType.sleep, opacity: 0.6 }}>{TimeFormatter.countdown(props.record.sleep.target_end_time)}</Text>
  519. }
  520. </View>
  521. </View>
  522. </View>
  523. }
  524. else {
  525. return <View className='pop_ring_bg pop_overview_bg'>
  526. <Text className='pop_duration_title'>{t('feature.track_time_duration.record_fast_sleep.item.sleep')}</Text>
  527. <View style={{ flexDirection: 'row', alignItems: 'center', marginTop: rpxToPx(8), display: 'flex', width: '100%' }}>
  528. <Text className='pop_duration_txt' style={{ color: ColorType.sleep }}>{sleepRealDuration()}</Text>
  529. </View>
  530. </View>
  531. }
  532. }
  533. function overview() {
  534. if (props.record.status == 'COMPLETED') {
  535. return completedOverView()
  536. }
  537. return <View>
  538. {
  539. props.record.fast && fastOverview()
  540. }
  541. {
  542. props.record.sleep && sleepOverview()
  543. }
  544. </View>
  545. }
  546. function showPredictedAlert() {
  547. showAlert({
  548. title: t('feature.track_time_duration.console.predicted_alert_title'),
  549. content: t('feature.track_time_duration.console.predicted_alert_content'),
  550. showCancel: false,
  551. confirmText: t('feature.track_time_duration.console.predicted_alert_btn')
  552. })
  553. }
  554. function stage() {
  555. var bgRing = getBgRing()
  556. var common = getCommon(null, false)
  557. common.radius = bigRingRadius;
  558. common.lineWidth = ringWidth;
  559. var timestamp, timestamp2, timestamp3
  560. var duration, duration2, duration3;
  561. var predicted2 = false; //预估
  562. var predicted3 = false;
  563. var currentDot = getDot(null, true)
  564. var currentDot2 = getDot(null, true)
  565. var currentDot3 = getDot(null, true)
  566. if (props.record.status == 'WAIT_FOR_START') {
  567. var date = new Date()
  568. date.setSeconds(0)
  569. date.setMilliseconds(0)
  570. var fastStart = props.schedule.fast.start_time
  571. var sleepStart = props.schedule.sleep.start_time
  572. var sleepEnd = props.schedule.sleep.end_time
  573. date.setHours(parseInt(fastStart.split(':')[0]))
  574. date.setMinutes(parseInt(fastStart.split(':')[1]))
  575. timestamp = date.getTime()
  576. date.setHours(parseInt(sleepStart.split(':')[0]))
  577. date.setMinutes(parseInt(sleepStart.split(':')[1]))
  578. timestamp2 = date.getTime()
  579. if (timestamp2 < timestamp) {
  580. timestamp2 += 24 * 3600 * 1000
  581. }
  582. date.setHours(parseInt(sleepEnd.split(':')[0]))
  583. date.setMinutes(parseInt(sleepEnd.split(':')[1]))
  584. timestamp3 = date.getTime()
  585. if (timestamp3 < timestamp2) {
  586. timestamp3 += 24 * 3600 * 1000
  587. }
  588. duration = durationArc(props.record.fast.target_start_time, props.record.sleep.target_start_time)
  589. duration2 = durationArc(props.record.sleep.target_start_time, props.record.sleep.target_end_time)
  590. duration3 = durationArc(props.record.sleep.target_end_time, props.record.fast.target_end_time)
  591. currentDot = null
  592. currentDot2 = null
  593. currentDot3 = null
  594. }
  595. else if (props.record.status == 'ONGOING1') {
  596. var date = new Date()
  597. timestamp = props.record.fast.real_start_time
  598. timestamp2 = props.record.sleep.target_start_time
  599. timestamp3 = props.record.sleep.target_end_time
  600. duration = durationArc(props.record.fast.real_start_time, date.getTime())
  601. duration2 = durationArc(props.record.sleep.target_start_time, props.record.sleep.target_end_time)
  602. duration3 = durationArc(props.record.sleep.target_end_time, props.record.fast.target_end_time)
  603. predicted2 = true
  604. predicted3 = true
  605. currentDot.color = ColorType.fast
  606. currentDot2 = null
  607. currentDot3 = null
  608. }
  609. else if (props.record.status == 'ONGOING2') {
  610. var date = new Date()
  611. timestamp = props.record.fast.real_start_time
  612. timestamp2 = props.record.sleep.real_start_time
  613. timestamp3 = props.record.sleep.target_end_time
  614. duration = durationArc(props.record.fast.real_start_time, props.record.sleep.real_start_time)
  615. duration2 = durationArc(props.record.sleep.real_start_time, date.getTime())
  616. duration3 = durationArc(props.record.sleep.target_end_time, props.record.fast.target_end_time)
  617. predicted2 = false
  618. predicted3 = true
  619. currentDot = null
  620. currentDot2.color = ColorType.sleep
  621. currentDot3 = null
  622. }
  623. else if (props.record.status == 'ONGOING3') {
  624. var date = new Date()
  625. timestamp = props.record.fast.real_start_time
  626. timestamp2 = props.record.sleep.real_start_time
  627. timestamp3 = props.record.sleep.real_end_time
  628. duration = durationArc(props.record.fast.real_start_time, props.record.sleep.real_start_time)
  629. duration2 = durationArc(props.record.sleep.real_start_time, props.record.sleep.real_end_time)
  630. duration3 = durationArc(props.record.sleep.real_end_time, date.getTime())
  631. currentDot = null
  632. currentDot2 = null
  633. currentDot3.color = ColorType.fast
  634. }
  635. else {
  636. timestamp = TimeFormatter.transferTimestamp(props.record.fast.real_start_time, props.record.fast.real_end_timezone.gmt)
  637. timestamp2 = TimeFormatter.transferTimestamp(props.record.sleep.real_start_time, props.record.fast.real_end_timezone.gmt)
  638. timestamp3 = TimeFormatter.transferTimestamp(props.record.sleep.real_end_time, props.record.fast.real_end_timezone.gmt)
  639. duration = durationArc(props.record.fast.real_start_time, props.record.sleep.real_start_time)
  640. duration2 = durationArc(props.record.sleep.real_start_time, props.record.sleep.real_end_time)
  641. duration3 = durationArc(props.record.sleep.real_end_time, props.record.fast.real_end_time)
  642. currentDot = null
  643. currentDot2 = null
  644. currentDot3 = null
  645. }
  646. const preRing: RealRing = {
  647. color: global.fastColor ? global.fastColor : ColorType.fast,
  648. startArc: startArc(timestamp),
  649. durationArc: duration
  650. }
  651. let sleepRing: RealRing = {
  652. color: global.sleepColor ? global.sleepColor : ColorType.sleep,
  653. startArc: startArc(timestamp2),
  654. durationArc: duration2
  655. }
  656. let wakeRing: RealRing = {
  657. color: global.fastColor ? global.fastColor : ColorType.fast,
  658. startArc: startArc(timestamp3),
  659. durationArc: duration3
  660. }
  661. if (duration2 < 0) {
  662. sleepRing = null
  663. }
  664. if (duration3 < 0) {
  665. wakeRing = null
  666. }
  667. return <View>
  668. <View className='pop_ring_bg'>
  669. <Rings common={common} bgRing={bgRing} canvasId={'pre_sleep_ring'} realRing={preRing} currentDot={currentDot} />
  670. <View className="pop_duration_bg">
  671. <Text className="pop_duration_title">{t('feature.track_time_duration.stage.a')}</Text>
  672. <Text className="pop_duration_value" style={{ color: ColorType.fast }}>{getStageDuration(0)}</Text>
  673. </View>
  674. </View>
  675. <View className='pop_ring_bg'>
  676. <Rings common={common} bgRing={bgRing} canvasId={'sleeping_ring'} realRing={sleepRing} currentDot={currentDot2} />
  677. <View className="pop_duration_bg">
  678. <Text className="pop_duration_title">{t('feature.track_time_duration.stage.b')}</Text>
  679. <View style={{ display: 'flex', flexDirection: 'row', alignItems: 'center' }}>
  680. <Text className="pop_duration_value" style={{ color: ColorType.sleep, marginBottom: 0 }}>{getStageDuration(1)}</Text>
  681. {
  682. predicted2 ? !sleepRing ? <View style={{ marginLeft: 5 }} onClick={showPredictedAlert}><IconInfo width={20} color={ColorType.sleep} /></View> : <View className='free' style={{ backgroundColor: ColorType.sleep, color: '#fff' }}>{t('feature.track_time_duration.console.predicted')}</View> : null
  683. }
  684. </View>
  685. </View>
  686. </View>
  687. <View className='pop_ring_bg'>
  688. <Rings common={common} bgRing={bgRing} canvasId={'later_sleep_ring'} realRing={wakeRing} currentDot={currentDot3} />
  689. <View className="pop_duration_bg">
  690. <Text className="pop_duration_title">{t('feature.track_time_duration.stage.c')}</Text>
  691. <View style={{ display: 'flex', flexDirection: 'row', alignItems: 'center' }}>
  692. <Text className="pop_duration_value" style={{ color: ColorType.fast, marginBottom: 0 }}>{getStageDuration(2)}</Text>
  693. {
  694. predicted3 ? !wakeRing ? <View style={{ marginLeft: 5 }} onClick={showPredictedAlert}><IconInfo width={20} color={ColorType.fast} /></View> : <View className='free' style={{ backgroundColor: ColorType.fast, color: '#fff' }}>{t('feature.track_time_duration.console.predicted')}</View> : null
  695. }
  696. </View>
  697. </View>
  698. </View>
  699. </View>
  700. }
  701. function events() {
  702. return <View style={{ display: 'flex', flexDirection: 'row', alignItems: 'center', justifyContent: 'center' }}>
  703. <TimelineFastSleep
  704. data={props.record}
  705. first_real_check_time={props.record.first_real_check_time ? props.record.first_real_check_time : 0}
  706. scenario={schedule ? { schedule: schedule } : null}
  707. diffTimeZone={diffTimeZone} multiTimeZone={multiTimeZone} />
  708. </View>
  709. }
  710. function durationPickerContent() {
  711. var color = getColor(props.record)
  712. var title = getDurationTitle(props.record, t)
  713. return <View style={{ color: '#fff', backgroundColor: 'transparent' }}>
  714. <PickerViews ref={durationPickerRef}
  715. onChange={durationChange}
  716. items={durationDatas(common)}
  717. value={isFast ? fastPickerValue : sleepPickerValue}
  718. themeColor={color}
  719. title={title}
  720. showBtns={true}
  721. onCancel={() => {
  722. setShowDurationPicker(false)
  723. global.pauseIndexTimer = false
  724. }} />
  725. </View>
  726. }
  727. function editPickerContent() {
  728. return <View style={{ color: '#fff', backgroundColor: 'transparent' }}>
  729. <PickerViews ref={durationPickerRef}
  730. onChange={durationChange}
  731. items={durationDatas(common)}
  732. value={isFast ? fastPickerValue : sleepPickerValue}
  733. themeColor={isFast ? ColorType.fast : ColorType.sleep}
  734. title={isFast ? t('feature.track_time_duration.action_sheet.edit_fasting_goal') :
  735. t('feature.track_time_duration.action_sheet.edit_sleeping_goal')}
  736. showBtns={true}
  737. onCancel={() => {
  738. setShowEditPicker(false)
  739. global.pauseIndexTimer = false
  740. }} />
  741. </View>
  742. }
  743. function durationChange(e) {
  744. global.pauseIndexTimer = false
  745. var count = (e[0] + common.duration.min) * 60 + e[1] * common.duration.step
  746. // var count = (e[0] + 1) * 60 + e[1] * 5
  747. if (showDurationPicker) {
  748. // global.changeTargetDuration(count, isFast)
  749. if (isFast) {
  750. detail.fast.target_end_time = detail.fast.target_start_time + count * 60 * 1000
  751. if (props.record.status == 'WAIT_FOR_START') {
  752. changeSchedule(count * 1000 * 60)
  753. }
  754. }
  755. else {
  756. detail.sleep.target_end_time = detail.sleep.target_start_time + count * 60 * 1000
  757. }
  758. setDetail(JSON.parse(JSON.stringify(detail)))
  759. }
  760. else {
  761. var params: any = {}
  762. if (isFast) {
  763. params = {
  764. fast: {
  765. target_duration: count * 60 * 1000
  766. }
  767. }
  768. }
  769. else {
  770. params = {
  771. sleep: {
  772. target_duration: count * 60 * 1000
  773. }
  774. }
  775. }
  776. updateRecord({
  777. ...params
  778. }, props.record.id).then(res => {
  779. global.indexPageRefresh()
  780. }).catch(e => {
  781. })
  782. }
  783. setShowDurationPicker(false)
  784. setShowEditPicker(false)
  785. }
  786. function modalContent() {
  787. if (showDurationPicker || showEditPicker) {
  788. return <Modal
  789. testInfo={null}
  790. dismiss={() => {
  791. setShowDurationPicker(false)
  792. setShowEditPicker(false)
  793. global.pauseIndexTimer = false
  794. }}
  795. confirm={() => { }}>
  796. {
  797. showDurationPicker ? durationPickerContent() : editPickerContent()
  798. }
  799. </Modal>
  800. }
  801. return <View />
  802. }
  803. function onlyStageContent() {
  804. var bgRing = getBgRing()
  805. var common = getCommon(null, false)
  806. common.radius = bigRingRadius;
  807. common.lineWidth = ringWidth;
  808. var timestamp, timestamp2, timestamp3
  809. var duration, duration2, duration3;
  810. var currentDot = getDot(null, true)
  811. if (props.record.status == 'WAIT_FOR_START') {
  812. var date = new Date()
  813. date.setSeconds(0)
  814. date.setMilliseconds(0)
  815. var fastStart = props.schedule.fast.start_time
  816. var sleepStart = props.schedule.sleep.start_time
  817. var sleepEnd = props.schedule.sleep.end_time
  818. date.setHours(parseInt(fastStart.split(':')[0]))
  819. date.setMinutes(parseInt(fastStart.split(':')[1]))
  820. timestamp = date.getTime()
  821. date.setHours(parseInt(sleepStart.split(':')[0]))
  822. date.setMinutes(parseInt(sleepStart.split(':')[1]))
  823. timestamp2 = date.getTime()
  824. if (timestamp2 < timestamp) {
  825. timestamp2 += 24 * 3600 * 1000
  826. }
  827. date.setHours(parseInt(sleepEnd.split(':')[0]))
  828. date.setMinutes(parseInt(sleepEnd.split(':')[1]))
  829. timestamp3 = date.getTime()
  830. if (timestamp3 < timestamp2) {
  831. timestamp3 += 24 * 3600 * 1000
  832. }
  833. duration = durationArc(props.record.fast.target_start_time, props.record.sleep.target_start_time)
  834. duration2 = durationArc(props.record.sleep.target_start_time, props.record.sleep.target_end_time)
  835. duration3 = durationArc(props.record.sleep.target_end_time, props.record.fast.target_end_time)
  836. currentDot = null;
  837. }
  838. else if (props.record.status == 'ONGOING1') {
  839. var date = new Date()
  840. timestamp = props.record.fast.real_start_time
  841. timestamp2 = props.record.sleep.target_start_time
  842. timestamp3 = props.record.sleep.target_end_time
  843. duration = durationArc(props.record.fast.real_start_time, date.getTime())
  844. duration2 = durationArc(props.record.sleep.target_start_time, props.record.sleep.target_end_time)
  845. duration3 = durationArc(props.record.sleep.target_end_time, props.record.fast.target_end_time)
  846. if (props.stageIndex == 0) {
  847. currentDot.color = ColorType.fast
  848. }
  849. else {
  850. currentDot = null
  851. }
  852. }
  853. else if (props.record.status == 'ONGOING2') {
  854. var date = new Date()
  855. timestamp = props.record.fast.real_start_time
  856. timestamp2 = props.record.sleep.real_start_time
  857. timestamp3 = props.record.sleep.target_end_time
  858. duration = durationArc(props.record.fast.real_start_time, props.record.sleep.real_start_time)
  859. duration2 = durationArc(props.record.sleep.real_start_time, date.getTime())
  860. duration3 = durationArc(props.record.sleep.target_end_time, props.record.fast.target_end_time)
  861. if (props.stageIndex == 1) {
  862. currentDot.color = ColorType.sleep
  863. }
  864. else {
  865. currentDot = null
  866. }
  867. }
  868. else if (props.record.status == 'ONGOING3') {
  869. var date = new Date()
  870. timestamp = props.record.fast.real_start_time
  871. timestamp2 = props.record.sleep.real_start_time
  872. timestamp3 = props.record.sleep.real_end_time
  873. duration = durationArc(props.record.fast.real_start_time, props.record.sleep.real_start_time)
  874. duration2 = durationArc(props.record.sleep.real_start_time, props.record.sleep.real_end_time)
  875. duration3 = durationArc(props.record.sleep.real_end_time, date.getTime())
  876. if (props.stageIndex == 2) {
  877. currentDot.color = ColorType.fast
  878. }
  879. else {
  880. currentDot = null
  881. }
  882. }
  883. else {
  884. timestamp = TimeFormatter.transferTimestamp(props.record.fast.real_start_time, props.record.fast.real_end_timezone.gmt)
  885. timestamp2 = TimeFormatter.transferTimestamp(props.record.sleep.real_start_time, props.record.fast.real_end_timezone.gmt)
  886. timestamp3 = TimeFormatter.transferTimestamp(props.record.sleep.real_end_time, props.record.fast.real_end_timezone.gmt)
  887. duration = durationArc(props.record.fast.real_start_time, props.record.sleep.real_start_time)
  888. duration2 = durationArc(props.record.sleep.real_start_time, props.record.sleep.real_end_time)
  889. duration3 = durationArc(props.record.sleep.real_end_time, props.record.fast.real_end_time)
  890. currentDot = null
  891. }
  892. const preRing: RealRing = {
  893. color: global.fastColor ? global.fastColor : ColorType.fast,
  894. startArc: startArc(timestamp),
  895. durationArc: duration
  896. }
  897. const sleepRing: RealRing = {
  898. color: global.sleepColor ? global.sleepColor : ColorType.sleep,
  899. startArc: startArc(timestamp2),
  900. durationArc: duration2
  901. }
  902. const wakeRing: RealRing = {
  903. color: global.fastColor ? global.fastColor : ColorType.fast,
  904. startArc: startArc(timestamp3),
  905. durationArc: duration3
  906. }
  907. return <View className='detail_container'>
  908. {/* <Text className='detail_popup_title'>{getTitle()}<Text className='detail_popup_subttitle'> {getSubTitle()}</Text></Text> */}
  909. <View style={{ marginTop: rpxToPx(0) }}>
  910. {
  911. props.stageIndex == 0 && <View className='pop_ring_bg' style={{ borderTopColor: 'transparent' }}>
  912. <Rings common={common} bgRing={bgRing} canvasId={'pre_sleep_ring'} realRing={preRing} currentDot={currentDot} />
  913. <View className="pop_duration_bg">
  914. <Text className="pop_duration_title">{t('feature.track_time_duration.stage.a')}</Text>
  915. <Text className="pop_duration_value" style={{ color: ColorType.fast }}>{getStageDuration(0)}</Text>
  916. </View>
  917. </View>
  918. }
  919. {
  920. props.stageIndex == 1 && <View className='pop_ring_bg' style={{ borderTopColor: 'transparent' }}>
  921. <Rings common={common} bgRing={bgRing} canvasId={'sleeping_ring'} realRing={sleepRing} currentDot={currentDot} />
  922. <View className="pop_duration_bg">
  923. <Text className="pop_duration_title">{t('feature.track_time_duration.stage.b')}</Text>
  924. <Text className="pop_duration_value" style={{ color: ColorType.sleep }}>{getStageDuration(1)}</Text>
  925. </View>
  926. </View>
  927. }
  928. {
  929. props.stageIndex == 2 && <View className='pop_ring_bg' style={{ borderTopColor: 'transparent' }}>
  930. <Rings common={common} bgRing={bgRing} canvasId={'later_sleep_ring'} realRing={wakeRing} currentDot={currentDot} />
  931. <View className="pop_duration_bg">
  932. <Text className="pop_duration_title">{t('feature.track_time_duration.stage.c')}</Text>
  933. <Text className="pop_duration_value" style={{ color: ColorType.fast }}>{getStageDuration(2)}</Text>
  934. </View>
  935. </View>
  936. }
  937. </View>
  938. </View>
  939. }
  940. if (props.onlyStage) {
  941. return onlyStageContent()
  942. }
  943. return <View className='detail_container'>
  944. <View style={{display:'flex',flexDirection:'row',alignItems:'flex-end'}}>
  945. <Text className='detail_popup_title'>{getTitle()}</Text>
  946. <Text className='detail_popup_subttitle'> {getSubTitle()}</Text>
  947. </View>
  948. {/* <Text className='detail_popup_title'>{getTitle()}<Text className='detail_popup_subttitle'> {getSubTitle()}</Text></Text> */}
  949. <View className='detail_tabbar'>
  950. <View onClick={() => { setTabIndex(0) }} className={tabIndex == 0 ? 'detail_tabitem_sel' : 'detail_tabitem_nor'}>{t('feature.day_night.overview')}</View>
  951. {
  952. // props.record.status == 'COMPLETED' &&
  953. // (props.record.sleep && props.record.sleep.status == 'COMPLETED') &&
  954. props.record.scenario == 'FAST_SLEEP' &&
  955. <View onClick={() => { setTabIndex(1) }} className={tabIndex == 1 ? 'detail_tabitem_sel' : 'detail_tabitem_nor'}>{t('feature.day_night.stages')}</View>
  956. }
  957. <View onClick={() => { setTabIndex(2) }} className={tabIndex == 2 ? 'detail_tabitem_sel' : 'detail_tabitem_nor'}>{t('feature.day_night.events')}</View>
  958. </View>
  959. <View className='detail_content'>
  960. {
  961. tabIndex == 0 ? overview() : tabIndex == 1 ? stage() : events()
  962. }
  963. </View>
  964. <View className='detail_bottom'>
  965. {
  966. process.env.TARO_ENV == 'weapp' ?
  967. <View className='detail_bottom_btn' onClick={(e) => {
  968. if (process.env.TARO_ENV == 'weapp') {
  969. e.stopPropagation()
  970. }
  971. global.updateFastSleepData(detail, schedule)
  972. props.onClose();
  973. }}>{getBottomText()}</View> :
  974. <View onClick={(e) => {
  975. global.updateFastSleepData(detail, schedule)
  976. props.onClose();
  977. }}>
  978. <LinearGradient
  979. style={{
  980. width: 300,
  981. height: 50,
  982. borderRadius: 25,
  983. alignItems: 'center',
  984. justifyContent: 'center',
  985. }}
  986. colors={[ColorType.fast, ColorType.sleep]}
  987. start={{ x: 0, y: 0 }}
  988. end={{ x: 1, y: 0 }}
  989. >
  990. <Text style={{ fontWeight: 'bold', fontSize: 20 }}>{getBottomText()}</Text>
  991. </LinearGradient>
  992. </View>
  993. // <View className='detail_bottom_btn' onClick={(e) => {
  994. // global.updateFastSleepData(detail, schedule)
  995. // props.onClose();
  996. // }}>{getBottomText()}</View>
  997. }
  998. </View>
  999. {
  1000. modalContent()
  1001. }
  1002. </View>
  1003. }