Leon há 1 ano atrás
pai
commit
eb866e88e6

Diff do ficheiro suprimidas por serem muito extensas
+ 10 - 0
src/components/basic/Icons.tsx


+ 8 - 0
src/components/input/LimitPickers.scss

@@ -38,4 +38,12 @@
 
 .picker-sel{
     background-color: $sleepColor;
+}
+
+.pickerEndTime{
+    text-align: center;
+    color: #fff;
+    opacity: 0.4;
+    font-size: 20px;
+    line-height: 20px;
 }

+ 18 - 53
src/components/input/LimitPickers.tsx

@@ -8,7 +8,9 @@ import { TimeFormatter } from "@/utils/time_format";
 // export default function Component(props: { limit: number, onChange: Function, onCancel: Function,isRealTime?:boolean,limitDay?:number,time?:number,ref?:any }) {
 const Component = forwardRef((props: {
     limit: number, onChange: Function, onCancel: Function,
-    isRealTime?: boolean, limitDay?: number, time?: number, themeColor?: string, title?: string
+    isRealTime?: boolean, limitDay?: number, time?: number, themeColor?: string, title?: string,
+    showEndTime?: boolean,
+    duration?: number
 }, ref) => {
 
     const days: string[] = [];
@@ -36,9 +38,6 @@ const Component = forwardRef((props: {
             setValues([(props.limitDay ? props.limitDay - 1 : 6) - getDaysDiff(date), date.getHours(), date.getMinutes()])
         }
     }, [])
-    // useEffect(() => {
-    //     setValues([6, today.getHours(), today.getMinutes()])
-    // }, [props.limit])
 
     useEffect(() => {
         var date = new Date();
@@ -108,39 +107,6 @@ const Component = forwardRef((props: {
 
     function onPickerChange(e) {
         setValues(e.detail.value)
-        /*
-        var list = e.detail.value
-
-        const date = new Date();
-        date.setDate(today.getDate() - ((props.limitDay ? props.limitDay - 1 : 6) - list[0]));
-        const year = date.getFullYear();
-        const month = date.getMonth() + 1;
-        const day = date.getDate();
-
-        const time = `${year}-${expandZero(month)}-${expandZero(day)}T${expandZero(hours[list[1]])}:${expandZero(minutes[list[2]])}:00`;
-        if (getTimestamp(time) > global.set_time) {
-            Taro.showToast({
-                icon: 'none',
-                title: t('feature.common.toast.min_value'),
-            })
-            setValues([list[0], (new Date(global.set_time)).getHours(), (new Date(global.set_time)).getMinutes()])
-            disableConfirm()
-        }
-        else {
-            var limitDate = new Date(props.limit)
-
-            if (getTimestamp(time) < props.limit) {
-                Taro.showToast({
-                    icon: 'none',
-                    title: t('feature.common.toast.max_value'),
-                })
-                setValues([(props.limitDay ? props.limitDay - 1 : 6) - getDaysDiff(limitDate), limitDate.getHours(), limitDate.getMinutes()])
-                disableConfirm()
-                return
-            }
-
-            setValues(e.detail.value)
-        }*/
 
     }
 
@@ -176,22 +142,6 @@ const Component = forwardRef((props: {
             })
             return
         }
-        // else {
-        //     var limitDate = new Date(props.limit)
-
-        //     if (getTimestamp(time) < props.limit) {
-
-        //         setValues([(props.limitDay ? props.limitDay - 1 : 6) - getDaysDiff(limitDate), limitDate.getHours(), limitDate.getMinutes()])
-        //         setTimeout(() => {
-        //             setValues([(props.limitDay ? props.limitDay - 1 : 6) - getDaysDiff(limitDate), limitDate.getHours(), limitDate.getMinutes()])
-        //         }, 300)
-        //         Taro.showToast({
-        //             icon: 'none',
-        //             title: t('feature.common.toast.max_time_value'),
-        //         })
-        //         return
-        //     }
-        // }
 
         if (!props.isRealTime) {
             date = new Date(global.set_time);
@@ -225,6 +175,18 @@ const Component = forwardRef((props: {
         return num < 10 ? `0${num}` : `${num}`;
     }
 
+    function getEndTime(){
+        var date = new Date(global.set_time);
+        date.setDate(today.getDate() - ((props.limitDay ? props.limitDay - 1 : 6) - values[0]));
+        date.setHours(values[1])
+        date.setMinutes(values[2])
+        var newDate = new Date(date.getTime()+props.duration!).getTime()
+        if (global.language == 'en') {
+            return TimeFormatter.dateDescription(newDate, true) + ' ' + TimeFormatter.timeDescription(newDate)
+          }
+          return TimeFormatter.dateDescription(newDate, true) + '' + TimeFormatter.timeDescription(newDate)
+    }
+
     function pickerDetail() {
         return <View style={{ display: 'flex', flexDirection: 'column' }}>
             <Text className='modal_title' style={{ color: color }}>{props.title ? props.title : '测试标题 '}</Text>
@@ -266,6 +228,9 @@ const Component = forwardRef((props: {
                 <Text style={{ color: '#fff', fontSize: 16, fontWeight: 'bold' }}>:</Text>
             </View> */}
             </View>
+            {
+                props.showEndTime && <Text className="pickerEndTime">预计{getEndTime()}结束</Text>
+            }
             <View className='modal_operate'>
                 <View className='modal_btn' style={{ backgroundColor: color + alpha }} onClick={cancel}>
                     <Text className='modal_cancel_text' style={{ color: color, fontWeight: 'bold' }}>{t('feature.common.picker_cancel_btn')}</Text>

+ 0 - 0
src/components/input/Switch.scss → src/components/input/Switch2.scss


+ 1 - 1
src/components/input/Switch.tsx → src/components/input/Switch2.tsx

@@ -1,5 +1,5 @@
 import { View, Image } from "@tarojs/components";
-import './Switch.scss'
+import './Switch2.scss'
 import { IconSwitchOff } from "../basic/Icons";
 import { rpxToPx } from "@/utils/tools";
 export default function Component(props: { isOn: boolean, onClick: Function }) {

+ 64 - 0
src/components/input/switch.js

@@ -0,0 +1,64 @@
+Component({
+  properties: {
+    conf: {
+      type: Object,
+      value: {
+        height: 0,
+        width: 0,
+        color: '',
+        checked: true,
+        disabled: false,
+        radius: true,
+      },
+      observer: function(newVal, oldVal) {
+        if (typeof(newVal.height) == 'number' && newVal.height > 0) {
+          oldVal.height = newVal.height
+          if (typeof(newVal.width) == 'number' && newVal.width > newVal.height) {
+            oldVal.width = newVal.width
+          } else {
+            oldVal.width = oldVal.height + 20
+          }
+        }
+        if (typeof(newVal.color) == 'string' && newVal.color.length > 0) {
+          oldVal.color = newVal.color
+        }
+        if (newVal.checked) {
+          oldVal.checked = true
+        } else {
+          oldVal.checked = false
+        }
+        if (newVal.disabled) {
+          oldVal.disabled = true
+        } else {
+          oldVal.disabled = false
+        }
+        if (newVal.noRadius) {
+          oldVal.noRadius = true
+        } else {
+          oldVal.noRadius = false
+        }
+        this.setData(oldVal)
+      }
+    },
+  },
+  data: {
+    height: 0,
+    width: 0,
+    color: '',
+    checked: true,
+    disabled: false,
+    noRadius: false,
+  },
+  methods: {
+    doSwitch: function() {
+      if (!this.data.disabled) {
+        var value = {}
+        value.checked = !this.data.checked
+        this.triggerEvent('doSwitch', value)
+        this.setData({
+          checked: !this.data.checked
+        })
+      }
+    }
+  },
+})

+ 4 - 0
src/components/input/switch.json

@@ -0,0 +1,4 @@
+{
+  "component": true,
+  "usingComponents": {}
+}

+ 3 - 0
src/components/input/switch.wxml

@@ -0,0 +1,3 @@
+<view catchtap="doSwitch" class="switch {{disabled?'switch_disabled':''}} {{noRadius?'switch_no_radius':''}} {{checked?'switch_checked':''}}" style="{{height>0?'height:'+height+'rpx;width:'+(width>height?width:(height+20))+'rpx;'+(noRadius?'':'border-radius:'+(height+4)+'rpx;'):''}}{{color.length>0?'background:'+color+';':''}}{{(checked && color.length>0)?'border-color:'+color+';':''}}">
+  <view style="{{height>0?'width:'+height+'rpx;height:'+height+'rpx;':''}}"></view>
+</view>

+ 64 - 0
src/components/input/switch.wxss

@@ -0,0 +1,64 @@
+.switch {
+  display: inline-block;
+  width: 100rpx;
+  height: 60rpx;
+  border-radius: 64rpx;
+  border: 2rpx solid #ccc;
+  background: #00c000;
+  position: relative;
+  transition: all 0.35s cubic-bezier(0.45, 1, 0.4, 1);
+  overflow: hidden;
+}
+
+.switch_checked {
+  border-color: #00c000;
+}
+
+.switch view {
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 60rpx;
+  height: 60rpx;
+  border-radius: 50%;
+  background: #fff;
+  box-shadow: 0 2rpx 6rpx rgba(0, 0, 0, 0.4);
+  transition: all 0.35s cubic-bezier(0.45, 1, 0.4, 1);
+}
+
+.switch_checked view {
+  left: 100%;
+  transform: translateX(-100%);
+}
+
+.switch::before {
+  display: block;
+  content: '';
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  border-radius: 9999rpx;
+  background: #fff;
+  transition: all 0.35s cubic-bezier(0.45, 1, 0.4, 1);
+}
+
+.switch_checked::before {
+  transform: scale(0);
+}
+
+.switch_disabled::after {
+  display: block;
+  content: '';
+  position: absolute;
+  top: -2rpx;
+  left: -2rpx;
+  right: -2rpx;
+  bottom: -2rpx;
+  background: rgba(0, 0, 0, 0.1);
+}
+
+.switch_no_radius, .switch_no_radius view, .switch_no_radius::before {
+  border-radius: 0;
+}

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

@@ -213,8 +213,8 @@ export default {
             overview: 'Overview',
             events: 'Events',
             stages: 'Stages',
-            get_local_time: 'Get local sunrise and sunset times',
-            get_local_time_sunrise: 'Get local sunset and sunrise times',
+            get_local_time: 'Show local nighttime',
+            get_local_time_sunrise: 'Show local daytime',
             to:' to '
         },
         track_time_duration: {
@@ -235,6 +235,28 @@ export default {
                 im_ready: 'I\'m ready',
                 got_it: 'Got it'
             },
+            reminders: {
+                schedule_title: 'Health Schedule Reminder',
+                fast_end_title: 'Fasting End Reminder',
+                wake_title: 'Wake-up Reminder',
+
+                schedule_fast_content: 'Once enabled, you will receive a reminder at the set start time.',
+                schedule_sleep_content: 'Once enabled, you will receive a reminder at the set bedtime.',
+                schedule_mix_content:'Once enabled, you will receive reminders at the set fasting start time and bedtime.',
+                post_fast_content: 'Once enabled, you will receive an end reminder {{time}}.',
+                post_sleep_content: 'Once enabled, you will receive a wake-up reminder {{time}}.',
+
+                enable_schedule_fast_content: 'We will remind you to start fasting daily at {{time}}.',
+                enable_schedule_sleep_content: 'We will remind you to go to bed daily at {{time}}.',
+                enable_schedule_mix_content: 'We will remind you to start fasting daily at {{time1}} and to go to bed daily at {{time2}}.',
+                enable_post_fast_content: 'We will remind you to end your fasting tomorrow at {{time}}.',
+                enable_post_sleep_content: 'We will remind you to wake up tomorrow at {{time}}.',
+
+                later: 'Later',
+                open: 'Enable now',
+                ok: 'OK'
+
+            },
             third_ring: {
                 night_ring: 'Night ring',
                 day_ring: 'Day ring',

+ 25 - 3
src/context/locales/zh.js

@@ -218,9 +218,9 @@ export default {
             overview: '概览',
             events: '事件',
             stages: '阶段',
-            get_local_time: '获取当前日落日出时间',
-            get_local_time_sunrise: '获取当前日出日落时间',
-            to:'至'
+            get_local_time: '显示当地时间',
+            get_local_time_sunrise: '显示当地时间',
+            to: '至'
         },
         track_time_duration: {
             common: {
@@ -240,6 +240,28 @@ export default {
                 im_ready: '我准备好了',
                 got_it: '好的'
             },
+            reminders: {
+                schedule_title: '健康日程提醒',
+                fast_end_title: '断食结束提醒',
+                wake_title: '起床提醒',
+
+                schedule_fast_content: '开启后, 您将在设定的开始时间获得提醒。',
+                schedule_sleep_content: '开启后, 您将在设定的就寝时间获得提醒。',
+                schedule_mix_content:'开启后, 您将在设定的断食开始时间及就寝时间获得提醒。',
+                post_fast_content: '开启后, 您将在{{time}} 获得结束提醒。',
+                post_sleep_content: '开启后, 您将在{{time}} 获得起床提醒。',
+
+                enable_schedule_fast_content: '每日 {{time}} 提醒您开始断食。',
+                enable_schedule_sleep_content: '每日 {{time}} 提醒您就寝。',
+                enable_schedule_mix_content: '每日 {{time1}} 提醒您开始断食,每日 {{time2}} 提醒您就寝。',
+                enable_post_fast_content: '{{time}} 提醒您结束断食。',
+                enable_post_sleep_content: '{{time}} 提醒您起床。',
+
+                later: '稍后',
+                open: '立即开启',
+                ok: '好的'
+
+            },
             third_ring: {
                 night_ring: '夜间',
                 day_ring: '白天',

+ 8 - 0
src/features/trackTimeDuration/components/DayNightCard.config.ts

@@ -0,0 +1,8 @@
+export default {
+    usingComponents: {
+      // 定义需要引入的第三方组件
+      // 1. key 值指定第三方组件名字,以小写开头
+      // 2. value 值指定第三方组件 js 文件的相对路径
+      'mySwitch': '@/components/input/switch',
+    },
+  }

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

@@ -101,4 +101,10 @@
     display: flex;
     align-items: center;
     justify-content: center;
+}
+
+.switch{
+    transform: scale(0.75);
+    transform-origin: right center;
+    color: red;
 }

+ 35 - 10
src/features/trackTimeDuration/components/DayNightCard.tsx

@@ -15,6 +15,7 @@ import Modal from '@/components/layout/Modal.weapp'
 import { rpxToPx } from '@/utils/tools'
 import { jumpPage } from '@/features/trackTimeDuration/hooks/Common'
 import DayNightDetailPopup from './DayNightDetailPopup'
+import { IconDay, IconInfo, IconNight } from '@/components/basic/Icons'
 
 let useNavigation;
 if (process.env.TARO_ENV == 'rn') {
@@ -888,9 +889,24 @@ export default function DayNightCard(props: { isNight: boolean, count: number })
             setShowDetailModal(true)
     }
 
+    function showLocationAlert(e) {
+        if (process.env.TARO_ENV == 'weapp') {
+            e.stopPropagation()
+        }
+        if (user.test_user && authInfo && authInfo.lat) {
+            return
+        }
+        Taro.showModal({
+            title: 'Note',
+            content: 'Sunset and sunrise times are global average. Actual times vary depending on your location and time of year.',
+            showCancel:false,
+            confirmText:'Got it'
+        })
+    }
+
     return <View style={{ color: '#fff' }} onLongPress={longClick}>
         <Box onClick={tapCard}>
-            <View style={{marginTop:-rpxToPx(16)}}>
+            <View style={{ marginTop: -rpxToPx(16) }}>
                 <View className='day_night_top'>
                     {
                         user.isLogin ? <Text className='day_night_title'>{props.isNight ? t('feature.day_night.night_ring_login') : t('feature.day_night.day_ring_login')}</Text> :
@@ -902,7 +918,9 @@ export default function DayNightCard(props: { isNight: boolean, count: number })
                     }
 
                     <View style={{ flex: 1 }} />
+                    {/* <mySwitch /> */}
                     <Switch checked={props.isNight ? dayStore.showDayRing : dayStore.showDayRing}
+                        className='switch'
                         color={props.isNight ? ColorType.night : ColorType.day}
                         onClick={(e) => { e.stopPropagation() }}
                         onChange={(e) => {
@@ -935,23 +953,30 @@ export default function DayNightCard(props: { isNight: boolean, count: number })
                     />
                 </View>
                 {
-                    user.isLogin && dayStore.showDayRing && <View style={{ marginTop:rpxToPx(40) }}>
-                        <View style={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
-                            <Text className='day_night_value' style={{ color: props.isNight ? ColorType.night : ColorType.day }}>{props.isNight ? nightDuration() : dayDuration()}</Text>
+                    user.isLogin && dayStore.showDayRing && <View style={{ marginTop: rpxToPx(40) }}>
+                        <View style={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }} onClick={showLocationAlert}>
+                            <View style={{ flexDirection: 'row', display: 'flex', alignItems: 'center' }}>
+                                {
+                                    user.test_user && authInfo && authInfo.lat ? props.isNight ? <IconNight width={rpxToPx(30)} color={ColorType.night} /> : <IconDay width={rpxToPx(30)} color={ColorType.day} /> :
+                                        <IconInfo width={rpxToPx(30)} color={props.isNight ? ColorType.night : ColorType.day} />
+                                }
+                                <Text className='day_night_value' style={{ color: props.isNight ? ColorType.night : ColorType.day, marginLeft: rpxToPx(10) }}>{props.isNight ? nightDuration() : dayDuration()}</Text>
+                            </View>
+
                             <Text className='day_night_desc'>{props.isNight ? nightDurationDesc1() : dayDurationDesc1()}</Text>
 
                         </View>
 
-                        <View style={{marginTop:rpxToPx(40),marginBottom:rpxToPx(20)}}>
+                        <View style={{ marginTop: rpxToPx(40), marginBottom: rpxToPx(20) }}>
                             {
                                 !user.test_user ? <View className={props.isNight ? 'day_night_card_btn buy_night' : 'day_night_card_btn buy_day'} onClick={buy}>{
                                     props.isNight ? t('feature.day_night.get_local_time') : t('feature.day_night.get_local_time_sunrise')
                                 }</View> :
-                                    authInfo && authInfo.lat ? 
-                                    <View style={{display:'flex',alignItems:'center',justifyContent:'center'}}>
-                                    <View className={props.isNight ? 'night_location_btn' : 'day_location_btn'} onClick={auth}>{getLocation()}</View>
-                                    </View>
-                                     :
+                                    authInfo && authInfo.lat ?
+                                        <View style={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
+                                            <View className={props.isNight ? 'night_location_btn' : 'day_location_btn'} onClick={auth}>{getLocation()}</View>
+                                        </View>
+                                        :
                                         <View className='day_night_card_btn' style={{ backgroundColor: props.isNight ? ColorType.night : ColorType.day }} onClick={auth}>{
                                             props.isNight ? t('feature.day_night.get_local_time') : t('feature.day_night.get_local_time_sunrise')
                                         }</View>

+ 98 - 16
src/features/trackTimeDuration/components/IndexConsole.tsx

@@ -1,7 +1,7 @@
 import { View, Text, Image, PageContainer } from '@tarojs/components'
 import './IndexConsole.scss'
 import { useTranslation } from 'react-i18next'
-import { useSelector } from 'react-redux';
+import { useDispatch, useSelector } from 'react-redux';
 import { endFast, endSleep, startFast, startSleep } from "../actions/TrackTimeActions";
 import { jumpPage } from '../hooks/Common';
 import { useEffect, useRef, useState } from 'react';
@@ -11,6 +11,9 @@ import { getColor, getTimePickerTitle } from '../hooks/Console';
 import { rpxToPx, vibrate } from '@/utils/tools';
 import { TimeFormatter } from '@/utils/time_format';
 import Modal from '@/components/layout/Modal.weapp';
+import Taro, { useDidShow } from '@tarojs/taro';
+import { wxPubFollow } from '@/services/permission';
+import { setWXFollow } from '@/store/permission';
 
 let useNavigation;
 if (process.env.TARO_ENV == 'rn') {
@@ -25,9 +28,10 @@ export default function IndexConsole(props: { record: any }) {
     const [fastDuration, setFastDuration] = useState<number>(0);
     const [sleepDuration, setSleepDuration] = useState<number>(0);
     const [expand, setExpand] = useState(false);
-
+    const permission = useSelector((state: any) => state.permission);
+    const common = useSelector((state: any) => state.common);
     const [firstEnter, setFirstEnter] = useState(true);
-
+    const dispatch = useDispatch();
     const [showTimeoutPicker, setShowTimeoutPicker] = useState(false)
 
     // const [fastPickerValue, setFastPickerValue] = useState([0, 0])
@@ -40,6 +44,12 @@ export default function IndexConsole(props: { record: any }) {
         navigation = useNavigation()
     }
 
+    useDidShow(() => {
+        wxPubFollow({ force_refresh: true }).then(res => {
+            dispatch(setWXFollow((res as any).wx_pub_followed));
+        })
+    })
+
     useEffect(() => {
         if (currentRecord.fast) {
             var fastCount = currentRecord.fast.target_end_time - currentRecord.fast.target_start_time
@@ -104,7 +114,7 @@ export default function IndexConsole(props: { record: any }) {
         operateType = 'endSleep'
         global.pauseIndexTimer = true
 
-        
+
         var last_check_time = props.record.current_record.last_real_check_time
         if (last_check_time + 24 * 3600 * 1000 <= new Date().getTime()) {
             setShowTimeoutPicker(true)
@@ -131,8 +141,8 @@ export default function IndexConsole(props: { record: any }) {
 
         var last_check_time = props.record.current_record.last_real_check_time
 
-        if (last_check_time + 24 * 3600 * 1000 <= new Date().getTime()||
-        props.record.current_record.fast.real_check_time+24 * 3600 * 1000 <= new Date().getTime()) {
+        if (last_check_time + 24 * 3600 * 1000 <= new Date().getTime() ||
+            props.record.current_record.fast.real_check_time + 24 * 3600 * 1000 <= new Date().getTime()) {
             setShowTimeoutPicker(true)
             return
         }
@@ -154,10 +164,19 @@ export default function IndexConsole(props: { record: any }) {
 
         var title = getTimePickerTitle(currentRecord, t, operateType == 'endFast')
         var color = getColor(currentRecord, operateType == 'endFast')
+        var duration = 0
+        if (operateType == 'startFast' && currentRecord.fast) {
+            duration = currentRecord.fast.target_end_time - currentRecord.fast.target_start_time
+        }
+        if (operateType == 'startSleep' && currentRecord.sleep) {
+            duration = currentRecord.sleep.target_end_time - currentRecord.sleep.target_start_time
+        }
         return <View className="modal_content">
             <LimitPickers ref={limitPickerRef} limit={limit} limitDay={8}
                 themeColor={color}
                 title={title}
+                showEndTime={operateType == 'startFast' || operateType == 'startSleep'}
+                duration={duration}
                 onCancel={hidePicker} onChange={(e) => {
                     pickerConfirm(e)
                     global.pauseIndexTimer = false
@@ -173,7 +192,7 @@ export default function IndexConsole(props: { record: any }) {
         var targetTime = props.record.current_record.fast.target_end_time
         if (props.record.current_record.status == 'ONGOING3') {
             limit = 0
-            targetTime = props.record.current_record.sleep.real_end_time+60*1000
+            targetTime = props.record.current_record.sleep.real_end_time + 60 * 1000
         }
         return <View className="modal_content">
             <LimitTimeoutPickers ref={limitPickerRef} limit={limit} limitDay={7}
@@ -220,39 +239,102 @@ export default function IndexConsole(props: { record: any }) {
         global.pauseIndexTimer = false
     }
 
-    function pickerConfirm(t: number) {
+
+    function followWxPub() {
+        const resource = common.resources.filter((item: any) => {
+            return item.code == 'follow_wx_pub'
+        })
+
+        jumpPage('/pages/common/H5?title=fast16cc 关注服务号&url=' + resource[0].url)
+    }
+
+    function pickerConfirm(t1: number) {
         // hidePicker()
-        var date = new Date(t)
+        var date = new Date(t1)
         var setDate = new Date(global.set_time);
         date.setMilliseconds(setDate.getMilliseconds());
         date.setSeconds(setDate.getSeconds());
 
-        t = date.getTime();
+        t1 = date.getTime();
 
         switch (operateType) {
             case 'startFast':
-                startFast(t, fastDuration).then(res => {
+                startFast(t1, fastDuration).then(res => {
                     global.indexPageRefresh()
                     setFirstEnter(false)
                     hidePicker()
+
+                    if (permission.wxPubFollow) {
+                        Taro.showModal({
+                            title: t('feature.track_time_duration.reminders.fast_end_title'),
+                            content:
+                                t('feature.track_time_duration.reminders.enable_post_fast_content',
+                                    { time: TimeFormatter.dateDescription(t1 + fastDuration, true) + ' ' + TimeFormatter.timeDescription(t1 + fastDuration) }
+                                ),
+                            showCancel: false,
+                            confirmText: t('feature.track_time_duration.reminders.ok')
+                        })
+                    }
+                    else {
+                        Taro.showModal({
+                            title: t('feature.track_time_duration.reminders.fast_end_title'),
+                            content: t('feature.track_time_duration.reminders.post_fast_content',
+                                { time: TimeFormatter.dateDescription(t1 + fastDuration, true) + ' ' + TimeFormatter.timeDescription(t1 + fastDuration) }
+                            ),
+                            cancelText: t('feature.track_time_duration.reminders.later'),
+                            confirmText: t('feature.track_time_duration.reminders.open'),
+                            success: function (res) {
+                                if (res.confirm) {
+                                    followWxPub()
+                                } else if (res.cancel) {
+                                }
+                            }
+                        })
+                    }
                 })
                 break
             case 'startSleep':
-                startSleep(t, sleepDuration).then(res => {
+                startSleep(t1, sleepDuration).then(res => {
                     global.indexPageRefresh()
                     setFirstEnter(false)
                     hidePicker()
+
+                    if (permission.wxPubFollow) {
+                        Taro.showModal({
+                            title: t('feature.track_time_duration.reminders.wake_title'),
+                            content:
+                                t('feature.track_time_duration.reminders.enable_post_sleep_content',
+                                    { time: TimeFormatter.dateDescription(t1 + sleepDuration, true) + ' ' + TimeFormatter.timeDescription(t1 + sleepDuration) }),
+                            showCancel: false,
+                            confirmText: t('feature.track_time_duration.reminders.ok')
+                        })
+                    }
+                    else {
+                        Taro.showModal({
+                            title: t('feature.track_time_duration.reminders.wake_title'),
+                            content: t('feature.track_time_duration.reminders.post_sleep_content',
+                                { time: TimeFormatter.dateDescription(t1 + sleepDuration, true) + ' ' + TimeFormatter.timeDescription(t1 + sleepDuration) }),
+                            cancelText: t('feature.track_time_duration.reminders.later'),
+                            confirmText: t('feature.track_time_duration.reminders.open'),
+                            success: function (res) {
+                                if (res.confirm) {
+                                    followWxPub()
+                                } else if (res.cancel) {
+                                }
+                            }
+                        })
+                    }
                 })
                 break
             case 'endSleep':
-                endSleep(t).then(res => {
+                endSleep(t1).then(res => {
                     global.indexPageRefresh()
                     setFirstEnter(false)
                     hidePicker()
                 })
                 break
             case 'endFast':
-                endFast(t).then(res => {
+                endFast(t1).then(res => {
                     global.indexPageRefresh()
                     setFirstEnter(false)
                     hidePicker()
@@ -300,10 +382,10 @@ export default function IndexConsole(props: { record: any }) {
                 }}
                 onClick={() => { alert('b') }}
                 onClickOverlay={() => { alert('a') }}
-                onAfterLeave={() => { 
+                onAfterLeave={() => {
                     hidePicker()
                     // setShowTimeoutPicker(false)
-                 }}
+                }}
                 show={showTimeoutPicker} round={true} overlay={true} position='bottom'
             >
                 {

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

@@ -6,7 +6,7 @@ import Box from "@/components/layout/Box";
 import './Schedule.scss'
 import { useTranslation } from "react-i18next";
 import TimelineFastSleep from "./TimelineFastSleep";
-import Switch from "@/components/input/Switch";
+import Switch from "@/components/input/Switch2";
 import { useDispatch, useSelector } from "react-redux";
 import { TimeFormatter } from "@/utils/time_format";
 import Buttons from "@/components/basic/Buttons";

+ 79 - 4
src/features/trackTimeDuration/components/SetSchedule.weapp.tsx

@@ -21,6 +21,8 @@ import { ColorType } from "@/context/themes/color";
 import TitleView from "./TitleView";
 import { jumpPage } from "../hooks/Common";
 import { vibrate } from "@/utils/tools";
+import { wxPubFollow } from "@/services/permission";
+import { setWXFollow } from "@/store/permission";
 
 export default function Component() {
   const isFastFirst = true;
@@ -28,6 +30,7 @@ export default function Component() {
   const dispatch = useDispatch();
   const canvasRef = useRef(null);
   const [scenario] = useState(useSelector((state: any) => state.scenario))
+  const permission = useSelector((state: any) => state.permission);
   // const scenario = useSelector((state: any) => state.scenario);
   const common = useSelector((state: any) => state.common);
 
@@ -39,7 +42,7 @@ export default function Component() {
   // const [count,setCount] = useState(0)
   const [beginChange, setBeginChange] = useState(true)
   const [operateType, setOperateType] = useState(0)
-  const [isModalTimePicker,setIsModalTimePicker] = useState(false)
+  const [isModalTimePicker, setIsModalTimePicker] = useState(false)
 
   var scheduleObj: { start_time: any; end_time: any; };
   if (scenario.name == 'FAST') {
@@ -104,8 +107,28 @@ export default function Component() {
 
   useDidShow(() => {
     setCount(count + 1)
+    wxPubFollow({ force_refresh: true }).then(res => {
+      dispatch(setWXFollow((res as any).wx_pub_followed));
+    })
   })
 
+  function followWxPub() {
+    const resource = common.resources.filter((item: any) => {
+      return item.code == 'follow_wx_pub'
+    })
+
+    // Taro.showModal({
+    //   title: '提示',
+    //   content: '关注公众号后可接收提醒\n点击确定,前往关注',
+    //   showCancel: true,
+    //   success(result) {
+    //     if (result.confirm) {
+    jumpPage('/pages/common/H5?title=fast16cc 关注服务号&url=' + resource[0].url)
+    //   }
+    // },
+    // })
+  }
+
 
   function start() {
     if (scenario.name == 'FAST' || scenario.name == 'SLEEP') {
@@ -127,7 +150,35 @@ export default function Component() {
         setBtnDisable(false)
         // global.checkData()
         global.indexPageRefresh()
-        Taro.navigateBack({ delta: 3 })
+
+        Taro.navigateBack({ delta: 3 }).then(res => {
+          if (permission.wxPubFollow) {
+            Taro.showModal({
+              title: t('feature.track_time_duration.reminders.schedule_title'),
+              content: scenario.name == 'FAST' ?
+                t('feature.track_time_duration.reminders.enable_schedule_fast_content') :
+                t('feature.track_time_duration.reminders.enable_schedule_sleep_content'),
+              showCancel: false,
+              confirmText: t('feature.track_time_duration.reminders.ok')
+            })
+          }
+          else {
+            Taro.showModal({
+              title: t('feature.track_time_duration.reminders.schedule_title'),
+              content: scenario.name == 'FAST' ?
+                t('feature.track_time_duration.reminders.schedule_fast_content', { time: startTime }) :
+                t('feature.track_time_duration.reminders.schedule_sleep_content', { time: startTime }),
+              cancelText: t('feature.track_time_duration.reminders.later'),
+              confirmText: t('feature.track_time_duration.reminders.open'),
+              success: function (res) {
+                if (res.confirm) {
+                  followWxPub()
+                } else if (res.cancel) {
+                }
+              }
+            })
+          }
+        })
       }).catch(e => {
         setBtnDisable(false)
       })
@@ -195,7 +246,31 @@ export default function Component() {
       setBtnDisable(false)
       dispatch(setStep('fast'))
       // global.checkData()
-      Taro.navigateBack({ delta: 4 })
+      Taro.navigateBack({ delta: 4 }).then(res => {
+        if (permission.wxPubFollow) {
+          Taro.showModal({
+            title: t('feature.track_time_duration.reminders.schedule_title'),
+            content:
+              t('feature.track_time_duration.reminders.schedule_mix_content'),
+            showCancel: false,
+            confirmText: t('feature.track_time_duration.reminders.ok')
+          })
+        }
+        else {
+          Taro.showModal({
+            title: t('feature.track_time_duration.reminders.schedule_title'),
+            content: t('feature.track_time_duration.reminders.enable_schedule_mix_content', { time1: scenario.schedule.fast.start_time, time2: scenario.schedule.sleep.start_time }),
+            cancelText: t('feature.track_time_duration.reminders.later'),
+            confirmText: t('feature.track_time_duration.reminders.open'),
+            success: function (res) {
+              if (res.confirm) {
+                followWxPub()
+              } else if (res.cancel) {
+              }
+            }
+          })
+        }
+      })
       global.indexPageRefresh()
     }).catch(e => {
       setBtnDisable(false)
@@ -355,7 +430,7 @@ export default function Component() {
         <View className="dial_bg" style={{ backgroundColor: global.isDebug ? 'pink' : 'transparent' }}>
           <Dial ref={canvasRef} />
         </View>
-        <View className="duration_bg" style={{ opacity: operateType == 1 || operateType == 2 ? 1 : 0.4, backgroundColor: global.isDebug ? 'pink' : 'transparent' }} onClick={() => { setIsModalTimePicker(false);setIsOpen(true) }}>
+        <View className="duration_bg" style={{ opacity: operateType == 1 || operateType == 2 ? 1 : 0.4, backgroundColor: global.isDebug ? 'pink' : 'transparent' }} onClick={() => { setIsModalTimePicker(false); setIsOpen(true) }}>
           <Text className="duration_title schedule_text_key">{t('feature.track_time_duration.dial.duration')}</Text>
           <Text className="duration_value schedule_text_value"  >{hours > 0 ? hours + TimeFormatter.getHoursUnit(hours) : ''}{minutes > 0 ? minutes + '分钟' : ''}</Text>
         </View>

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

@@ -42,7 +42,7 @@ export default function () {
                             <Text className={item.checked ? "single_check_text_sel" : "single_check_text_nor"}>{item.title}</Text>
                             {
                                 item.checked ? <IconCheck width={rpxToPx(48)} height={rpxToPx(48)} color={ColorType.fast}/> :
-                                    <IconPlus color={ColorType.fast} />
+                                    <IconPlus color='#fff' />
                             }
                         </View>
                     })

+ 1 - 1
src/features/trackTimeDuration/components/TimelineStage.rn.tsx

@@ -5,7 +5,7 @@ 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 Switch from '@/components/input/Switch2';
 import { useSelector } from 'react-redux';
 import Taro from '@tarojs/taro';
 import { jumpPage } from '../hooks/Common';

+ 1 - 1
src/features/trackTimeDuration/components/TimelineStage.weapp.tsx

@@ -5,7 +5,7 @@ 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 Switch from '@/components/input/Switch2';
 import { useSelector } from 'react-redux';
 import Taro from '@tarojs/taro';
 import { jumpPage } from '../hooks/Common';

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

@@ -5,7 +5,7 @@ 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 Switch from '@/components/input/Switch2';
 import { useSelector } from 'react-redux';
 import Taro from '@tarojs/taro';
 import { jumpPage } from '../hooks/Common';

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

@@ -38,7 +38,7 @@ import StageSelector from "@/features/trackTimeDuration/components/StageSelector
 import { ChooseScenarioBtn } from "@/features/common/SpecBtns";
 import { clearNightStore, showNight } from "@/store/night";
 import { showDay } from "@/store/day";
-import { clientInfo } from "@/services/common";
+import { clientInfo, staticResources } from "@/services/common";
 import { changeFastDuration, changeSleepDuration, setCurrentRecord, setSchedule } from "@/store/ring";
 import { checkAuthorized } from "@/utils/check_authorized";
 import NoData from "@/components/view/NoData";
@@ -89,6 +89,7 @@ export default function Page() {
 
 
     useEffect(() => {
+        dispatch(staticResources() as any);
         timer = setInterval(() => {
             if (global.pauseIndexTimer || pauseTimer) {
                 return
@@ -204,6 +205,7 @@ export default function Page() {
 
     function uploadUserClient() {
         var systemInfo = Taro.getSystemInfoSync();
+        console.log(systemInfo)
         var split = new Date().toString().split(' ');
         var timeZoneFormatted = split[split.length - 2];
         clientInfo({

+ 0 - 2
src/store/night.tsx

@@ -33,8 +33,6 @@ const nightSlice = createSlice({
     reducers: {
         showNight(state, action) {
             state.showNightRing = action.payload;
-
-            debugger
         },
         setNightRingData(state, action) {
             const { sunrise, sunset, date } = action.payload

+ 0 - 1
src/utils/time_format.ts

@@ -272,7 +272,6 @@ export class TimeFormatter {
     const dt = new Date(num);
 
     const now = new Date();
-    debugger
 
     const diff = now.getTime() - dt.getTime();
     const day = 1000 * 60 * 60 * 24;

Alguns ficheiros não foram mostrados porque muitos ficheiros mudaram neste diff