Leon před 1 rokem
rodič
revize
e4bc9b0101

+ 0 - 2
src/components/layout/layout.tsx

@@ -47,8 +47,6 @@ export default function Layout(props: {
                 headerTitle: showTitle ? props.title ? props.title : '' : '',
             });
         }
-        console.log(showTitle)
-
     }, [showTitle])
 
     function onRefresh() {

+ 6 - 4
src/components/view/Timeline.scss

@@ -1,6 +1,8 @@
+// $timelineWidth:486px;
 $timelineWidth:486px;
 .timeline {
   display: flex;
+  // flex: ;
   flex-direction: column;
   color: #fff;
   // max-height: 70vh;
@@ -41,7 +43,7 @@ $timelineWidth:486px;
   font-size: 32px;
   line-height: 32px;
   height: 32px;
-  width: $timelineWidth;
+  // width: $timelineWidth;
   margin-top: 12px;
   display: flex;
   flex-direction: row;
@@ -56,7 +58,7 @@ $timelineWidth:486px;
   color: #fff;
   font-size: 28px;
   line-height: 32px;
-  margin-left: 6px;
+  // margin-left: 6px;
   // background-color: orange;
   opacity: 0.3;
   // margin-top: 6px;
@@ -67,7 +69,7 @@ $timelineWidth:486px;
   color: #fff;
   font-size: 32px;
   line-height: 32px;
-  margin-left: 6px;
+  // margin-left: 6px;
   // background-color: orange;
   opacity: 0.3;
   // margin-top: 6px;
@@ -86,7 +88,7 @@ $timelineWidth:486px;
   display: flex;
   flex-direction: row;
   align-items: center;
-  width: $timelineWidth;
+  // width: $timelineWidth;
   // justify-content: space-between;
   padding-bottom: 16px;
   border-bottom-style: solid;

+ 2 - 2
src/components/view/Timeline.tsx

@@ -9,7 +9,7 @@ if (process.env.TARO_ENV == 'rn') {
     LinearGradient = require('react-native-linear-gradient').default
 }
 
-export default function Component(props: { items: any[], title?: string, type?: TimelineType, showLastLine?: boolean }) {
+export default function Component(props: { items: any[], title?: string, type?: TimelineType, showLastLine?: boolean,width?:number }) {
     return <View className="timeline">
         <View style={{ position: 'relative' }}>
             {
@@ -33,7 +33,7 @@ export default function Component(props: { items: any[], title?: string, type?:
                                 <View style={{ flex: 1 }} />
                             </View>
                         </View>
-                        <View className="timeline-detail">{item.content}
+                        <View className="timeline-detail" style={{width:props.width?rpxToPx(props.width):rpxToPx(468)}}>{item.content}
                             {
                                 item.date && <View className="timeline-date">{item.date}</View>
                             }

+ 2 - 0
src/context/locales/en.js

@@ -113,6 +113,8 @@ export default {
             maintain:'Item under maintenance',
             multi_timezones:'Mult. time zones',
             different_timezone:'Other time zone',
+            multi_tz_desc:'Multiple time zones were involved in these events.',
+            diff_tz_desc:'These events occured in {{location}} time which differs from your current time zone.',
             toast: {
                 min_value: 'Cannot go any lower',
                 max_value: 'Cannot go any higher',

+ 2 - 0
src/context/locales/zh.js

@@ -115,6 +115,8 @@ export default {
             maintain:'项目维护中',
             multi_timezones:'跨多时区',
             different_timezone:'其他时区',
+            multi_tz_desc:'上述事件涉及到多个时区。',
+            diff_tz_desc:'上述事件发生在{{location}}时区, 与您当前所在的时区不同。',
             toast: {
                 min_value: '不能再小了',
                 max_value: '不能再大了',

+ 2 - 2
src/features/trackTimeDuration/components/ClockHeader.tsx

@@ -173,8 +173,8 @@ export default function ClockHeader(props: { homeData: any }) {
 
     function durationChange(e) {
         // debugger
-        // var count = (e[0] + common.duration.min) * 60 + e[1] * common.duration.step
-        var count = (e[0] + 1) * 60 + e[1] * 5
+        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)
         }

+ 86 - 60
src/features/trackTimeDuration/components/DayLight.tsx

@@ -8,6 +8,7 @@ import { systemLocation } from '@/services/common'
 import { clearLocation, getPerm, latestLocation, uploadPerm } from '@/services/user'
 import { TimeFormatter } from '@/utils/time_format'
 import { ColorType } from '@/context/themes/color'
+import { rpxToPx } from '@/utils/tools'
 export default function DayLight() {
     const [showRing, setShowRing] = useState(false)
     const [isTomorrow, setIsTomorrow] = useState(false)
@@ -189,98 +190,123 @@ export default function DayLight() {
 
 
     return <View>
-        <View className='daylight_row'>
-            <Text>Night ring</Text>
-            <Switch checked={showRing}
-                color={ColorType.night}
-                onChange={(e) => {
-                    setShowRing(e.detail.value)
-                    global.showNightRing = e.detail.value
-                    global.refreshIndex()
-                    Taro.setStorage({
-                        key: 'showLightRing',
-                        data: e.detail.value
-                    })
-
-                    uploadPerm({ show_night_ring: e.detail.value })
-                }}
-            />
-        </View>
-        {
-            showRing && <View>
-                <View className="daylight_row">
-                    <Text>Sunset today</Text>
-                    <Text>{sunsetTime}</Text>
+        <View className='cell_bg'>
+            <View className='cell_full'>
+                <Text className="cell_title">Night ring</Text>
+                <Switch checked={showRing}
+                    color={ColorType.night}
+                    onChange={(e) => {
+                        setShowRing(e.detail.value)
+                        global.showNightRing = e.detail.value
+                        global.refreshIndex()
+                        Taro.setStorage({
+                            key: 'showLightRing',
+                            data: e.detail.value
+                        })
+
+                        uploadPerm({ show_night_ring: e.detail.value })
+                    }}
+                />
+            </View>
+            {
+                showRing && <View className="cell_line" style={{ height: 1 }} />
+            }
+            {
+                showRing && <View className="cell_full">
+                    <Text className="cell_title">Sunset today</Text>
+                    <Text className="cell_value">{sunsetTime}</Text>
                 </View>
-                <View className="daylight_row">
-                    <Text>Sunrise tomororow</Text>
-                    <Text>{sunriseTime}</Text>
+            }
+            {
+                showRing && <View className="cell_line" style={{ height: 1 }} />
+            }
+            {
+                showRing && <View className="cell_full">
+                    <Text className="cell_title">Sunrise tomororow</Text>
+                    <Text className="cell_value">{sunriseTime}</Text>
                 </View>
-                <Text className='daylight_note'>{
-                    !isMember ? 'Sunset and sunrise times are global average. For actual times at your location, join our Pro program.' :
-                        authInfo ? 'Calculated based on your location.' :
-                            'Sunset and sunrise times are global average. For actual times at your location, enter your location.'
-                }</Text>
+            }
+        </View>
+        {
+            showRing && <Text className='cell_footer' >{
+                !isMember ? 'Sunset and sunrise times are global average. For actual times at your location, join our Pro program.' :
+                    authInfo ? 'Calculated based on your location.' :
+                        'Sunset and sunrise times are global average. For actual times at your location, enter your location.'
+            }</Text>
+        }
+
+        {
+            showRing && <View style={{marginTop:rpxToPx(40)}}>
+
+
+
                 {/* <Text className='daylight_note'>{isMember && authInfo ? 'Calculated based on your location.' : 'Sunset and sunrise times are global average. For actual times at your location, join our Pro program.'}</Text> */}
                 {
-                    isMember ? <View>
+                    isMember ? <View className="cell_bg">
                         {
-                            showLocatin && <View className='daylight_item' onClick={auth}>
-                                <Text style={{ flex: 1 }}>Location</Text>
-                                {
-                                    authInfo ? <Text className='address'>{(authInfo as any).address.city}</Text> :
-                                        <Text>Enter</Text>
-                                }
-                                <Image className="daylight_arrow" src={require('@/assets/images/arrow3.png')} />
+                            showLocatin && <View className="cell_full" onClick={auth}>
+                                <Text className="cell_title">Location</Text>
+                                <Text className="cell_value">{authInfo ? (authInfo as any).address.city : 'Enter'}</Text>
+                                <Image className="cell_arrow" src={require('@/assets/images/arrow3.png')} />
                             </View>
                         }
-
+                        {
+                            showLocatin && <View className="cell_line" style={{ height: 1 }} />
+                        }
 
                         {
-                            authInfo && showLocatin && <View className='daylight_item' >
-                                <Text style={{ flex: 1 }}>Latitude</Text>
+                            authInfo && showLocatin && <View className="cell_full" >
+                                <Text className="cell_title">Latitude</Text>
 
-                                <Text>{(authInfo as any).latitude}</Text>
+                                <Text className="cell_value">{(authInfo as any).latitude}</Text>
 
 
                             </View>
                         }
                         {
-                            authInfo && showLocatin && <View className='daylight_item'>
-                                <Text style={{ flex: 1 }}>Longitude</Text>
-
-                                <Text>{(authInfo as any).longitude}</Text>
-
-                            </View>
+                            showLocatin && <View className="cell_line" style={{ height: 1 }} />
                         }
                         {
-                            authInfo && showLocatin && <View className='daylight_item'>
-                                <Text style={{ flex: 1 }}>Time zone</Text>
+                            authInfo && showLocatin && <View className="cell_full">
+                                <Text className="cell_title" >Longitude</Text>
 
-                                <Text>{timezone}</Text>
+                                <Text className="cell_value">{(authInfo as any).longitude}</Text>
 
                             </View>
                         }
                         {
-                            authInfo && <Text style={{ color: '#fff' }} onClick={() => {
-                                var enable = !showLocatin
-                                setShowLocation(enable)
-                                Taro.setStorage({
-                                    key: 'hideLocation',
-                                    data: !enable
-                                })
-                            }}>{showLocatin ? 'Hide my location' : 'Show my location'}</Text>
+                            showLocatin && <View className="cell_line" style={{ height: 1 }} />
                         }
                         {
-                            authInfo && showLocatin && <Text style={{ color: '#fff' }} onClick={clearData}>清除位置数据</Text>
+                            authInfo && showLocatin && <View className="cell_full">
+                                <Text className="cell_title">Time zone</Text>
+
+                                <Text className="cell_value">{timezone}</Text>
+
+                            </View>
                         }
 
+
                     </View> :
                         <View className='become_vip' onClick={buy}>
                             <Text style={{ color: '#000' }}>Become Pro</Text>
                         </View>
                 }
 
+                {
+                    authInfo && <Text className='cell_footer' onClick={() => {
+                        var enable = !showLocatin
+                        setShowLocation(enable)
+                        Taro.setStorage({
+                            key: 'hideLocation',
+                            data: !enable
+                        })
+                    }}>{showLocatin ? 'Hide my location' : 'Show my location'}</Text>
+                }
+                {
+                    authInfo && showLocatin && <Text className='cell_footer' onClick={clearData}>清除位置数据</Text>
+                }
+
             </View>
         }
 

+ 1 - 1
src/features/trackTimeDuration/components/IndexConsole.tsx

@@ -39,7 +39,7 @@ export default function IndexConsole(props: { record: any }) {
 
         var sleepCount = currentRecord.sleep.target_end_time - currentRecord.sleep.target_start_time
         setSleepDuration(sleepCount)
-    }, [])
+    }, [props.record])
 
 
     function tapStartFast() {

+ 22 - 0
src/features/trackTimeDuration/components/RecordFastSleep.scss

@@ -13,9 +13,31 @@
     padding-left: 40px;
     padding-right: 40px;
     margin-top: 20px;
+    position: relative;
+    overflow: hidden;
     // margin-bottom: 16px;
 }
 
+.btnDelete{
+    position: absolute;
+    right: 0;
+    top: 0;
+    bottom: 0;
+    width: 120px;
+    background-color: red;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    color: #fff;
+    text-align: center;
+    transition: all 0.2s;
+    transform: translateX(120px);
+}
+
+.btnDeleteAni{
+    transform: translateX(0);
+}
+
 .modalTitle1 {
     font-size: 40px;
     line-height: 40px;

+ 49 - 3
src/features/trackTimeDuration/components/RecordFastSleep.tsx

@@ -21,6 +21,8 @@ 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 { sqrt } from 'mathjs'
 
 let AppState;
@@ -32,7 +34,9 @@ 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 }) => {
@@ -44,10 +48,14 @@ const RecordFastSleep = memo((props: { data: any, type: string, index: number })
     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()
     };
@@ -65,6 +73,12 @@ const RecordFastSleep = memo((props: { data: any, type: string, index: number })
         // 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];
@@ -126,6 +140,7 @@ const RecordFastSleep = memo((props: { data: any, type: string, index: number })
             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)
@@ -148,7 +163,7 @@ const RecordFastSleep = memo((props: { data: any, type: string, index: number })
 
         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} />
+                subTitle={subTitle(timestamp)} first_real_check_time={timestamp} diffTimeZone={diffTimeZone} multiTimeZone={multiTimeZone} />
         </View>
     }
 
@@ -518,13 +533,44 @@ const RecordFastSleep = memo((props: { data: any, type: string, index: number })
         </View>
     }
 
+    function touchStart(e) {
+        startX = e.touches[0].clientX
+
+    }
+
+    function touchMove(e) {
+        let x = startX
+        let deltaX = e.touches[0].clientX - x
+
+
+        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
+    }
+
     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">
+        <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}>删除</View>
 
         </View>
         {

+ 6 - 0
src/features/trackTimeDuration/components/TimelineFastSleep.scss

@@ -25,4 +25,10 @@
     font-size: 48px;
     margin-bottom: 40px;
     text-align: center;
+}
+
+.tz_note_desc{
+    opacity: 0.4;
+    color: #FA5151;
+    font-size: 24px;
 }

+ 65 - 48
src/features/trackTimeDuration/components/TimelineFastSleep.tsx

@@ -1,42 +1,44 @@
 import Timeline from "@/components/view/Timeline";
 import { TimeFormatter } from "@/utils/time_format";
-import { View } from "@tarojs/components";
+import { View, Text } from "@tarojs/components";
 import getStatus from "../hooks/Record";
 import { ColorType } from "@/context/themes/color";
 import { useTranslation } from "react-i18next";
 import { useEffect, useState } from "react";
 import { useSelector } from "react-redux";
+import './TimelineFastSleep.scss'
 
-export default function TimelineFastSleep(props: { data: any, title?: string, first_real_check_time?: number }) {
+export default function TimelineFastSleep(props: { data: any, title?: string, first_real_check_time?: number,multiTimeZone?: boolean, diffTimeZone?: boolean }) {
     const { t } = useTranslation()
-    const [diffTimeZone, setDiffTimeZone] = useState(false)
+    const [diffTimeZone, setDiffTimeZone] = useState(props.diffTimeZone)
+    const [multTimeZone, setMulTimeZone] = useState(props.multiTimeZone)
     const scenario = useSelector((state: any) => state.scenario);
 
     useEffect(() => {
-        var split = new Date().toString().split(' ');
-        var currentTZ = split[split.length - 2];
-        if (props.data.fast) {
-            if (props.data.fast.real_start_time_zone && props.data.fast.real_start_time_zone != currentTZ) {
-                setDiffTimeZone(true)
-                return
-            }
-            if (props.data.fast.real_end_time_zone && props.data.fast.real_end_time_zone != currentTZ) {
-                setDiffTimeZone(true)
-                return
-            }
-        }
+        // var split = new Date().toString().split(' ');
+        // var currentTZ = split[split.length - 2];
+        // if (props.data.fast) {
+        //     if (props.data.fast.real_start_time_zone && props.data.fast.real_start_time_zone != currentTZ) {
+        //         setDiffTimeZone(true)
+        //         return
+        //     }
+        //     if (props.data.fast.real_end_time_zone && props.data.fast.real_end_time_zone != currentTZ) {
+        //         setDiffTimeZone(true)
+        //         return
+        //     }
+        // }
 
-        if (props.data.sleep) {
-            if (props.data.sleep.real_start_time_zone && props.data.sleep.real_start_time_zone != currentTZ) {
-                setDiffTimeZone(true)
-                return
-            }
-            if (props.data.sleep.real_end_time_zone && props.data.sleep.real_end_time_zone != currentTZ) {
-                setDiffTimeZone(true)
-                return
-            }
-        }
-        setDiffTimeZone(false)
+        // if (props.data.sleep) {
+        //     if (props.data.sleep.real_start_time_zone && props.data.sleep.real_start_time_zone != currentTZ) {
+        //         setDiffTimeZone(true)
+        //         return
+        //     }
+        //     if (props.data.sleep.real_end_time_zone && props.data.sleep.real_end_time_zone != currentTZ) {
+        //         setDiffTimeZone(true)
+        //         return
+        //     }
+        // }
+        // setDiffTimeZone(false)
 
     }, [props.data])
 
@@ -45,19 +47,23 @@ export default function TimelineFastSleep(props: { data: any, title?: string, fi
         if (isEnd) {
             if (obj.real_end_time) {
                 var newTimestamp = TimeFormatter.transferTimestamp(obj.real_end_time, obj.real_end_time_zone)
-                return diffTimeZone ? TimeFormatter.timelineFullFormatTime(newTimestamp) : TimeFormatter.timelineFormatTime(obj.real_end_time)
+                return TimeFormatter.timelineFormatTime(newTimestamp)
+                // return diffTimeZone ? TimeFormatter.timelineFullFormatTime(newTimestamp) : TimeFormatter.timelineFormatTime(obj.real_end_time)
             }
             else {
-                return diffTimeZone ? TimeFormatter.timelineFullFormatTime(obj.target_end_time) : TimeFormatter.timelineFormatTime(obj.target_end_time)
+                return TimeFormatter.timelineFormatTime(obj.target_end_time)
+                // return diffTimeZone ? TimeFormatter.timelineFullFormatTime(obj.target_end_time) : TimeFormatter.timelineFormatTime(obj.target_end_time)
             }
         }
         else {
             if (obj.real_start_time) {
                 var newTimestamp = TimeFormatter.transferTimestamp(obj.real_start_time, obj.real_start_time_zone)
-                return diffTimeZone ? TimeFormatter.timelineFullFormatTime(newTimestamp) : TimeFormatter.timelineFormatTime(obj.real_start_time)
+                return TimeFormatter.timelineFormatTime(newTimestamp)
+                // return diffTimeZone ? TimeFormatter.timelineFullFormatTime(newTimestamp) : TimeFormatter.timelineFormatTime(obj.real_start_time)
             }
             else {
-                return diffTimeZone ? TimeFormatter.timelineFullFormatTime(obj.target_start_time) : TimeFormatter.timelineFormatTime(obj.target_start_time)
+                return TimeFormatter.timelineFormatTime(obj.target_start_time)
+                // return diffTimeZone ? TimeFormatter.timelineFullFormatTime(obj.target_start_time) : TimeFormatter.timelineFormatTime(obj.target_start_time)
             }
         }
 
@@ -140,16 +146,15 @@ export default function TimelineFastSleep(props: { data: any, title?: string, fi
         if (props.data.fast.real_start_time_zone) {
             timeZone = ' ' + props.data.fast.real_start_time_zone
         }
-        debugger
         timelineItems.push(
             {
                 status: getStatus(true, true, props.data),
                 title: getStatus(true, true, props.data) == 'padding' ?
                     t('feature.track_time_duration.common.start_fast') :
                     t('feature.track_time_duration.common.started_fasting'),
-                content: props.data.status == 'WAIT_FOR_START' ? scenario.schedule.fast.start_time : formateTime(props.data.fast, false),
-                date: props.data.status == 'WAIT_FOR_START' ? '' :
-                    (diffTimeZone ? timeZone : showDate(props.data.fast, false) ? formateDate(props.data.fast, false) : ''),
+                content: props.data.status == 'WAIT_FOR_START' ? formateDate(props.data.fast, false) + scenario.schedule.fast.start_time : formateDate(props.data.fast, false) + formateTime(props.data.fast, false),
+                date: props.data.status == 'WAIT_FOR_START' ? '' : multTimeZone ? timeZone : '',
+                // (diffTimeZone ? timeZone : showDate(props.data.fast, false) ? formateDate(props.data.fast, false) : ''),
                 color: global.fastColor ? global.fastColor : ColorType.fast
             }
         )
@@ -160,17 +165,17 @@ export default function TimelineFastSleep(props: { data: any, title?: string, fi
             timeZone = ' ' + props.data.sleep.real_start_time_zone
         }
         var status = getStatus(false, true, props.data)
-        var strContent = props.data.status == 'WAIT_FOR_START' ? scenario.schedule.sleep.start_time : formateTime(props.data.sleep, false)
-        var strDate = props.data.status == 'WAIT_FOR_START' ? getWaitForStartDate(scenario.schedule.sleep.start_time) :
-            (diffTimeZone ? timeZone : showDate(props.data.sleep, false) ? formateDate(props.data.sleep, false) : '')
+        var strContent = props.data.status == 'WAIT_FOR_START' ? formateDate(props.data.sleep, false) + scenario.schedule.sleep.start_time : formateDate(props.data.sleep, false) + formateTime(props.data.sleep, false)
+        var strDate = props.data.status == 'WAIT_FOR_START' ? getWaitForStartDate(scenario.schedule.sleep.start_time) : multTimeZone ? timeZone : ''
+        // (diffTimeZone ? timeZone : showDate(props.data.sleep, false) ? formateDate(props.data.sleep, false) : '')
         timelineItems.push(
             {
                 status: status,
                 title: status == 'padding' ?
                     t('feature.track_time_duration.common.start_sleep') :
                     t('feature.track_time_duration.common.started_sleeping'),
-                content: status=='un_done'?'':strContent,
-                date: status=='un_done'?'':strDate,
+                content: status == 'un_done' ? '' : strContent,
+                date: status == 'un_done' ? '' : strDate,
                 color: global.sleepColor ? global.sleepColor : ColorType.sleep
             }
         )
@@ -181,17 +186,17 @@ export default function TimelineFastSleep(props: { data: any, title?: string, fi
             timeZone = ' ' + props.data.sleep.real_end_time_zone
         }
         var status = getStatus(false, false, props.data)
-        var strContent = props.data.status == 'WAIT_FOR_START' ? scenario.schedule.sleep.end_time : formateTime(props.data.sleep, true)
-        var strDate = props.data.status == 'WAIT_FOR_START' ? getWaitForStartDate(scenario.schedule.sleep.end_time) :
-            (diffTimeZone ? timeZone : showDate(props.data.sleep, true) ? formateDate(props.data.sleep, true) : '')
+        var strContent: string = props.data.status == 'WAIT_FOR_START' ? formateDate(props.data.sleep, true) + scenario.schedule.sleep.end_time : formateDate(props.data.sleep, true) + formateTime(props.data.sleep, true)
+        var strDate = props.data.status == 'WAIT_FOR_START' ? getWaitForStartDate(scenario.schedule.sleep.end_time) : multTimeZone ? timeZone : ''
+        // (diffTimeZone ? timeZone : showDate(props.data.sleep, true) ? formateDate(props.data.sleep, true) : '')
         timelineItems.push(
             {
                 status: status,
                 title: status == 'padding' ?
                     t('feature.track_time_duration.common.end_sleep') :
                     t('feature.track_time_duration.common.ended_sleeping'),
-                content: status=='un_done'?'':strContent,
-                date: status=='un_done'?'':strDate,
+                content: status == 'un_done' ? '' : strContent,
+                date: status == 'un_done' ? '' : strDate,
                 color: global.sleepColor ? global.sleepColor : ColorType.sleep
             }
         )
@@ -207,13 +212,25 @@ export default function TimelineFastSleep(props: { data: any, title?: string, fi
                 title: getStatus(true, false, props.data) == 'padding' ?
                     t('feature.track_time_duration.common.end_fast') :
                     t('feature.track_time_duration.common.ended_fasting'),
-                content: props.data.status == 'WAIT_FOR_START' ? scenario.schedule.fast.end_time : formateTime(props.data.fast, true),
-                date: props.data.status == 'WAIT_FOR_START' ? getWaitForStartDate(scenario.schedule.fast.end_time) :
-                    (diffTimeZone ? timeZone : showDate(props.data.fast, true) ? formateDate(props.data.fast, true) : ''),
+                content: props.data.status == 'WAIT_FOR_START' ? formateDate(props.data.fast, true) + scenario.schedule.fast.end_time : formateDate(props.data.fast, true) + formateTime(props.data.fast, true),
+                date: props.data.status == 'WAIT_FOR_START' ? getWaitForStartDate(scenario.schedule.fast.end_time) : multTimeZone ? timeZone : '',
+                // (diffTimeZone ? timeZone : showDate(props.data.fast, true) ? formateDate(props.data.fast, true) : ''),
                 color: global.fastColor ? global.fastColor : ColorType.fast
             }
         )
     }
 
-    return <Timeline items={timelineItems} title={props.title} />
+    return <View style={{ display: 'flex', flexDirection: 'column' }}>
+        <View style={{ display: 'flex', flexDirection: 'row' }}>
+            <Timeline items={timelineItems} title={props.title} width={468} />
+            <View>
+            </View>
+        </View>
+        {
+            multTimeZone && <Text className="tz_note_desc">{t('feature.common.multi_tz_desc')}</Text>
+        }
+        {
+            diffTimeZone && <Text className="tz_note_desc">{t('feature.common.diff_tz_desc',{location:'Shanghai'})}</Text>
+        }
+    </View>
 }

+ 219 - 0
src/features/trackTimeDuration/components/TimelineFastSleep的副本.tsx

@@ -0,0 +1,219 @@
+import Timeline from "@/components/view/Timeline";
+import { TimeFormatter } from "@/utils/time_format";
+import { View } from "@tarojs/components";
+import getStatus from "../hooks/Record";
+import { ColorType } from "@/context/themes/color";
+import { useTranslation } from "react-i18next";
+import { useEffect, useState } from "react";
+import { useSelector } from "react-redux";
+
+export default function TimelineFastSleep(props: { data: any, title?: string, first_real_check_time?: number }) {
+    const { t } = useTranslation()
+    const [diffTimeZone, setDiffTimeZone] = useState(false)
+    const scenario = useSelector((state: any) => state.scenario);
+
+    useEffect(() => {
+        var split = new Date().toString().split(' ');
+        var currentTZ = split[split.length - 2];
+        if (props.data.fast) {
+            if (props.data.fast.real_start_time_zone && props.data.fast.real_start_time_zone != currentTZ) {
+                setDiffTimeZone(true)
+                return
+            }
+            if (props.data.fast.real_end_time_zone && props.data.fast.real_end_time_zone != currentTZ) {
+                setDiffTimeZone(true)
+                return
+            }
+        }
+
+        if (props.data.sleep) {
+            if (props.data.sleep.real_start_time_zone && props.data.sleep.real_start_time_zone != currentTZ) {
+                setDiffTimeZone(true)
+                return
+            }
+            if (props.data.sleep.real_end_time_zone && props.data.sleep.real_end_time_zone != currentTZ) {
+                setDiffTimeZone(true)
+                return
+            }
+        }
+        setDiffTimeZone(false)
+
+    }, [props.data])
+
+
+    function formateTime(obj: any, isEnd: boolean) {
+        if (isEnd) {
+            if (obj.real_end_time) {
+                var newTimestamp = TimeFormatter.transferTimestamp(obj.real_end_time, obj.real_end_time_zone)
+                return diffTimeZone ? TimeFormatter.timelineFullFormatTime(newTimestamp) : TimeFormatter.timelineFormatTime(obj.real_end_time)
+            }
+            else {
+                return diffTimeZone ? TimeFormatter.timelineFullFormatTime(obj.target_end_time) : TimeFormatter.timelineFormatTime(obj.target_end_time)
+            }
+        }
+        else {
+            if (obj.real_start_time) {
+                var newTimestamp = TimeFormatter.transferTimestamp(obj.real_start_time, obj.real_start_time_zone)
+                return diffTimeZone ? TimeFormatter.timelineFullFormatTime(newTimestamp) : TimeFormatter.timelineFormatTime(obj.real_start_time)
+            }
+            else {
+                return diffTimeZone ? TimeFormatter.timelineFullFormatTime(obj.target_start_time) : TimeFormatter.timelineFormatTime(obj.target_start_time)
+            }
+        }
+
+    }
+
+    function showDate(obj: any, isEnd: boolean) {
+        var dt = 0
+        if (isEnd) {
+            if (obj.real_end_time) {
+                dt = obj.real_end_time
+            }
+            else {
+                dt = obj.target_end_time
+            }
+        }
+        else {
+            if (obj.real_start_time) {
+                dt = obj.real_start_time
+            }
+            else {
+                dt = obj.target_start_time
+            }
+        }
+        // debugger
+        var dt2 = props.first_real_check_time ? props.first_real_check_time : 0
+        var date1 = new Date(dt)
+        var date2 = new Date(dt2)
+        if (date1.getFullYear() == date2.getFullYear() &&
+            date1.getMonth() == date2.getMonth() &&
+            date1.getDate() == date2.getDate()) {
+            return false
+        }
+        return true
+    }
+
+    function formateDate(obj: any, isEnd: boolean) {
+        if (isEnd) {
+            if (obj.real_end_time) {
+                return TimeFormatter.dateDescription(obj.real_end_time)
+            }
+            else {
+                return TimeFormatter.dateDescription(obj.target_end_time)
+            }
+        }
+        else {
+            if (obj.real_start_time) {
+                return TimeFormatter.dateDescription(obj.real_start_time)
+            }
+            else {
+                return TimeFormatter.dateDescription(obj.target_start_time)
+            }
+        }
+
+    }
+
+    function getWaitForStartDate(time: string) {
+        var strTime
+        if (scenario.name == 'SLEEP') {
+            strTime = scenario.schedule.sleep.start_time
+        }
+        else {
+            strTime = scenario.schedule.fast.start_time
+        }
+        var count = parseInt(strTime.split(':')[0]) * 60 + parseInt(strTime.split(':')[1])
+        var count2 = parseInt(time.split(':')[0]) * 60 + parseInt(time.split(':')[1])
+        if (count > count2) {
+            return global.language == 'en' ? 'Tomorrow' : '明天'
+        }
+        return ''
+    }
+
+    var timelineItems: any = [];
+    /*
+    attention:
+    status == 待开始时
+    timeline的时间不以时间戳进行处理,而是以target时间字符串进行显示
+    */
+    if (props.data.fast && scenario.name != 'SLEEP') {
+        var timeZone = ''
+        if (props.data.fast.real_start_time_zone) {
+            timeZone = ' ' + props.data.fast.real_start_time_zone
+        }
+        debugger
+        timelineItems.push(
+            {
+                status: getStatus(true, true, props.data),
+                title: getStatus(true, true, props.data) == 'padding' ?
+                    t('feature.track_time_duration.common.start_fast') :
+                    t('feature.track_time_duration.common.started_fasting'),
+                content: props.data.status == 'WAIT_FOR_START' ? scenario.schedule.fast.start_time : formateTime(props.data.fast, false),
+                date: props.data.status == 'WAIT_FOR_START' ? '' :
+                    (diffTimeZone ? timeZone : showDate(props.data.fast, false) ? formateDate(props.data.fast, false) : ''),
+                color: global.fastColor ? global.fastColor : ColorType.fast
+            }
+        )
+    }
+    if (props.data.sleep && scenario.name != 'FAST') {
+        var timeZone = ''
+        if (props.data.sleep.real_start_time_zone) {
+            timeZone = ' ' + props.data.sleep.real_start_time_zone
+        }
+        var status = getStatus(false, true, props.data)
+        var strContent = props.data.status == 'WAIT_FOR_START' ? scenario.schedule.sleep.start_time : formateTime(props.data.sleep, false)
+        var strDate = props.data.status == 'WAIT_FOR_START' ? getWaitForStartDate(scenario.schedule.sleep.start_time) :
+            (diffTimeZone ? timeZone : showDate(props.data.sleep, false) ? formateDate(props.data.sleep, false) : '')
+        timelineItems.push(
+            {
+                status: status,
+                title: status == 'padding' ?
+                    t('feature.track_time_duration.common.start_sleep') :
+                    t('feature.track_time_duration.common.started_sleeping'),
+                content: status=='un_done'?'':strContent,
+                date: status=='un_done'?'':strDate,
+                color: global.sleepColor ? global.sleepColor : ColorType.sleep
+            }
+        )
+    }
+    if (props.data.sleep && scenario.name != 'FAST') {
+        var timeZone = ''
+        if (props.data.sleep.real_end_time_zone) {
+            timeZone = ' ' + props.data.sleep.real_end_time_zone
+        }
+        var status = getStatus(false, false, props.data)
+        var strContent = props.data.status == 'WAIT_FOR_START' ? scenario.schedule.sleep.end_time : formateTime(props.data.sleep, true)
+        var strDate = props.data.status == 'WAIT_FOR_START' ? getWaitForStartDate(scenario.schedule.sleep.end_time) :
+            (diffTimeZone ? timeZone : showDate(props.data.sleep, true) ? formateDate(props.data.sleep, true) : '')
+        timelineItems.push(
+            {
+                status: status,
+                title: status == 'padding' ?
+                    t('feature.track_time_duration.common.end_sleep') :
+                    t('feature.track_time_duration.common.ended_sleeping'),
+                content: status=='un_done'?'':strContent,
+                date: status=='un_done'?'':strDate,
+                color: global.sleepColor ? global.sleepColor : ColorType.sleep
+            }
+        )
+    }
+    if (props.data.fast && scenario.name != 'SLEEP') {
+        var timeZone = ''
+        if (props.data.fast.real_end_time_zone) {
+            timeZone = ' ' + props.data.fast.real_end_time_zone
+        }
+        timelineItems.push(
+            {
+                status: getStatus(true, false, props.data),
+                title: getStatus(true, false, props.data) == 'padding' ?
+                    t('feature.track_time_duration.common.end_fast') :
+                    t('feature.track_time_duration.common.ended_fasting'),
+                content: props.data.status == 'WAIT_FOR_START' ? scenario.schedule.fast.end_time : formateTime(props.data.fast, true),
+                date: props.data.status == 'WAIT_FOR_START' ? getWaitForStartDate(scenario.schedule.fast.end_time) :
+                    (diffTimeZone ? timeZone : showDate(props.data.fast, true) ? formateDate(props.data.fast, true) : ''),
+                color: global.fastColor ? global.fastColor : ColorType.fast
+            }
+        )
+    }
+
+    return <Timeline items={timelineItems} title={props.title} />
+}

+ 15 - 51
src/features/trackTimeDuration/components/TimelineStage.weapp.tsx

@@ -14,7 +14,7 @@ import TotalTime from './TotalTime';
 
 
 
-export default function Component(props: { data: any, title?: string, subTitle?: string, isSchedule?: boolean, first_real_check_time?: number }) {
+export default function Component(props: { data: any, title?: string, subTitle?: string, isSchedule?: boolean, first_real_check_time?: number, multiTimeZone?: boolean, diffTimeZone?: boolean }) {
     // debugger
     const [segmentIndex, setSegmentIndex] = useState(0)
     const permission = useSelector((state: any) => state.permission);
@@ -52,16 +52,16 @@ export default function Component(props: { data: any, title?: string, subTitle?:
         })
     }
 
-    return <View style={{ display: 'flex', flexDirection: 'column', width: rpxToPx(578) }}>
-        {/* <Text className='box_title'>{props.title ? props.title : 'Title'}</Text> */}
-        <View className="box_header" style={{ backgroundColor: global.isDebug ? 'pink' : 'transparent' }}>
-            <Text className="box_title" style={{ backgroundColor: global.isDebug ? 'red' : 'transparent' }}>{props.title ? props.title : 'Title'}</Text>
-            {
-                props.isSchedule && process.env.TARO_ENV == 'weapp' &&
-                <Switch isOn={permission.wxPubFollow} onClick={() => followWxPub()} />
-            }
+    return <View style={{ display: 'flex', flexDirection: 'column', width: rpxToPx(578), height: rpxToPx(800) }}>
+        <View style={{ marginBottom: 0 }}>
+            <Segment titles={[
+                t('feature.track_time_duration.schedule.total_time'),
+                t('feature.track_time_duration.record_fast_sleep.timeline'),
+            ]} changed={(e) => {
+                setSegmentIndex(e);
+                global.segmentIndex = e
+            }} />
         </View>
-        <Text className='box_subtitle'>{props.subTitle ? props.subTitle : 'subTitle'}</Text>
         <View className="segment_detail" style={{
             display: 'flex', alignItems: 'center',
             flexDirection: 'column', justifyContent: 'center'
@@ -70,52 +70,16 @@ export default function Component(props: { data: any, title?: string, subTitle?:
                 position: 'relative', width: '100%', display: 'flex', alignItems: 'center',
                 flexDirection: 'column', justifyContent: 'center'
             }}>
-                {/* <View style={{ backgroundColor: 'pink' }}>
+                <View>
                     {
-                        segmentIndex == 0 ? <TimelineFastSleep data={props.data} /> : <Stage data={props.data} />
+                        segmentIndex == 0 ? <TotalTime record={props.data} /> :
+                            <TimelineFastSleep data={props.data} first_real_check_time={props.first_real_check_time} diffTimeZone={props.diffTimeZone} multiTimeZone={props.multiTimeZone} />
                     }
-                </View> */}
-
-                <View style={{ position: 'relative' }}>
-                    <View style={{ opacity: segmentIndex == 0 ? 1 : 0,height:200 }}>
-                        <TotalTime record={props.data} />
-
-                    </View>
-                    {props.data.scenario == 'FAST_SLEEP' && <View style={{
-                        opacity: segmentIndex == 1 ? 1 : 0,
-                        // position: 'absolute', left: 0, top: 0, right: 0, bottom: 0,
-                    }}>
-                        <TimelineFastSleep data={props.data} first_real_check_time={props.first_real_check_time} />
-                        {/* <Stage data={props.data} /> */}
-                    </View>}
                 </View>
+            </View>
+        </View>
 
 
-                {/* <View style={{ opacity: segmentIndex == 0 ? 1 : 0 }}>
-                    <TimelineFastSleep data={props.data} />
-                </View>
-                {
-                    props.data.scenario == 'FAST_SLEEP' && <View style={{
-                        position: 'absolute', left: 0, top: 0, right: 0, bottom: 0,
-                        opacity: segmentIndex == 1 ? 1 : 0
-                    }}>
-                        <Stage data={props.data} />
-                    </View>
-                } */}
 
-            </View>
-        </View>
-        {
-            props.data.scenario == 'FAST_SLEEP' &&
-            <View style={{ marginBottom: 0 }}>
-                <Segment titles={[
-                    t('feature.track_time_duration.schedule.total_time'),
-                    t('feature.track_time_duration.record_fast_sleep.timeline'),
-                ]} changed={(e) => {
-                    setSegmentIndex(e);
-                    global.segmentIndex = e
-                }} />
-            </View>
-        }
     </View>
 }

+ 121 - 0
src/features/trackTimeDuration/components/TimelineStage.weapp的副本.tsx

@@ -0,0 +1,121 @@
+import { View, Text } from '@tarojs/components'
+import './TimelineStage.scss'
+import { useEffect, useState } from 'react';
+import Segment from '@/components/navigation/Segment';
+import TimelineFastSleep from './TimelineFastSleep';
+import Stage from './Stage';
+import { useTranslation } from 'react-i18next';
+import Switch from '@/components/input/Switch';
+import { useSelector } from 'react-redux';
+import Taro from '@tarojs/taro';
+import { jumpPage } from '../hooks/Common';
+import { rpxToPx } from '@/utils/tools';
+import TotalTime from './TotalTime';
+
+
+
+export default function Component(props: { data: any, title?: string, subTitle?: string, isSchedule?: boolean, first_real_check_time?: number }) {
+    // debugger
+    const [segmentIndex, setSegmentIndex] = useState(0)
+    const permission = useSelector((state: any) => state.permission);
+    const common = useSelector((state: any) => state.common);
+
+
+
+
+    const { t } = useTranslation()
+
+    function followWxPub() {
+        const resource = common.resources.filter((item: any) => {
+            return item.code == 'follow_wx_pub'
+        })
+
+        const title = permission.wxPubFollow ? t('feature.track_time_duration.follow_wx_pub.h5_followed_title') :
+            t('feature.track_time_duration.follow_wx_pub.h5_unfollowed_title')
+
+        Taro.showModal({
+            title: permission.wxPubFollow ? t('feature.track_time_duration.follow_wx_pub.modal_followed_title') :
+                t('feature.track_time_duration.follow_wx_pub.modal_unfollowed_title'),
+            content: permission.wxPubFollow ? t('feature.track_time_duration.follow_wx_pub.modal_followed_content') :
+                t('feature.track_time_duration.follow_wx_pub.modal_unfollowed_content'),
+            showCancel: true,
+            cancelText: permission.wxPubFollow ? t('feature.track_time_duration.follow_wx_pub.modal_followed_cancel_btn') :
+                t('feature.track_time_duration.follow_wx_pub.modal_unfollowed_cancel_btn'),
+            confirmText: permission.wxPubFollow ? t('feature.track_time_duration.follow_wx_pub.modal_followed_confirm_btn') :
+                t('feature.track_time_duration.follow_wx_pub.modal_unfollowed_confirm_btn'),
+            success(result) {
+                if (result.confirm) {
+                    global.forceRefreshWXPub = true
+                    jumpPage('/pages/common/H5?title=' + title + '&url=' + resource[0].url)
+                }
+            },
+        })
+    }
+
+    return <View style={{ display: 'flex', flexDirection: 'column', width: rpxToPx(578) }}>
+        {/* <Text className='box_title'>{props.title ? props.title : 'Title'}</Text> */}
+        <View className="box_header" style={{ backgroundColor: global.isDebug ? 'pink' : 'transparent' }}>
+            <Text className="box_title" style={{ backgroundColor: global.isDebug ? 'red' : 'transparent' }}>{props.title ? props.title : 'Title'}</Text>
+            {
+                props.isSchedule && process.env.TARO_ENV == 'weapp' &&
+                <Switch isOn={permission.wxPubFollow} onClick={() => followWxPub()} />
+            }
+        </View>
+        <Text className='box_subtitle'>{props.subTitle ? props.subTitle : 'subTitle'}</Text>
+        <View className="segment_detail" style={{
+            display: 'flex', alignItems: 'center',
+            flexDirection: 'column', justifyContent: 'center'
+        }}>
+            <View style={{
+                position: 'relative', width: '100%', display: 'flex', alignItems: 'center',
+                flexDirection: 'column', justifyContent: 'center'
+            }}>
+                {/* <View style={{ backgroundColor: 'pink' }}>
+                    {
+                        segmentIndex == 0 ? <TimelineFastSleep data={props.data} /> : <Stage data={props.data} />
+                    }
+                </View> */}
+
+                <View style={{ position: 'relative' }}>
+                    <View style={{ opacity: segmentIndex == 0 ? 1 : 0,height:200 }}>
+                        <TotalTime record={props.data} />
+
+                    </View>
+                    {props.data.scenario == 'FAST_SLEEP' && <View style={{
+                        opacity: segmentIndex == 1 ? 1 : 0,
+                        // position: 'absolute', left: 0, top: 0, right: 0, bottom: 0,
+                    }}>
+                        <TimelineFastSleep data={props.data} first_real_check_time={props.first_real_check_time} />
+                        {/* <Stage data={props.data} /> */}
+                    </View>}
+                </View>
+
+
+                {/* <View style={{ opacity: segmentIndex == 0 ? 1 : 0 }}>
+                    <TimelineFastSleep data={props.data} />
+                </View>
+                {
+                    props.data.scenario == 'FAST_SLEEP' && <View style={{
+                        position: 'absolute', left: 0, top: 0, right: 0, bottom: 0,
+                        opacity: segmentIndex == 1 ? 1 : 0
+                    }}>
+                        <Stage data={props.data} />
+                    </View>
+                } */}
+
+            </View>
+        </View>
+        {
+            props.data.scenario == 'FAST_SLEEP' &&
+            <View style={{ marginBottom: 0 }}>
+                <Segment titles={[
+                    t('feature.track_time_duration.schedule.total_time'),
+                    t('feature.track_time_duration.record_fast_sleep.timeline'),
+                ]} changed={(e) => {
+                    setSegmentIndex(e);
+                    global.segmentIndex = e
+                }} />
+            </View>
+        }
+    </View>
+}

+ 191 - 23
src/features/trackTimeDuration/components/TotalTime.tsx

@@ -1,15 +1,42 @@
-import { View, Text, Image } from "@tarojs/components";
+import { View, Text, Image, PageContainer } from "@tarojs/components";
 import './TotalTime.scss'
 import { useTranslation } from "react-i18next";
 import { ColorType } from "@/context/themes/color";
 import { rpxToPx } from "@/utils/tools";
 import { TimeFormatter } from "@/utils/time_format";
+import Modal from "@/components/layout/Modal.weapp";
+import { useEffect, useRef, useState } from "react";
+import { durationDatas, durationIndex, getColor, getDurationTitle } from "../hooks/Console";
+import PickerViews from "@/components/input/PickerViews";
+import { useSelector } from "react-redux";
+import Taro from "@tarojs/taro";
 
 export default function TotalTime(props: { record: any }) {
+    const [showDurationPicker, setShowDurationPicker] = useState(false)
+    const [fastPickerValue, setFastPickerValue] = useState([0, 0])
+    const [sleepPickerValue, setSleepPickerValue] = useState([0, 0])
+    const [showEditPicker, setShowEditPicker] = useState(false)
+    const common = useSelector((state: any) => state.common);
+    const [isFast, setIsFast] = useState(true)
+    const durationPickerRef = useRef(null)
     const { t } = useTranslation()
 
+    useEffect(()=>{
+        getStateDetail()
+    },[])
+
+    function getStateDetail() {
+        var current_record = props.record
+        // var fastCount = current_record.fast.target_end_time - current_record.fast.target_start_time
+        // setFastDuration(fastCount)
+        setFastPickerValue(durationIndex(current_record.fast.target_start_time, current_record.fast.target_end_time, common))
+
+        // var sleepCount = current_record.sleep.target_end_time - current_record.sleep.target_start_time
+        // setSleepDuration(sleepCount)
+        setSleepPickerValue(durationIndex(current_record.sleep.target_start_time, current_record.sleep.target_end_time, common))
+    }
+
     function sleepCompleteStatus() {
-        debugger
         if (props.record.sleep.status == "NOT_STARTED") {
             return t('feature.common.not_started')
         }
@@ -47,14 +74,62 @@ export default function TotalTime(props: { record: any }) {
         return TimeFormatter.countdown(props.record.sleep.target_end_time)
     }
 
+    function setFastDuration() {
+        setIsFast(true)
+        if (disableChange(true)) return
+        if (props.record.status == 'WAIT_FOR_START') {
+            setShowDurationPicker(true)
+        }
+        else {
+            setShowEditPicker(true)
+        }
+    }
+
+    function setSleepDuration() {
+        setIsFast(false)
+        if (disableChange(false)) return
+        if (props.record.status == 'WAIT_FOR_START') {
+            Taro.showToast({
+                title: t('feature.track_time_duration.common.start_fasting_first'),
+                icon: 'none'
+            })
+            return;
+        }
+        if (props.record.status == 'WAIT_FOR_START' || props.record.status == 'ONGOING1') {
+            setShowDurationPicker(true)
+        }
+        else {
+            setShowEditPicker(true)
+        }
+    }
+
+    function disableChange(isFastStatus) {
+        if (props.record.status == 'WAIT_FOR_START') {
+            return false;
+        }
+        if (isFastStatus) {
+            if (props.record.status != 'COMPLETED')
+                return false;
+            return true
+        }
+        else {
+            if (props.record.status == 'ONGOING3' || props.record.status == 'COMPLETED') {
+                return true
+            }
+            return false;
+        }
+    }
+
     function fastOtherStatus() {
         return <View>
             <View className="cell_full" >
                 <Text className="cell_title" style={{ opacity: 0.2 }}>已进行</Text>
-                <Text className="cell_value" 
-                style={{ color: props.record.status == 'WAIT_FOR_START' ?
-                 '#fff' : ColorType.fast, 
-                 opacity: props.record.status == 'WAIT_FOR_START' ? 0.2 : 1 }}>{fastGoingText()}</Text>
+                <Text className="cell_value"
+                    style={{
+                        color: props.record.status == 'WAIT_FOR_START' ?
+                            '#fff' : ColorType.fast,
+                        opacity: props.record.status == 'WAIT_FOR_START' ? 0.2 : 1
+                    }}>{fastGoingText()}</Text>
             </View>
             <View className="cell_line" style={{ height: 1 }} />
             <View className="cell_full" >
@@ -68,9 +143,11 @@ export default function TotalTime(props: { record: any }) {
         return <View>
             <View className="cell_full" >
                 <Text className="cell_title" style={{ opacity: 0.2 }}>已进行</Text>
-                <Text className="cell_value" style={{ color: props.record.status == 'WAIT_FOR_START'||props.record.status == 'ONGOING1' ?
-                 '#fff' : ColorType.sleep, 
-                 opacity: props.record.status == 'WAIT_FOR_START'||props.record.status == 'ONGOING1' ? 0.2 : 1 }}>{sleepGoingText()}</Text>
+                <Text className="cell_value" style={{
+                    color: props.record.status == 'WAIT_FOR_START' || props.record.status == 'ONGOING1' ?
+                        '#fff' : ColorType.sleep,
+                    opacity: props.record.status == 'WAIT_FOR_START' || props.record.status == 'ONGOING1' ? 0.2 : 1
+                }}>{sleepGoingText()}</Text>
             </View>
             <View className="cell_line" style={{ height: 1 }} />
             <View className="cell_full" >
@@ -80,7 +157,97 @@ export default function TotalTime(props: { record: any }) {
         </View>
     }
 
-    return <View style={{ marginLeft: -rpxToPx(50), marginRight: -rpxToPx(50) }}>
+    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)
+                }} />
+        </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)
+                }} />
+        </View>
+    }
+
+    function durationChange(e) {
+        // debugger
+        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)
+        }
+        else {
+
+        }
+        setShowDurationPicker(false)
+        setShowEditPicker(false)
+    }
+
+    function modalContent() {
+        if (showDurationPicker || showEditPicker) {
+            if (process.env.TARO_ENV == 'weapp') {
+                return <Modal
+                    testInfo={null}
+                    dismiss={() => {
+                        setShowDurationPicker(false)
+                        setShowEditPicker(false)
+                    }}
+                    confirm={() => { }}>
+                    {
+                        showDurationPicker ? durationPickerContent() : editPickerContent()
+                    }
+                </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={() => { setShowDurationPicker(false); setShowEditPicker(false) }}
+                    show={showDurationPicker} round={true} overlay={true} position='bottom'
+                >
+                    {
+                        showDurationPicker ? durationPickerContent() : editPickerContent()
+                    }
+                </PageContainer>
+            }
+        }
+        return <View />
+    }
+
+    return <View style={{ width: rpxToPx(600) }}>
         {
             props.record.fast && <View>
                 <Text className="cell_header">断食</Text>
@@ -90,21 +257,21 @@ export default function TotalTime(props: { record: any }) {
                             <View className="cell_full" >
                                 <Text className="cell_title">实际完成</Text>
                                 <Text className="cell_value" style={{ color: ColorType.fast }}>{TimeFormatter.durationFormate(props.record.fast.real_start_time, props.record.fast.real_end_time)}</Text>
-                                <Image className="cell_arrow" src={require('@/assets/images/arrow3.png')} />
+                                {/* <Image className="cell_arrow" src={require('@/assets/images/arrow3.png')} /> */}
                             </View> :
-                            <View className="cell_full" >
+                            <View className="cell_full" onClick={setFastDuration}>
                                 <Text className="cell_title">本次目标</Text>
                                 <Text className="cell_value">{TimeFormatter.durationFormate(props.record.fast.target_start_time, props.record.fast.target_end_time)}</Text>
-                                <Image className="cell_arrow" src={require('@/assets/images/arrow3.png')} />
+                                {!disableChange(true) && <Image className="cell_arrow" src={require('@/assets/images/arrow3.png')} />}
                             </View>
                     }
                     <View className="cell_line" style={{ height: 1 }} />
                     {
                         props.record.status == 'COMPLETED' ?
-                            <View className="cell_full" >
+                            <View className="cell_full" onClick={setFastDuration}>
                                 <Text className="cell_title" style={{ opacity: 0.2 }}>本次目标</Text>
-                                <Text className="cell_value" style={{ opacity: 0.2,color:'#fff' }}>{TimeFormatter.durationFormate(props.record.fast.target_start_time, props.record.fast.target_end_time)}</Text>
-                                <Image className="cell_arrow" src={require('@/assets/images/arrow3.png')} />
+                                <Text className="cell_value" style={{ opacity: 0.2, color: '#fff' }}>{TimeFormatter.durationFormate(props.record.fast.target_start_time, props.record.fast.target_end_time)}</Text>
+                                {!disableChange(true) && <Image className="cell_arrow" src={require('@/assets/images/arrow3.png')} />}
                             </View> :
                             fastOtherStatus()
                     }
@@ -121,28 +288,29 @@ export default function TotalTime(props: { record: any }) {
                             <View className="cell_full" >
                                 <Text className="cell_title">实际完成</Text>
                                 <Text className="cell_value" style={{ color: ColorType.sleep }}>{sleepCompleteStatus()}</Text>
-                                <Image className="cell_arrow" src={require('@/assets/images/arrow3.png')} />
                             </View> :
-                            <View className="cell_full" >
+                            <View className="cell_full" onClick={setSleepDuration}>
                                 <Text className="cell_title">本次目标</Text>
                                 <Text className="cell_value">{TimeFormatter.durationFormate(props.record.sleep.target_start_time, props.record.sleep.target_end_time)}</Text>
-                                <Image className="cell_arrow" src={require('@/assets/images/arrow3.png')} />
+                                {!disableChange(false) && <Image className="cell_arrow" src={require('@/assets/images/arrow3.png')} />}
                             </View>
                     }
                     <View className="cell_line" style={{ height: 1 }} />
                     {
                         props.record.status == 'COMPLETED' || props.record.status == 'ONGOING3' ?
-                            <View className="cell_full" >
+                            <View className="cell_full" onClick={setSleepDuration}>
                                 <Text className="cell_title" style={{ opacity: 0.2 }}>本次目标</Text>
-                                <Text className="cell_value" style={{ opacity: 0.2,color:'#fff' }}>{TimeFormatter.durationFormate(props.record.sleep.target_start_time, props.record.sleep.target_end_time)}</Text>
-                                <Image className="cell_arrow" src={require('@/assets/images/arrow3.png')} />
+                                <Text className="cell_value" style={{ opacity: 0.2, color: '#fff' }}>{TimeFormatter.durationFormate(props.record.sleep.target_start_time, props.record.sleep.target_end_time)}</Text>
+                                {!disableChange(false) && <Image className="cell_arrow" src={require('@/assets/images/arrow3.png')} />}
                             </View> :
                             sleepOtherStatus()
                     }
                 </View>
             </View>
         }
-
+        {
+            modalContent()
+        }
 
     </View>
 }

+ 1 - 2
src/features/trackTimeDuration/components/WeekCalendar.scss

@@ -48,8 +48,7 @@
     margin-left: 46px;
     border-radius: 16px;
     overflow: hidden;
-    height: 520px;
-    // width: 658px;
+    // height: 520px;
     display: flex;
     flex-direction: row;
 }

+ 64 - 55
src/features/trackTimeDuration/components/WeekCalendar.tsx

@@ -1,6 +1,6 @@
 import { View, ScrollView, Text } from "@tarojs/components";
 import './WeekCalendar.scss'
-import { useEffect, useState,useMemo,memo } from "react";
+import { useEffect, useState, useMemo, memo } from "react";
 import { ColorType } from "@/context/themes/color";
 import WeekCalendarItem from "./WeekCalendarItem";
 import { rpxToPx } from "@/utils/tools";
@@ -13,15 +13,16 @@ let scrollTimer;
 let isScrolling;
 let fingerDrag = false;
 
-const WeekCalendar = memo(()=>{
+
+const WeekCalendar = memo(() => {
     const [calendars, setCalendars] = useState<any>([])
     const [current, setCurrent] = useState(0)
     const [summary, setSummary] = useState<any>(null)
     const [calendarData, setCalendarData] = useState<any>(null)
     const [minTime, setMinTime] = useState(0)
-    const [left,setLeft] = useState(0)
+    const [left, setLeft] = useState(0)
     const [isLoading, setIsLoading] = useState(false)
-    const pageSize = 7
+    const pageSize = 15
 
     useEffect(() => {
         pageIndex = -1
@@ -43,15 +44,15 @@ const WeekCalendar = memo(()=>{
             if (pageIndex == 0) {
                 setCalendars(list)
                 setCurrent(list.length - 1)
-                setSummary(list[list.length - 1].summary_stats?list[list.length - 1].summary_stats:null)
+                setSummary(list[list.length - 1].summary_stats ? list[list.length - 1].summary_stats : null)
                 setCalendarData(list[list.length - 1])
                 setMinTime((res as any).extra.real_start_time_min)
-                setLeft((list.length - 1) * rpxToPx(658))
+                setLeft((list.length - 1) * parseInt(rpxToPx(658) + ''))
                 setIsLoading(false)
             }
             else {
                 var array = list.concat(calendars)
-                updateList(array)
+                updateList(array,list)
 
             }
 
@@ -59,21 +60,22 @@ const WeekCalendar = memo(()=>{
         // clockSummaryStats({start:new Date().getTime()-7*24*3600*1000,end:new Date().getTime()}).then(res => { })
     }
 
-    function updateList(array) {
+    function updateList(array,list) {
         timer = setInterval(() => {
             if (!isScrolling) {
                 setCalendars(array)
-                setCurrent(current + 7)
-                setSummary(array[current + 7].summary_stats?array[current + 7].summary_stats:null)
-                setCalendarData(array[current + 7])
-                setLeft((current + 7) * rpxToPx(658))
+                setCurrent(current + list.length)
+                setSummary(array[current + list.length].summary_stats ? array[current + list.length].summary_stats : null)
+                setCalendarData(array[current + list.length])
+                setLeft((current + list.length-1) * parseInt(rpxToPx(658) + ''))
                 setIsLoading(false)
                 clearInterval(timer);
+                timer = null;
             }
         }, 30)
     }
 
-    function dragStart(e){
+    function dragStart(e) {
         fingerDrag = true
     }
 
@@ -82,33 +84,30 @@ const WeekCalendar = memo(()=>{
     }
 
     function onScroll(e) {
-        // if (!fingerDrag) {
-        //     return
-        // }
+        if (!fingerDrag) return
         isScrolling = true
-        var x = e.detail.scrollLeft
-        var page = parseInt(x / rpxToPx(586) + '')
-        // console.log(page,calendars.length)
-        if (current != page && page<calendars.length) {
-            console.log(page)
+        var x = e.detail.scrollLeft + 5
+        var page = parseInt(x / parseInt(rpxToPx(658) + '') + '')
+
+        if (current != page && page < calendars.length && page >= 0) {
             setCurrent(page)
-            setSummary(calendars[page].summary_stats?calendars[page].summary_stats:null)
+            setSummary(calendars[page].summary_stats ? calendars[page].summary_stats : null)
             setCalendarData(calendars[page])
-            if (page <= 2) {
+            // if (page <= 0) {
 
-                // getRecords();
-            }
+            //     getRecords();
+            // }
         }
-        if (scrollTimer)
-            clearTimeout(scrollTimer);
-
-        scrollTimer = setTimeout(() => {
-            isScrolling = false
-            fingerDrag = false;
-        }, 300) as any
+        // if (scrollTimer)
+        //     clearTimeout(scrollTimer);
 
+        // scrollTimer = setTimeout(() => {
+        //     isScrolling = false
+        //     fingerDrag = false;
+        // }, 300) as any
     }
 
+
     function getDate(timestamp) {
         var date = new Date(timestamp)
         return `${date.getMonth() + 1}月${date.getDate()}日`
@@ -128,32 +127,42 @@ const WeekCalendar = memo(()=>{
             </View>
         </View>
         <Text className="calendar_summary_desc">{getDate(calendarData.start)} 周日中午 - {getDate(calendarData.end)} 周日中午</Text>
+
         <View className="chart_bg">
-            <View className="chart_content_bg" />
-            <ScrollView className="chart_scroll"
-            style={{width:rpxToPx(658)}}
-                onScroll={onScroll}
-                onDragEnd={dragEnd}
-                onDragStart={dragStart}
-                scrollLeft={left}
-                scrollX pagingEnabled={true}
-                enableFlex enhanced>
-                {
-                    calendars.map((item) => {
-                        return <WeekCalendarItem data={item} />
-                    })
-                }
-
-            </ScrollView>
-            <View className="chart_times">
-                <Text className="chart_times_txt">12:00</Text>
-                <Text className="chart_times_txt">18:00</Text>
-                <Text className="chart_times_txt">24:00</Text>
-                <Text className="chart_times_txt">06:00</Text>
-                <Text className="chart_times_txt">12:00</Text>
+            <View className="chart_bg">
+                <View className="chart_content_bg" />
+                <ScrollView
+                    // className="chart_scroll"
+                    style={{
+                        marginLeft: rpxToPx(46),
+                        width: parseInt(rpxToPx(658) + ''),
+                        height: parseInt(rpxToPx(520) + ''),
+                        flexDirection: 'row', display: 'flex',
+                    }}
+                    onScroll={onScroll}
+                    onDragEnd={dragEnd}
+                    onDragStart={dragStart}
+                    scrollLeft={left}
+                    scrollX pagingEnabled={true}
+                    enableFlex enhanced>
+                    {
+                        calendars.map((item, index) => {
+
+                            return <WeekCalendarItem data={item} key={index} />
+                        })
+                    }
+
+                </ScrollView>
+                <View className="chart_times">
+                    <Text className="chart_times_txt">12:00</Text>
+                    <Text className="chart_times_txt">18:00</Text>
+                    <Text className="chart_times_txt">24:00</Text>
+                    <Text className="chart_times_txt">06:00</Text>
+                    <Text className="chart_times_txt">12:00</Text>
+                </View>
             </View>
-        </View>
 
+        </View>
     </View>
 })
 

+ 0 - 1
src/features/trackTimeDuration/components/WeekCalendarItem.scss

@@ -2,7 +2,6 @@
     display: flex;
     flex-direction: column;
     height: 520px;
-    // width: 658px;
     // background-color: red;
     flex-shrink: 0;
 }

+ 1 - 1
src/features/trackTimeDuration/components/WeekCalendarItem.tsx

@@ -63,7 +63,7 @@ export default function WeekCalendarItem(props: { data: any }) {
             return null;
         }
     }
-    return <View className="chart_content" style={{width:rpxToPx(658)}}>
+    return <View className="chart_content" style={{width:parseInt(rpxToPx(658)+'')}}>
         <View className="chart_top_week">
             <Text className="chart_week_text">周日</Text>
             <Text className="chart_week_text">周一</Text>

+ 1 - 1
src/pages/clock/Index.tsx

@@ -143,7 +143,7 @@ export default function Page() {
             if (user.isLogin) {
                 isPause = (res as any).fast_sleep.current_record.status=='WAIT_FOR_START'
                 dispatch(updateScenario((res as any).fast_sleep.current_record))
-
+                dispatch(setConfigs((res as any).time_input_schema));
                 dispatch(setScenario((res as any).fast_sleep.scenario));
             }
         })

+ 7 - 2
src/store/common.tsx

@@ -13,6 +13,7 @@ interface CommonState {
     showTabbar: boolean | true;
     showFoodTabBadge: boolean | false;
     pageIndex: number | 0;
+    recordSelID: any | null; //删除id
 }
 
 const initialState: CommonState = {
@@ -23,13 +24,17 @@ const initialState: CommonState = {
     duration: null,
     showTabbar: true,
     showFoodTabBadge: false,
-    pageIndex: 0
+    pageIndex: 0,
+    recordSelID:null
 }
 
 const commonSlice = createSlice({
     name: 'permission',
     initialState,
     reducers: {
+        setSelID(state,action){
+            state.recordSelID = action.payload;
+        },
         //静态资源
         setResources(state, action) {
             state.resources = action.payload;
@@ -68,4 +73,4 @@ const commonSlice = createSlice({
 });
 
 export default commonSlice.reducer;
-export const { setResources, setMealTags, setFoodScales, setConfigs, setTabbarStatus, changeTabbar, setFoodTabBadge } = commonSlice.actions;
+export const {setSelID, setResources, setMealTags, setFoodScales, setConfigs, setTabbarStatus, changeTabbar, setFoodTabBadge } = commonSlice.actions;

+ 0 - 1
src/utils/time_format.ts

@@ -318,7 +318,6 @@ export class TimeFormatter {
   }
   //格式化时间间隔
   static formateTimeDifference(startTimestamp: number, endTimestamp: number, ingoreSeconds?: boolean): string {
-    debugger
     const diff = Math.abs(endTimestamp - startTimestamp);
     // 计算小时、分钟和秒数
     const hours = Math.floor(diff / (1000 * 60 * 60));