| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088 |
- import { View, Text, PageContainer, Image } from '@tarojs/components'
- import './CircadianDetailPopup.scss'
- import { useEffect, useRef, useState } from 'react'
- import TimelineFastSleep from './TimelineFastSleep'
- import { RealRing } from "@/features/trackTimeDuration/components/Rings";
- import Rings from "./Rings";
- import { bigRingRadius, getBgRing, getCommon, getDot, ringWidth } from '../hooks/RingData';
- import { ColorType } from '@/context/themes/color';
- import { useTranslation } from 'react-i18next';
- import { TimeFormatter } from '@/utils/time_format';
- import { getTimezone, rpxToPx } from '@/utils/tools';
- import { useSelector } from 'react-redux';
- import { durationDatas, durationIndex, getColor, getDurationTitle } from '../hooks/Console';
- import Modal from '@/components/layout/Modal.weapp';
- import { updateRecord } from '@/services/trackTimeDuration';
- import PickerViews from '@/components/input/PickerViews';
- import Taro from '@tarojs/taro';
- import { IconInfo, IconMinus, IconPlus } from '@/components/basic/Icons';
- let LinearGradient
- if (process.env.TARO_ENV == 'rn') {
- LinearGradient = require('react-native-linear-gradient').default
- }
- export default function CircadianDetailPopup(props: { record: any, schedule?: any, onClose: Function, stageIndex?: number, onlyStage?: boolean }) {
- const [tabIndex, setTabIndex] = useState(0)
- const [diffTimeZone, setDiffTimeZone] = useState(false)
- const [multiTimeZone, setMultiTimeZone] = useState(false)
- const [detail, setDetail] = useState(JSON.parse(JSON.stringify(props.record)))
- const [showDurationPicker, setShowDurationPicker] = useState(false)
- const [fastPickerValue, setFastPickerValue] = useState([0, 0])
- const [sleepPickerValue, setSleepPickerValue] = useState([0, 0])
- const [showEditPicker, setShowEditPicker] = useState(false)
- const [schedule, setSchedule] = useState(props.schedule)
- const [isFast, setIsFast] = useState(true)
- const durationPickerRef = useRef(null)
- const common = useSelector((state: any) => state.common);
- const { t } = useTranslation()
- useEffect(() => {
- if (props.record.status == 'COMPLETED') {
- if ((props.record.sleep && props.record.sleep.status == 'COMPLETED') &&
- props.record.scenario == 'FAST_SLEEP') {
- setTabIndex(1)
- }
- else {
- setTabIndex(2)
- }
- }
- }, [])
- useEffect(() => {
- checkTimezone()
- // var current_record = props.record
- if (detail.fast)
- setFastPickerValue(durationIndex(detail.fast.target_start_time, detail.fast.target_end_time, common))
- if (detail.sleep)
- setSleepPickerValue(durationIndex(detail.sleep.target_start_time, detail.sleep.target_end_time, common))
- }, [detail])
- useEffect(() => {
- setDetail(JSON.parse(JSON.stringify(props.record)))
- }, [props.record])
- function checkTimezone() {
- var currentTZ = getTimezone()
- var isDiff = false;
- var isMulti = false;
- var tempTZ = '';
- if (props.record.fast) {
- if (props.record.fast.real_start_timezone.gmt) {
- tempTZ = props.record.fast.real_start_timezone.gmt
- if (props.record.fast.real_start_timezone.gmt != currentTZ) {
- isDiff = true
- }
- }
- if (props.record.fast.real_end_timezone.gmt) {
- if (tempTZ != props.record.fast.real_end_timezone.gmt) {
- isMulti = true
- }
- if (props.record.fast.real_end_timezone.gmt != currentTZ) {
- isDiff = true
- }
- }
- }
- if (props.record.sleep) {
- if (props.record.sleep.real_start_timezone.gmt) {
- if (tempTZ == '') {
- tempTZ = props.record.sleep.real_start_timezone.gmt
- }
- else if (tempTZ != props.record.sleep.real_start_timezone.gmt) {
- isMulti = true
- }
- if (props.record.sleep.real_start_timezone.gmt != currentTZ) {
- isDiff = true
- }
- }
- if (props.record.sleep.real_end_timezone.gmt) {
- if (tempTZ != props.record.sleep.real_end_timezone.gmt) {
- isMulti = true
- }
- if (props.record.sleep.real_end_timezone.gmt != currentTZ) {
- isDiff = true
- }
- }
- }
- setDiffTimeZone(isDiff)
- setMultiTimeZone(isMulti)
- }
- function getTitle() {
- if (props.record.status == 'COMPLETED') {
- var timestamp = props.record.first_real_check_time
- if (props.record.first_timezone) {
- timestamp = TimeFormatter.transferTimestamp(timestamp, props.record.first_timezone.gmt)
- }
- return TimeFormatter.getDayOfWeek(new Date(timestamp).getDay(), true)
- }
- if (props.record.status == 'WAIT_FOR_START') {
- return t('feature.track_time_duration.common.schedule')
- }
- return t('feature.track_time_duration.common.current_schedule')
- }
- function getSubTitle() {
- if (props.record.status == 'COMPLETED') {
- var timestamp = props.record.first_real_check_time
- if (props.record.first_timezone) {
- timestamp = TimeFormatter.transferTimestamp(timestamp, props.record.first_timezone.gmt)
- }
- return TimeFormatter.dateDescription(timestamp, true)
- }
- return ''
- }
- function getBottomText() {
- if (props.record.status == 'WAIT_FOR_START') {
- return t('feature.track_time_duration.common.im_ready')
- }
- if (props.record.status == 'COMPLETED') {
- return t('feature.track_time_duration.common.got_it')
- }
- return t('feature.track_time_duration.common.okay')
- }
- const startArc = (time: number) => {
- var date = new Date(time);
- var hour = date.getHours();
- var minute = date.getMinutes();
- var second = date.getSeconds();
- return (hour * 3600 + minute * 60 + second) / (24 * 3600) * 2 * Math.PI - Math.PI / 2.0;
- }
- function durationArc(start_time: number, end_time: number) {
- var duration = (end_time - start_time) / 1000;
- return duration / (24 * 3600) * 2 * Math.PI;
- }
- function getStageDuration(index) {
- var start, end;
- switch (index) {
- case 0:
- if (props.record.status == 'WAIT_FOR_START') {
- start = props.record.fast.target_start_time
- end = props.record.sleep.target_start_time
- }
- else if (props.record.status == 'ONGOING1') {
- return TimeFormatter.countdown(props.record.fast.real_start_time)
- }
- else {
- start = props.record.fast.real_start_time
- end = props.record.sleep.real_start_time
- }
- break
- case 1:
- if (props.record.status == 'WAIT_FOR_START' ||
- props.record.status == 'ONGOING1') {
- start = props.record.sleep.target_start_time
- end = props.record.sleep.target_end_time
- }
- else if (props.record.status == 'ONGOING2') {
- return TimeFormatter.countdown(props.record.sleep.real_start_time)
- }
- else {
- start = props.record.sleep.real_start_time
- end = props.record.sleep.real_end_time
- }
- break
- case 2:
- if (props.record.status == 'WAIT_FOR_START' ||
- props.record.status == 'ONGOING1' ||
- props.record.status == 'ONGOING2') {
- start = props.record.sleep.target_end_time
- end = props.record.fast.target_end_time
- }
- else if (props.record.status == 'ONGOING3') {
- return TimeFormatter.countdown(props.record.sleep.real_end_time)
- }
- else {
- start = props.record.sleep.real_end_time
- end = props.record.fast.real_end_time
- }
- break
- case 3:
- start = props.record.fast.real_start_time
- end = props.record.fast.real_end_time
- if (props.record.fast.status == 'NOT_COMPLETED') {
- return t('feature.track_time_duration.stage.not_completed')
- }
- break
- case 4:
- if (props.record.sleep.status == 'NOT_STARTED') {
- return t('feature.track_time_duration.stage.not_started')
- }
- else if (props.record.sleep.status == 'NOT_COMPLETED') {
- return t('feature.track_time_duration.stage.not_completed')
- }
- start = props.record.sleep.real_start_time
- end = props.record.sleep.real_end_time
- break;
- }
- if (start > end) {
- return t('feature.track_time_duration.console.no_duration_available')
- // return '-' + TimeFormatter.durationFormate2(start, end)
- }
- return TimeFormatter.calculateTimeDifference(start, end)
- }
- function completedOverView() {
- var bgRing = getBgRing()
- var common = getCommon(null, false)
- common.radius = bigRingRadius;
- common.lineWidth = ringWidth;
- var fastRing: RealRing = null
- if (props.record.fast) {
- var timestamp = TimeFormatter.transferTimestamp(props.record.fast.real_start_time, props.record.fast.real_end_timezone.gmt)
- fastRing = {
- color: global.fastColor ? global.fastColor : ColorType.fast,
- startArc: startArc(timestamp),//startArc(props.record.fast.real_start_time),
- durationArc: durationArc(props.record.fast.real_start_time, props.record.fast.real_end_time)
- }
- if (props.record.fast.status == 'NOT_COMPLETED') {
- fastRing.durationArc = 0.01
- }
- }
- var sleepRing: RealRing = null
- if (props.record.sleep && props.record.sleep.status == 'COMPLETED') {
- var timestamp = TimeFormatter.transferTimestamp(props.record.sleep.real_start_time,
- props.record.fast ? props.record.fast.real_end_timezone.gmt : props.record.sleep.real_end_timezone.gmt)
- sleepRing = {
- color: global.sleepColor ? global.sleepColor : ColorType.sleep,
- startArc: startArc(timestamp),//startArc(props.record.sleep.real_start_time),
- durationArc: durationArc(props.record.sleep.real_start_time, props.record.sleep.real_end_time)
- }
- }
- if (props.record.sleep && props.record.sleep.status == 'NOT_COMPLETED') {
- var timestamp = TimeFormatter.transferTimestamp(props.record.sleep.real_start_time,
- props.record.fast ? props.record.fast.real_end_timezone.gmt : props.record.sleep.real_end_timezone.gmt)
- sleepRing = {
- color: global.sleepColor ? global.sleepColor : ColorType.sleep,
- startArc: startArc(timestamp),//startArc(props.record.sleep.real_start_time),
- durationArc: 0.01
- }
- }
- return <View>
- {
- props.record.fast && <View className='pop_ring_bg'>
- <Rings common={common} bgRing={bgRing} canvasId={'pop_fast_ring'} realRing={fastRing} />
- <View className="pop_duration_bg">
- <Text className="pop_duration_title">{t('feature.track_time_duration.record_fast_sleep.item.fast')}</Text>
- <Text className="pop_duration_value" style={{ color: ColorType.fast }}>{getStageDuration(3)}</Text>
- </View>
- </View>
- }
- {
- props.record.sleep && <View className='pop_ring_bg'>
- <Rings common={common} bgRing={bgRing} canvasId={'pop_sleep_ring'} realRing={sleepRing} />
- <View className="pop_duration_bg">
- <Text className="pop_duration_title">{t('feature.track_time_duration.record_fast_sleep.item.sleep')}</Text>
- <Text className="pop_duration_value" style={{ color: ColorType.sleep }}>{getStageDuration(4)}</Text>
- </View>
- </View>
- }
- </View>
- }
- function tapDuration(isFast: boolean) {
- if (isFast) {
- setIsFast(true)
- global.pauseIndexTimer = true
- if (props.record.status == 'WAIT_FOR_START') {
- setShowDurationPicker(true)
- }
- else {
- setShowEditPicker(true)
- }
- }
- else {
- setIsFast(false)
- if (props.record.status == 'WAIT_FOR_START' && props.record.scenario == 'FAST_SLEEP') {
- Taro.showToast({
- title: t('feature.track_time_duration.common.start_fasting_first'),
- icon: 'none'
- })
- return;
- }
- global.pauseIndexTimer = true
- if (props.record.status == 'WAIT_FOR_START' || props.record.status == 'ONGOING1') {
- setShowDurationPicker(true)
- }
- else {
- setShowEditPicker(true)
- }
- }
- }
- function tapMinus(isFast: boolean) {
- if (isFast) {
- var fastDuration = detail.fast.target_end_time - detail.fast.target_start_time
- if (fastDuration == 3600000) {
- Taro.showToast({
- icon: 'none',
- title: 'feature.common.toast.min_value'
- })
- return
- }
- var count = fastDuration - common.duration.step * 60 * 1000
- count = count < 3600000 ? 3600000 : count
- detail.fast.target_end_time = detail.fast.target_start_time + count;
- setFastPickerValue(durationIndex(detail.fast.target_start_time, detail.fast.target_end_time, common))
- if (props.record.status == 'WAIT_FOR_START') {
- // var start = props.schedule.fast.start_time
- // var startCount = (parseInt(start.split(':')[0]) * 60 + parseInt(start.split(':')[1])) * 60 * 1000
- // var endCount = startCount + count
- // if (endCount >= 24 * 3600 * 1000) {
- // endCount -= 24 * 3600 * 1000
- // }
- // endCount = endCount / 60000
- // var endHour = Math.floor(endCount / 60)
- // var endMinute = endCount % 60
- // var endTime = TimeFormatter.padZero(endHour) + ':' + TimeFormatter.padZero(endMinute)
- // console.log(endTime)
- changeSchedule(count)
- }
- }
- else {
- if (props.record.status == 'WAIT_FOR_START' && props.record.scenario == 'FAST_SLEEP') {
- Taro.showToast({
- title: t('feature.track_time_duration.common.start_fasting_first'),
- icon: 'none'
- })
- return;
- }
- var sleepDuration = detail.sleep.target_end_time - detail.sleep.target_start_time
- if (sleepDuration == 3600000) {
- Taro.showToast({
- icon: 'none',
- title: 'feature.common.toast.min_value'
- })
- return
- }
- var count = sleepDuration - common.duration.step * 60 * 1000
- count = count < 3600000 ? 3600000 : count
- detail.sleep.target_end_time = detail.sleep.target_start_time + count;
- setSleepPickerValue(durationIndex(detail.sleep.target_start_time, detail.sleep.target_end_time, common))
- }
- setDetail(JSON.parse(JSON.stringify(detail)))
- }
- function tapPlus(isFast: boolean) {
- if (isFast) {
- var fastDuration = detail.fast.target_end_time - detail.fast.target_start_time
- if (fastDuration == 23 * 3600000) {
- Taro.showToast({
- icon: 'none',
- title: 'feature.common.toast.max_value'
- })
- return
- }
- var count = fastDuration + common.duration.step * 60 * 1000
- count = count > 23 * 3600000 ? 23 * 3600000 : count
- detail.fast.target_end_time = detail.fast.target_start_time + count;
- setFastPickerValue(durationIndex(detail.fast.target_start_time, detail.fast.target_end_time, common))
- if (props.record.status == 'WAIT_FOR_START') {
- changeSchedule(count)
- // var start = props.schedule.fast.start_time
- // var startCount = (parseInt(start.split(':')[0]) * 60 + parseInt(start.split(':')[1])) * 60 * 1000
- // var endCount = startCount + count
- // if (endCount >= 24 * 3600 * 1000) {
- // endCount -= 24 * 3600 * 1000
- // }
- // endCount = endCount / 60000
- // var endHour = Math.floor(endCount / 60)
- // var endMinute = endCount % 60
- // var endTime = TimeFormatter.padZero(endHour) + ':' + TimeFormatter.padZero(endMinute)
- // console.log(endTime)
- }
- }
- else {
- if (props.record.status == 'WAIT_FOR_START' && props.record.scenario == 'FAST_SLEEP') {
- Taro.showToast({
- title: t('feature.track_time_duration.common.start_fasting_first'),
- icon: 'none'
- })
- return;
- }
- var sleepDuration = detail.sleep.target_end_time - detail.sleep.target_start_time
- if (sleepDuration == 23 * 3600000) {
- Taro.showToast({
- icon: 'none',
- title: 'feature.common.toast.max_value'
- })
- return
- }
- var count = sleepDuration + common.duration.step * 60 * 1000
- count = count > 23 * 3600000 ? 23 * 3600000 : count
- detail.sleep.target_end_time = detail.sleep.target_start_time + count;
- setSleepPickerValue(durationIndex(detail.sleep.target_start_time, detail.sleep.target_end_time, common))
- }
- setDetail(JSON.parse(JSON.stringify(detail)))
- }
- function changeSchedule(count: number) {
- if (!schedule) {
- return
- }
- var obj = JSON.parse(JSON.stringify(schedule))
- var start = schedule.fast.start_time
- var startCount = (parseInt(start.split(':')[0]) * 60 + parseInt(start.split(':')[1])) * 60 * 1000
- var endCount = startCount + count
- if (endCount >= 24 * 3600 * 1000) {
- endCount -= 24 * 3600 * 1000
- }
- endCount = endCount / 60000
- var endHour = Math.floor(endCount / 60)
- var endMinute = endCount % 60
- var endTime = TimeFormatter.padZero(endHour) + ':' + TimeFormatter.padZero(endMinute)
- obj.fast.end_time = endTime
- setSchedule(obj)
- }
- function sleepRealDuration() {
- return getStageDuration(4)
- }
- function fastOverview() {
- if (props.record.fast.status == 'WAIT_FOR_START') {
- return <View className='pop_ring_bg pop_overview_bg'>
- <Text className='pop_duration_title'>{t('feature.track_time_duration.record_fast_sleep.item.fast')}</Text>
- <View onClick={() => tapDuration(true)} style={{ flexDirection: 'row', alignItems: 'center', marginTop: rpxToPx(8), display: 'flex', width: '100%' }}>
- <Text className='pop_duration_txt' style={{ color: ColorType.fast }}>{TimeFormatter.durationFormate(detail.fast.target_start_time, detail.fast.target_end_time)}</Text>
- <View onClick={(e) => {
- if (process.env.TARO_ENV == 'weapp') {
- e.stopPropagation()
- }
- tapMinus(true)
- }} className='minus' style={{ backgroundColor: ColorType.fast, opacity: 0.6 }}><IconMinus color='#090909' /></View>
- <View onClick={(e) => {
- if (process.env.TARO_ENV == 'weapp') {
- e.stopPropagation()
- }
- tapPlus(true)
- }} className='plus' style={{ backgroundColor: ColorType.fast }}><IconPlus color='#090909' /></View>
- </View>
- </View>
- }
- else if (props.record.status != 'COMPLETED') {
- return <View className='pop_ring_bg pop_overview_bg'>
- <Text className='pop_duration_title'>{t('feature.track_time_duration.record_fast_sleep.item.fast')}</Text>
- <View onClick={() => tapDuration(true)} style={{ flexDirection: 'row', alignItems: 'center', marginTop: rpxToPx(8), display: 'flex', width: '100%' }}>
- <Text className='pop_duration_txt'>{TimeFormatter.durationFormate(detail.fast.target_start_time, detail.fast.target_end_time)}</Text>
- <Image onClick={() => tapDuration(true)} className="arrow2" src={require('@/assets/images/arrow3.png')} />
- </View>
- <View style={{ marginTop: rpxToPx(20), display: 'flex', flexDirection: 'row', alignItems: 'center' }}>
- <View className='countdown_time_bg'>
- <Text className='title' style={{ color: '#fff', opacity: 0.4 }}>{t('feature.track_time_duration.console.countup')}</Text>
- <Text className='value' style={{ color: ColorType.fast }}>{TimeFormatter.formateTimeNow(props.record.fast.real_start_time)}</Text>
- </View>
- <View className='countdown_time_bg'>
- {
- 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> :
- <Text className='title' style={{ color: '#fff', opacity: 0.4 }}>{t('feature.track_time_duration.console.countdown_not_due')}</Text>
- }
- {
- props.record.fast.target_end_time < new Date().getTime() ?
- <Text className='value' style={{ color: ColorType.alert }}>{TimeFormatter.countdown(props.record.fast.target_end_time)}</Text> :
- <Text className='value' style={{ color: ColorType.fast, opacity: 0.6 }}>{TimeFormatter.countdown(props.record.fast.target_end_time)}</Text>
- }
- </View>
- </View>
- </View>
- }
- }
- function sleepOverview() {
- if (props.record.sleep.status == 'WAIT_FOR_START') {
- return <View className='pop_ring_bg pop_overview_bg'>
- <Text className='pop_duration_title'>{t('feature.track_time_duration.record_fast_sleep.item.sleep')}</Text>
- <View onClick={() => tapDuration(false)} style={{ flexDirection: 'row', alignItems: 'center', marginTop: rpxToPx(8), display: 'flex', width: '100%' }}>
- <Text className='pop_duration_txt' style={{ color: ColorType.sleep }}>{TimeFormatter.durationFormate(detail.sleep.target_start_time, detail.sleep.target_end_time)}</Text>
- <View onClick={(e) => {
- if (process.env.TARO_ENV == 'weapp') {
- e.stopPropagation()
- }
- tapMinus(false)
- }} className='minus' style={{ backgroundColor: ColorType.sleep, opacity: 0.6 }}><IconMinus color='#090909' /></View>
- <View onClick={(e) => {
- if (process.env.TARO_ENV == 'weapp') {
- e.stopPropagation()
- }
- tapPlus(false)
- }} className='plus' style={{ backgroundColor: ColorType.sleep }}><IconPlus color='#090909' /></View>
- </View>
- </View>
- }
- else if (props.record.sleep.status == 'WAIT_FOR_END') {
- return <View className='pop_ring_bg pop_overview_bg'>
- <Text className='pop_duration_title'>{t('feature.track_time_duration.record_fast_sleep.item.sleep')}</Text>
- <View onClick={() => tapDuration(false)} style={{ flexDirection: 'row', alignItems: 'center', marginTop: rpxToPx(8), display: 'flex', width: '100%' }}>
- <Text className='pop_duration_txt'>{TimeFormatter.durationFormate(detail.sleep.target_start_time, detail.sleep.target_end_time)}</Text>
- <Image onClick={() => tapDuration(false)} className="arrow2" src={require('@/assets/images/arrow3.png')} />
- </View>
- <View style={{ marginTop: rpxToPx(20), display: 'flex', flexDirection: 'row', alignItems: 'center' }}>
- <View className='countdown_time_bg'>
- <Text className='title'>{t('feature.track_time_duration.console.countup')}</Text>
- <Text className='value' style={{ color: ColorType.sleep }}>{TimeFormatter.formateTimeNow(props.record.sleep.real_start_time)}</Text>
- </View>
- <View className='countdown_time_bg'>
- {
- props.record.sleep.target_end_time < new Date().getTime() ? <Text className='title'>{t('feature.track_time_duration.console.timeout')}</Text> :
- <Text className='title'>{t('feature.track_time_duration.console.countdown_not_due')}</Text>
- }
- {
- props.record.sleep.target_end_time < new Date().getTime() ?
- <Text className='value' style={{ color: ColorType.alert }}>{TimeFormatter.countdown(props.record.sleep.target_end_time)}</Text> :
- <Text className='value' style={{ color: ColorType.sleep, opacity: 0.6 }}>{TimeFormatter.countdown(props.record.sleep.target_end_time)}</Text>
- }
- </View>
- </View>
- </View>
- }
- else {
- return <View className='pop_ring_bg pop_overview_bg'>
- <Text className='pop_duration_title'>{t('feature.track_time_duration.record_fast_sleep.item.sleep')}</Text>
- <View style={{ flexDirection: 'row', alignItems: 'center', marginTop: rpxToPx(8), display: 'flex', width: '100%' }}>
- <Text className='pop_duration_txt' style={{ color: ColorType.sleep }}>{sleepRealDuration()}</Text>
- </View>
- </View>
- }
- }
- function overview() {
- if (props.record.status == 'COMPLETED') {
- return completedOverView()
- }
- return <View>
- {
- props.record.fast && fastOverview()
- }
- {
- props.record.sleep && sleepOverview()
- }
- </View>
- }
- function showPredictedAlert() {
- Taro.showModal({
- title: t('feature.track_time_duration.console.predicted_alert_title'),
- content: t('feature.track_time_duration.console.predicted_alert_content'),
- showCancel: false,
- confirmText: t('feature.track_time_duration.console.predicted_alert_btn')
- })
- }
- function stage() {
- var bgRing = getBgRing()
- var common = getCommon(null, false)
- common.radius = bigRingRadius;
- common.lineWidth = ringWidth;
- var timestamp, timestamp2, timestamp3
- var duration, duration2, duration3;
- var predicted2 = false; //预估
- var predicted3 = false;
- var currentDot = getDot(null, true)
- var currentDot2 = getDot(null, true)
- var currentDot3 = getDot(null, true)
- if (props.record.status == 'WAIT_FOR_START') {
- var date = new Date()
- date.setSeconds(0)
- date.setMilliseconds(0)
- var fastStart = props.schedule.fast.start_time
- var sleepStart = props.schedule.sleep.start_time
- var sleepEnd = props.schedule.sleep.end_time
- date.setHours(parseInt(fastStart.split(':')[0]))
- date.setMinutes(parseInt(fastStart.split(':')[1]))
- timestamp = date.getTime()
- date.setHours(parseInt(sleepStart.split(':')[0]))
- date.setMinutes(parseInt(sleepStart.split(':')[1]))
- timestamp2 = date.getTime()
- if (timestamp2 < timestamp) {
- timestamp2 += 24 * 3600 * 1000
- }
- date.setHours(parseInt(sleepEnd.split(':')[0]))
- date.setMinutes(parseInt(sleepEnd.split(':')[1]))
- timestamp3 = date.getTime()
- if (timestamp3 < timestamp2) {
- timestamp3 += 24 * 3600 * 1000
- }
- duration = durationArc(props.record.fast.target_start_time, props.record.sleep.target_start_time)
- duration2 = durationArc(props.record.sleep.target_start_time, props.record.sleep.target_end_time)
- duration3 = durationArc(props.record.sleep.target_end_time, props.record.fast.target_end_time)
- currentDot = null
- currentDot2 = null
- currentDot3 = null
- }
- else if (props.record.status == 'ONGOING1') {
- var date = new Date()
- timestamp = props.record.fast.real_start_time
- timestamp2 = props.record.sleep.target_start_time
- timestamp3 = props.record.sleep.target_end_time
- duration = durationArc(props.record.fast.real_start_time, date.getTime())
- duration2 = durationArc(props.record.sleep.target_start_time, props.record.sleep.target_end_time)
- duration3 = durationArc(props.record.sleep.target_end_time, props.record.fast.target_end_time)
- predicted2 = true
- predicted3 = true
- currentDot.color = ColorType.fast
- currentDot2 = null
- currentDot3 = null
- }
- else if (props.record.status == 'ONGOING2') {
- var date = new Date()
- timestamp = props.record.fast.real_start_time
- timestamp2 = props.record.sleep.real_start_time
- timestamp3 = props.record.sleep.target_end_time
- duration = durationArc(props.record.fast.real_start_time, props.record.sleep.real_start_time)
- duration2 = durationArc(props.record.sleep.real_start_time, date.getTime())
- duration3 = durationArc(props.record.sleep.target_end_time, props.record.fast.target_end_time)
- predicted2 = false
- predicted3 = true
- currentDot = null
- currentDot2.color = ColorType.sleep
- currentDot3 = null
- }
- else if (props.record.status == 'ONGOING3') {
- var date = new Date()
- timestamp = props.record.fast.real_start_time
- timestamp2 = props.record.sleep.real_start_time
- timestamp3 = props.record.sleep.real_end_time
- duration = durationArc(props.record.fast.real_start_time, props.record.sleep.real_start_time)
- duration2 = durationArc(props.record.sleep.real_start_time, props.record.sleep.real_end_time)
- duration3 = durationArc(props.record.sleep.real_end_time, date.getTime())
- currentDot = null
- currentDot2 = null
- currentDot3.color = ColorType.fast
- }
- else {
- timestamp = TimeFormatter.transferTimestamp(props.record.fast.real_start_time, props.record.fast.real_end_timezone.gmt)
- timestamp2 = TimeFormatter.transferTimestamp(props.record.sleep.real_start_time, props.record.fast.real_end_timezone.gmt)
- timestamp3 = TimeFormatter.transferTimestamp(props.record.sleep.real_end_time, props.record.fast.real_end_timezone.gmt)
- duration = durationArc(props.record.fast.real_start_time, props.record.sleep.real_start_time)
- duration2 = durationArc(props.record.sleep.real_start_time, props.record.sleep.real_end_time)
- duration3 = durationArc(props.record.sleep.real_end_time, props.record.fast.real_end_time)
- currentDot = null
- currentDot2 = null
- currentDot3 = null
- }
- const preRing: RealRing = {
- color: global.fastColor ? global.fastColor : ColorType.fast,
- startArc: startArc(timestamp),
- durationArc: duration
- }
- let sleepRing: RealRing = {
- color: global.sleepColor ? global.sleepColor : ColorType.sleep,
- startArc: startArc(timestamp2),
- durationArc: duration2
- }
- let wakeRing: RealRing = {
- color: global.fastColor ? global.fastColor : ColorType.fast,
- startArc: startArc(timestamp3),
- durationArc: duration3
- }
- if (duration2 < 0) {
- sleepRing = null
- }
- if (duration3 < 0) {
- wakeRing = null
- }
- return <View>
- <View className='pop_ring_bg'>
- <Rings common={common} bgRing={bgRing} canvasId={'pre_sleep_ring'} realRing={preRing} currentDot={currentDot} />
- <View className="pop_duration_bg">
- <Text className="pop_duration_title">{t('feature.track_time_duration.stage.a')}</Text>
- <Text className="pop_duration_value" style={{ color: ColorType.fast }}>{getStageDuration(0)}</Text>
- </View>
- </View>
- <View className='pop_ring_bg'>
- <Rings common={common} bgRing={bgRing} canvasId={'sleeping_ring'} realRing={sleepRing} currentDot={currentDot2} />
- <View className="pop_duration_bg">
- <Text className="pop_duration_title">{t('feature.track_time_duration.stage.b')}</Text>
- <View style={{ display: 'flex', flexDirection: 'row', alignItems: 'center' }}>
- <Text className="pop_duration_value" style={{ color: ColorType.sleep, marginBottom: 0 }}>{getStageDuration(1)}</Text>
- {
- 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
- }
- </View>
- </View>
- </View>
- <View className='pop_ring_bg'>
- <Rings common={common} bgRing={bgRing} canvasId={'later_sleep_ring'} realRing={wakeRing} currentDot={currentDot3} />
- <View className="pop_duration_bg">
- <Text className="pop_duration_title">{t('feature.track_time_duration.stage.c')}</Text>
- <View style={{ display: 'flex', flexDirection: 'row', alignItems: 'center' }}>
- <Text className="pop_duration_value" style={{ color: ColorType.fast, marginBottom: 0 }}>{getStageDuration(2)}</Text>
- {
- 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
- }
- </View>
- </View>
- </View>
- </View>
- }
- function events() {
- return <View style={{ display: 'flex', flexDirection: 'row', alignItems: 'center', justifyContent: 'center' }}>
- <TimelineFastSleep
- data={props.record}
- first_real_check_time={props.record.first_real_check_time ? props.record.first_real_check_time : 0}
- scenario={schedule ? { schedule: schedule } : null}
- diffTimeZone={diffTimeZone} multiTimeZone={multiTimeZone} />
- </View>
- }
- function durationPickerContent() {
- var color = getColor(props.record)
- var title = getDurationTitle(props.record, t)
- return <View style={{ color: '#fff', backgroundColor: 'transparent' }}>
- <PickerViews ref={durationPickerRef}
- onChange={durationChange}
- items={durationDatas(common)}
- value={isFast ? fastPickerValue : sleepPickerValue}
- themeColor={color}
- title={title}
- showBtns={true}
- onCancel={() => {
- setShowDurationPicker(false)
- global.pauseIndexTimer = false
- }} />
- </View>
- }
- function editPickerContent() {
- return <View style={{ color: '#fff', backgroundColor: 'transparent' }}>
- <PickerViews ref={durationPickerRef}
- onChange={durationChange}
- items={durationDatas(common)}
- value={isFast ? fastPickerValue : sleepPickerValue}
- themeColor={isFast ? ColorType.fast : ColorType.sleep}
- title={isFast ? t('feature.track_time_duration.action_sheet.edit_fasting_goal') :
- t('feature.track_time_duration.action_sheet.edit_sleeping_goal')}
- showBtns={true}
- onCancel={() => {
- setShowEditPicker(false)
- global.pauseIndexTimer = false
- }} />
- </View>
- }
- function durationChange(e) {
- global.pauseIndexTimer = false
- var count = (e[0] + common.duration.min) * 60 + e[1] * common.duration.step
- // var count = (e[0] + 1) * 60 + e[1] * 5
- if (showDurationPicker) {
- // global.changeTargetDuration(count, isFast)
- if (isFast) {
- detail.fast.target_end_time = detail.fast.target_start_time + count * 60 * 1000
- if (props.record.status == 'WAIT_FOR_START') {
- changeSchedule(count * 1000 * 60)
- }
- }
- else {
- detail.sleep.target_end_time = detail.sleep.target_start_time + count * 60 * 1000
- }
- setDetail(JSON.parse(JSON.stringify(detail)))
- }
- else {
- var params: any = {}
- if (isFast) {
- params = {
- fast: {
- target_duration: count * 60 * 1000
- }
- }
- }
- else {
- params = {
- sleep: {
- target_duration: count * 60 * 1000
- }
- }
- }
- updateRecord({
- ...params
- }, props.record.id).then(res => {
- global.indexPageRefresh()
- }).catch(e => {
- })
- }
- setShowDurationPicker(false)
- setShowEditPicker(false)
- }
- function modalContent() {
- if (showDurationPicker || showEditPicker) {
- return <Modal
- testInfo={null}
- dismiss={() => {
- setShowDurationPicker(false)
- setShowEditPicker(false)
- global.pauseIndexTimer = false
- }}
- confirm={() => { }}>
- {
- showDurationPicker ? durationPickerContent() : editPickerContent()
- }
- </Modal>
- }
- return <View />
- }
- function onlyStageContent() {
- var bgRing = getBgRing()
- var common = getCommon(null, false)
- common.radius = bigRingRadius;
- common.lineWidth = ringWidth;
- var timestamp, timestamp2, timestamp3
- var duration, duration2, duration3;
- var currentDot = getDot(null, true)
- if (props.record.status == 'WAIT_FOR_START') {
- var date = new Date()
- date.setSeconds(0)
- date.setMilliseconds(0)
- var fastStart = props.schedule.fast.start_time
- var sleepStart = props.schedule.sleep.start_time
- var sleepEnd = props.schedule.sleep.end_time
- date.setHours(parseInt(fastStart.split(':')[0]))
- date.setMinutes(parseInt(fastStart.split(':')[1]))
- timestamp = date.getTime()
- date.setHours(parseInt(sleepStart.split(':')[0]))
- date.setMinutes(parseInt(sleepStart.split(':')[1]))
- timestamp2 = date.getTime()
- if (timestamp2 < timestamp) {
- timestamp2 += 24 * 3600 * 1000
- }
- date.setHours(parseInt(sleepEnd.split(':')[0]))
- date.setMinutes(parseInt(sleepEnd.split(':')[1]))
- timestamp3 = date.getTime()
- if (timestamp3 < timestamp2) {
- timestamp3 += 24 * 3600 * 1000
- }
- duration = durationArc(props.record.fast.target_start_time, props.record.sleep.target_start_time)
- duration2 = durationArc(props.record.sleep.target_start_time, props.record.sleep.target_end_time)
- duration3 = durationArc(props.record.sleep.target_end_time, props.record.fast.target_end_time)
- currentDot = null;
- }
- else if (props.record.status == 'ONGOING1') {
- var date = new Date()
- timestamp = props.record.fast.real_start_time
- timestamp2 = props.record.sleep.target_start_time
- timestamp3 = props.record.sleep.target_end_time
- duration = durationArc(props.record.fast.real_start_time, date.getTime())
- duration2 = durationArc(props.record.sleep.target_start_time, props.record.sleep.target_end_time)
- duration3 = durationArc(props.record.sleep.target_end_time, props.record.fast.target_end_time)
- if (props.stageIndex == 0) {
- currentDot.color = ColorType.fast
- }
- else {
- currentDot = null
- }
- }
- else if (props.record.status == 'ONGOING2') {
- var date = new Date()
- timestamp = props.record.fast.real_start_time
- timestamp2 = props.record.sleep.real_start_time
- timestamp3 = props.record.sleep.target_end_time
- duration = durationArc(props.record.fast.real_start_time, props.record.sleep.real_start_time)
- duration2 = durationArc(props.record.sleep.real_start_time, date.getTime())
- duration3 = durationArc(props.record.sleep.target_end_time, props.record.fast.target_end_time)
- if (props.stageIndex == 1) {
- currentDot.color = ColorType.sleep
- }
- else {
- currentDot = null
- }
- }
- else if (props.record.status == 'ONGOING3') {
- var date = new Date()
- timestamp = props.record.fast.real_start_time
- timestamp2 = props.record.sleep.real_start_time
- timestamp3 = props.record.sleep.real_end_time
- duration = durationArc(props.record.fast.real_start_time, props.record.sleep.real_start_time)
- duration2 = durationArc(props.record.sleep.real_start_time, props.record.sleep.real_end_time)
- duration3 = durationArc(props.record.sleep.real_end_time, date.getTime())
- if (props.stageIndex == 2) {
- currentDot.color = ColorType.fast
- }
- else {
- currentDot = null
- }
- }
- else {
- timestamp = TimeFormatter.transferTimestamp(props.record.fast.real_start_time, props.record.fast.real_end_timezone.gmt)
- timestamp2 = TimeFormatter.transferTimestamp(props.record.sleep.real_start_time, props.record.fast.real_end_timezone.gmt)
- timestamp3 = TimeFormatter.transferTimestamp(props.record.sleep.real_end_time, props.record.fast.real_end_timezone.gmt)
- duration = durationArc(props.record.fast.real_start_time, props.record.sleep.real_start_time)
- duration2 = durationArc(props.record.sleep.real_start_time, props.record.sleep.real_end_time)
- duration3 = durationArc(props.record.sleep.real_end_time, props.record.fast.real_end_time)
- currentDot = null
- }
- const preRing: RealRing = {
- color: global.fastColor ? global.fastColor : ColorType.fast,
- startArc: startArc(timestamp),
- durationArc: duration
- }
- const sleepRing: RealRing = {
- color: global.sleepColor ? global.sleepColor : ColorType.sleep,
- startArc: startArc(timestamp2),
- durationArc: duration2
- }
- const wakeRing: RealRing = {
- color: global.fastColor ? global.fastColor : ColorType.fast,
- startArc: startArc(timestamp3),
- durationArc: duration3
- }
- return <View className='detail_container'>
- {/* <Text className='detail_popup_title'>{getTitle()}<Text className='detail_popup_subttitle'> {getSubTitle()}</Text></Text> */}
- <View style={{ marginTop: rpxToPx(0) }}>
- {
- props.stageIndex == 0 && <View className='pop_ring_bg' style={{ borderTopColor: 'transparent' }}>
- <Rings common={common} bgRing={bgRing} canvasId={'pre_sleep_ring'} realRing={preRing} currentDot={currentDot} />
- <View className="pop_duration_bg">
- <Text className="pop_duration_title">{t('feature.track_time_duration.stage.a')}</Text>
- <Text className="pop_duration_value" style={{ color: ColorType.fast }}>{getStageDuration(0)}</Text>
- </View>
- </View>
- }
- {
- props.stageIndex == 1 && <View className='pop_ring_bg' style={{ borderTopColor: 'transparent' }}>
- <Rings common={common} bgRing={bgRing} canvasId={'sleeping_ring'} realRing={sleepRing} currentDot={currentDot} />
- <View className="pop_duration_bg">
- <Text className="pop_duration_title">{t('feature.track_time_duration.stage.b')}</Text>
- <Text className="pop_duration_value" style={{ color: ColorType.sleep }}>{getStageDuration(1)}</Text>
- </View>
- </View>
- }
- {
- props.stageIndex == 2 && <View className='pop_ring_bg' style={{ borderTopColor: 'transparent' }}>
- <Rings common={common} bgRing={bgRing} canvasId={'later_sleep_ring'} realRing={wakeRing} currentDot={currentDot} />
- <View className="pop_duration_bg">
- <Text className="pop_duration_title">{t('feature.track_time_duration.stage.c')}</Text>
- <Text className="pop_duration_value" style={{ color: ColorType.fast }}>{getStageDuration(2)}</Text>
- </View>
- </View>
- }
- </View>
- </View>
- }
- if (props.onlyStage) {
- return onlyStageContent()
- }
- return <View className='detail_container'>
- <Text className='detail_popup_title'>{getTitle()}<Text className='detail_popup_subttitle'> {getSubTitle()}</Text></Text>
- <View className='detail_tabbar'>
- <View onClick={() => { setTabIndex(0) }} className={tabIndex == 0 ? 'detail_tabitem_sel' : 'detail_tabitem_nor'}>{t('feature.day_night.overview')}</View>
- {
- // props.record.status == 'COMPLETED' &&
- // (props.record.sleep && props.record.sleep.status == 'COMPLETED') &&
- props.record.scenario == 'FAST_SLEEP' &&
- <View onClick={() => { setTabIndex(1) }} className={tabIndex == 1 ? 'detail_tabitem_sel' : 'detail_tabitem_nor'}>{t('feature.day_night.stages')}</View>
- }
- <View onClick={() => { setTabIndex(2) }} className={tabIndex == 2 ? 'detail_tabitem_sel' : 'detail_tabitem_nor'}>{t('feature.day_night.events')}</View>
- </View>
- <View className='detail_content'>
- {
- tabIndex == 0 ? overview() : tabIndex == 1 ? stage() : events()
- }
- </View>
- <View className='detail_bottom'>
- {
- process.env.TARO_ENV == 'weapp' ?
- <View className='detail_bottom_btn' onClick={(e) => {
- if (process.env.TARO_ENV == 'weapp') {
- e.stopPropagation()
- }
- global.updateFastSleepData(detail, schedule)
- props.onClose();
- }}>{getBottomText()}</View> :
- <View onClick={(e) => {
- global.updateFastSleepData(detail, schedule)
- props.onClose();
- }}>
- <LinearGradient
- style={{
- width: 300,
- height: 50,
- borderRadius: 25,
- alignItems: 'center',
- justifyContent: 'center',
- }}
- colors={[ColorType.fast, ColorType.sleep]}
- start={{ x: 0, y: 0 }}
- end={{ x: 1, y: 0 }}
- >
- <Text style={{ fontWeight: 'bold', fontSize: 20 }}>{getBottomText()}</Text>
- </LinearGradient>
- </View>
- // <View className='detail_bottom_btn' onClick={(e) => {
- // global.updateFastSleepData(detail, schedule)
- // props.onClose();
- // }}>{getBottomText()}</View>
- }
- </View>
- {
- modalContent()
- }
- </View>
- }
|