leon 1 سال پیش
والد
کامیت
fa634aeb0d

+ 13 - 8
src/features/trackTimeDuration/components/MainCard.scss

@@ -1,4 +1,4 @@
-.ring_center{
+.ring_center {
     position: absolute;
     left: 0;
     top: 0;
@@ -10,17 +10,17 @@
     flex-direction: column;
 }
 
-.badge{
+.badge {
     width: 16px;
     height: 16px;
     border-radius: 8px;
     background-color: red;
     position: absolute;
     right: 20px;
-    top:10px;
+    top: 10px;
 }
 
-.log_row{
+.log_row {
     display: flex;
     flex-direction: row;
     align-items: center;
@@ -31,7 +31,7 @@
     border-bottom: solid 2px #99999966;
 }
 
-.fast_log_btn{
+.fast_log_btn {
     display: flex;
     height: 88px;
     border-radius: 44px;
@@ -43,17 +43,22 @@
     position: relative;
 }
 
-.schedule{
+.fast_log_btn_disable {
+    background-color: rgba(202, 202, 202, 0.2);
+    color: #CACACA;
+}
+
+.schedule {
     display: flex;
     flex-direction: column;
 }
 
-.schedule_name{
+.schedule_name {
     color: #CACACA;
     font-size: 24px;
 }
 
-.schedule_time{
+.schedule_time {
     color: #818080;
     font-weight: bold;
     font-size: 40px;

+ 288 - 33
src/features/trackTimeDuration/components/MainFastEatCard.tsx

@@ -1,6 +1,6 @@
 import { View, Text } from "@tarojs/components";
 import './MainCard.scss'
-import { useEffect, useState } from "react";
+import { useEffect, useRef, useState } from "react";
 import Modal from "@/components/layout/Modal.weapp";
 import { rpxToPx } from "@/utils/tools";
 import Rings, { RingCommon, BgRing, TargetRing, CurrentDot } from "@/features/trackTimeDuration/components/Rings";
@@ -9,16 +9,39 @@ import moment from 'moment-timezone'
 import { MainColorType } from "@/context/themes/color";
 import { fastWindow } from "@/services/trackTimeDuration";
 import { useSelector } from "react-redux";
-
+import { jumpPage } from "../hooks/Common";
+import ConsolePicker from "./ConsolePicker";
+import { endFast, startFast } from "../actions/TrackTimeActions";
+import formatMilliseconds from "@/utils/format_time";
+
+let useNavigation;
+
+let Linking, PushNotification;
+let checkNotification;
+let min = 0
+let max = 0
+let defaultTimestamp = 0
+
+if (process.env.TARO_ENV == 'rn') {
+    useNavigation = require("@react-navigation/native").useNavigation
+    Linking = require('react-native').Linking;
+    // JPush = require('jpush-react-native').default;
+    PushNotification = require('react-native-push-notification')
+    checkNotification = require('@/utils/native_permission_check').checkNotification;
+}
 export default function MainFastEatCard(props: { count: any }) {
-    const [isFast, setIsFast] = useState(true)
     const [isFastMode, setIsFastMode] = useState(true)
 
     const [showModal, setShowModal] = useState(false)
+    const [showTimePicker, setShowTimePicker] = useState(false);
+    const limitPickerRef = useRef(null)
+    const [operateType, setOperateType] = useState('startFast')
+    const [btnDisable, setBtnDisable] = useState(false)
+    const [logEvent, setLogEvent] = useState('LOG_ONCE');
 
     const [startScheduleTime, setStartScheduleTime] = useState('00:00')
     const [endScheduleTime, setEndScheduleTime] = useState('00:00')
-    const [eatData, setEatData] = useState(null)
+    const [eatData, setEatData] = useState<any>(null)
     const [fastData, setFastData] = useState<any>(null)
     const [startTime, setStartTime] = useState<any>(null)
     const [endTime, setEndTime] = useState<any>(null)
@@ -28,6 +51,11 @@ export default function MainFastEatCard(props: { count: any }) {
 
     const user = useSelector((state: any) => state.user);
 
+    let navigation;
+    if (useNavigation) {
+        navigation = useNavigation()
+    }
+
     useEffect(() => {
         fastWindow().then(res => {
             setLoaded(true)
@@ -39,7 +67,7 @@ export default function MainFastEatCard(props: { count: any }) {
             setEndScheduleTime(fast_win.fast.schedule_end_time)
 
             var now = new Date().getTime()
-            if ((fast.status == 'ONGOING' || fast.target_start_time <= now && fast.target_end_time >= now) ||
+            if ((fast.status == 'WAIT_FOR_END' || fast.target_start_time <= now && fast.target_end_time >= now) ||
                 isCurrentTimeInRange(fast.schedule_start_time, fast.schedule_end_time)) {
                 setIsFastMode(true)
             }
@@ -57,10 +85,21 @@ export default function MainFastEatCard(props: { count: any }) {
         }
     }, [props.count])
 
+    function refresh() {
+        fastWindow().then(res => {
+            const { eat_win, fast_win } = res
+            const fast = fast_win.fast
+            setEatData(eat_win)
+            setFastData(fast_win)
+            setStartScheduleTime(fast_win.fast.schedule_start_time)
+            setEndScheduleTime(fast_win.fast.schedule_end_time)
+        })
+    }
+
     function update(fast) {
         var now = new Date().getTime()
 
-        if (fast.status == 'ONGOING') {
+        if (fast.status == 'WAIT_FOR_END') {
             setStatus('process')
         }
         else if ((fast.target_start_time <= now && fast.target_end_time >= now) || isCurrentTimeInRange(fast.schedule_start_time, fast.schedule_end_time)) {
@@ -84,8 +123,7 @@ export default function MainFastEatCard(props: { count: any }) {
         color: '#EAE9E9'
     }
 
-    function targetRing() {
-
+    function scheduleRing() {
         var starts: any = startScheduleTime.split(':')
         var ends: any = endScheduleTime.split(':')
         const startSeconds: any = parseInt(starts[0] + '') * 60 + parseInt(starts[1] + '')
@@ -105,26 +143,69 @@ export default function MainFastEatCard(props: { count: any }) {
         }
     }
 
+    function targetRing() {
+        if (status != 'process') {
+            return null
+        }
+        var starts: any = startScheduleTime.split(':')
+        var ends: any = endScheduleTime.split(':')
+        const startSeconds: any = parseInt(starts[0] + '') * 60 + parseInt(starts[1] + '')
+        const endSeconds: any = parseInt(ends[0] + '') * 60 + parseInt(ends[1] + '')
+        const color = isFastMode ? '#9AE2FE' : '#FE810C66'
+        var startArc = isFastMode ? startSeconds / 1440 * 2 * Math.PI - Math.PI / 2 : endSeconds / 1440 * 2 * Math.PI - Math.PI / 2
+
+        const fastCount = endSeconds - startSeconds > 0 ? endSeconds - startSeconds : endSeconds - startSeconds + 1440
+        const eatCount = 1440 - fastCount
+
+        var durationArc = isFastMode ? fastCount / 1440 * 2 * Math.PI : eatCount / 1440 * 2 * Math.PI
+
+        if (isFastMode) {
+            var dt = new Date(fastData.fast.target_start_time)
+            var realSeconds = dt.getHours() * 3600 + dt.getMinutes() * 60 + dt.getSeconds()
+            startArc = realSeconds / (1440 * 60) * 2 * Math.PI - Math.PI / 2
+            durationArc = ((fastData.fast.target_end_time - fastData.fast.target_start_time) / 1000) / (1440 * 60) * 2 * Math.PI
+        }
+
+        return {
+            color,
+            startArc,
+            durationArc,
+            radius: isFastMode ? 90 : null,
+            lineWidth: isFastMode ? 10 : null
+        }
+    }
+
+
+
     function realRing() {
         if (isFastMode) {
-            if (isFast) {
+            if (status != 'upcoming') {
                 var starts: any = startTime ? startTime.split(':') : startScheduleTime.split(':')
                 const startSeconds = parseInt(starts[0] + '') * 3600 + parseInt(starts[1] + '') * 60
 
                 const color = MainColorType.fast
-                const startArc = startSeconds / (1440 * 60) * 2 * Math.PI - Math.PI / 2
+                var startArc = startSeconds / (1440 * 60) * 2 * Math.PI - Math.PI / 2
                 var endSeconds = new Date().getHours() * 3600 + new Date().getMinutes() * 60 + new Date().getSeconds()
                 if (endTime) {
                     var ends: any = endTime.split(':')
                     endSeconds = parseInt(ends[0] + '') * 3600 + parseInt(ends[1] + '') * 60
                 }
                 const fastCount = endSeconds - startSeconds > 0 ? endSeconds - startSeconds : endSeconds - startSeconds + 1440 * 60
-                const durationArc = fastCount / (1440 * 60) * 2 * Math.PI
+                var durationArc = fastCount / (1440 * 60) * 2 * Math.PI
+
+                if (status == 'process') {
+                    var dt = new Date(fastData.fast.target_start_time)
+                    var realSeconds = dt.getHours() * 3600 + dt.getMinutes() * 60 + dt.getSeconds()
+                    startArc = realSeconds / (1440 * 60) * 2 * Math.PI - Math.PI / 2
+                    durationArc = ((new Date().getTime() - fastData.fast.target_start_time) / 1000) / (1440 * 60) * 2 * Math.PI
+                }
 
                 return {
                     color,
                     startArc,
-                    durationArc
+                    durationArc,
+                    radius: status == 'process' ? 90 : null,
+                    lineWidth: status == 'process' ? 15 : null
                 }
             }
         }
@@ -143,7 +224,9 @@ export default function MainFastEatCard(props: { count: any }) {
                 return {
                     color,
                     startArc,
-                    durationArc
+                    durationArc,
+                    radius: 90,
+                    lineWidth: 10
                 }
             }
         }
@@ -169,6 +252,46 @@ export default function MainFastEatCard(props: { count: any }) {
         return currentTime >= startTime && currentTime <= endTime;
     }
 
+    function getTimeToDestination(timeStr, isPasted) {
+        // 获取当前时间
+        const now = new Date();
+        const currentHours = now.getHours();
+        const currentMinutes = now.getMinutes();
+        const currentSeconds = now.getSeconds();
+
+        // 解析目标时间
+        const [targetHours, targetMinutes] = timeStr.split(':').map(Number);
+
+        // 计算时间差
+        let hours = targetHours - currentHours;
+        let minutes = targetMinutes - currentMinutes;
+        let seconds = 60 - currentSeconds;
+
+        if (minutes < 0) {
+            minutes += 60;
+            hours--;
+        }
+
+        if (hours < 0) {
+            hours += 24;
+        }
+
+        if (seconds === 60) {
+            seconds = 0;
+            minutes++;
+        }
+
+        // 如果是过去的时间,则返回剩余时间
+        if (isPasted) {
+            hours = 24 - hours;
+            minutes = 60 - minutes;
+            seconds = 60 - seconds;
+        }
+
+        // 格式化输出
+        return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
+    }
+
     function ring() {
         var offset = 0
 
@@ -187,7 +310,7 @@ export default function MainFastEatCard(props: { count: any }) {
             whiteIcon: true
         }
 
-        return <Rings common={common} bgRing={bgRing} targetRing={targetRing()} realRing={realRing()} currentDot={currentDot} canvasId={'smal11l'} />
+        return <Rings common={common} bgRing={bgRing} scheduleRing={scheduleRing()} targetRing={targetRing()} realRing={realRing()} currentDot={currentDot} canvasId={'smal11l'} />
     }
 
     function formatTime(format: string, timestamp?: number) {
@@ -226,11 +349,9 @@ export default function MainFastEatCard(props: { count: any }) {
                 milliSeconds = new Date().getTime() - fastData.fast.real_start_time
                 break;
             case 'new':
-                milliSeconds = new Date().getTime() - fastData.fast.target_start_time
-                break;
+                return getTimeToDestination(fastData.fast.schedule_start_time, true)
             case 'upcoming':
-                milliSeconds = fastData.fast.target_start_time - new Date().getTime()
-                break;
+                return getTimeToDestination(fastData.fast.schedule_start_time, false)
 
         }
         var seconds = Math.floor(milliSeconds / 1000)
@@ -240,11 +361,134 @@ export default function MainFastEatCard(props: { count: any }) {
         return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${remainingSeconds.toString().padStart(2, '0')}`;
     }
 
+    function getEatTime() {
+
+        return getTimeToDestination(eatData.schedule_start_time, isCurrentTimeInRange(eatData.schedule_start_time, eatData.schedule_end_time))
+    }
+
+    function tapFastStart() {
+
+    }
+
+    function tapFastEnd() {
+
+    }
+
+    function tapStartLog() {
+        if (status == 'upcoming'){
+            return;
+        }
+        if (!user.isLogin) {
+            jumpPage('/pages/account/ChooseAuth', 'ChooseAuth', navigation)
+            return
+        }
+        defaultTimestamp = new Date().getTime()
+        min = defaultTimestamp - 1 * 24 * 3600 * 1000
+        max = defaultTimestamp
+
+        setOperateType('startFast')
+        setShowTimePicker(true)
+    }
+
+    function tapEndLog() {
+        if (status != 'process') {
+            return
+        }
+        defaultTimestamp = new Date().getTime()
+        // defaultTimestamp = e ? new Date().getTime() : logEventTimestamp
+        min = defaultTimestamp - 1 * 24 * 3600 * 1000
+        max = defaultTimestamp
+        setOperateType('endFast')
+        setShowTimePicker(true)
+    }
+
+    function modalContent() {
+        global.set_time = new Date().getTime()
+        return <Modal
+            testInfo={null}
+            dismiss={() => {
+                setShowTimePicker(false)
+            }}
+            confirm={() => { }}>
+            {
+                timePickerContent()
+            }
+        </Modal>
+    }
+
+    function timePickerContent() {
+        var title = operateType == 'endFast' ? '结束断食' : '开始断食'
+        var color = MainColorType.fast
+        var endTimestamp = 0
+        if (operateType == 'endFast') {
+            endTimestamp = fastData.fast.target_end_time
+        }
+
+        var duration = fastData.fast.target_duration
+
+        return <View className="modal_content">
+            <ConsolePicker ref={limitPickerRef}
+                themeColor={color}
+                title={title}
+                onCancel={() => {
+                    setShowTimePicker(false)
+                }}
+                min={min}
+                max={max}
+                current={defaultTimestamp}
+                duration={duration}
+                endTimestamp={endTimestamp}
+                isFast={true}
+                isEnd={operateType == 'endFast'}
+                isTimeout={false}
+                isLoading={btnDisable}
+                onChange={(e) => {
+                    pickerConfirm(e, null)
+                    global.pauseIndexTimer = false
+                }}
+            />
+        </View>
+    }
+
+    function pickerConfirm(t1: number, event: any) {
+        if (btnDisable) {
+            return
+        }
+        global.scenario = 'FAST'
+        setBtnDisable(true)
+
+        var date = new Date(t1)
+        var setDate = new Date(global.set_time);
+        date.setMilliseconds(setDate.getMilliseconds());
+        date.setSeconds(setDate.getSeconds());
+
+        t1 = date.getTime();
+
+        if (operateType == 'startFast') {
+            startFast(t1, fastData.fast.target_duration, event ? event : logEvent).then(res => {
+                setBtnDisable(false)
+                refresh()
+                setShowTimePicker(false)
+            }).catch(e => {
+                setBtnDisable(false)
+            })
+        }
+        else {
+            endFast(t1, event ? event : logEvent).then(res => {
+                setBtnDisable(false)
+                refresh()
+                setShowTimePicker(false)
+            }).catch(e => {
+                setBtnDisable(false)
+            })
+        }
+    }
+
     if (!loaded) {
         return <View />
     }
 
-    return <View style={{ alignItems: 'center', display: 'flex', flexDirection: 'column' }}>
+    return <View style={{ alignItems: 'center', display: 'flex', flexDirection: 'column', width: rpxToPx(750), flexShrink: 0 }}>
 
         <View style={{ width: rpxToPx(750), }} />
         <View onClick={() => { setShowModal(true) }}>Fast Eat Night{props.count}</View>
@@ -257,34 +501,42 @@ export default function MainFastEatCard(props: { count: any }) {
                 {
                     isFastMode && <Text>{getFastStatus()}</Text>
                 }
-                <Text className="time1">{getFastTime()}</Text>
+                <Text className="time1">{isFastMode ? getFastTime() : getEatTime()}</Text>
                 <Text className="date1">{global.language == 'en' ? formatTime('dddd, MMM D') : formatTime('MMMD日 dddd')}</Text>
             </View>
         </View>
+        <View>{isFastMode?formatMilliseconds(fastData.fast.target_duration):formatMilliseconds(eatData.target_end_time-eatData.target_start_time)}</View>
         {
             isFastMode && <View>
                 <View className="log_row">
-                    <View className="schedule">
-                        <Text className="schedule_name">
-                            Fast starts:
-                        </Text>
-                        <Text className="schedule_time">
-                            {startScheduleTime}
-                        </Text>
-                    </View>
+                    {
+                        status == 'process' ? <View className="schedule_name">Fast starts</View> : <View className="schedule" onClick={tapFastStart}>
+                            <Text className="schedule_name">
+                                Fast starts:
+                            </Text>
+                            <Text className="schedule_time">
+                                {startScheduleTime}
+                            </Text>
+                        </View>
+                    }
+
+                    {
+                        status == 'process' ? <View className="schedule_time">{dayjs(fastData.fast.target_start_time).format('HH:mm')}</View> : 
+                        <View onClick={tapStartLog} className={status == 'new' ? "fast_log_btn" : "fast_log_btn fast_log_btn_disable"}>Log{status == 'new' && <View className="badge" />}</View>
+                    }
+
 
-                    <View className="fast_log_btn">Log{status == 'new' && <View className="badge" />}</View>
                 </View>
                 <View className="log_row">
-                    <View className="schedule">
+                    <View className="schedule" onClick={tapFastEnd}>
                         <Text className="schedule_name">
-                            Fast starts:
+                            Fast ends:
                         </Text>
                         <Text className="schedule_time">
-                            {endScheduleTime}
+                            {status == 'process' ?dayjs(fastData.fast.target_end_time).format('HH:mm'):endScheduleTime}
                         </Text>
                     </View>
-                    <View className="fast_log_btn">Log</View>
+                    <View onClick={tapEndLog} className={status == 'process' ? "fast_log_btn" : "fast_log_btn fast_log_btn_disable"}>Log</View>
                 </View>
             </View>
         }
@@ -297,5 +549,8 @@ export default function MainFastEatCard(props: { count: any }) {
                 <View style={{ width: 100, height: 100, backgroundColor: 'red' }}>{props.count}</View>
             </Modal>
         }
+        {
+            showTimePicker && modalContent()
+        }
     </View>
 }

+ 13 - 3
src/features/trackTimeDuration/components/MainSleepActiveCard.tsx

@@ -1,19 +1,29 @@
 import { View, Text } from "@tarojs/components";
 import './MainCard.scss'
-import { useState } from "react";
+import { useEffect, useState } from "react";
 import { rpxToPx } from "@/utils/tools";
 import Rings, { RingCommon, BgRing, TargetRing, CurrentDot } from "@/features/trackTimeDuration/components/Rings";
 import dayjs from "dayjs";
 import moment from 'moment-timezone'
 import { MainColorType } from "@/context/themes/color";
+import { useSelector } from "react-redux";
+import { sleepWindow } from "@/services/trackTimeDuration";
 
-export default function MainSleepActiveCard() {
+export default function MainSleepActiveCard(props: { count: any }) {
     const [isSleep, setIsSleep] = useState(true)
     const [isSleepMode, setIsSleepMode] = useState(true)
 
     const startScheduleTime = '19:00'
     const endScheduleTime = '06:00'
 
+    const user = useSelector((state: any) => state.user);
+
+    useEffect(() => {
+        sleepWindow().then(res => {
+
+        })
+    }, [user.isLogin])
+
     function formatTime(format: string, timestamp?: number) {
 
         return dayjs().format(format)
@@ -59,7 +69,7 @@ export default function MainSleepActiveCard() {
     function realRing() {
 
         if (isSleepMode) {
-            if (isCurrentTimeInRange( startScheduleTime,endScheduleTime)) {
+            if (isCurrentTimeInRange(startScheduleTime, endScheduleTime)) {
                 var starts: any = startScheduleTime.split(':')
                 const startSeconds = parseInt(starts[0] + '') * 60 + parseInt(starts[1] + '')
 

+ 26 - 4
src/features/trackTimeDuration/components/Rings.weapp.tsx

@@ -25,12 +25,22 @@ export type RealRing = {
     color: string;
     startArc: number;
     durationArc: number;
+    radius?: number;
+    lineWidth?: number;
 }
 
 export type TargetRing = {
     color: string;
     startArc: number;
     durationArc: number;
+    radius?: number;
+    lineWidth?: number;
+}
+
+export type ScheduleRing = {
+    color: string;
+    startArc: number;
+    durationArc: number;
 }
 
 export type BgRing = {
@@ -44,6 +54,7 @@ export default function Rings(props: {
     currentDot?: CurrentDot;
     realRing?: RealRing; 
     targetRing?: TargetRing; 
+    scheduleRing?:ScheduleRing;
     breathAnimation?:boolean;
     bgRing: BgRing; 
     canvasId?: string;
@@ -185,12 +196,23 @@ export default function Rings(props: {
         ctx.lineCap = 'round'; // 设置为圆角
         ctx.stroke();
 
+        // 绘制schedule进度环
+        if (props.scheduleRing){
+            ctx.beginPath();
+            ctx.arc(center, center, radius, props.scheduleRing!.startArc,
+                props.scheduleRing!.startArc + props.scheduleRing!.durationArc);
+            ctx.lineWidth = lineWidth;
+            ctx.strokeStyle = props.scheduleRing!.color;
+            ctx.lineCap = 'round'; // 设置为圆角
+            ctx.stroke();
+        }
+
         // 绘制target进度环
         if (props.targetRing) {
             ctx.beginPath();
-            ctx.arc(center, center, radius, props.targetRing!.startArc,
+            ctx.arc(center, center, props.targetRing!.radius?props.targetRing!.radius:radius, props.targetRing!.startArc,
                 props.targetRing!.startArc + props.targetRing!.durationArc);
-            ctx.lineWidth = lineWidth;
+            ctx.lineWidth = props.targetRing!.lineWidth?props.targetRing!.lineWidth:lineWidth;
             ctx.strokeStyle = props.targetRing!.color;
             ctx.lineCap = 'round'; // 设置为圆角
             ctx.stroke();
@@ -200,9 +222,9 @@ export default function Rings(props: {
         if (props.realRing) {
             if (props.realRing.durationArc <0.01) props.realRing.durationArc=0.01;
             ctx.beginPath();
-            ctx.arc(center, center, radius, props.realRing!.startArc,
+            ctx.arc(center, center, props.realRing!.radius?props.realRing!.radius:radius, props.realRing!.startArc,
                 props.realRing!.startArc + props.realRing!.durationArc);
-            ctx.lineWidth = lineWidth;
+            ctx.lineWidth = props.realRing!.lineWidth?props.realRing!.lineWidth:lineWidth;
             ctx.strokeStyle = props.realRing!.color;
             ctx.lineCap = 'round'; // 设置为圆角
             ctx.stroke();

+ 80 - 0
src/pages/clock/Clock.tsx

@@ -1,8 +1,88 @@
 import { View } from "@tarojs/components";
 import './Clock.scss'
 import ClockNew from "./ClockNew";
+import { useEffect } from "react";
+import Taro, { useShareAppMessage } from "@tarojs/taro";
+import { useDispatch } from "react-redux";
+import { getInfoSuccess } from "@/store/user";
+import { useTranslation } from "react-i18next";
+
+let useNavigation;
+
+if (process.env.TARO_ENV == 'rn') {
+    useNavigation = require("@react-navigation/native").useNavigation
+}
 
 export default function Clock() {
+    const dispatch = useDispatch();
+
+    const { t } = useTranslation()
+    let navigation;
+    if (useNavigation) {
+        navigation = useNavigation()
+    }
+
+
+    if (process.env.TARO_ENV == 'weapp') {
+        useShareAppMessage((e) => {
+            return {
+                title: t('feature.track_time_duration.common.share_title'),
+                path: 'pages/clock/Clock'
+            }
+        })
+    }
+    
+    useEffect(() => {
+        if (navigation) {
+            navigation.setOptions({
+                headerTitle: '',
+            });
+        }
+        global.memberAlert = false;
+        if (process.env.TARO_ENV == 'weapp') {
+            loadWXCache()
+        }
+        else {
+            loadRNCache()
+        }
+    }, [])
+
+    function loadWXCache() {
+        var gps = Taro.getStorageSync('gps')
+        if (gps) {
+            global.locationDetail = JSON.parse(gps)
+        }
+        global.memberAlert = Taro.getStorageSync('memberAlert') || false
+        var userData = Taro.getStorageSync('userData')
+        if (userData) {
+            dispatch(getInfoSuccess(JSON.parse(userData)));
+        }
+    }
+
+    async function loadRNCache() {
+        var showDayRing = await getStorage('showDayRing') || false;
+        var showNightRing = await getStorage('showNightRing') || false;
+        global.memberAlert = await getStorage('memberAlert') || false
+        var gps = await getStorage('gps')
+        if (gps) {
+            global.locationDetail = JSON.parse(gps)
+        }
+        var userData = await getStorage('userData')
+        console.log(userData)
+        if (userData) {
+            dispatch(getInfoSuccess(JSON.parse(userData)));
+        }
+    }
+
+    async function getStorage(key: string) {
+        try {
+            const res = await Taro.getStorage({ key });
+            return res.data;
+        } catch {
+            return '';
+        }
+    }
+    
     return <View>
         <ClockNew />
     </View>

+ 21 - 8
src/pages/clock/ClockNew.tsx

@@ -10,7 +10,7 @@ import { rpxToPx } from "@/utils/tools";
 export default function ClockNew() {
     const [count, setCount] = useState(0)
     const [scrollLeft, setScrollLeft] = useState(rpxToPx(750) * 0)
-    
+
 
     useEffect(() => {
         setInterval(() => {
@@ -22,10 +22,17 @@ export default function ClockNew() {
         setScrollLeft(rpxToPx(750) * index)
     }
 
-    function scroll(e){
+    function scroll(e) {
         console.log(e.detail.scrollLeft)
     }
+    //https://blog.csdn.net/weixin_43525284/article/details/130182218
     return <View>
+
+        {/* <ScrollView scrollX={true} enableFlex={true} pagingEnabled={true} scrollWithAnimation={true} style={{ width: 200, height: 200, display: 'flex', flexDirection: 'row', overflow: 'hidden' }} enhanced>
+            <View style={{ width: 200, height: 200, backgroundColor: 'red', flexShrink: 0, display: 'flex' }} />
+            <View style={{ width: 200, height: 200, backgroundColor: 'blue', flexShrink: 0, display: 'flex' }} />
+            <View style={{ width: 200, height: 200, backgroundColor: 'yellow', flexShrink: 0, display: 'flex' }} />
+        </ScrollView> */}
         <View className="tabs">
             <View className="item" onClick={() => tapScroll(0)}> tab 0</View>
             <View className="item" onClick={() => tapScroll(1)}>tab 1</View>
@@ -34,17 +41,23 @@ export default function ClockNew() {
         <ScrollView scrollX
             scrollLeft={scrollLeft}
             scrollWithAnimation={true}
-            // pagingEnabled={true} 
+            pagingEnabled={true}
             enableFlex
-            // enhanced 
             onScroll={scroll}
-            style={{ width: rpxToPx(750), flexDirection: 'row', }}>
-            <View style={{ display: 'flex', flexDirection: 'row', width: '100%' }}>
+            style={{ width: rpxToPx(750), display: 'flex', flexDirection: 'row', overflow: 'hidden' }}
+            enhanced>
+            <View style={{ display: 'flex', flexShrink: 0, width: rpxToPx(750) }}>
                 <MainFastEatCard count={count} />
+            </View>
+            <View style={{ display: 'flex', flexShrink: 0, width: rpxToPx(750) }}>
                 <MainDayNightCard count={count} />
-
-                <MainSleepActiveCard />
             </View>
+            <View style={{ display: 'flex', flexShrink: 0, width: rpxToPx(750) }}>
+                <MainSleepActiveCard count={count} />
+            </View>
+
+
+
 
         </ScrollView>
         {/* <Swiper style={{height:500}}>

+ 1 - 0
src/services/http/api.js

@@ -52,6 +52,7 @@ export const API_FAST_CALENDARS = `${baseUrl}/api/fast/calendars/`
 export const API_CLOCK_RECORD_UPDATE = `${baseUrl}/api/clock/records`
 export const API_CLOCK_STREAKS = `${baseUrl}/api/clock/streaks`
 export const API_FAST_WINDOW = `${baseUrl}/api/fast/fast-eat-windows`
+export const API_SLEEP_WINDOW = `${baseUrl}/api/fast/sleep-active-windows`
 
 
 

+ 15 - 5
src/services/trackTimeDuration.tsx

@@ -1,6 +1,6 @@
 
 
-import { API_FAST_PLANS, API_FAST_CHECKS, API_FAST_CLOCKS, API_CLOCK_RECORDS, API_CLOCK_HOME, API_CLOCK_STATS, API_CLOCK_SUMMARY_RECORDS, API_CLOCK_RECORD_UPDATE, API_CLOCK_STREAKS, API_EAT_WAKES, API_FAST_WINDOW } from './http/api'
+import { API_FAST_PLANS, API_FAST_CHECKS, API_FAST_CLOCKS, API_CLOCK_RECORDS, API_CLOCK_HOME, API_CLOCK_STATS, API_CLOCK_SUMMARY_RECORDS, API_CLOCK_RECORD_UPDATE, API_CLOCK_STREAKS, API_EAT_WAKES, API_FAST_WINDOW, API_SLEEP_WINDOW } from './http/api'
 import { request } from './http/request';
 import { getLocalPush } from '@/features/trackTimeDuration/actions/TrackTimeActions';
 
@@ -61,7 +61,7 @@ export const clockSummaryStats = (params: any) => {
     })
 }
 
-export const eatWakes = (params:any)=>{
+export const eatWakes = (params: any) => {
     return new Promise((resolve) => {
         request({
             url: API_EAT_WAKES, method: 'GET', data: { ...params }
@@ -151,17 +151,17 @@ export const clearTimeRecords = () => {
 
 }
 
-export const getStreaks = (params:any)=>{
+export const getStreaks = (params: any) => {
     return new Promise((resolve) => {
         request({
-            url: API_CLOCK_STREAKS, method: 'GET', data: {...params}
+            url: API_CLOCK_STREAKS, method: 'GET', data: { ...params }
         }).then(res => {
             resolve(res);
         })
     })
 }
 
-export const fastWindow = ()=>{
+export const fastWindow = () => {
     return new Promise((resolve) => {
         request({
             url: API_FAST_WINDOW, method: 'GET', data: {}
@@ -169,4 +169,14 @@ export const fastWindow = ()=>{
             resolve(res);
         })
     })
+}
+
+export const sleepWindow = () => {
+    return new Promise((resolve) => {
+        request({
+            url: API_SLEEP_WINDOW, method: 'GET', data: {}
+        }).then(res => {
+            resolve(res);
+        })
+    })
 }

+ 14 - 0
src/utils/format_time.ts

@@ -0,0 +1,14 @@
+export default function formatMilliseconds(ms) {
+    const hours = Math.floor(ms / (1000 * 60 * 60));
+    const minutes = Math.floor((ms % (1000 * 60 * 60)) / (1000 * 60));
+  
+    if (hours === 0) {
+      return `${minutes}分钟`;
+    }
+  
+    if (minutes === 0) {
+      return `${hours}小时`;
+    }
+  
+    return `${hours}小时${minutes}分钟`;
+  }