leon 1 anno fa
parent
commit
13c6a695c5

+ 2 - 2
src/_health/base/new_date_picker.tsx

@@ -30,11 +30,11 @@ export default function NewDatePicker(props: { value?: any, onChange?: any, colo
     }, [])
 
     function itemDatas() {
-        return [['Today','Yesterday']]
+        return [['Yesterday','Today']]
     }
 
     function itemValues() {
-        return [props.isToday?0:1]
+        return [props.isToday?1:0]
     }
 
     function longDatas() {

+ 3 - 0
src/_health/components/card.scss

@@ -1,4 +1,5 @@
 .main_card {
+    display: flex;
     background-color: #fff;
     display: flex;
     border-radius: 26px;
@@ -6,5 +7,7 @@
     width: 698px;
     flex-direction: column;
     overflow: hidden;
+    -webkit-backface-visibility: hidden;
+    -webkit-mask-image: -webkit-radial-gradient(white,black);
     flex-shrink: 0;
 }

+ 58 - 0
src/_health/components/fast_sleep_popup.scss

@@ -0,0 +1,58 @@
+/* #ifdef weapp */
+.popup_container1 {
+    position: fixed;
+    left: 0;
+    right: 0;
+    top: 0;
+    bottom: 0;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    background-color: #00000080;
+}
+
+/* #endif */
+
+/* #ifdef rn */
+.popup_container1 {
+    position: absolute;
+    left: 0;
+    right: 0;
+    top: 0;
+    bottom: 0;
+    background-color: #00000080;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+}
+
+/* #endif */
+
+.fast_sleep_content {
+    width: 536px;
+    display: flex;
+    border-radius: 36px;
+    flex-direction: column;
+    padding-top: 48px;
+    padding-bottom: 48px;
+    align-items: center;
+    background-color: #fff;
+}
+
+.pop_line1 {
+    width: 440px;
+    height: 1px;
+    transform: scaleY(0.5);
+    margin-top: 36px;
+    margin-bottom: 36px;
+    background-color: #000;
+    opacity: 0.1;
+}
+
+.pop_steps {
+    width: 440px;
+    display: flex;
+    flex-direction: column;
+    align-items: flex-start;
+    margin-bottom: 36px;
+}

+ 232 - 0
src/_health/components/fast_sleep_popup.tsx

@@ -0,0 +1,232 @@
+import { View, Image, Text } from "@tarojs/components";
+import './fast_sleep_popup.scss'
+import Card from "./card";
+import NewButton, { NewButtonType } from "../base/new_button";
+import { rpxToPx } from "@/utils/tools";
+import { useTranslation } from "react-i18next";
+import { useSelector } from "react-redux";
+import { MainColorType } from "@/context/themes/color";
+import { TimeFormatter } from "@/utils/time_format";
+import StatusIndicator, { StatusType } from "../base/status_indicator";
+import { IconCheck } from "@/components/basic/Icons";
+
+export default function FastSleepPopup(props: { close: any, data: any }) {
+    const health = useSelector((state: any) => state.health);
+    const { t } = useTranslation()
+
+    function total() {
+        const { fast } = props.data
+        return diffentTime(fast.period.start_time, fast.period.end_time)
+    }
+
+    function total1() {
+        const { fast, sleep } = props.data
+        return diffentTime(fast.period.start_time, sleep.period.start_time)
+    }
+
+    function total2() {
+        const { sleep } = props.data
+        return diffentTime(sleep.period.start_time, sleep.period.end_time)
+    }
+
+    function total3() {
+        const { fast, sleep } = props.data
+        return diffentTime(sleep.period.end_time, fast.period.end_time)
+    }
+
+    function step1() {
+        if (health.fast_with_sleep.status == 'OG2_MISALIGNED') {
+            return '-'
+        }
+        const { fast, sleep, status } = props.data
+        if (status == 'WFS') {
+            return ('-')
+        }
+        else if (status == 'OG1') {
+            return TimeFormatter.countdown(fast.real.start_timestamp)
+        }
+        else if (status == 'OG2_NO1') {
+            return ('-')
+        }
+        return TimeFormatter.calculateTimeDifference(fast.real.start_timestamp, sleep.real.start_timestamp)
+    }
+
+    function step2() {
+        const { fast, sleep, status } = props.data
+        if (status == 'WFS' || status == 'OG1') {
+            return '-'
+        }
+
+        if (status == 'OG2_NO1' || status == 'OG2') {
+            return TimeFormatter.countdown(sleep.real.start_timestamp)
+        }
+        else if (status == 'OG3') {
+            return TimeFormatter.calculateTimeDifference(sleep.real.start_timestamp, sleep.real.end_timestamp)
+        }
+        return TimeFormatter.calculateTimeDifference(sleep.target.start_timestamp, sleep.target.end_timestamp)
+    }
+
+    function step3() {
+        const { fast, sleep, status } = props.data
+        if (status == 'WFS' || status == 'OG1' || status == 'OG2_NO1' || status == 'OG2') {
+            return '-'
+        }
+        if (status == 'OG3') {
+            return TimeFormatter.countdown(sleep.real.end_timestamp)
+        }
+        return TimeFormatter.calculateTimeDifference(sleep.target.end_timestamp, fast.target.end_timestamp)
+    }
+
+    function diffentTime(time2, time1) {
+        var duration = 0
+
+        var t1 = parseInt(time1.split(':')[0]) * 60 + parseInt(time1.split(':')[1])
+        var t2 = parseInt(time2.split(':')[0]) * 60 + parseInt(time2.split(':')[1])
+        duration = t1 - t2 >= 0 ? (t1 - t2) * 60 * 1000 : (t1 - t2) * 60 * 1000 + 24 * 3600 * 1000
+
+        var now = new Date().getTime()
+        return TimeFormatter.calculateTimeDifference(now, now + duration)
+    }
+
+    function beforeStatus() {
+        const { status } = props.data
+        var type = StatusType.normal
+        if (status == 'WFS') {
+            type = StatusType.normal
+        }
+        else if (status == 'OG1') {
+            type = StatusType.ing
+        }
+        else {
+            type = StatusType.img
+        }
+        return type
+    }
+
+    function beforeSleep() {
+        const type = beforeStatus()
+        return <StatusIndicator type={type}
+            color={MainColorType.fast}
+            fontColor={MainColorType.g01}
+            text={t('health.fast_befor_bed')}
+        >
+            {
+                type == StatusType.img && <Image style={{ width: rpxToPx(20), height: rpxToPx(20) }} src={require('@assets/_health/checked.png')} />
+            }
+        </StatusIndicator>
+
+    }
+
+    function ingStatus() {
+        const { status } = props.data
+        var type = StatusType.normal
+        if (status == 'WFS' || status == 'OG1') {
+            type = StatusType.normal
+        }
+        else if (status == 'OG2') {
+            type = StatusType.ing
+        }
+        else {
+            type = StatusType.img
+        }
+        return type;
+    }
+
+    function sleeping() {
+        const type = ingStatus()
+        return <StatusIndicator type={type}
+            color={MainColorType.sleep}
+            fontColor={MainColorType.g01}
+            text={t('health.fast_while_sleep')}
+        >
+            {
+                type == StatusType.img && <Image style={{ width: rpxToPx(20), height: rpxToPx(20) }} src={require('@assets/_health/checked.png')} />
+            }
+        </StatusIndicator>
+    }
+
+    function afterStatus() {
+        const { status } = props.data
+        var type = StatusType.normal
+        if (status == 'WFS' || status == 'OG1' || status == 'OG2') {
+            type = StatusType.normal
+        }
+        else if (status == 'OG3') {
+            type = StatusType.ing
+        }
+        else {
+            type = StatusType.img
+        }
+        return type;
+    }
+
+    function afterSleep() {
+        const type = afterStatus()
+        return <StatusIndicator type={type}
+            color={MainColorType.fast}
+            fontColor={MainColorType.g01}
+            text={t('health.fast_after_sleep')}
+        >
+            {
+                type == StatusType.img && <Image style={{ width: rpxToPx(20), height: rpxToPx(20) }} src={require('@assets/_health/checked.png')} />
+            }
+        </StatusIndicator>
+    }
+
+    return <View className="popup_container1">
+        <View className="fast_sleep_content">
+            <View className="h34 bold">{t('health.my_fast_journal')}</View>
+            <View className="h24 bold g01" style={{ marginTop: rpxToPx(8) }}>{t('health.my_fast_duration', { time: total() })}</View>
+            <View className="pop_line1" />
+            <View className="pop_steps">
+                {
+                    beforeSleep()
+                }
+                <View style={{ display: 'flex', flexDirection: 'row' }}>
+                    <View style={{
+                        marginLeft: rpxToPx(12.5),
+                        marginRight: rpxToPx(24),
+                        width: 1, height: rpxToPx(103),
+                        backgroundColor: (ingStatus() == StatusType.ing || afterStatus() == StatusType.ing) ? MainColorType.g01 : MainColorType.g03
+                    }} />
+                    <Text className="bold h24"
+                        style={{ marginTop: rpxToPx(12), color: beforeStatus() == StatusType.ing ? MainColorType.fast : '#000' }}><Text className="h34">{step1()}</Text> / {total1()}</Text>
+                </View>
+                {
+                    sleeping()
+                }
+                <View style={{ display: 'flex', flexDirection: 'row' }}>
+                    <View style={{
+                        marginLeft: rpxToPx(12.5),
+                        marginRight: rpxToPx(24),
+                        width: 1, height: rpxToPx(103),
+                        backgroundColor: afterStatus() == StatusType.ing ? MainColorType.g01 : MainColorType.g03
+                    }} />
+                    <Text className="bold h24"
+                        style={{ marginTop: rpxToPx(12), color: ingStatus() == StatusType.ing ? MainColorType.sleep : '#000' }}><Text className="h34">{step2()}</Text> / {total2()}</Text>
+                </View>
+                {
+                    afterSleep()
+                }
+                <View style={{ display: 'flex', flexDirection: 'row' }}>
+                    <View style={{
+                        marginLeft: rpxToPx(12.5),
+                        marginRight: rpxToPx(24.5),
+                        width: 1, height: rpxToPx(103),
+                        backgroundColor: 'transparent'
+                    }} />
+                    <Text className="bold h24"
+                        style={{ marginTop: rpxToPx(12), color: afterStatus() == StatusType.ing ? MainColorType.fast : '#000' }}><Text className="h34">{step3()}</Text> / {total3()}</Text>
+                </View>
+            </View>
+            <NewButton
+                type={NewButtonType.fill}
+                color={MainColorType.fast}
+                width={rpxToPx(440)}
+                height={rpxToPx(96)}
+                title={t('health.ok')}
+                onClick={props.close}
+            />
+        </View>
+    </View>
+}

+ 11 - 6
src/_health/pages/fast_sleep.tsx

@@ -17,9 +17,11 @@ import FastSleepCard from "../components/fast_sleep_card";
 import FastSleepDetailCard from "../components/fast_sleep_detail_card";
 import MainHistory from "@/features/health/MainHistory";
 import StickyDateList from "../components/sticky_date_list";
+import FastSleepPopup from "../components/fast_sleep_popup";
 
 export default function FastSleep() {
     const health = useSelector((state: any) => state.health);
+    const [showPopCard,setShowPopCard] = useState(false)
     const [time, setTime] = useState(dayjs().format('HH:mm'))
     const [count, setCount] = useState(0)
 
@@ -100,32 +102,32 @@ export default function FastSleep() {
                     onChange={e => setCurrent(e.detail.current)}
                     current={current}
                     indicatorDots>
-                    <SwiperItem>
+                    <SwiperItem onClick={()=>setShowPopCard(true)}>
                         <Card>
                             <FastSleepCard step={0} data={data} />
 
                         </Card>
                     </SwiperItem>
-                    <SwiperItem>
+                    <SwiperItem onClick={()=>setShowPopCard(true)}>
                         <Card>
                             <FastSleepCard step={1} data={data} />
                         </Card>
                     </SwiperItem>
-                    <SwiperItem>
+                    <SwiperItem onClick={()=>setShowPopCard(true)}>
                         <Card>
                             <FastSleepCard step={2} data={data} />
                         </Card>
                     </SwiperItem>
-                    <SwiperItem>
+                    <SwiperItem onClick={()=>setShowPopCard(true)}>
                         <Card>
                             <FastSleepCard step={3} data={data} />
                         </Card>
                     </SwiperItem>
                 </Swiper>
             }
-            {
+            {/* {
                 health.fast_with_sleep.status != 'OG2_MISALIGNED' && <FastSleepDetailCard data={data} />
-            }
+            } */}
 
 
 
@@ -138,6 +140,9 @@ export default function FastSleep() {
             }} refreshSuccess={() => {
                 setIsPulling(false)
             }} />
+            {
+                showPopCard && <FastSleepPopup close={()=>{setShowPopCard(false)}} data={data}/>
+            }
         </View>
     </StickyDateList>
 }

+ 1 - 1
src/_health/pages/log_time.tsx

@@ -632,7 +632,7 @@ export default function LogTime() {
                         onChange={(e) => {
                             // console.log(e)
                             var list = JSON.parse(JSON.stringify(array))
-                            list[index].today = e==0
+                            list[index].today = e==1
                             list[index].extra.confirm_time = new Date().getTime()
                             setArray(list)
                         }}

+ 54 - 129
src/_health/pages/schedules.tsx

@@ -347,141 +347,66 @@ export default function Schedules() {
             <NewHeader type={NewHeaderType.left} title={getTitle()} />
 
             <Card>
-                {
-                    errors.map((item, index) => {
-                        return <View key={index} className='error_tip'>
+                <View>
+                    {
+                        errors.map((item, index) => {
+                            return <View key={index} className='error_tip'>
+                                <StatusIndicator type={StatusType.img}
+                                    fontColor="#000"
+                                    fontSize={rpxToPx(24)}
+                                    text={item} color={MainColorType.error}>
+                                    <IconError color="#fff" width={rpxToPx(26)} />
+                                </StatusIndicator>
+                            </View>
+                            // return <View key={index} className='error_tip'>{item}</View>
+                        })
+                    }
+                    {
+                        showAutoSave && <View className='success_tip'>
                             <StatusIndicator type={StatusType.img}
                                 fontColor="#000"
                                 fontSize={rpxToPx(24)}
-                                text={item} color={MainColorType.error}>
-                                <IconError color="#fff" width={rpxToPx(26)} />
+                                text='已自动保存' color={MainColorType.success}>
+                                <IconSuccess color="#fff" width={rpxToPx(26)} />
                             </StatusIndicator>
                         </View>
-                        // return <View key={index} className='error_tip'>{item}</View>
-                    })
-                }
-                {
-                    showAutoSave && <View className='success_tip'>
-                        <StatusIndicator type={StatusType.img}
-                            fontColor="#000"
-                            fontSize={rpxToPx(24)}
-                            text='已自动保存' color={MainColorType.success}>
-                            <IconSuccess color="#fff" width={rpxToPx(26)} />
-                        </StatusIndicator>
-                    </View>
-                }
-                {
-                    !health.finish_setup && selMode == '' && <View className='success_tip' style={{ backgroundColor: MainColorType.blue + '1A', color: MainColorType.blue }}>You haven't finished setting up your schedule yet!</View>
-                }
-                {
-                    list.map((obj, i) => {
-                        return <ScheduleItem
-                            key={i * 100}
-                            obj={obj}
-                            highlight={false}
-                            showLine={i < list.length - 1}
-                            errors={errors}
-                            selMode={selMode}
-                            disable={!health.finish_setup}
-                            onChange={time => {
-                                obj.time = time
-                                setSelItem(obj)
-                                setShowTimePicker(false)
-                                var array = JSON.parse(JSON.stringify(list))
-                                array[i].time = time
-                                array[i].op_ms = new Date().getTime()
-                                setList(array)
-                                checkData(array)
-                            }}
-                            onDelete={() => {
-                                delSchedule(obj.id).then(res => {
+                    }
+                    {
+                        !health.finish_setup && selMode == '' && <View className='success_tip' style={{ backgroundColor: MainColorType.blue + '1A', color: MainColorType.blue }}>You haven't finished setting up your schedule yet!</View>
+                    }
+                    {
+                        list.map((obj, i) => {
+                            return <ScheduleItem
+                                key={i * 100}
+                                obj={obj}
+                                highlight={false}
+                                showLine={i < list.length - 1}
+                                errors={errors}
+                                selMode={selMode}
+                                disable={!health.finish_setup}
+                                onChange={time => {
+                                    obj.time = time
+                                    setSelItem(obj)
+                                    setShowTimePicker(false)
                                     var array = JSON.parse(JSON.stringify(list))
-                                    array.splice(i, 1)
+                                    array[i].time = time
+                                    array[i].op_ms = new Date().getTime()
                                     setList(array)
-
-                                    global.refreshWindow()
-                                })
-                            }}
-                        // onClick={() => {
-                        //     setSelIndex(i)
-                        //     setSelItem(obj)
-                        //     setShowTimePicker(true)
-                        // }}
-                        />
-                        // return <AtSwipeAction key={i * 100}
-                        //     isOpened={false}
-                        //     autoClose
-                        //     disabled={obj.window != 'EAT' && obj.window != 'ACTIVE'}
-                        //     options={[
-                        //         {
-                        //             text: '删除',
-                        //             style: {
-                        //                 backgroundColor: '#FF4949'
-                        //             }
-                        //         }
-                        //     ]}
-                        //     onClick={() => {
-                        //         if (obj.window == 'ACTIVE' || obj.window == 'EAT') {
-                        //             // if (item.list.length == 1) {
-                        //             //     Taro.showToast({
-                        //             //         title: '至少保留一项',
-                        //             //         icon: 'none'
-                        //             //     })
-                        //             //     return;
-                        //             // }
-                        //         }
-                        //         showAlert({
-                        //             title: '删除',
-                        //             content: '确认删除此计划',
-                        //             showCancel: true,
-                        //             cancel: () => {
-                        //                 console.log('cancel')
-                        //             },
-                        //             confirm: () => {
-                        //                 // delItem(index, i)
-                        //             }
-                        //         })
-                        //     }}
-                        // ><View className='schedule_item' key={i} style={{
-                        //     width: rpxToPx(700),
-                        //     boxSizing: 'border-box',
-                        //     backgroundColor: (obj.window == selMode && highlight) ? getThemeColor(selMode) + '08' : '#fff'
-
-                        // }}>
-                        //         <View className='item_left2'>
-                        //             <StatusIndicator
-                        //                 type={obj.is_conflict ? StatusType.img : StatusType.normal}
-                        //                 text={obj.title}
-                        //                 fontSize={rpxToPx(34)}
-                        //                 fontColor="#000"
-                        //                 color={obj.is_conflict ? MainColorType.error : errors.length == 0 ? getThemeColor(obj.window) : 'transparent'} >
-                        //                 {
-                        //                     obj.is_conflict && <IconError color="#fff" width={rpxToPx(26)} />
-                        //                 }
-
-                        //             </StatusIndicator>
-                        //             <View style={{ flex: 1 }} />
-                        //             {
-                        //                 !obj.is_all_day && !obj.reminder && <IconNotificationOff color={MainColorType.g03} width={rpxToPx(28)} />
-                        //             }
-                        //             <View style={{ width: rpxToPx(12) }} />
-                        //             {
-                        //                 !obj.is_all_day && <View className='edit_item_time' onClick={() => {
-                        //                     setSelIndex(i)
-                        //                     setSelItem(obj)
-                        //                     setShowTimePicker(true)
-                        //                 }} style={itemStyle(obj)}>{obj.time}</View>
-                        //             }
-
-
-                        //         </View>
-                        //         {
-                        //             i < list.length - 1 && <View className='border_footer_line' style={{ left: rpxToPx(66) }} />
-                        //         }
-                        //     </View>
-                        // </AtSwipeAction>
-                    })
-                }
+                                    checkData(array)
+                                }}
+                                onDelete={() => {
+                                    delSchedule(obj.id).then(res => {
+                                        var array = JSON.parse(JSON.stringify(list))
+                                        array.splice(i, 1)
+                                        setList(array)
+
+                                        global.refreshWindow()
+                                    })
+                                }}
+                            />
+                        })
+                    }
+                </View>
             </Card>
             <View style={{ height: 20, flexShrink: 0 }} />
             {
@@ -490,7 +415,7 @@ export default function Schedules() {
                     <StatusIndicator type={StatusType.img}
                         fontColor={getAddColor()}
                         fontSize={rpxToPx(34)}
-                        text={(selMode == 'FAST' || selMode == 'EAT')?t('health.add_meal'):t('health.add_active')} color={getAddColor()}>
+                        text={(selMode == 'FAST' || selMode == 'EAT') ? t('health.add_meal') : t('health.add_active')} color={getAddColor()}>
                         <IconAdd color="#fff" width={rpxToPx(26)} />
                     </StatusIndicator>
                     {/* <IconAdd color={getAddColor()} width={rpxToPx(34)} />

+ 8 - 1
src/context/locales/en.js

@@ -927,7 +927,14 @@ export default {
         set_to_rise_desc:'To calculate nighttime from Sunset to Sunrise, we need to use your location information.',
         rise_to_set_desc:'To calculate daytime from Sunrise to Sunset, we need to use your location information.',
 
-        more_actions:'More Actions'
+        more_actions:'More Actions',
 
+        fast_befor_bed:'Fasting before Bedtime',
+        fast_while_sleep:'Fasting while Sleeping',
+        fast_after_sleep:'Fasting after Waking Up',
+        my_fast_journal:'My Fasting Journey',
+        my_fast_duration:'Total {{time}}',
+
+        ok:'OK',
     }
 }

+ 8 - 1
src/context/locales/zh.js

@@ -928,7 +928,14 @@ export default {
         set_to_rise_desc: '为计算夜晚时间(日落到日出)需要用到您的位置信息。',
         rise_to_set_desc: '为计算白天时间(日出到日落)需要用到您的位置信息。',
 
-        more_actions: '更多操作'
+        more_actions: '更多操作',
 
+        fast_befor_bed:'睡前断食',
+        fast_while_sleep:'睡眠期间断食',
+        fast_after_sleep:'起床后断食',
+        my_fast_journal:'我的断食旅程',
+        my_fast_duration:'全长 {{time}}',
+
+        ok:'我知道了',
     }
 }

+ 7 - 6
src/features/health/MainConsole.tsx

@@ -438,11 +438,11 @@ export default function MainConsole(props: { type: WindowType }) {
                         list.push(t('health.finish_setup'))
                     }
                     list.push(t('health.add_active'))
-                    var scenario = getScenario(health.windows,'ACTIVE')
-                    if (scenario.status !='WFS'){
+                    var scenario = getScenario(health.windows, 'ACTIVE')
+                    if (scenario.status != 'WFS') {
                         list.push(t('health.mark_done'))
                     }
-                    
+
 
                     if (health.finish_setup) {
                         list.push(t('health.edit_schedule'))
@@ -455,8 +455,8 @@ export default function MainConsole(props: { type: WindowType }) {
                         list.push(t('health.finish_setup'))
                     }
                     list.push(t('health.add_meal'))
-                    var scenario = getScenario(health.windows,'EAT')
-                    if (scenario.status !='WFS'){
+                    var scenario = getScenario(health.windows, 'EAT')
+                    if (scenario.status != 'WFS') {
                         list.push(t('health.mark_done'))
                     }
                     if (health.finish_setup) {
@@ -899,8 +899,9 @@ export default function MainConsole(props: { type: WindowType }) {
 
         </View>
         {
-            !hideGuideTip && !health.finish_setup && <View className="guide_tip h26" onClick={()=>{
+            user.isLogin && !hideGuideTip && !health.finish_setup && <View className="guide_tip h26" onClick={() => {
                 tapGuide();
+                setHideGuideTip(true)
             }}>{t('health.console_guide_tip')}
                 <NewButton type={NewButtonType.img} btnStyle={{
                     position: 'absolute',