leon 1 ano atrás
pai
commit
7d813cdef6

+ 4 - 0
src/app.config.ts

@@ -99,6 +99,10 @@ process.env.TARO_ENV === 'weapp' && (appConfig.tabBar = {
       pagePath: 'pages/explore/Index',
       text: '发现',
     },
+    {
+      pagePath: 'pages/notification/setting',
+      text: '提醒',
+    },
     {
       pagePath: 'pages/metric/Metric',
       text: '指标',

+ 16 - 0
src/components/input/FSwitch.scss

@@ -0,0 +1,16 @@
+/* #ifdef weapp */
+.myswitch {
+    // width: 100px !important;
+    // height: 50px !important;
+    transform: scale(0.85);
+    transform-origin: right center;
+    margin-right: -10px;
+
+}
+
+/* #endif */
+
+/* #ifdef rn */
+.myswitch {}
+
+/* #endif */

+ 28 - 0
src/components/input/FSwitch.tsx

@@ -0,0 +1,28 @@
+import { Switch } from "@tarojs/components";
+import './FSwitch.scss'
+import { useEffect } from "react";
+
+let RNSwitch;
+if (process.env.TARO_ENV == 'rn') {
+    RNSwitch = require("react-native").Switch
+}
+export default function FSwitch(props: { color: string, checked: boolean, onChange: Function }) {
+    useEffect(()=>{
+        console.log(props.checked)
+    },[props.checked])
+
+    if (process.env.TARO_ENV == 'rn') {
+        return <RNSwitch className="myswitch" trackColor={{ true: props.color }}
+            value={props.checked}
+            onChange={(e) => {
+                props.onChange(e.nativeEvent.value)
+            }}
+        />
+    }
+
+    return <Switch className="myswitch" color={props.color} checked={props.checked}
+        onChange={(e) => {
+            props.onChange(e.detail.value)
+        }}
+    />
+}

+ 4 - 2
src/components/navigation/TabBar.tsx

@@ -17,9 +17,8 @@ export default function Component(props: { index: number }) {
                 })
                 break;
             case 2:
-
                 Taro.switchTab({
-                    url: '/pages/explore/Index'
+                    url: '/pages/notification/setting'
                 })
                 break;
             case 1:
@@ -51,6 +50,9 @@ export default function Component(props: { index: number }) {
         <View className={selIndex == 0 ? 'tabbar-item tabbar-item-sel' : 'tabbar-item'} onClick={() => switchTab(0)}>
             <Text>首页</Text>
         </View>
+        <View className={selIndex == 2 ? 'tabbar-item tabbar-item-sel' : 'tabbar-item'} onClick={() => switchTab(2)}>
+            <Text>提醒</Text>
+        </View>
         {/* <View className={selIndex == 4 ? 'tabbar-item tabbar-item-sel' : 'tabbar-item'} onClick={() => switchTab(4)}>
             <View style={{ position: 'relative' }}>
                 <Text>饮食</Text>

+ 14 - 4
src/features/trackTimeDuration/components/IndexConsoleMuti.tsx

@@ -27,6 +27,7 @@ export default function IndexConsoleMuti(props: { status: string, event: string,
     const [sleepEnd, setSleepEnd] = useState<any>(null)
     const [showPicker, setShowPicker] = useState(false)
     const [operateType, setOperateType] = useState('startFast')
+    const [commitLoading,setCommitLoading] = useState(false)
     const pickerRef = useRef(null)
 
 
@@ -35,6 +36,9 @@ export default function IndexConsoleMuti(props: { status: string, event: string,
     }
 
     function confirm() {
+        if (commitLoading){
+            return;
+        }
         var fast: any = {}
         var sleep: any = {}
         switch (props.event) {
@@ -254,6 +258,8 @@ export default function IndexConsoleMuti(props: { status: string, event: string,
                 }
                 break;
         }
+
+        setCommitLoading(true)
         var params: any = {
         }
         if (props.scenario == 'FAST_SLEEP') {
@@ -269,9 +275,13 @@ export default function IndexConsoleMuti(props: { status: string, event: string,
         }
         params.showAlert = true
         batchClocks(params).then(res => {
+            setCommitLoading(false)
             getLocalPush()
             global.indexPageRefresh()
-            global.scrollToLatest()
+            if ((res as any).current_record.status == "WAIT_FOR_START"){
+                global.scrollToLatest()
+            }
+            
             global.refrehWeekly()
             global.refreshStreaks()
             if (props.event == 'end_fast')
@@ -279,7 +289,7 @@ export default function IndexConsoleMuti(props: { status: string, event: string,
 
             cancel()
         }).catch(e => {
-
+            setCommitLoading(false)
         })
     }
 
@@ -506,9 +516,9 @@ export default function IndexConsoleMuti(props: { status: string, event: string,
                 <Text className='modal_cancel_text' style={{ color: color, fontWeight: 'bold' }}>{t('feature.common.picker_cancel_btn')}</Text>
             </View>
             <View className='btn_space' />
-            <View className='modal_btn' style={{ backgroundColor: color, flexDirection: 'row', alignItems: 'center', justifyContent: 'center', opacity: isLoading ? 0.6 : 1 }} onClick={confirm}>
+            <View className='modal_btn' style={{ backgroundColor: color, flexDirection: 'row', alignItems: 'center', justifyContent: 'center', opacity: commitLoading ? 0.6 : 1 }} onClick={confirm}>
                 {
-                    isLoading && process.env.TARO_ENV == 'rn' && <View style={{ display: 'flex', overflow: 'hidden', height: 20, marginRight: 5 }}><AtActivityIndicator mode="center" color="#000" /></View>
+                    commitLoading  && <View style={{ display: 'flex', overflow: 'hidden', height: 20, marginRight: 5 }}><AtActivityIndicator mode="center" color="#000" /></View>
                 }
 
                 <Text className='modal_confirm_text' style={{ color: '#000', fontWeight: 'bold' }}>{t('feature.common.picker_confirm_btn')}</Text>

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

@@ -504,7 +504,7 @@ export default function Page() {
                     setTimeout(() => {
                         Taro.createSelectorQuery().select('#latest').boundingClientRect((rect) => {
                             Taro.pageScrollTo({
-                                scrollTop: (rect as any).top,
+                                scrollTop: (rect as any).top-40,
                                 duration: 150
                             })
                         }).exec()

+ 582 - 0
src/pages/notification/setting copy.tsx

@@ -0,0 +1,582 @@
+import { View, Text, ScrollView } from "@tarojs/components";
+import Metric from "@/features/trackSomething/components/Metric";
+import { useDidShow, usePullDownRefresh, useShareAppMessage } from "@tarojs/taro";
+import { useTranslation } from "react-i18next";
+import Segment from '@/components/navigation/Segment'
+import { useEffect, useState } from "react";
+import { kIsAndroid, kIsIOS, rpxToPx } from "@/utils/tools";
+import './setting.scss'
+import { getNotifySettings, postNotifySettings } from "@/services/notifications";
+import { ColorType } from "@/context/themes/color";
+import { getLocalPush } from "@/features/trackTimeDuration/actions/TrackTimeActions";
+import { useSelector } from "react-redux";
+import ProductList from "../store/product_list";
+import { jumpPage } from "@/features/trackTimeDuration/hooks/Common";
+import { getPerm, userAccess } from "@/services/user";
+import '@/features/trackTimeDuration/components/CheckAccess.scss';
+import Modal from "@/components/layout/Modal.weapp";
+import Layout from "@/components/layout/layout";
+import { NaviBarTitleShowType, TemplateType } from "@/utils/types";
+import TitleView from "@/features/trackTimeDuration/components/TitleView";
+import showAlert from "@/components/basic/Alert";
+import Tabbar from "@/components/navigation/TabBar";
+
+let useNavigation;
+let AppState, Switch;
+let OneSignal
+let NativeAppEventEmitter
+let Jto
+let PushNotification
+let checkNotification
+if (process.env.TARO_ENV == 'rn') {
+    OneSignal = require('react-native-onesignal').OneSignal
+    NativeAppEventEmitter = require('react-native').NativeAppEventEmitter
+    Jto = require('react-native').NativeModules.NativeBridge;
+    PushNotification = require('react-native-push-notification')
+    checkNotification = require('@/utils/native_permission_check').checkNotification;
+
+    AppState = require("react-native").AppState
+    Switch = require("react-native").Switch
+    useNavigation = require("@react-navigation/native").useNavigation
+}
+export default function Page() {
+    const { t } = useTranslation()
+    const [segmentIndex, setSegmentIndex] = useState(0)
+    const [notification, setNotification] = useState<any>(null)
+    const [isExtra, setIsExtra] = useState(false)
+    const [isSunrise, setIsSunrise] = useState(false)
+    const [isSunset, setIsSunset] = useState(false)
+    const [isSolarNoon, setIsSolarNoon] = useState(false)
+    const [loaded, setLoaded] = useState(false)
+
+    const [systemFast, setSystemFast] = useState(true)
+    const [systemExtra, setSystemExtra] = useState(true)
+    const [systemSun, setSystemSun] = useState(true)
+    const [isAuthorized, setIsAuthorized] = useState(false)
+    const [showMemberAlert, setShowMemberAlert] = useState(false)
+    const user = useSelector((state: any) => state.user);
+    const accessObj = useSelector((state: any) => state.access);
+
+    let navigation;
+    if (useNavigation) {
+        navigation = useNavigation()
+    }
+
+    // useEffect(() => {
+
+    // }, [])
+
+    useEffect(() => {
+        if (!user.isLogin) {
+            return;
+        }
+        checkSetting()
+        getSettings()
+        getMemberStatus()
+        if (process.env.TARO_ENV == 'rn') {
+            navigation.setOptions({
+                headerTitle: '',
+            });
+            AppState.addEventListener('change', handleAppStateChange);
+            rnNotification()
+
+        }
+
+        if (process.env.TARO_ENV == 'rn') {
+            // AppState.addEventListener('change', handleAppStateChange);
+            navigation.addListener('focus', () => {
+                rnNotification()
+                getMemberStatus()
+            });
+
+            // 当页面即将消失时执行
+            navigation.addListener('blur', () => {
+            });
+
+        }
+    }, [user.isLogin])
+
+    const handleAppStateChange = (nextAppState) => {
+        console.log(nextAppState)
+        if (nextAppState != 'active') {
+            return
+        }
+        if (nextAppState == 'active') {
+            rnNotification()
+            checkSetting()
+            getMemberStatus()
+        }
+
+    };
+
+    function rnNotification() {
+        if (kIsIOS) {
+            Jto.getNotificationAuthStatus()
+            NativeAppEventEmitter.addListener('notificationResult', (data) => {
+                global.notification = data
+                setIsAuthorized(data == 'authorized')
+            })
+            NativeAppEventEmitter.addListener('operateNotificationResult', (data) => {
+                global.notification = data
+                setIsAuthorized(data == 'authorized')
+            })
+        }
+        else {
+            OneSignal.Notifications.canRequestPermission().then((status) => {
+                if (status) {
+                    OneSignal.Notifications.getPermissionAsync().then((res) => {
+                        if (res) {
+                            global.notification = 'authorized'
+                            setIsAuthorized(true)
+                        }
+                        else {
+                            global.notification = 'denied'
+                            setIsAuthorized(false)
+                        }
+                    })
+                }
+                else {
+                    global.notification = 'not_determined'
+                    setIsAuthorized(false)
+                }
+            })
+
+        }
+    }
+
+
+
+    function getMemberStatus() {
+        const { access } = accessObj
+        if (access && access.member) {
+            if (access.member.status == 'NON_MEMBER') {
+                postNotifySettings({
+                    notification: {
+                        follow_sun: {
+                            sunrise: {
+                                in_app: 'OFF'
+                            },
+                            sunset: {
+                                in_app: 'OFF'
+                            },
+                            solar_noon: {
+                                in_app: 'OFF'
+                            }
+                        }
+                    }
+                }).then(res => {
+                    setIsSolarNoon(false)
+                    setIsSunset(false)
+                    setIsSunrise(false)
+                    global.swiperDayNightRefresh()
+                })
+            }
+        }
+    }
+
+    useDidShow(() => {
+        console.log('notfication setting user did show')
+    })
+
+    function getSettings() {
+        getNotifySettings().then(res => {
+            var dt = (res as any).notification
+            setNotification(dt)
+            setIsExtra(dt.fast_sleep.extra_reminders.in_app == 'ON')
+            setIsSunrise(dt.follow_sun.sunrise.in_app == 'ON')
+            setIsSunset(dt.follow_sun.sunset.in_app == 'ON')
+            setIsSolarNoon(dt.follow_sun.solar_noon.in_app == 'ON')
+
+            setLoaded(true)
+        })
+    }
+
+    function checkSetting() {
+        console.log('notification setting begin')
+        if (process.env.TARO_ENV == 'rn' && kIsAndroid) {
+            var Jto = require('react-native').NativeModules.NativeBridge;
+            Jto.getChannelStatus().then(result => {
+                var data = JSON.parse(result);
+                console.log('notification setting', data)
+                if (data.all) {
+
+                }
+                else {
+                    var REMINDER_FS_STATUS = ''
+                    var REMINDER_SUN_STATUS = ''
+                    var REMINDER_FS_EXTRA_STATUS = ''
+
+                    if ('REMINDER_FS' in data) {
+                        REMINDER_FS_STATUS = data.REMINDER_FS ? 'ON' : 'OFF'
+                        setSystemFast(data.REMINDER_FS)
+                    }
+                    else {
+                        REMINDER_FS_STATUS = 'NA'
+                    }
+
+                    if ('REMINDER_SUN' in data) {
+                        REMINDER_SUN_STATUS = data.REMINDER_SUN ? 'ON' : 'OFF'
+                        setSystemSun(data.REMINDER_SUN)
+                    }
+                    else {
+                        REMINDER_SUN_STATUS = 'NA'
+                    }
+
+                    if ('REMINDER_FS_EXTRA' in data) {
+                        REMINDER_FS_EXTRA_STATUS = data.REMINDER_FS_EXTRA ? 'ON' : 'OFF'
+                        setSystemExtra(data.REMINDER_FS_EXTRA)
+                    }
+                    else {
+                        REMINDER_FS_EXTRA_STATUS = 'NA'
+                    }
+
+                    postNotifySettings({
+                        channels: {
+                            REMINDER_FS: {
+                                system: REMINDER_FS_STATUS
+                            },
+                            REMINDER_SUN: {
+                                system: REMINDER_SUN_STATUS
+                            },
+                            REMINDER_FS_EXTRA: {
+                                system: REMINDER_FS_EXTRA_STATUS
+                            }
+                        }
+                    }).then(res => {
+                    })
+                }
+            })
+        }
+
+    }
+
+    function goSetting() {
+        if (process.env.TARO_ENV == 'rn' && kIsAndroid) {
+            var Jto = require('react-native').NativeModules.NativeBridge;
+            Jto.openNotificationSettings()
+        }
+    }
+
+    function free() {
+        return <View className="setting_container">
+            <View className="setting_section">
+                <Text className="setting_section_title">Fasting</Text>
+            </View>
+            <Text className="setting_header">Reminders</Text>
+            <View className="setting_cell">
+                <Text className="setting_cell_title" style={{ flex: 1 }}>At your scheduled time</Text>
+                <Text className="setting_cell_value1">{notification.fast_sleep.reminders.in_app}</Text>
+            </View>
+            <Text className="setting_footer">A timely reminder so you never miss your scheduled time for fasting.</Text>
+        </View>
+    }
+
+
+    function confirm() {
+        jumpPage('', 'ProductList', navigation)
+        setShowMemberAlert(false)
+    }
+
+
+
+    function alertPop() {
+        return <View className="fast_alert_container">
+            <View className="fast_alert_content" catchMove>
+                <View className="fast_alert_title">Pro Access</View>
+                <View className="fast_alert_detail">With Pro Membership, you can set custom reminders and will be reminded even when you're not actively using the app.</View>
+                <View className='fast_alert_confirm' onClick={confirm}>
+                    <Text style={{ fontWeight: 'bold', color: ColorType.black }}>Become a Pro Member</Text>
+                </View>
+                <View className="fast_alert_cancel" onClick={() => { setShowMemberAlert(false) }}>Not now</View>
+
+            </View>
+        </View>
+    }
+
+    function notificationOpen() {
+        if (process.env.TARO_ENV === 'rn') {
+            PushNotification.checkPermissions((res) => {
+                //允许授权
+                if ((kIsIOS && res.authorizationStatus == 2) || (!kIsIOS && res.alert)) {
+                    setIsAuthorized(true)
+                }
+                else {
+                    showAlert({
+                        title: 'title',
+                        content: 'content',
+                        cancelText: t('feature.track_time_duration.reminders.later'),
+                        confirmText: t('feature.track_time_duration.reminders.open'),
+                        showCancel: true,
+                        cancel: () => {
+                        },
+                        confirm: () => {
+                            checkNotification()
+                        }
+                    })
+                }
+            })
+        }
+    }
+
+    function pro(isLogin: boolean) {
+        if (process.env.TARO_ENV=='weapp') return proDetail(isLogin)
+        return <ScrollView style={{ flex: 1 }}>
+            {
+                proDetail(isLogin)
+            }
+        </ScrollView>
+    }
+
+    function proDetail(isLogin: boolean) {
+        return <View className="setting_container">
+            <View className="setting_section">
+                <Text className="setting_section_title">Fast & Sleep</Text>
+            </View>
+            <Text className="setting_header">Reminders</Text>
+            <View className="setting_cell">
+                <Text className="setting_cell_title" style={{ flex: 1 }}>At schedule time</Text>
+                {
+                    isLogin ? <Text className="setting_cell_value1">{systemFast ? 'Always' : 'Off'}</Text> :
+                        <Text className="setting_cell_value1">Off</Text>
+                }
+
+            </View>
+            <Text className="setting_footer">A timely reminder so you never miss your schedule time for fasting and/or sleep.</Text>
+            <Text className="setting_header">Extra Reminders (Pro)</Text>
+            <View className="setting_cell">
+                <Text className="setting_cell_title" style={{ flex: 1 }}>Missed previous action</Text>
+                <Switch className="myswitch" value={isLogin ? (isAuthorized ? isExtra : false) : false} color={ColorType.fast} trackColor={{ true: ColorType.fast }} onChange={(e) => {
+                    if (!isLogin) {
+                        jumpPage('/pages/account/ChooseAuth', 'ChooseAuth', navigation)
+                        return
+                    }
+
+                    if (!isAuthorized) {
+                        notificationOpen()
+                        return
+                    }
+                    const value = e.nativeEvent.value
+                    if (e.nativeEvent.value) {
+                        if (accessObj && accessObj.access && accessObj.access.member.status == 'NON_MEMBER') {
+                            // setTimeout(() => {
+                            //     setIsSunrise(false)
+                            // }, 1000)
+
+                            // jumpPage('', 'ProductList', navigation)
+                            setShowMemberAlert(true)
+                            return
+                        }
+
+                    }
+                    postNotifySettings({
+                        notification: {
+                            fast_sleep: {
+                                extra_reminders: {
+                                    in_app: value ? 'ON' : 'OFF'
+                                }
+                            }
+                        }
+                    }).then(res => {
+                        setIsExtra(value)
+                        getLocalPush()
+                    })
+                }} />
+            </View>
+            <Text className="setting_footer">In case you missed your previous action, receive another reminder to log it together with the current one. This gives you extra protection against any streak loss.</Text>
+            <View className="setting_section">
+                <Text className="setting_section_title">The Sun (Pro)</Text>
+            </View>
+            <Text className="setting_header">Reminders for Your Daily Local Solar Times</Text>
+            <View className="setting_cell_group">
+                <View className="setting_cell_group_item">
+                    <Text className="setting_cell_title" style={{ flex: 1 }}>Sunrise</Text>
+                    <Switch className="myswitch" value={isLogin ? (isAuthorized ? isSunrise : false) : false} color={ColorType.fast} trackColor={{ true: ColorType.fast }} onChange={(e) => {
+                        // setIsMulti(e.nativeEvent.value)
+                        if (!isLogin) {
+                            jumpPage('/pages/account/ChooseAuth', 'ChooseAuth', navigation)
+                            return
+                        }
+                        if (!isAuthorized) {
+                            notificationOpen()
+                            return
+                        }
+                        const value = e.nativeEvent.value
+                        if (e.nativeEvent.value) {
+                            if (accessObj && accessObj.access && accessObj.access.member.status == 'NON_MEMBER') {
+                                // setTimeout(() => {
+                                //     setIsSunrise(false)
+                                // }, 1000)
+
+                                // jumpPage('', 'ProductList', navigation)
+                                setShowMemberAlert(true)
+                                return
+                            }
+
+                        }
+                        postNotifySettings({
+                            notification: {
+                                follow_sun: {
+                                    sunrise: {
+                                        in_app: value ? 'ON' : 'OFF'
+                                    }
+                                }
+                            }
+                        }).then(res => {
+                            setIsSunrise(value)
+                            // setIsSunrise(e.nativeEvent.value)
+                            global.swiperDayNightRefresh()
+                        })
+                    }} />
+                </View>
+                <View className="new_item_cell_line" />
+                <View className="setting_cell_group_item">
+                    <Text className="setting_cell_title" style={{ flex: 1 }}>Sunset</Text>
+                    <Switch className="myswitch" value={isLogin ? (isAuthorized ? isSunset : false) : false} trackColor={{ true: ColorType.fast }} color={ColorType.fast} onChange={(e) => {
+                        // setIsMulti(e.nativeEvent.value)
+                        if (!isLogin) {
+                            jumpPage('/pages/account/ChooseAuth', 'ChooseAuth', navigation)
+                            return
+                        }
+                        if (!isAuthorized) {
+                            notificationOpen()
+                            return
+                        }
+                        const value = e.nativeEvent.value
+                        if (e.nativeEvent.value) {
+                            if (accessObj && accessObj.access && accessObj.access.member.status == 'NON_MEMBER') {
+                                // setTimeout(() => {
+                                //     setIsSunset(false)
+                                // }, 1000)
+
+                                // jumpPage('', 'ProductList', navigation)
+                                setShowMemberAlert(true)
+                                return
+                            }
+
+                        }
+                        postNotifySettings({
+                            notification: {
+                                follow_sun: {
+                                    sunset: {
+                                        in_app: value ? 'ON' : 'OFF'
+                                    }
+                                }
+                            }
+                        }).then(res => {
+                            setIsSunset(value)
+                            global.swiperDayNightRefresh()
+                        })
+                    }} />
+                </View>
+                <View className="new_item_cell_line" />
+                <View className="setting_cell_group_item">
+                    <Text className="setting_cell_title" style={{ flex: 1 }}>Solar noon</Text>
+                    <Switch className="myswitch" value={isLogin ? (isAuthorized ? isSolarNoon : false) : false} trackColor={{ true: ColorType.fast }} color={ColorType.fast} onChange={(e) => {
+                        // setIsMulti(e.nativeEvent.value)
+                        if (!isLogin) {
+                            jumpPage('/pages/account/ChooseAuth', 'ChooseAuth', navigation)
+                            return
+                        }
+                        if (!isAuthorized) {
+                            notificationOpen()
+                            return
+                        }
+                        const value = e.nativeEvent.value
+                        if (e.nativeEvent.value) {
+                            if (accessObj && accessObj.access && accessObj.access.member.status == 'NON_MEMBER') {
+                                // setTimeout(() => {
+                                //     setIsSolarNoon(false)
+                                // }, 1000)
+
+                                // jumpPage('', 'ProductList', navigation)
+                                setShowMemberAlert(true)
+                                return
+                            }
+
+                        }
+                        postNotifySettings({
+                            notification: {
+                                follow_sun: {
+                                    solar_noon: {
+                                        in_app: value ? 'ON' : 'OFF'
+                                    }
+                                }
+                            }
+                        }).then(res => {
+                            debugger
+                            setIsSolarNoon(value)
+                            global.swiperDayNightRefresh()
+                        })
+                    }} />
+                </View>
+            </View>
+            <Text className="setting_footer">Note for polar region, during Polar Day (Midnight Sun) when the Sun is up all day or Polar Night when the Sun is down all day, the only reminder available is the daily Solar Noon.</Text>
+        </View>
+    }
+
+    function checkSystemChannel() {
+        if (!systemFast) {
+            return true;
+        }
+        if (!systemExtra && isExtra) {
+            return true;
+        }
+        if (!systemSun && (isSolarNoon || isSunrise || isSunset)) {
+            return true;
+        }
+
+        return false;
+    }
+
+    if (!user.isLogin)
+        return <View className="container" style={{ flex: 1 }}>
+            <Layout title={t('page.reminders.title')}
+                titleShowStyle={NaviBarTitleShowType.scrollToShow}
+                type={TemplateType.customHeader}
+                header={headerView()}
+            // triggered={triggered}
+            // refresh={refresh}
+            >
+                {
+                    pro(false)
+                }
+            </Layout>
+        </View>
+
+    function headerView() {
+        return <TitleView title={t('page.reminders.title')} showAddBtn={false}>
+        </TitleView>
+    }
+
+    return <View className="container" style={{ flex: 1 }}>
+        <Layout title={t('page.reminders.title')}
+            titleShowStyle={NaviBarTitleShowType.scrollToShow}
+            type={TemplateType.customHeader}
+            header={headerView()}
+        // triggered={triggered}
+        // refresh={refresh}
+        >
+            <View>
+                {
+                    loaded && pro(true)
+                }
+                {
+                    process.env.TARO_ENV == 'rn' && kIsAndroid && checkSystemChannel() && <View className="setting_tip" onClick={goSetting}>
+                        <Text className="setting_tip_text">Jump to App's Notifications settings{'>>'}</Text>
+                    </View>
+                }
+                {
+                    showMemberAlert && process.env.TARO_ENV == 'weapp' && alertPop()
+                }
+                {
+                    showMemberAlert && process.env.TARO_ENV == 'rn' && <Modal dismiss={() => { setShowMemberAlert(false) }}>
+                        <View style={{ backgroundColor: 'rgba(0,0,0,0.95)', width: '100%', height: '100%', alignItems: 'center', justifyContent: 'center' }}>
+                            {alertPop()}
+                        </View>
+                    </Modal>
+                }
+            </View>
+        </Layout>
+        <Tabbar index={2} />
+    </View>
+}

+ 0 - 15
src/pages/notification/setting.scss

@@ -104,22 +104,7 @@
     letter-spacing: 0;
 }
 
-/* #ifdef weapp */
-.myswitch{
-    // width: 100px !important;
-    // height: 50px !important;
-    transform: scale(0.85);
-    transform-origin: right center;
-    margin-right: -10px;
 
-}
-
-/* #endif */
-
-/* #ifdef rn */
-.myswitch{
-}
-/* #endif */
 
 .new_item_cell_line{
     height: 1px;

+ 122 - 90
src/pages/notification/setting.tsx

@@ -9,7 +9,7 @@ import './setting.scss'
 import { getNotifySettings, postNotifySettings } from "@/services/notifications";
 import { ColorType } from "@/context/themes/color";
 import { getLocalPush } from "@/features/trackTimeDuration/actions/TrackTimeActions";
-import { useSelector } from "react-redux";
+import { useDispatch, useSelector } from "react-redux";
 import ProductList from "../store/product_list";
 import { jumpPage } from "@/features/trackTimeDuration/hooks/Common";
 import { getPerm, userAccess } from "@/services/user";
@@ -19,9 +19,13 @@ import Layout from "@/components/layout/layout";
 import { NaviBarTitleShowType, TemplateType } from "@/utils/types";
 import TitleView from "@/features/trackTimeDuration/components/TitleView";
 import showAlert from "@/components/basic/Alert";
+import Tabbar from "@/components/navigation/TabBar";
+import FSwitch from "@/components/input/FSwitch";
+import { wxPubFollow } from "@/services/permission";
+import { setWXFollow } from "@/store/permission";
 
 let useNavigation;
-let AppState, Switch;
+let AppState;
 let OneSignal
 let NativeAppEventEmitter
 let Jto
@@ -35,11 +39,11 @@ if (process.env.TARO_ENV == 'rn') {
     checkNotification = require('@/utils/native_permission_check').checkNotification;
 
     AppState = require("react-native").AppState
-    Switch = require("react-native").Switch
     useNavigation = require("@react-navigation/native").useNavigation
 }
 export default function Page() {
     const { t } = useTranslation()
+    const dispatch = useDispatch();
     const [segmentIndex, setSegmentIndex] = useState(0)
     const [notification, setNotification] = useState<any>(null)
     const [isExtra, setIsExtra] = useState(false)
@@ -55,6 +59,8 @@ export default function Page() {
     const [showMemberAlert, setShowMemberAlert] = useState(false)
     const user = useSelector((state: any) => state.user);
     const accessObj = useSelector((state: any) => state.access);
+    const common = useSelector((state: any) => state.common);
+    const permission = useSelector((state: any) => state.permission);
 
     let navigation;
     if (useNavigation) {
@@ -95,6 +101,13 @@ export default function Page() {
         }
     }, [user.isLogin])
 
+    useEffect(() => {
+        if (process.env.TARO_ENV == 'weapp') {
+            setIsAuthorized(permission.wxPubFollow)
+        }
+
+    }, [permission.wxPubFollow])
+
     const handleAppStateChange = (nextAppState) => {
         console.log(nextAppState)
         if (nextAppState != 'active') {
@@ -190,8 +203,20 @@ export default function Page() {
         })
     }
 
+    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 checkSetting() {
-        console.log('notification setting begin')
+        if (process.env.TARO_ENV == 'weapp') {
+            wxPubFollow({ force_refresh: true }).then(res => {
+                dispatch(setWXFollow((res as any).wx_pub_followed));
+            })
+            return
+        }
         if (process.env.TARO_ENV == 'rn' && kIsAndroid) {
             var Jto = require('react-native').NativeModules.NativeBridge;
             Jto.getChannelStatus().then(result => {
@@ -292,7 +317,7 @@ export default function Page() {
         </View>
     }
 
-    function notificationOpen(){
+    function notificationOpen() {
         if (process.env.TARO_ENV === 'rn') {
             PushNotification.checkPermissions((res) => {
                 //允许授权
@@ -318,44 +343,47 @@ export default function Page() {
     }
 
     function pro(isLogin: boolean) {
+        if (process.env.TARO_ENV == 'weapp') return proDetail(isLogin)
         return <ScrollView style={{ flex: 1 }}>
-            {/* <ProductList /> */}
-            {/* <Text style={{fontSize:30,color:'#fff'}} onClick={iap}>iap test</Text> */}
-            <View className="setting_container">
-                <View className="setting_section">
-                    <Text className="setting_section_title">Fast & Sleep</Text>
-                </View>
-                <Text className="setting_header">Reminders</Text>
-                <View className="setting_cell">
-                    <Text className="setting_cell_title" style={{ flex: 1 }}>At schedule time</Text>
-                    {
-                        isLogin ? <Text className="setting_cell_value1">{systemFast ? 'Always' : 'Off'}</Text> :
-                            <Text className="setting_cell_value1">Off</Text>
-                    }
+            {
+                proDetail(isLogin)
+            }
+        </ScrollView>
+    }
 
-                </View>
-                <Text className="setting_footer">A timely reminder so you never miss your schedule time for fasting and/or sleep.</Text>
-                <Text className="setting_header">Extra Reminders (Pro)</Text>
-                <View className="setting_cell">
-                    <Text className="setting_cell_title" style={{ flex: 1 }}>Missed previous action</Text>
-                    <Switch className="myswitch" value={isLogin ? (isAuthorized ? isExtra : false) : false} color={ColorType.fast} trackColor={{ true: ColorType.fast }} onChange={(e) => {
+    function proDetail(isLogin: boolean) {
+        return <View className="setting_container">
+            <View className="setting_section">
+                <Text className="setting_section_title">Fast & Sleep</Text>
+            </View>
+            <Text className="setting_header">Reminders</Text>
+            <View className="setting_cell">
+                <Text className="setting_cell_title" style={{ flex: 1 }}>At schedule time</Text>
+                {
+                    isLogin ? <Text className="setting_cell_value1">{systemFast ? 'Always' : 'Off'}</Text> :
+                        <Text className="setting_cell_value1">Off</Text>
+                }
+
+            </View>
+            <Text className="setting_footer">A timely reminder so you never miss your schedule time for fasting and/or sleep.</Text>
+            <Text className="setting_header">Extra Reminders (Pro)</Text>
+            <View className="setting_cell">
+                <Text className="setting_cell_title" style={{ flex: 1 }}>Missed previous action</Text>
+                <FSwitch color={ColorType.fast}
+                    checked={isLogin ? (isAuthorized ? isExtra : false) : false}
+                    onChange={(value) => {
                         if (!isLogin) {
                             jumpPage('/pages/account/ChooseAuth', 'ChooseAuth', navigation)
                             return
                         }
+                        debugger
 
                         if (!isAuthorized) {
                             notificationOpen()
                             return
                         }
-                        const value = e.nativeEvent.value
-                        if (e.nativeEvent.value) {
+                        if (value) {
                             if (accessObj && accessObj.access && accessObj.access.member.status == 'NON_MEMBER') {
-                                // setTimeout(() => {
-                                //     setIsSunrise(false)
-                                // }, 1000)
-
-                                // jumpPage('', 'ProductList', navigation)
                                 setShowMemberAlert(true)
                                 return
                             }
@@ -373,18 +401,21 @@ export default function Page() {
                             setIsExtra(value)
                             getLocalPush()
                         })
-                    }} />
-                </View>
-                <Text className="setting_footer">In case you missed your previous action, receive another reminder to log it together with the current one. This gives you extra protection against any streak loss.</Text>
-                <View className="setting_section">
-                    <Text className="setting_section_title">The Sun (Pro)</Text>
-                </View>
-                <Text className="setting_header">Reminders for Your Daily Local Solar Times</Text>
-                <View className="setting_cell_group">
-                    <View className="setting_cell_group_item">
-                        <Text className="setting_cell_title" style={{ flex: 1 }}>Sunrise</Text>
-                        <Switch className="myswitch" value={isLogin ? (isAuthorized ? isSunrise : false) : false} color={ColorType.fast} trackColor={{ true: ColorType.fast }} onChange={(e) => {
-                            // setIsMulti(e.nativeEvent.value)
+                    }}
+                />
+            </View>
+            <Text className="setting_footer">In case you missed your previous action, receive another reminder to log it together with the current one. This gives you extra protection against any streak loss.</Text>
+            <View className="setting_section">
+                <Text className="setting_section_title">The Sun (Pro)</Text>
+            </View>
+            <Text className="setting_header">Reminders for Your Daily Local Solar Times</Text>
+            <View className="setting_cell_group">
+                <View className="setting_cell_group_item">
+                    <Text className="setting_cell_title" style={{ flex: 1 }}>Sunrise</Text>
+                    <FSwitch
+                        color={ColorType.fast}
+                        checked={isLogin ? (isAuthorized ? isSunrise : false) : false}
+                        onChange={(value) => {
                             if (!isLogin) {
                                 jumpPage('/pages/account/ChooseAuth', 'ChooseAuth', navigation)
                                 return
@@ -393,14 +424,8 @@ export default function Page() {
                                 notificationOpen()
                                 return
                             }
-                            const value = e.nativeEvent.value
-                            if (e.nativeEvent.value) {
+                            if (value) {
                                 if (accessObj && accessObj.access && accessObj.access.member.status == 'NON_MEMBER') {
-                                    // setTimeout(() => {
-                                    //     setIsSunrise(false)
-                                    // }, 1000)
-
-                                    // jumpPage('', 'ProductList', navigation)
                                     setShowMemberAlert(true)
                                     return
                                 }
@@ -416,16 +441,19 @@ export default function Page() {
                                 }
                             }).then(res => {
                                 setIsSunrise(value)
-                                // setIsSunrise(e.nativeEvent.value)
+
                                 global.swiperDayNightRefresh()
                             })
-                        }} />
-                    </View>
-                    <View className="new_item_cell_line" />
-                    <View className="setting_cell_group_item">
-                        <Text className="setting_cell_title" style={{ flex: 1 }}>Sunset</Text>
-                        <Switch className="myswitch" value={isLogin ? (isAuthorized ? isSunset : false) : false} trackColor={{ true: ColorType.fast }} color={ColorType.fast} onChange={(e) => {
-                            // setIsMulti(e.nativeEvent.value)
+                        }}
+                    />
+                </View>
+                <View className="new_item_cell_line" />
+                <View className="setting_cell_group_item">
+                    <Text className="setting_cell_title" style={{ flex: 1 }}>Sunset</Text>
+                    <FSwitch
+                        color={ColorType.fast}
+                        checked={isLogin ? (isAuthorized ? isSunset : false) : false}
+                        onChange={(value) => {
                             if (!isLogin) {
                                 jumpPage('/pages/account/ChooseAuth', 'ChooseAuth', navigation)
                                 return
@@ -434,8 +462,7 @@ export default function Page() {
                                 notificationOpen()
                                 return
                             }
-                            const value = e.nativeEvent.value
-                            if (e.nativeEvent.value) {
+                            if (value) {
                                 if (accessObj && accessObj.access && accessObj.access.member.status == 'NON_MEMBER') {
                                     // setTimeout(() => {
                                     //     setIsSunset(false)
@@ -459,13 +486,16 @@ export default function Page() {
                                 setIsSunset(value)
                                 global.swiperDayNightRefresh()
                             })
-                        }} />
-                    </View>
-                    <View className="new_item_cell_line" />
-                    <View className="setting_cell_group_item">
-                        <Text className="setting_cell_title" style={{ flex: 1 }}>Solar noon</Text>
-                        <Switch className="myswitch" value={isLogin ? (isAuthorized ? isSolarNoon : false) : false} trackColor={{ true: ColorType.fast }} color={ColorType.fast} onChange={(e) => {
-                            // setIsMulti(e.nativeEvent.value)
+                        }}
+                    />
+                </View>
+                <View className="new_item_cell_line" />
+                <View className="setting_cell_group_item">
+                    <Text className="setting_cell_title" style={{ flex: 1 }}>Solar noon</Text>
+                    <FSwitch
+                        color={ColorType.fast}
+                        checked={isLogin ? (isAuthorized ? isSolarNoon : false) : false}
+                        onChange={(value) => {
                             if (!isLogin) {
                                 jumpPage('/pages/account/ChooseAuth', 'ChooseAuth', navigation)
                                 return
@@ -474,8 +504,7 @@ export default function Page() {
                                 notificationOpen()
                                 return
                             }
-                            const value = e.nativeEvent.value
-                            if (e.nativeEvent.value) {
+                            if (value) {
                                 if (accessObj && accessObj.access && accessObj.access.member.status == 'NON_MEMBER') {
                                     // setTimeout(() => {
                                     //     setIsSolarNoon(false)
@@ -500,12 +529,12 @@ export default function Page() {
                                 setIsSolarNoon(value)
                                 global.swiperDayNightRefresh()
                             })
-                        }} />
-                    </View>
+                        }}
+                    />
                 </View>
-                <Text className="setting_footer">Note for polar region, during Polar Day (Midnight Sun) when the Sun is up all day or Polar Night when the Sun is down all day, the only reminder available is the daily Solar Noon.</Text>
             </View>
-        </ScrollView>
+            <Text className="setting_footer">Note for polar region, during Polar Day (Midnight Sun) when the Sun is up all day or Polar Night when the Sun is down all day, the only reminder available is the daily Solar Noon.</Text>
+        </View>
     }
 
     function checkSystemChannel() {
@@ -550,24 +579,27 @@ export default function Page() {
         // triggered={triggered}
         // refresh={refresh}
         >
-            {
-                loaded && pro(true)
-            }
-            {
-                process.env.TARO_ENV == 'rn' && kIsAndroid && checkSystemChannel() && <View className="setting_tip" onClick={goSetting}>
-                    <Text className="setting_tip_text">Jump to App's Notifications settings{'>>'}</Text>
-                </View>
-            }
-            {
-                showMemberAlert && process.env.TARO_ENV == 'weapp' && alertPop()
-            }
-            {
-                showMemberAlert && process.env.TARO_ENV == 'rn' && <Modal dismiss={() => { setShowMemberAlert(false) }}>
-                    <View style={{ backgroundColor: 'rgba(0,0,0,0.95)', width: '100%', height: '100%', alignItems: 'center', justifyContent: 'center' }}>
-                        {alertPop()}
+            <View>
+                {
+                    loaded && pro(true)
+                }
+                {
+                    process.env.TARO_ENV == 'rn' && kIsAndroid && checkSystemChannel() && <View className="setting_tip" onClick={goSetting}>
+                        <Text className="setting_tip_text">Jump to App's Notifications settings{'>>'}</Text>
                     </View>
-                </Modal>
-            }
+                }
+                {
+                    showMemberAlert && process.env.TARO_ENV == 'weapp' && alertPop()
+                }
+                {
+                    showMemberAlert && process.env.TARO_ENV == 'rn' && <Modal dismiss={() => { setShowMemberAlert(false) }}>
+                        <View style={{ backgroundColor: 'rgba(0,0,0,0.95)', width: '100%', height: '100%', alignItems: 'center', justifyContent: 'center' }}>
+                            {alertPop()}
+                        </View>
+                    </Modal>
+                }
+            </View>
         </Layout>
+        <Tabbar index={2} />
     </View>
 }

+ 7 - 0
src/pages/store/product_list.config.ts

@@ -0,0 +1,7 @@
+export default definePageConfig({
+    usingComponents: {
+        // 'ec-canvas': '../../lib/ec-canvas/ec-canvas',
+        // 'demo':'../../components/demo'
+    },
+    "navigationBarTitleText": "选择会员计划"
+})

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

@@ -1,4 +1,4 @@
-const online = process.env.TARO_ENV == 'weapp' ? false : false;
+const online = process.env.TARO_ENV == 'weapp' ? true : false;
 
 import { WX_VERSION as _WX_VERSION, APP_VERSION as _APP_VERSION } from "../../../config/env";
 

+ 0 - 1
src/utils/time_format.ts

@@ -114,7 +114,6 @@ export class TimeFormatter {
   static dateTimeFormate(timestamp: number, ignoreWeek?: boolean) {
     const currentDate = new Date();
     const inputDate = new Date(timestamp);
-    debugger
 
     // 判断是否是今天
     if (