CircadianDetailPopup.tsx 50 KB

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