| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643 |
- import Box from "@/components/layout/Box";
- import Header from "@/components/layout/Header";
- import Modal from "@/components/layout/Modal";
- import RecordItem from "@/features/common/RecordItem";
- import { delRecord } from "@/services/trackTimeDuration";
- import { ModalType } from "@/utils/types";
- import { View, Text, Image, PageContainer } from "@tarojs/components";
- import Taro from "@tarojs/taro";
- import { useEffect, useState, memo } from "react";
- import TimelineFastSleep from "./TimelineFastSleep";
- import { TimeFormatter } from "@/utils/time_format";
- import './RecordFastSleep.scss'
- import { bigRingRadius, getBgRing, getCommon, getDot, getReal, getTarget, ringWidth, smallRingRadius } from "../hooks/RingData";
- import Rings from "./Rings";
- import Segment from "@/components/navigation/Segment";
- import Stage from "./Stage";
- import CenterContentTitleModal from "@/features/common/CenterContentTitleModal";
- import { useTranslation } from "react-i18next";
- import { ColorType } from "@/context/themes/color";
- import TimelineStage from "./TimelineStage";
- import { jumpPage } from "../hooks/Common";
- import { RealRing, CurrentDot } from "@/features/trackTimeDuration/components/Rings";
- import { rpxToPx } from "@/utils/tools";
- import { useDispatch, useSelector } from "react-redux";
- import { setSelID } from "@/store/common";
- import CircadianDetailPopup from "./CircadianDetailPopup";
- // import { sqrt } from 'mathjs'
- let AppState;
- if (process.env.TARO_ENV == 'rn') {
- AppState = require("react-native").AppState
- }
- let stageCanvasId = new Date().getTime()
- let startX = 0
- let startY = 0
- //https://www.php.cn/faq/629819.html
- // export default function RecordFastSleep(props: { data: any, type: string, delSuccess?: Function, index: any }) {
- const RecordFastSleep = memo((props: { data: any, type: string, index: number }) => {
- const [count, setCount] = useState(0)
- const [showDetailModal, setShowDetailModal] = useState(false)
- const [segmentIndex, setSegmentIndex] = useState(0)
- const [diffTimeZone, setDiffTimeZone] = useState(false)
- const [multiTimeZone, setMultiTimeZone] = useState(false)
- const [showMore, setShowMore] = useState(false)
- const [selIndex, setSelIndex] = useState(0)
- const [showMoreModal, setShowMoreModal] = useState(false)
- const [showDel, setShowDel] = useState(false)
- const { t } = useTranslation()
- var canvasId = props.data.id
- const record = props.data;
- const common = useSelector((state: any) => state.common);
- const dispatch = useDispatch();
- const handleAppStateChange = (nextAppState) => {
- checkTimezone()
- };
- useEffect(() => {
- checkTimezone()
- if (process.env.TARO_ENV == 'rn') {
- AppState.addEventListener('change', handleAppStateChange);
- }
- if (record.scenario != 'FAST_SLEEP') {
- setShowMore(false)
- setSelIndex(0)
- }
- if (props.index==-20000){
- global.refreshRecent = ()=>{
- setCount((index)=>index+1)
- }
- setTimeout(()=>{
- setCount((index)=>index+1)
- },100)
- }
- // console.log(sqrt(-4).toString())
- }, [props.data])
- useEffect(() => {
- if (common.recordSelID != props.data.id) {
- setShowDel(false)
- }
- }, [common.recordSelID])
- function checkTimezone() {
- var split = new Date().toString().split(' ');
- var currentTZ = split[split.length - 2];
- var isDiff = false;
- var isMulti = false;
- var tempTZ = '';
- if (props.data.fast) {
- if (props.data.fast.real_start_time_zone) {
- tempTZ = props.data.fast.real_start_time_zone
- if (props.data.fast.real_start_time_zone != currentTZ) {
- isDiff = true
- }
- }
- if (props.data.fast.real_end_time_zone) {
- if (tempTZ != props.data.fast.real_end_time_zone) {
- isMulti = true
- }
- if (props.data.fast.real_end_time_zone != currentTZ) {
- isDiff = true
- }
- }
- }
- if (props.data.sleep) {
- if (props.data.sleep.real_start_time_zone) {
- if (tempTZ == '') {
- tempTZ = props.data.sleep.real_start_time_zone
- }
- else if (tempTZ != props.data.sleep.real_start_time_zone) {
- isMulti = true
- }
- if (props.data.sleep.real_start_time_zone != currentTZ) {
- isDiff = true
- }
- }
- if (props.data.sleep.real_end_time_zone) {
- if (tempTZ != props.data.sleep.real_end_time_zone) {
- isMulti = true
- }
- if (props.data.sleep.real_end_time_zone != currentTZ) {
- isDiff = true
- }
- }
- }
- setDiffTimeZone(isDiff)
- setMultiTimeZone(isMulti)
- }
- function del() {
- var id = props.data.id
- delRecord(id
- ).then(res => {
- // global.refreshTime()
- global.indexPageRefresh()
- Taro.showToast({
- title: t('page.records_history.del_success')
- })
- dispatch(setSelID(-1))
- if (global.delFastSleep)
- global.delFastSleep(props.data)
- // props.delSuccess && props.delSuccess(props.data)
- // Taro.navigateBack()
- })
- }
- function subTitle(timestamp) {
- if (multiTimeZone) {
- return t('feature.common.multi_timezones')
- }
- if (diffTimeZone) {
- return t('feature.common.different_timezone')
- }
- return TimeFormatter.getDateAndWeek(timestamp)
- }
- function schedules() {
- var timestamp = props.data.first_real_check_time
- return <View style={{ display: 'flex', flexDirection: 'column' }}>
- <TimelineStage data={props.data} title={t('feature.track_time_duration.record_fast_sleep.pop_title')}
- subTitle={subTitle(timestamp)} first_real_check_time={timestamp} diffTimeZone={diffTimeZone} multiTimeZone={multiTimeZone} />
- </View>
- }
- function showDetail(e) {
- setShowDel(false);
- if (props.type == 'latest') {
- setSegmentIndex(0)
- global.segmentIndex = 0
- setShowDetailModal(true)
- return;
- }
- setShowDetailModal(true)
- }
- function getDuration(obj) {
- if (obj.status == 'NOT_STARTED' || obj.status == 'NOT_COMPLETED') {
- return ''
- }
- var start = obj.real_start_time
- var end = obj.real_end_time
- if (!end) {
- end = (new Date()).getTime()
- }
- return TimeFormatter.durationFormate(start, end)
- // return TimeFormatter.calculateTimeDifference(start, end)
- }
- function getStageDuration() {
- var start, end;
- switch (selIndex) {
- case 0:
- start = record.fast.real_start_time
- end = record.sleep.real_start_time
- break
- case 1:
- start = record.sleep.real_start_time
- end = record.sleep.real_end_time
- break
- case 2:
- start = record.sleep.real_end_time
- end = record.fast.real_end_time
- break
- }
- return TimeFormatter.durationFormate(start, end)
- }
- function durationArc(start_time: number, end_time: number) {
- var duration = (end_time - start_time) / 1000;
- return duration / (24 * 3600) * 2 * Math.PI;
- }
- function bigRing() {
- var common = getCommon(null, true)
- common.radius = bigRingRadius;
- common.lineWidth = ringWidth;
- var bgRing = getBgRing()
- if (props.type == 'record' || props.type == 'latest') {
- var realRing = getReal(record, true, true)
- if (props.data.status == 'ONGOING3') {
- realRing.color = 'rgba(0,0,0,0)'
- }
- if ((props.data.scenario == 'FAST' && props.data.fast.status == "NOT_COMPLETED") ||
- (props.data.scenario == 'SLEEP' && props.data.sleep.status == "NOT_COMPLETED")) {
- realRing.durationArc = 0.01
- }
- if (props.data.scenario=='FAST_SLEEP' && props.data.fast.status == "NOT_COMPLETED"){
- realRing.durationArc = 0.01
- }
- return <Rings common={common} bgRing={bgRing} canvasId={canvasId} realRing={realRing} />
- }
- else {
- var currentDot1 = getDot(record, true)
- var targetBigRing1 = getTarget(record, true)
- if (record.status == 'ONGOING') {
- var realRing1 = getReal(record, true, false)
- return <Rings common={common} bgRing={bgRing} currentDot={currentDot1} realRing={realRing1} targetRing={targetBigRing1} canvasId={canvasId} />
- }
- if (record.status == 'WAIT_FOR_START') {
- return <Rings common={common} bgRing={bgRing} currentDot={currentDot1} canvasId={canvasId} />
- }
- if (record.status == 'NOT_COMPLETED') {
- return <Rings common={common} bgRing={bgRing} currentDot={currentDot1} canvasId={canvasId} />
- }
- var realRing1 = getReal(record, true, false)
- return <Rings common={common} bgRing={bgRing} realRing={realRing1} currentDot={currentDot1} targetRing={targetBigRing1} canvasId={canvasId} />
- }
- }
- function bigMoreRing() {
- var common = getCommon(null, true)
- common.radius = bigRingRadius;
- common.lineWidth = ringWidth;
- var bgRing = getBgRing()
- var realRing = getReal(record, true, true)
- realRing.color = ColorType.fast + '66'
- var list: any = []
- if (record.scenario == 'FAST_SLEEP') {
- if (selIndex == 0) {
- const realRingBig: RealRing = {
- color: global.fastColor ? global.fastColor : ColorType.fast,
- startArc: startArc(record.fast.real_start_time),
- durationArc: durationArc(record.fast.real_start_time, record.sleep.real_start_time)
- }
- list.push(realRingBig)
- }
- if (selIndex == 1) {
- const realRingBig: RealRing = {
- color: global.fastColor ? global.fastColor : ColorType.fast,
- startArc: startArc(record.sleep.real_start_time),
- durationArc: durationArc(record.sleep.real_start_time, record.sleep.real_end_time)
- }
- list.push(realRingBig)
- }
- if (selIndex == 2) {
- const realRingBig: RealRing = {
- color: global.fastColor ? global.fastColor : ColorType.fast,
- startArc: startArc(record.sleep.real_end_time),
- durationArc: durationArc(record.sleep.real_end_time, record.fast.real_end_time)
- }
- list.push(realRingBig)
- }
- }
- return <Rings common={common} bgRing={bgRing} canvasId={stageCanvasId} stageList={list} realRing={realRing} />
- }
- 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 smallRing() {
- if (record.scenario == 'FAST_SLEEP') {
- var common = getCommon(null, false)
- common.radius = smallRingRadius;
- common.lineWidth = ringWidth;
- var bgRing = getBgRing()
- var realRing = getReal(record, false, false)
- if (props.type == 'record' || props.type == 'latest') {
- var showReal = false;
- if (record.sleep.status == 'WAIT_FOR_END') {
- realRing.durationArc = durationArc(record.sleep.target_start_time, (new Date()).getTime())
- showReal = true
- // return <Rings common={common} bgRing={bgRing} canvasId={canvasId + 'small'} realRing={realRing} />
- }
- else if (record.sleep.status == 'NOT_COMPLETED') {
- realRing.durationArc = 0.01
- showReal = true
- // return <Rings common={common} bgRing={bgRing} canvasId={canvasId + 'small'} realRing={realRing} />
- }
- else if (record.sleep.status == 'COMPLETED') {
- realRing = getReal(record, false, true)
- showReal = true
- // return <Rings common={common} bgRing={bgRing} canvasId={canvasId + 'small'} realRing={realRing} />
- }
- return <Rings common={common} bgRing={bgRing} canvasId={canvasId + 'small'} realRing={showReal ? realRing : null} />
- // if (record.sleep.status == 'WAIT_FOR_END') {
- // realRing.durationArc = durationArc(record.sleep.target_start_time, (new Date()).getTime())
- // return <Rings common={common} bgRing={bgRing} canvasId={canvasId + 'small'} realRing={realRing} />
- // }
- // else if (record.sleep.status == 'NOT_COMPLETED') {
- // realRing.durationArc = 0.01
- // return <Rings common={common} bgRing={bgRing} canvasId={canvasId + 'small'} realRing={realRing} />
- // }
- // else if (record.sleep.status == 'COMPLETED') {
- // realRing = getReal(record, false, true)
- // return <Rings common={common} bgRing={bgRing} canvasId={canvasId + 'small'} realRing={realRing} />
- // }
- // return <Rings common={common} bgRing={bgRing} canvasId={canvasId + 'small'} />
- }
- else {
- var currentDot = getDot(record, false)
- var targetRing = getTarget(record, false)
- if (record.status == 'ONGOING2') {
- var realRing = getReal(record, false, false)
- return <Rings common={common} bgRing={bgRing} realRing={realRing} currentDot={currentDot} targetRing={targetRing} canvasId={canvasId + 'small'} />
- }
- if (record.status == 'ONGOING3') {
- currentDot.color = 'rgba(0, 255, 255, 0.5)'
- }
- return <Rings common={common} bgRing={bgRing} currentDot={currentDot} canvasId={canvasId + 'small'} />
- }
- }
- return null
- }
- function rings() {
- return <View style={{ position: 'relative', zIndex: 1 }}>
- {
- bigRing()
- }
- <View style={{ display: 'flex', position: 'absolute', left: 0, right: 0, top: 0, bottom: 0, alignItems: 'center', justifyContent: 'center' }}>
- {
- smallRing()
- }
- </View>
- </View>
- }
- function recordTime() {
- var timestamp = props.data.first_real_check_time
- if (props.data.first_time_zone) {
- timestamp = TimeFormatter.transferTimestamp(timestamp, props.data.first_time_zone)
- }
- return TimeFormatter.dateDescription(timestamp, true)
- }
- function getArrowText() {
- if (multiTimeZone) {
- return t('feature.common.multi_timezones')
- }
- if (diffTimeZone) {
- return t('feature.common.different_timezone')
- }
- return recordTime()
- }
- function tapStage(e, index) {
- stageCanvasId = new Date().getTime()
- setSelIndex(index);
- // setCount(pre=>pre+1);
- e.stopPropagation()
- }
- function moreStage() {
- var common = getCommon(null, false)
- common.radius = smallRingRadius;
- common.lineWidth = ringWidth;
- var bgRing = getBgRing()
- var realRing = getReal(record, false, true)
- return <View style={{ zIndex: 10000 }}>
- <View style={{ display: 'flex', flexDirection: 'row', alignItems: 'center', position: 'relative' }}>
- {bigMoreRing()}
- <View style={{ display: 'flex', position: 'absolute', left: 0, width: 99, top: 0, height: 99, alignItems: 'center', justifyContent: 'center', zIndex: 10000 }}>
- <Rings common={common} bgRing={bgRing} canvasId={stageCanvasId + 'small'} realRing={realRing} />
- </View>
- <View className="duration_bg">
- {
- <Text className="duration_title">{t('feature.track_time_duration.record_fast_sleep.item.fast')}</Text>
- }
- {
- <Text className="duration_value" style={{ color: global.fastColor ? global.fastColor : ColorType.fast }}>{getStageDuration()}</Text>
- }
- {
- <Text className="duration_title">{t('feature.track_time_duration.record_fast_sleep.item.sleep')}</Text>
- }
- {
- <Text className="duration_value" style={{ color: global.sleepColor ? global.sleepColor : ColorType.sleep }}>{getDuration(record.sleep)}</Text>
- }
- </View>
- </View>
- <View style={{ flex: 1, marginLeft: -rpxToPx(46), marginRight: -rpxToPx(46), marginTop: 20 }}>
- <View className={selIndex == 0 ? "single_check_sel" : "single_check_nor"} onClick={(e) => { tapStage(e, 0) }}>
- <Text className={selIndex == 0 ? "single_check_text_sel" : "single_check_text_nor"}>{t('feature.track_time_duration.stage.a')}</Text>
- {
- selIndex == 0 && <Image src={require('@assets/images/check_black.png')} className="single_checked" />
- }
- </View>
- <View className={selIndex == 1 ? "single_check_sel" : "single_check_nor"} onClick={(e) => { tapStage(e, 1) }}>
- <Text className={selIndex == 1 ? "single_check_text_sel" : "single_check_text_nor"}>{t('feature.track_time_duration.stage.b')}</Text>
- {
- selIndex == 1 && <Image src={require('@assets/images/check_black.png')} className="single_checked" />
- }
- </View>
- <View className={selIndex == 2 ? "single_check_sel" : "single_check_nor"} onClick={(e) => { tapStage(e, 2) }}>
- <Text className={selIndex == 2 ? "single_check_text_sel" : "single_check_text_nor"}>{t('feature.track_time_duration.stage.c')}</Text>
- {
- selIndex == 2 && <Image src={require('@assets/images/check_black.png')} className="single_checked" />
- }
- </View>
- </View>
- </View>
- }
- function recordDetail() {
- var fastDuration = ''
- var sleepDuration = ''
- var showFast = false;
- var showSleep = false;
- if (record.scenario == 'FAST_SLEEP') {
- fastDuration = getDuration(record.fast)
- sleepDuration = getDuration(record.sleep)
- if (record.status == 'ONGOING3') {
- fastDuration = t('feature.common.wait_for_end')
- }
- if (record.status == 'COMPLETED' && record.fast.status=='NOT_COMPLETED'){
- fastDuration = t('feature.common.not_completed')
- }
- if (record.sleep.status == "NOT_STARTED") {
- sleepDuration = t('feature.common.not_started')
- }
- else if (record.sleep.status == 'NOT_COMPLETED') {
- sleepDuration = t('feature.common.not_completed')
- }
- showFast = true
- showSleep = true
- }
- else if (record.scenario == 'FAST') {
- fastDuration = getDuration(record.fast)
- if (record.fast.status == 'NOT_COMPLETED') {
- fastDuration = t('feature.common.not_completed')
- }
- showFast = true
- }
- else {
- sleepDuration = getDuration(record.sleep)
- if (record.sleep.status == 'NOT_COMPLETED') {
- sleepDuration = t('feature.common.not_completed')
- }
- showSleep = true
- }
- return <View style={{ display: 'flex', flexDirection: 'column', margin: rpxToPx(8), boxSizing: 'border-box' }}>
- <View className="fast_sleep_item1">
- {
- rings()
- }
- <View className="duration_bg">
- {
- showFast && <Text className="duration_title">{t('feature.track_time_duration.record_fast_sleep.item.fast')}</Text>
- }
- {
- showFast && <Text className="duration_value" style={{ color: global.fastColor ? global.fastColor : ColorType.fast }}>{fastDuration}</Text>
- }
- {
- showSleep && <Text className="duration_title">{t('feature.track_time_duration.record_fast_sleep.item.sleep')}</Text>
- }
- {
- showSleep && <Text className="duration_value" style={{ color: global.sleepColor ? global.sleepColor : ColorType.sleep }}>{sleepDuration}</Text>
- }
- </View>
- <View className="record_arrow_bg" style={{ backgroundColor: global.isDebug ? 'red' : 'transparent' }}>
- <View style={{ flex: 1 }} />
- <Text className='recordTime'>{getArrowText()}</Text>
- <Image className="arrow2" src={require('@/assets/images/arrow3.png')} />
- </View>
- </View>
- </View>
- }
- function touchStart(e) {
- startX = e.touches[0].clientX
- startY = e.touches[0].clientY
- }
- function touchMove(e) {
- let x = startX
- let y = startY
- let deltaX = e.touches[0].clientX - x
- let deltaY = e.touches[0].clientY - y
- if (Math.abs(deltaX) > Math.abs(deltaY)) {
- if (deltaX < -60) {
- setShowDel(true)
- dispatch(setSelID(props.data.id))
- global.selId = props.data.id
- }
- else if (deltaX > 60) {
- setShowDel(false)
- // global.selId = -1
- }
- }
- }
- function touchEnd(e) {
- startX = 0
- }
- function modalContent() {
- if (process.env.TARO_ENV == 'weapp') {
- return <Modal
- testInfo={null}
- dismiss={() => {
- setShowDetailModal(false)
- }}
- confirm={() => { }}>
- {
- <CircadianDetailPopup
- record={record}
- onClose={() => setShowDetailModal(false)} />
- }
- </Modal>
- }
- else if (process.env.TARO_ENV == 'rn') {
- return <PageContainer style={{ backgroundColor: '#1c1c1c' }}
- // overlayStyle='background-color:rgba(0,0,0,0.9)'
- // custom-style='background-color:#1c1c1c'
- overlayStyle={{ backgroundColor: 'rgba(0,0,0,0.9)' }}
- customStyle={{ backgroundColor: '#1c1c1c' }}
- closeOnSlideDown={false}
- onBeforeEnter={() => {
- }}
- onBeforeLeave={() => {
- }}
- onClick={() => { alert('b') }}
- onClickOverlay={() => { alert('a') }}
- onAfterLeave={() => { setShowDetailModal(false) }}
- show={showDetailModal} round={true} overlay={true} position='bottom'
- >
- {
- <CircadianDetailPopup
- record={record}
- onClose={() => setShowDetailModal(false)} />
- }
- </PageContainer>
- }
- }
- return <View style={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
- <View style={{ position: 'absolute', left: 0, top: 0, width: 0, height: 0, opacity: 0 }}>{count}</View>
- <View className='time_operate_item'
- onTouchStart={touchStart}
- onTouchMove={touchMove}
- onTouchEnd={touchEnd}
- >
- <RecordItem canDel={record.status == 'COMPLETED'} delete={del}
- onClick={showDetail}
- >{recordDetail()}
- </RecordItem>
- <View className={showDel ? 'btnDelete btnDeleteAni' : 'btnDelete'} onClick={del}>{t('feature.track_time_duration.record_fast_sleep.delete')}</View>
- </View>
- {/* {
- (props.type == 'record' || props.type == 'latest') &&
- record.scenario == 'FAST_SLEEP' &&
- record.sleep.status == 'COMPLETED' &&
- <View className="more_stage" onClick={(e) => {
- e.stopPropagation()
- setShowMoreModal(true)
- }}>
- <Text className="more_stage_text">{showMore ? '隐藏更多' : '显示更多'}</Text>
- </View>
- } */}
- {
- showDetailModal && modalContent()
- // showDetailModal && <Modal children={schedules()}
- // modalType={ModalType.center}
- // dismiss={() => setShowDetailModal(false)}
- // confirm={() => { }} />
- }
- {
- showMoreModal && <Modal children={moreStage()}
- modalType={ModalType.center}
- dismiss={() => setShowMoreModal(false)}
- confirm={() => { }} />
- }
- </View>
- })
- export default RecordFastSleep;
|