leon há 1 ano atrás
pai
commit
259a961e48
57 ficheiros alterados com 1079 adições e 433 exclusões
  1. 4 1
      ios/AppDelegate.mm
  2. 3 1
      ios/Podfile
  3. 41 0
      ios/PrivacyInfo.xcprivacy
  4. BIN
      ios/assets/src/assets/images/home_focus.png
  5. BIN
      ios/assets/src/assets/images/home_nonfocus.png
  6. BIN
      ios/assets/src/assets/images/profile_focus.png
  7. BIN
      ios/assets/src/assets/images/profile_nonfocus.png
  8. 9 7
      ios/hola.xcodeproj/project.pbxproj
  9. 3 3
      ios/hola.xcodeproj/xcshareddata/xcschemes/hola.xcscheme
  10. 5 9
      ios/hola/Info.plist
  11. 3 23
      ios/hola/LaunchScreen.storyboard
  12. 1 1
      ios/main.jsbundle
  13. 0 1
      package.json
  14. 1 0
      src/app.scss
  15. BIN
      src/assets/images/home_focus.png
  16. BIN
      src/assets/images/home_nonfocus.png
  17. BIN
      src/assets/images/profile_focus.png
  18. BIN
      src/assets/images/profile_nonfocus.png
  19. 1 1
      src/components/basic/ActionSheet.tsx
  20. 0 14
      src/components/basic/Alert.tsx
  21. 1 1
      src/components/input/Inputs.tsx
  22. 38 5
      src/components/layout/Modal.weapp.tsx
  23. 1 1
      src/components/layout/layout.tsx
  24. 12 6
      src/context/locales/en.js
  25. 12 5
      src/context/locales/zh.js
  26. 15 2
      src/features/auth/components/CreateAccount.tsx
  27. 19 4
      src/features/auth/components/Login.tsx
  28. 12 0
      src/features/daynight/DayNightCard.scss
  29. 72 68
      src/features/daynight/DayNightCard.tsx
  30. 5 2
      src/features/daynight/DayNightSwiper.tsx
  31. 1 1
      src/features/trackTimeDuration/components/ChooseScenario.tsx
  32. 2 26
      src/features/trackTimeDuration/components/ConsolePicker.tsx
  33. 28 14
      src/features/trackTimeDuration/components/IndexConsole.tsx
  34. 106 32
      src/features/trackTimeDuration/components/SetSchedule.rn.tsx
  35. 86 18
      src/features/trackTimeDuration/components/SetSchedule.weapp.tsx
  36. 5 5
      src/features/trackTimeDuration/components/StreakItem.tsx
  37. 72 10
      src/features/trackTimeDuration/components/Streaks.scss
  38. 57 4
      src/features/trackTimeDuration/components/Streaks.tsx
  39. 4 1
      src/features/trackTimeDuration/components/TimelineStage.rn.tsx
  40. 1 1
      src/features/trackTimeDuration/components/TitleView.scss
  41. 51 8
      src/features/trackTimeDuration/components/WeekCalendar.tsx
  42. 52 9
      src/features/trackTimeDuration/components/WeekCalendarItem.tsx
  43. 4 0
      src/pages/account/EditPage.tsx
  44. 24 2
      src/pages/account/Profile.tsx
  45. 4 0
      src/pages/account/ProfileSetting.tsx
  46. 18 0
      src/pages/account/Setting.tsx
  47. 3 1
      src/pages/clock/Clock.scss
  48. 139 44
      src/pages/clock/Clock.tsx
  49. 12 5
      src/pages/clock/StreakDetail.tsx
  50. 29 14
      src/pages/common/H5.tsx
  51. 18 21
      src/pages/common/RecordsHistory.tsx
  52. 58 34
      src/pages/rn/RNMain.tsx
  53. 1 1
      src/services/http/api.js
  54. 1 1
      src/services/http/request.ts
  55. 3 3
      src/utils/check_authorized.tsx
  56. 35 19
      src/utils/native_permission_check.tsx
  57. 7 4
      src/utils/push.tsx

+ 4 - 1
ios/AppDelegate.mm

@@ -67,12 +67,15 @@ static NSString *const kRNConcurrentRoot = @"concurrentRoot";
   if (@available(iOS 13.0, *)) {
     rootView.backgroundColor = [UIColor systemBackgroundColor];
   } else {
-    rootView.backgroundColor = [UIColor whiteColor];
+    rootView.backgroundColor = [UIColor blackColor];
   }
 
   self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
+  self.window.backgroundColor = [UIColor blackColor];
   UIViewController *rootViewController = [self.reactDelegate createRootViewController];
   rootViewController.view = rootView;
+  rootViewController.view.backgroundColor = [UIColor blackColor];
+  
   self.window.rootViewController = rootViewController;
   [self.window makeKeyAndVisible];
   [super application:application didFinishLaunchingWithOptions:launchOptions];

+ 3 - 1
ios/Podfile

@@ -10,7 +10,9 @@ setup_permissions([
   'LocationAccuracy',
   'LocationAlways',
   'LocationWhenInUse',
-  'Notifications'
+  'Notifications',
+  'Camera',
+  'PhotoLibrary'
 ])
 
 target 'hola' do

+ 41 - 0
ios/PrivacyInfo.xcprivacy

@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>NSPrivacyAccessedAPITypes</key>
+	<array>
+		<dict>
+			<key>NSPrivacyAccessedAPIType</key>
+			<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
+			<key>NSPrivacyAccessedAPITypeReasons</key>
+			<array>
+				<string>CA92.1</string>
+			</array>
+		</dict>
+		<dict>
+			<key>NSPrivacyAccessedAPITypeReasons</key>
+			<array>
+				<string>0A2A.1</string>
+			</array>
+			<key>NSPrivacyAccessedAPIType</key>
+			<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
+		</dict>
+		<dict>
+			<key>NSPrivacyAccessedAPITypeReasons</key>
+			<array>
+				<string>E174.1</string>
+			</array>
+			<key>NSPrivacyAccessedAPIType</key>
+			<string>NSPrivacyAccessedAPICategoryDiskSpace</string>
+		</dict>
+		<dict>
+			<key>NSPrivacyAccessedAPITypeReasons</key>
+			<array>
+				<string>35F9.1</string>
+			</array>
+			<key>NSPrivacyAccessedAPIType</key>
+			<string>NSPrivacyAccessedAPICategorySystemBootTime</string>
+		</dict>
+	</array>
+</dict>
+</plist>

BIN
ios/assets/src/assets/images/home_focus.png


BIN
ios/assets/src/assets/images/home_nonfocus.png


BIN
ios/assets/src/assets/images/profile_focus.png


BIN
ios/assets/src/assets/images/profile_nonfocus.png


+ 9 - 7
ios/hola.xcodeproj/project.pbxproj

@@ -39,7 +39,7 @@
 		00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
 		00E356F21AD99517003FC87E /* holaTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = holaTests.m; sourceTree = "<group>"; };
 		064FE7D59874E5A1126C807C /* ExpoModulesProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ExpoModulesProvider.swift; path = "Pods/Target Support Files/Pods-hola-holaTests/ExpoModulesProvider.swift"; sourceTree = "<group>"; };
-		13B07F961A680F5B00A75B9A /* hola.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = hola.app; sourceTree = BUILT_PRODUCTS_DIR; };
+		13B07F961A680F5B00A75B9A /* fast16cc.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = fast16cc.app; sourceTree = BUILT_PRODUCTS_DIR; };
 		13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = hola/Images.xcassets; sourceTree = "<group>"; };
 		13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = hola/Info.plist; sourceTree = "<group>"; };
 		13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = hola/main.m; sourceTree = "<group>"; };
@@ -52,6 +52,7 @@
 		35B0D6E12B4D58540059F156 /* hola.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = hola.entitlements; path = hola/hola.entitlements; sourceTree = "<group>"; };
 		35B0D6E92B5B872F0059F156 /* assets */ = {isa = PBXFileReference; lastKnownFileType = folder; path = assets; sourceTree = "<group>"; };
 		35B0D6EC2B5B8D360059F156 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = main.jsbundle; sourceTree = "<group>"; };
+		35C2DB5B2BDA830E00846349 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
 		35D120583D7F592A3931F5B3 /* Pods-hola.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-hola.release.xcconfig"; path = "Target Support Files/Pods-hola/Pods-hola.release.xcconfig"; sourceTree = "<group>"; };
 		5C2DF1055D750361F8EB3838 /* libPods-hola-holaTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-hola-holaTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
 		79481516D62ED012C19B3DCA /* Pods-hola.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-hola.debug.xcconfig"; path = "Target Support Files/Pods-hola/Pods-hola.debug.xcconfig"; sourceTree = "<group>"; };
@@ -114,6 +115,7 @@
 				13B07FB71A68108700A75B9A /* main.m */,
 				35B0D6DE2B4D4EE10059F156 /* AppDelegate.h */,
 				35B0D6DF2B4D4EE10059F156 /* AppDelegate.mm */,
+				35C2DB5B2BDA830E00846349 /* PrivacyInfo.xcprivacy */,
 			);
 			name = hola;
 			sourceTree = "<group>";
@@ -174,7 +176,7 @@
 		83CBBA001A601CBA00E9B192 /* Products */ = {
 			isa = PBXGroup;
 			children = (
-				13B07F961A680F5B00A75B9A /* hola.app */,
+				13B07F961A680F5B00A75B9A /* fast16cc.app */,
 				00E356EE1AD99517003FC87E /* holaTests.xctest */,
 			);
 			name = Products;
@@ -240,7 +242,7 @@
 			);
 			name = hola;
 			productName = hola;
-			productReference = 13B07F961A680F5B00A75B9A /* hola.app */;
+			productReference = 13B07F961A680F5B00A75B9A /* fast16cc.app */;
 			productType = "com.apple.product-type.application";
 		};
 /* End PBXNativeTarget section */
@@ -522,7 +524,7 @@
 					"$(inherited)",
 					"@executable_path/Frameworks",
 				);
-				MARKETING_VERSION = 1.0;
+				MARKETING_VERSION = 1.0.0;
 				OTHER_LDFLAGS = (
 					"$(inherited)",
 					"-ObjC",
@@ -530,7 +532,7 @@
 				);
 				OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_DEBUG";
 				PRODUCT_BUNDLE_IDENTIFIER = com.hye.fast;
-				PRODUCT_NAME = hola;
+				PRODUCT_NAME = fast16cc;
 				PROVISIONING_PROFILE_SPECIFIER = "";
 				SWIFT_OPTIMIZATION_LEVEL = "-Onone";
 				SWIFT_VERSION = 5.0;
@@ -554,7 +556,7 @@
 					"$(inherited)",
 					"@executable_path/Frameworks",
 				);
-				MARKETING_VERSION = 1.0;
+				MARKETING_VERSION = 1.0.0;
 				OTHER_LDFLAGS = (
 					"$(inherited)",
 					"-ObjC",
@@ -562,7 +564,7 @@
 				);
 				OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE";
 				PRODUCT_BUNDLE_IDENTIFIER = com.hye.fast;
-				PRODUCT_NAME = hola;
+				PRODUCT_NAME = fast16cc;
 				PROVISIONING_PROFILE_SPECIFIER = "";
 				SWIFT_VERSION = 5.0;
 				VERSIONING_SYSTEM = "apple-generic";

+ 3 - 3
ios/hola.xcodeproj/xcshareddata/xcschemes/hola.xcscheme

@@ -15,7 +15,7 @@
             <BuildableReference
                BuildableIdentifier = "primary"
                BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
-               BuildableName = "hola.app"
+               BuildableName = "fast16cc.app"
                BlueprintName = "hola"
                ReferencedContainer = "container:hola.xcodeproj">
             </BuildableReference>
@@ -55,7 +55,7 @@
          <BuildableReference
             BuildableIdentifier = "primary"
             BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
-            BuildableName = "hola.app"
+            BuildableName = "fast16cc.app"
             BlueprintName = "hola"
             ReferencedContainer = "container:hola.xcodeproj">
          </BuildableReference>
@@ -72,7 +72,7 @@
          <BuildableReference
             BuildableIdentifier = "primary"
             BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
-            BuildableName = "hola.app"
+            BuildableName = "fast16cc.app"
             BlueprintName = "hola"
             ReferencedContainer = "container:hola.xcodeproj">
          </BuildableReference>

+ 5 - 9
ios/hola/Info.plist

@@ -5,7 +5,7 @@
 	<key>CFBundleDevelopmentRegion</key>
 	<string>en</string>
 	<key>CFBundleDisplayName</key>
-	<string>hola</string>
+	<string>fast16cc</string>
 	<key>CFBundleExecutable</key>
 	<string>$(EXECUTABLE_NAME)</string>
 	<key>CFBundleIdentifier</key>
@@ -35,6 +35,8 @@
 	<string>1</string>
 	<key>ITSAppUsesNonExemptEncryption</key>
 	<false/>
+	<key>LSApplicationCategoryType</key>
+	<string>public.app-category.healthcare-fitness</string>
 	<key>LSRequiresIPhoneOS</key>
 	<true/>
 	<key>NSAppTransportSecurity</key>
@@ -52,12 +54,6 @@
 	<string>Your camera is used to take photos of your food.</string>
 	<key>NSContactsUsageDescription</key>
 	<string>Allow $(PRODUCT_NAME) to access your contacts</string>
-	<key>NSHealthClinicalHealthRecordsShareUsageDescription</key>
-	<string>Read and understand clinical health data.</string>
-	<key>NSHealthShareUsageDescription</key>
-	<string>Read and understand health data.</string>
-	<key>NSHealthUpdateUsageDescription</key>
-	<string>Share workout data with other apps.</string>
 	<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
 	<string>Your location is used to calculate your local sunrise and sunset times.</string>
 	<key>NSLocationAlwaysUsageDescription</key>
@@ -67,13 +63,13 @@
 	<key>NSMicrophoneUsageDescription</key>
 	<string>Allow $(PRODUCT_NAME) to access your microphone</string>
 	<key>NSMotionUsageDescription</key>
-	<string>Allow $(PRODUCT_NAME) to access your device's accelerometer</string>
+	<string>Allow $(PRODUCT_NAME) to access your device&apos;s accelerometer</string>
 	<key>NSPhotoLibraryAddUsageDescription</key>
 	<string>Your photos are used to for your avatar.</string>
 	<key>NSPhotoLibraryUsageDescription</key>
 	<string>Your photos are used to for your avatar.</string>
 	<key>NSUserNotificationsUsageDescription</key>
-	<string>helloworld</string>
+	<string>You&apos;ll get reminders at scheduled times.</string>
 	<key>UILaunchStoryboardName</key>
 	<string>LaunchScreen</string>
 	<key>UIRequiredDeviceCapabilities</key>

+ 3 - 23
ios/hola/LaunchScreen.storyboard

@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="15702" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="32700.99.1234" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
     <device id="retina4_7" orientation="portrait" appearance="light"/>
     <dependencies>
         <deployment identifier="iOS"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15704"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22684"/>
         <capability name="Safe area layout guides" minToolsVersion="9.0"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
@@ -15,28 +15,8 @@
                     <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
                         <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
-                        <subviews>
-                            <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="hola" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="GJd-Yh-RWb">
-                                <rect key="frame" x="0.0" y="202" width="375" height="43"/>
-                                <fontDescription key="fontDescription" type="boldSystem" pointSize="36"/>
-                                <nil key="highlightedColor"/>
-                            </label>
-                            <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Powered by React Native" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="MN2-I3-ftu">
-                                <rect key="frame" x="0.0" y="626" width="375" height="21"/>
-                                <fontDescription key="fontDescription" type="system" pointSize="17"/>
-                                <nil key="highlightedColor"/>
-                            </label>
-                        </subviews>
-                        <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
-                        <constraints>
-                            <constraint firstItem="Bcu-3y-fUS" firstAttribute="bottom" secondItem="MN2-I3-ftu" secondAttribute="bottom" constant="20" id="OZV-Vh-mqD"/>
-                            <constraint firstItem="Bcu-3y-fUS" firstAttribute="centerX" secondItem="GJd-Yh-RWb" secondAttribute="centerX" id="Q3B-4B-g5h"/>
-                            <constraint firstItem="MN2-I3-ftu" firstAttribute="centerX" secondItem="Bcu-3y-fUS" secondAttribute="centerX" id="akx-eg-2ui"/>
-                            <constraint firstItem="MN2-I3-ftu" firstAttribute="leading" secondItem="Bcu-3y-fUS" secondAttribute="leading" id="i1E-0Y-4RG"/>
-                            <constraint firstItem="GJd-Yh-RWb" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="bottom" multiplier="1/3" constant="1" id="moa-c2-u7t"/>
-                            <constraint firstItem="GJd-Yh-RWb" firstAttribute="leading" secondItem="Bcu-3y-fUS" secondAttribute="leading" symbolic="YES" id="x7j-FC-K8j"/>
-                        </constraints>
                         <viewLayoutGuide key="safeArea" id="Bcu-3y-fUS"/>
+                        <color key="backgroundColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                     </view>
                 </viewController>
                 <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>

Diff do ficheiro suprimidas por serem muito extensas
+ 1 - 1
ios/main.jsbundle


+ 0 - 1
package.json

@@ -101,7 +101,6 @@
 		"react-native-device-info": "~10.3.0",
 		"react-native-gesture-handler": "~2.9.0",
 		"react-native-haptic-feedback": "^2.2.0",
-		"react-native-health": "^1.18.0",
 		"react-native-linear-gradient": "^2.8.3",
 		"react-native-pager-view": "~6.0.1",
 		"react-native-permissions": "^4.1.5",

+ 1 - 0
src/app.scss

@@ -344,6 +344,7 @@ page {
 
 .cell_value {
     font-size: 28px;
+    color: #fff;
 }
 
 .cell_arrow {

BIN
src/assets/images/home_focus.png


BIN
src/assets/images/home_nonfocus.png


BIN
src/assets/images/profile_focus.png


BIN
src/assets/images/profile_nonfocus.png


+ 1 - 1
src/components/basic/ActionSheet.tsx

@@ -22,7 +22,7 @@ export default function showActionSheet(props: any) {
         const options = {
             options: list,
             cancelButtonIndex: list.length - 1,
-            destructiveButtonIndex: list.length - 1,
+            // destructiveButtonIndex: list.length - 1,
             title: props.title,
             message: props.message,
         };

+ 0 - 14
src/components/basic/Alert.tsx

@@ -6,20 +6,6 @@ if (process.env.TARO_ENV == 'rn') {
     Alert = require('react-native').Alert
 }
 export default function showAlert(props: any) {
-    /*
-    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) {
-                                            Linking.openURL('app-settings:notifications')
-                                        } else if (res.cancel) {
-                                        }
-                                    }
-    */
     if (process.env.TARO_ENV == 'weapp') {
         Taro.showModal({
             title: props.title,

+ 1 - 1
src/components/input/Inputs.tsx

@@ -55,7 +55,7 @@ export default function Component({
                 type={openType == 'nickname' ? 'nickname' : isSecure ? 'safe-password' : 'text'}
                 // type={openType?openType:'text'}
                 onInput={handleInputChange}
-
+                placeholderStyle='color:#ffffff66'
                 // onConfirm={() => onConfirm()}
                 focus={autoFocus}
                 confirmType="done"

+ 38 - 5
src/components/layout/Modal.weapp.tsx

@@ -1,16 +1,17 @@
 import { View, Text, ScrollView } from '@tarojs/components'
 import './Modal.scss'
-import React, { useState } from 'react';
+import React, { useEffect, useRef, useState } from 'react';
 import { ModalType } from '@/utils/types';
 import Box from './Box';
 import Taro from '@tarojs/taro';
 import { vibrate } from '@/utils/tools';
 
 
-let ModalRN
+let ModalRN, Animated
 
 if (process.env.TARO_ENV == 'rn') {
     ModalRN = require("react-native").Modal
+    Animated = require("react-native").Animated
 }
 
 export default function Modal(props: {
@@ -25,6 +26,34 @@ export default function Modal(props: {
 }) {
 
     const [isDismiss, setIsDismiss] = useState(false)
+    let animation, animatedStyle;
+    if (process.env.TARO_ENV == 'rn') {
+        animation = useRef(new Animated.Value(0)).current;
+        animatedStyle = {
+            transform: [
+                {
+                    translateY: animation.interpolate({
+                        inputRange: [0, 1],
+                        outputRange: [200, 0],
+                    }),
+                },
+            ],
+        };
+    }
+
+    useEffect(() => {
+        if (process.env.TARO_ENV == 'rn') {
+            startAnimation()
+        }
+    }, [])
+
+    const startAnimation = () => {
+        Animated.spring(animation, {
+            toValue: 1,
+            duration:50,
+            useNativeDriver: true,
+        }).start();
+    };
 
     //阻止中间内容点击事件穿透
     function click(e) {
@@ -75,17 +104,21 @@ export default function Modal(props: {
     global.dismissModal = dismiss;
 
     if (process.env.TARO_ENV == 'rn') {
-        return <ModalRN transparent>
+        return <ModalRN transparent
+        // animationType="slide"
+        // style={{backgroundColor:'red'}}
+        >
             <View style={{ flex: 1, backgroundColor: '#000000cc' }}>
                 <View style={{ flex: 1, backgroundColor: 'transparent' }} onClick={(e) => {
                     dismiss()
                 }}></View>
-                <View className={isDismiss ? 'modal_bottom_content modal_bottom_dismiss' : 'modal_bottom_content'} style={{ flexShrink: 0 }} onClick={onClick}>
+                <Animated.View className={isDismiss ? 'modal_bottom_content modal_bottom_dismiss' : 'modal_bottom_content'} 
+                style={[{ flexShrink: 0 },animatedStyle]} onClick={onClick}>
                     {
                         props.children
                     }
 
-                </View>
+                </Animated.View>
             </View>
         </ModalRN>
     }

+ 1 - 1
src/components/layout/layout.tsx

@@ -82,7 +82,7 @@ export default function Layout(props: {
             // else {
             //     setShowTitle(false)
             // }
-            console.log(e)
+            // console.log(e)
             if (e.detail.scrollTop > 70) {
                 setShowTitle(true)
             }

+ 12 - 6
src/context/locales/en.js

@@ -33,7 +33,7 @@ export default {
             share_title: 'My explore'
         },
         more: {
-            title: 'Me',
+            title: 'Profile',
             un_login: 'Not logged in',
             stone: 'Reverse aging stone',
             stone_desc: 'Member system upgrading, during which metric recording is temporarily exempt from reverse aging stone recording. Please stay tuned.',
@@ -93,10 +93,13 @@ export default {
             logout: 'Log out'
         },
         user_profile: {
-            title: 'Edit profile',
+            title: 'Edit Profile',
             nickname: 'Nickname',
             save: 'Save',
             nickname_footer: 'The community leaderboard feature is coming out soon, and a personalized name will let you stand out.'
+        },
+        edit_nickname:{
+            title:'Edit Nickname'
         }
     },
     feature: {
@@ -321,14 +324,14 @@ export default {
                 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}}.',
+                post_fast_content: 'Once enabled, you will receive an end reminder {{date}} at {{time}}.',
+                post_sleep_content: 'Once enabled, you will receive a wake-up reminder {{date}} at {{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}}.',
+                enable_post_fast_content: 'We will remind you to end your fasting {{date}} at {{time}}.',
+                enable_post_sleep_content: 'We will remind you to wake up {{date}} at {{time}}.',
 
                 later: 'Later',
                 open: 'Enable now',
@@ -362,6 +365,9 @@ export default {
                 current: 'Current',
                 longest: 'Longest',
                 no_data:'Start a new streak today!',
+                countdown_title:'Don\'t lose your {{name}}. Keep it going!',
+                countdown_fast:'Current fast streak will reset to zero in {{time}}.',
+                countdown_sleep:'Current sleep streak will reset to zero in {{time}}.'
             },
             change_tz_alert: {
                 title: 'New Time Zone Detected',

+ 12 - 5
src/context/locales/zh.js

@@ -96,7 +96,11 @@ export default {
             nickname: '昵称',
             save: '保存',
             nickname_footer: '即将推出社区排行榜, 个性化的名字将在社区中脱颖而出。'
-        }
+        },
+        edit_nickname:{
+            title:'编辑昵称'
+        },
+        
 
 
 
@@ -325,14 +329,14 @@ export default {
                 schedule_fast_content: '开启后, 您将在设定的断食时间收到提醒。',
                 schedule_sleep_content: '开启后, 您将在设定的就寝时间收到提醒。',
                 schedule_mix_content: '开启后, 您将在设定的断食及就寝时间收到提醒。',
-                post_fast_content: '开启后, 您将在{{time}} 收到断食结束提醒。',
-                post_sleep_content: '开启后, 您将在{{time}} 收到起床提醒。',
+                post_fast_content: '开启后, 您将在{{date}} {{time}} 收到断食结束提醒。',
+                post_sleep_content: '开启后, 您将在{{date}} {{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}} 您将通过公众号收到起床提醒。',
+                enable_post_fast_content: '{{date}} {{time}} 您将通过公众号收到断食结束提醒。',
+                enable_post_sleep_content: '{{date}} {{time}} 您将通过公众号收到起床提醒。',
 
                 later: '稍后',
                 open: '立即开启',
@@ -364,6 +368,9 @@ export default {
                 current: '目前保持',
                 longest: '最长保持',
                 no_data:'从今天开始新的连续纪录吧!',
+                countdown_title:'别让连续纪录终止, 将它一直保持下去!',
+                countdown_fast:'当前断食连续天数将在 {{time}} 后重置归零。',
+                countdown_sleep:'当前睡眠连续天数将在 {{time}} 后重置归零。'
             },
             change_tz_alert: {
                 title: '检测到新时区',

+ 15 - 2
src/features/auth/components/CreateAccount.tsx

@@ -186,10 +186,16 @@ export default function Component(props: { login: () => void }) {
 
   function agreement() {
     console.log(common.resources)
-    debugger
     const resource = common.resources.filter((item: any) => {
       return item.code == 'user_agreement'
     })
+    if (!resource || resource.length == 0) {
+      Taro.showToast({
+        title: 'Not found.',
+        icon: 'none'
+      })
+      return
+    }
 
     jumpPage('/pages/common/H5?title=User Agreement&url=' + resource[0].url, 'H5', navigation, {
       title: 'User Agreement',
@@ -201,6 +207,13 @@ export default function Component(props: { login: () => void }) {
     const resource = common.resources.filter((item: any) => {
       return item.code == 'privacy'
     })
+    if (!resource || resource.length == 0) {
+      Taro.showToast({
+        title: 'Not found.',
+        icon: 'none'
+      })
+      return
+    }
 
     jumpPage('/pages/common/H5?title=Privacy Policy&url=' + resource[0].url, 'H5', navigation, {
       title: 'Privacy Policy',
@@ -230,7 +243,7 @@ export default function Component(props: { login: () => void }) {
       </View>
 
       <View style={{ width: 10 }} />
-      <Text className='agree_text' style={{ color: '#ffffff66' }}>I have read and agreed to the <Text style={{ color: '#ffffff' }} onClick={agreement}>User Agreement</Text> and <Text onClick={privacy} style={{ color: '#ffffff' }}>Privacy Policy</Text></Text>
+      <Text className='agree_text' style={{ color: '#ffffff66' }}>I agree to <Text onClick={privacy} style={{ color: '#ffffff' }}> Privacy Policy.</Text></Text>
     </View>
     {/* <View className="agree_view">
       <Image style='width:12px;height:12px;' src={check} />

+ 19 - 4
src/features/auth/components/Login.tsx

@@ -98,17 +98,24 @@ export default function Login(props: { register: () => void }) {
         // dispatch(login(name, password) as any);
     }
 
-    function tapCheck(){
+    function tapCheck() {
         setChecked(!checked)
     }
 
     function agreement() {
-        console.log(common.resources)
-        debugger
         const resource = common.resources.filter((item: any) => {
             return item.code == 'user_agreement'
         })
 
+        if (!resource || resource.length == 0) {
+            Taro.showToast({
+                title: 'Not found.',
+                icon: 'none'
+            })
+            return
+        }
+        debugger
+
         jumpPage('/pages/common/H5?title=User Agreement&url=' + resource[0].url, 'H5', navigation, {
             title: 'User Agreement',
             url: resource[0].url
@@ -119,6 +126,14 @@ export default function Login(props: { register: () => void }) {
         const resource = common.resources.filter((item: any) => {
             return item.code == 'privacy'
         })
+        debugger
+        if (!resource|| resource.length == 0) {
+            Taro.showToast({
+                title: 'Not found.',
+                icon: 'none'
+            })
+            return
+        }
 
         jumpPage('/pages/common/H5?title=Privacy Policy&url=' + resource[0].url, 'H5', navigation, {
             title: 'Privacy Policy',
@@ -147,7 +162,7 @@ export default function Login(props: { register: () => void }) {
             </View>
 
             <View style={{ width: 10 }} />
-            <Text className='agree_text' style={{ color: '#ffffff66' }}>I have read and agreed to the <Text style={{ color: '#ffffff' }} onClick={agreement}>User Agreement</Text> and <Text onClick={privacy} style={{ color: '#ffffff' }}>Privacy Policy</Text></Text>
+            <Text className='agree_text' style={{ color: '#ffffff66' }}>I agree to <Text onClick={privacy} style={{ color: '#ffffff' }}> Privacy Policy.</Text></Text>
         </View>
         <View style={{ flex: 1 }} />
         <View className="footer">

+ 12 - 0
src/features/daynight/DayNightCard.scss

@@ -341,4 +341,16 @@
     margin-left: 6px;
     background-color: #ffffff33;
     color: #ffffff99;
+}
+
+.rn_card_bg{
+    margin-left: 46px;
+    margin-right: 46px;
+    display: flex;
+    width: 658px;
+    background-color: $boxColor;
+    box-sizing: border-box;
+    border-radius: $boxBorderRadius;
+    padding: 40px;
+    flex-direction: column;
 }

+ 72 - 68
src/features/daynight/DayNightCard.tsx

@@ -441,8 +441,8 @@ export default function DayNightCard(props: { isNight: boolean, count: number })
                         dispatch(updateMember({ isMember: isMember, gpsInfo: (data as any) }))
                         showRing()
                         Taro.showToast({
-                            title:t('feature.day_night.location_updated'),
-                            icon:'none'
+                            title: t('feature.day_night.location_updated'),
+                            icon: 'none'
                         })
                     })
                 },
@@ -454,7 +454,7 @@ export default function DayNightCard(props: { isNight: boolean, count: number })
                             showCancel: true,
                             cancelText: t('feature.auth_sys.location_cancel'),
                             confirmText: t('feature.auth_sys.location_confirm'),
-                            confirm:()=>{
+                            confirm: () => {
                                 Linking.openURL('app-settings:')
                             }
                         })
@@ -494,7 +494,7 @@ export default function DayNightCard(props: { isNight: boolean, count: number })
                     showRing()
                     dispatch(updateMember({ isMember: isMember, gpsInfo: (data as any) }))
 
-                    if (global.swiperDayNightRefresh){
+                    if (global.swiperDayNightRefresh) {
                         global.swiperDayNightRefresh()
                     }
                 })
@@ -922,7 +922,7 @@ export default function DayNightCard(props: { isNight: boolean, count: number })
         }
 
         return <View style={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
-            <Text className='ring_city'>{getCity()}</Text>
+            <Text className='ring_city' numberOfLines={1}>{getCity()}</Text>
             <Text className='ring_clock' style={{ color: props.isNight ? ColorType.night : ColorType.day }}>{current}</Text>
             <Text className='ring_timezone'>{
                 offset > 0 ? t('feature.day_night.ahead_desc', { time: time }) : t('feature.day_night.behind_desc', { time: time })
@@ -930,78 +930,82 @@ export default function DayNightCard(props: { isNight: boolean, count: number })
         </View>
     }
 
-    return <Box><View style={{ position: 'relative' }}>
-        <View style={{ display: 'flex', flexDirection: 'column', zIndex: 1 }} onClick={showLocationAlert} onLongPress={longClick}>
-            <View className="ring_full_container" style={{ paddingBottom: 0 }}>
-                <View style={{
-                    display: 'flex',
-                    flexDirection: 'row',
-                    marginTop: 0,
-                    marginBottom: 0,
-                    padding: 0,
-                    alignItems: 'center'
-                }}>
-                    <View style={{ display: 'flex', position: 'relative' }}>
-                        {
-                            props.isNight ? nightRing() : dayRing()
-                        }
-                        <View style={{ color: '#fff', position: 'absolute', left: 0, right: 0, top: 0, bottom: 0, alignItems: 'center', justifyContent: 'center', display: 'flex' }}>{currentTime()}</View>
-                    </View>
-                    <View style={{ display: 'flex', flexDirection: 'column', flexShrink: 0, flex: 1, marginLeft: rpxToPx(52) }}>
-                        <View style={{ display: 'flex', flexDirection: 'row', alignItems: 'center' }}>
-                            <Text className='ring_card_duration_title'>{props.isNight ? t('feature.common.overnight') : t('feature.common.day')}</Text>
+    function cardContent() {
+        return <View style={{ position: 'relative' }}>
+            <View style={{ display: 'flex', flexDirection: 'column', zIndex: 1 }} onClick={showLocationAlert} onLongPress={longClick}>
+                <View className="ring_full_container" style={{ paddingBottom: 0 }}>
+                    <View style={{
+                        display: 'flex',
+                        flexDirection: 'row',
+                        marginTop: 0,
+                        marginBottom: 0,
+                        padding: 0,
+                        alignItems: 'center'
+                    }}>
+                        <View style={{ display: 'flex', position: 'relative' }}>
                             {
-                                !props.isNight && global.dayObj && global.dayObj.is_polar_day && <View className='polar_tag'>{t('feature.day_night.polar_day')}</View>
-                            }
-                            {
-                                props.isNight && global.nightObj && global.nightObj.is_polar_night && <View className='polar_tag'>{t('feature.day_night.polar_night')}</View>
+                                props.isNight ? nightRing() : dayRing()
                             }
+                            <View style={{ color: '#fff', position: 'absolute', left: 0, right: 0, top: 0, bottom: 0, alignItems: 'center', justifyContent: 'center', display: 'flex' }}>{currentTime()}</View>
                         </View>
+                        <View style={{ display: 'flex', flexDirection: 'column', flexShrink: 0, flex: 1, marginLeft: rpxToPx(52) }}>
+                            <View style={{ display: 'flex', flexDirection: 'row', alignItems: 'center' }}>
+                                <Text className='ring_card_duration_title'>{props.isNight ? t('feature.common.overnight') : t('feature.common.day')}</Text>
+                                {
+                                    !props.isNight && global.dayObj && global.dayObj.is_polar_day && <View className='polar_tag'>{t('feature.day_night.polar_day')}</View>
+                                }
+                                {
+                                    props.isNight && global.nightObj && global.nightObj.is_polar_night && <View className='polar_tag'>{t('feature.day_night.polar_night')}</View>
+                                }
+                            </View>
 
-                        <Text className='ring_card_duration_value' style={{ color: props.isNight ? ColorType.night : ColorType.day }}>{props.isNight ? getSunsetDuration() : getSunriseDuration()}</Text>
+                            <Text className='ring_card_duration_value' style={{ color: props.isNight ? ColorType.night : ColorType.day }}>{props.isNight ? getSunsetDuration() : getSunriseDuration()}</Text>
 
-                    </View>
-                    {/* {
+                        </View>
+                        {/* {
                         !showArrow() && <Image className="card_arrow2" src={require('@/assets/images/arrow3.png')} />
                     } */}
-                    <View className='day_card_header'>
-                        {
-                            props.isNight && global.nightObj && <DayNightStatus
-                                authInfo={authInfo}
-                                isNight={props.isNight}
-                                sunrise_ts={global.nightObj.sunrise.timestamp}
-                                sunset_ts={global.nightObj.sunset.timestamp}
-                            />
-                        }
-                        {
-                            !props.isNight && global.dayObj && <DayNightStatus
-                                authInfo={authInfo}
-                                isNight={props.isNight}
-                                sunrise_ts={global.dayObj.sunrise.timestamp}
-                                sunset_ts={global.dayObj.sunset.timestamp}
-                            />
-                        }
-                    </View>
-                    <View className='day_night_card_footer1' style={{ backgroundColor: global.isDebug ? 'red' : 'transparent' }}>
-                        {
-                            !showArrow() && <View className='footer_sun_icon_bg' style={{ backgroundColor: global.isDebug ? 'pink' : 'transparent' }}>
-                                {
-                                    footerIcon()
-                                }
-                            </View>
-                        }
-                        <Text className='footer_desc_text' style={{ backgroundColor: global.isDebug ? 'black' : 'transparent' }}>{showArrow() ? completedDate() : footerDesc()}</Text>
-                        <Image className="card_arrowaaa" style={{ backgroundColor: global.isDebug ? 'blue' : 'transparent' }} src={require('@/assets/images/arrow3.png')} />
+                        <View className='day_card_header'>
+                            {
+                                props.isNight && global.nightObj && <DayNightStatus
+                                    authInfo={authInfo}
+                                    isNight={props.isNight}
+                                    sunrise_ts={global.nightObj.sunrise.timestamp}
+                                    sunset_ts={global.nightObj.sunset.timestamp}
+                                />
+                            }
+                            {
+                                !props.isNight && global.dayObj && <DayNightStatus
+                                    authInfo={authInfo}
+                                    isNight={props.isNight}
+                                    sunrise_ts={global.dayObj.sunrise.timestamp}
+                                    sunset_ts={global.dayObj.sunset.timestamp}
+                                />
+                            }
+                        </View>
+                        <View className='day_night_card_footer1' style={{ backgroundColor: global.isDebug ? 'red' : 'transparent' }}>
+                            {
+                                !showArrow() && <View className='footer_sun_icon_bg' style={{ backgroundColor: global.isDebug ? 'pink' : 'transparent' }}>
+                                    {
+                                        footerIcon()
+                                    }
+                                </View>
+                            }
+                            <Text className='footer_desc_text' style={{ backgroundColor: global.isDebug ? 'black' : 'transparent' }}>{showArrow() ? completedDate() : footerDesc()}</Text>
+                            <Image className="card_arrowaaa" style={{ backgroundColor: global.isDebug ? 'blue' : 'transparent' }} src={require('@/assets/images/arrow3.png')} />
+                        </View>
                     </View>
                 </View>
             </View>
+            {
+                showDetailPopup && modalContent()
+            }
+            {
+                showDetailModal && modalContent2()
+            }
         </View>
-        {
-            showDetailPopup && modalContent()
-        }
-        {
-            showDetailModal && modalContent2()
-        }
-    </View>
-    </Box>
+    }
+
+    return process.env.TARO_ENV =='weapp'?<Box>{cardContent()}</Box>:
+    <View className='rn_card_bg'>{cardContent()}</View>
 }

+ 5 - 2
src/features/daynight/DayNightSwiper.tsx

@@ -100,9 +100,12 @@ export default function DayNightSwiper(props: { count: number }) {
 
     return <Swiper
         className="rn_swiper"
-        indicatorDots indicatorColor='#333'
+        indicatorDots 
+        indicatorColor='#333'
+        indicatorActiveColor='#999'
         current={current}
-        indicatorActiveColor='#999'>
+        
+        >
         <SwiperItem>
             <DayNightCard isNight={firstNight} count={props.count} />
         </SwiperItem>

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

@@ -326,7 +326,7 @@ export default function Component() {
                 // titleSize={t('page.choose_scenario.title_size')}
             />
             {
-                scenarios.length > 0 && <View style={{ position: 'relative', zIndex: 1 }}>
+                scenarios.length > 0 && <View style={{ position: 'relative', zIndex: 1,marginTop:20 }}>
                     <SingleSelect items={items()} itemSelect={handleItemSelect} selIndex={selIndex} />
                 </View>
             }

+ 2 - 26
src/features/trackTimeDuration/components/ConsolePicker.tsx

@@ -166,14 +166,14 @@ const Component = forwardRef((props: {
         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) + ' at ' + TimeFormatter.timeDescription(newDate)
         }
         return TimeFormatter.dateDescription(newDate, true) + ' ' + TimeFormatter.timeDescription(newDate)
     }
 
     function getEndTimestamp(timestamp) {
         if (global.language == 'en') {
-            return TimeFormatter.dateDescription(timestamp, true) + ' ' + TimeFormatter.timeDescription(timestamp)
+            return TimeFormatter.dateDescription(timestamp, true) + ' at ' + TimeFormatter.timeDescription(timestamp)
         }
         return TimeFormatter.dateDescription(timestamp, true) + ' ' + TimeFormatter.timeDescription(timestamp)
     }
@@ -203,30 +203,6 @@ const Component = forwardRef((props: {
         }
     }
 
-    function pickerTimeText2() {
-        if (props.isTimeout) {
-            if (props.isFast) {
-                return `原定于${getEndTimestamp(props.endTimestamp!)}结束`
-            }
-            else {
-                return `原定于${getEndTimestamp(props.endTimestamp!)}起床`
-            }
-        }
-        if (props.isFast) {
-            if (props.isEnd) {
-                return `原定于${getEndTimestamp(props.endTimestamp!)}结束`
-            }
-            return `预计${getEndTime()}结束`
-        }
-        else {
-            if (props.isEnd) {
-                return `原定于${getEndTimestamp(props.endTimestamp!)}起床`
-            }
-            return `预计${getEndTime()}起床`
-
-        }
-    }
-
     function pickerDetail() {
         return <View style={{ display: 'flex', flexDirection: 'column', opacity: loaded ? 1 : 0 }}>
             <Text className='modal_title' style={{ color: color }}>{props.title ? props.title : '测试标题 '}</Text>

+ 28 - 14
src/features/trackTimeDuration/components/IndexConsole.tsx

@@ -21,11 +21,12 @@ import showAlert from '@/components/basic/Alert';
 let useNavigation;
 
 let Linking;
-let JPush;
+let JPush, checkNotification;
 if (process.env.TARO_ENV == 'rn') {
     useNavigation = require("@react-navigation/native").useNavigation
     Linking = require('react-native').Linking;
     JPush = require('jpush-react-native').default;
+    checkNotification = require('@/utils/native_permission_check').checkNotification;
 }
 let operateType = ''
 let min = 0
@@ -59,9 +60,12 @@ export default function IndexConsole(props: { record: any }) {
     }
 
     useDidShow(() => {
-        wxPubFollow({ force_refresh: true }).then(res => {
-            dispatch(setWXFollow((res as any).wx_pub_followed));
-        })
+        if (process.env.TARO_ENV=='weapp'){
+            wxPubFollow({ force_refresh: true }).then(res => {
+                dispatch(setWXFollow((res as any).wx_pub_followed));
+            })
+        }
+        
     })
 
     useEffect(() => {
@@ -446,7 +450,7 @@ export default function IndexConsole(props: { record: any }) {
                                 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) }
+                                        { date: TimeFormatter.dateDescription(t1 + fastDuration, true), time: TimeFormatter.timeDescription(t1 + fastDuration) }
                                     ),
                                 showCancel: false,
                                 confirmText: t('feature.track_time_duration.reminders.ok')
@@ -456,7 +460,7 @@ export default function IndexConsole(props: { record: any }) {
                             showAlert({
                                 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) }
+                                    { date: TimeFormatter.dateDescription(t1 + fastDuration, true), time: TimeFormatter.timeDescription(t1 + fastDuration) }
                                 ),
                                 showCancel: true,
                                 cancelText: t('feature.track_time_duration.reminders.later'),
@@ -472,7 +476,7 @@ export default function IndexConsole(props: { record: any }) {
                                     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) }
+                                            { date: TimeFormatter.dateDescription(t1 + fastDuration, true), time: TimeFormatter.timeDescription(t1 + fastDuration) }
                                         ),
                                     showCancel: false,
                                     confirmText: t('feature.track_time_duration.reminders.ok')
@@ -482,17 +486,20 @@ export default function IndexConsole(props: { record: any }) {
                                 showAlert({
                                     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) }
+                                        { date: TimeFormatter.dateDescription(t1 + fastDuration, true), time: TimeFormatter.timeDescription(t1 + fastDuration) }
                                     ),
                                     showCancel: true,
                                     cancelText: t('feature.track_time_duration.reminders.later'),
                                     confirmText: t('feature.track_time_duration.reminders.open'),
                                     confirm: () => {
-                                        Linking.openURL('app-settings:notifications')
+                                        // Linking.openURL('app-settings:notifications')
+                                        checkNotification()
                                     }
                                 })
                             }
                         })
+
+
                     }
 
 
@@ -513,7 +520,7 @@ export default function IndexConsole(props: { record: any }) {
                                 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) }),
+                                        { date: TimeFormatter.dateDescription(t1 + sleepDuration, true), time: TimeFormatter.timeDescription(t1 + sleepDuration) }),
                                 showCancel: false,
                                 confirmText: t('feature.track_time_duration.reminders.ok')
                             })
@@ -523,7 +530,7 @@ export default function IndexConsole(props: { record: any }) {
                             showAlert({
                                 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) }),
+                                    { date: TimeFormatter.dateDescription(t1 + sleepDuration, true), time: TimeFormatter.timeDescription(t1 + sleepDuration) }),
                                 cancelText: t('feature.track_time_duration.reminders.later'),
                                 confirmText: t('feature.track_time_duration.reminders.open'),
                                 showCancel: true,
@@ -539,7 +546,7 @@ export default function IndexConsole(props: { record: any }) {
                                     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) }),
+                                            { date: TimeFormatter.dateDescription(t1 + sleepDuration, true), time: TimeFormatter.timeDescription(t1 + sleepDuration) }),
                                     showCancel: false,
                                     confirmText: t('feature.track_time_duration.reminders.ok')
                                 })
@@ -548,16 +555,23 @@ export default function IndexConsole(props: { record: any }) {
                                 showAlert({
                                     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) }),
+                                        { date: TimeFormatter.dateDescription(t1 + sleepDuration, true), time: TimeFormatter.timeDescription(t1 + sleepDuration) }),
                                     cancelText: t('feature.track_time_duration.reminders.later'),
                                     confirmText: t('feature.track_time_duration.reminders.open'),
                                     showCancel: true,
                                     confirm: () => {
-                                        Linking.openURL('app-settings:notifications')
+                                        checkNotification()
+                                        // Linking.openURL('app-settings:notifications')
                                     }
                                 })
                             }
                         })
+
+
+
+
+
+
                     }
 
                 }).catch((e) => {

+ 106 - 32
src/features/trackTimeDuration/components/SetSchedule.rn.tsx

@@ -22,15 +22,18 @@ import { jumpPage } from "../hooks/Common";
 import { rpxToPx, vibrate } from "@/utils/tools";
 import { PixelRatio } from "react-native";
 import { clientId } from "@/services/user";
+import showAlert from "@/components/basic/Alert";
 
 let useNavigation;
 
 let JPush;
 let Linking;
+let checkNotification;
 if (process.env.TARO_ENV == 'rn') {
     useNavigation = require("@react-navigation/native").useNavigation
     Linking = require('react-native').Linking;
     JPush = require('jpush-react-native').default;
+    checkNotification = require('@/utils/native_permission_check').checkNotification;
 }
 export default function Component() {
     const isFastFirst = true;
@@ -120,24 +123,8 @@ export default function Component() {
 
     function checkPermission() {
         start()
-        return
-        JPush.isNotificationEnabled((res) => {
-            console.log(res)
-            if (res) {
-                start()
-            }
-            else {
-                start()
-                // JPush.init({ appKey: "7cf918ada725a9e9aecc8a17", channel: "dev", production: false });
-                // JPush.getRegistrationID(obj => {
-                //     // alert('register id=' + obj.registerID)
-                //     global.registerID = obj.registerID
-                //     setTimeout(()=>{
-                //         clientId()
-                //     },3000)
-                // })
-            }
-        })
+        // const test = require('@/utils/push').default
+        // test()
     }
 
     function start() {
@@ -165,18 +152,22 @@ export default function Component() {
                     global.indexPageRefresh()
                 }
 
-                if (process.env.TARO_ENV == 'weapp') {
-                    Taro.navigateBack({ delta: 3 })
-                }
-                else {
-                    navigation.popToTop()
-                }
+                // if (process.env.TARO_ENV == 'weapp') {
+                //     Taro.navigateBack({ delta: 3 })
+                // }
+                // else {
+                //     navigation.popToTop()
+                // }
+
+                // setTimeout(() => {
+                popScheduleAlert(scenario, startTime)
+
+                // }, 1000)
             }).catch(e => {
                 setBtnDisable(false)
             })
         }
         else {
-            debugger
             if ((scenario.step == 'fast' && isFastFirst) || (scenario.step == 'sleep' && !isFastFirst)) {
                 var obj = JSON.parse(JSON.stringify(scenario))
                 if (isFastFirst) {
@@ -223,7 +214,6 @@ export default function Component() {
     }
 
     function commit() {
-        debugger
         setBtnDisable(true)
         setPlan({
             scenario: scenario.name,
@@ -243,20 +233,104 @@ export default function Component() {
                 global.checkData()
             }
 
-            if (global.indexPageRefresh){
+            if (global.indexPageRefresh) {
                 global.indexPageRefresh()
             }
 
 
-            if (process.env.TARO_ENV == 'weapp') {
-                Taro.navigateBack({ delta: 4 })
+            // if (process.env.TARO_ENV == 'weapp') {
+            //     Taro.navigateBack({ delta: 4 })
+            // }
+            // else {
+            //     navigation.popToTop()
+            // }
+
+            // setTimeout(() => {
+            popMixScheduleAlert(scenario.schedule.fast.start_time, startTime)
+
+            // }, 1000)
+
+        }).catch(e => {
+            setBtnDisable(false)
+        })
+    }
+
+    function popScheduleAlert(scenario, startTime) {
+        JPush.isNotificationEnabled((res) => {
+            if (res) {
+                showAlert({
+                    title: t('feature.track_time_duration.reminders.schedule_title'),
+                    content: scenario.name == 'FAST' ?
+                        t('feature.track_time_duration.reminders.enable_schedule_fast_content', { time: startTime }) :
+                        t('feature.track_time_duration.reminders.enable_schedule_sleep_content', { time: startTime }),
+                    showCancel: false,
+                    confirmText: t('feature.track_time_duration.reminders.ok'),
+                    cancel: () => {
+                        navigation.popToTop()
+                    },
+                    confirm: () => {
+                        navigation.popToTop()
+                    },
+                })
             }
             else {
-                navigation.popToTop()
+                showAlert({
+                    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'),
+                    showCancel: true,
+                    cancel: () => {
+                        navigation.popToTop()
+                    },
+                    confirm: () => {
+                        navigation.popToTop()
+                        checkNotification()
+                        // Linking.openURL('app-settings:notifications')
+                    }
+                })
             }
+        })
+    }
 
-        }).catch(e => {
-            setBtnDisable(false)
+    function popMixScheduleAlert(time1, time2) {
+        console.log(time1,time2)
+        JPush.isNotificationEnabled((res) => {
+            if (res) {
+                showAlert({
+                    title: t('feature.track_time_duration.reminders.schedule_title'),
+                    content: t('feature.track_time_duration.reminders.enable_schedule_mix_content', { time1: time1, time2: time2 }),
+                    showCancel: false,
+                    confirmText: t('feature.track_time_duration.reminders.ok'),
+                    cancel: () => {
+                        navigation.popToTop()
+                    },
+                    confirm: () => {
+                        navigation.popToTop()
+                    },
+                })
+            }
+            else {
+                showAlert({
+                    title: t('feature.track_time_duration.reminders.schedule_title'),
+                    content:
+                        t('feature.track_time_duration.reminders.schedule_mix_content'),
+                    cancelText: t('feature.track_time_duration.reminders.later'),
+                    confirmText: t('feature.track_time_duration.reminders.open'),
+                    showCancel: true,
+                    cancel: () => {
+                        navigation.popToTop()
+                    },
+                    confirm: () => {
+                        navigation.popToTop()
+                        checkNotification()
+                        // Linking.openURL('app-settings:notifications')
+                    }
+
+                })
+            }
         })
     }
 

+ 86 - 18
src/features/trackTimeDuration/components/SetSchedule.weapp.tsx

@@ -23,6 +23,7 @@ import { jumpPage } from "../hooks/Common";
 import { vibrate } from "@/utils/tools";
 import { wxPubFollow } from "@/services/permission";
 import { setWXFollow } from "@/store/permission";
+import showAlert from "@/components/basic/Alert";
 
 export default function Component() {
   const isFastFirst = true;
@@ -151,16 +152,14 @@ export default function Component() {
         // global.checkData()
         global.indexPageRefresh()
 
-        console.log('set schedule 3 navi back')
-        Taro.navigateBack({ delta: 3 }).then(res => {
+        popScheduleAlert(scenario, startTime)
+        // console.log('set schedule 3 navi back')
+        // Taro.navigateBack({ delta: 3 }).then(res => {
 
-        })
-
-        debugger
-        setTimeout(() => {
-          debugger
-          global.popScheduleAlert(scenario, startTime)
-        }, 1000)
+        // })
+        // setTimeout(() => {
+        //   global.popScheduleAlert(scenario, startTime)
+        // }, 1000)
       }).catch(e => {
         setBtnDisable(false)
       })
@@ -226,16 +225,12 @@ export default function Component() {
       }
     }).then(res => {
       setBtnDisable(false)
-      dispatch(setStep('fast'))
-      // global.checkData()
-      Taro.navigateBack({ delta: 4 })
-      console.log('set schedule 4 navi back')
+      // dispatch(setStep('fast'))
+      // // global.checkData()
+      // Taro.navigateBack({ delta: 4 })
+      // console.log('set schedule 4 navi back')
 
-      debugger
-      setTimeout(() => {
-        debugger
-        global.popMixScheduleAlert(scenario.schedule.fast.start_time, scenario.schedule.sleep.start_time)
-      }, 1000)
+      popMixScheduleAlert(scenario.schedule.fast.start_time, startTime)
 
 
 
@@ -245,6 +240,79 @@ export default function Component() {
     })
   }
 
+  function popScheduleAlert(scenario, startTime) {
+    if (permission.wxPubFollow) {
+      showAlert({
+        title: t('feature.track_time_duration.reminders.schedule_title'),
+        content: scenario.name == 'FAST' ?
+          t('feature.track_time_duration.reminders.enable_schedule_fast_content', { time: startTime }) :
+          t('feature.track_time_duration.reminders.enable_schedule_sleep_content', { time: startTime }),
+        showCancel: false,
+        confirmText: t('feature.track_time_duration.reminders.ok'),
+        cancel: () => {
+          Taro.navigateBack({ delta: 3 })
+        },
+        confirm: () => {
+          Taro.navigateBack({ delta: 3 })
+        }
+      })
+    }
+    else {
+      showAlert({
+        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'),
+        showCancel: true,
+        cancel: () => {
+          Taro.navigateBack({ delta: 3 })
+        },
+        confirm: () => {
+          Taro.navigateBack({ delta: 3 })
+          followWxPub()
+        }
+      })
+    }
+  }
+
+  function popMixScheduleAlert(time1, time2) {
+    if (permission.wxPubFollow) {
+      showAlert({
+        title: t('feature.track_time_duration.reminders.schedule_title'),
+        content: t('feature.track_time_duration.reminders.enable_schedule_mix_content', { time1: time1, time2: time2 }),
+        showCancel: false,
+        confirmText: t('feature.track_time_duration.reminders.ok'),
+        cancel: () => {
+          Taro.navigateBack({ delta: 4 })
+        },
+        confirm: () => {
+          Taro.navigateBack({ delta: 4 })
+        }
+      })
+    }
+    else {
+      showAlert({
+        title: t('feature.track_time_duration.reminders.schedule_title'),
+        content:
+          t('feature.track_time_duration.reminders.schedule_mix_content'),
+        cancelText: t('feature.track_time_duration.reminders.later'),
+        confirmText: t('feature.track_time_duration.reminders.open'),
+        showCancel: true,
+        cancel: () => {
+          Taro.navigateBack({ delta: 4 })
+        },
+        confirm: () => {
+          Taro.navigateBack({ delta: 4 })
+          followWxPub()
+        }
+
+      })
+
+    }
+  }
+
   function onStartTimeChange(e: string) {
     setIsTimeOpen(false)
     setBeginChange(true)

+ 5 - 5
src/features/trackTimeDuration/components/StreakItem.tsx

@@ -102,11 +102,11 @@ export default function StreakItem(props: { isFast: boolean, data: any }) {
                 </ScrollView>
         }
 
-        <View style={{ flexDirection: 'row', height: rpxToPx(36), overflow: 'hidden' }}>
+        <View style={{ flexDirection: 'row', height: rpxToPx(36), overflow: 'hidden',alignItems:'flex-end' }}>
             <Text className='streak_item_note'>{t('feature.track_time_duration.streaks.current')}</Text>
             {
-                props.data.current.num_days == 0 ? <Text className='streak_item_value' style={{ color: '#fff', opacity: 0.4 }}>{props.data.current.num_days}</Text> :
-                    <Text className='streak_item_value' style={{ color: props.isFast ? ColorType.fast : ColorType.sleep }}>{props.data.current.num_days}</Text>
+                props.data.current.num_days == 0 ? <Text className='streak_item_value' style={{ color: '#fff', opacity: 0.4,marginBottom:-2 }}>{props.data.current.num_days}</Text> :
+                    <Text className='streak_item_value' style={{ color: props.isFast ? ColorType.fast : ColorType.sleep,marginBottom:-2 }}>{props.data.current.num_days}</Text>
             }
             {
                 props.data.current.num_days == 0 ? <Text className='streak_item_note' style={{ color: '#fff', opacity: 0.4, fontWeight: 'bold' }}>{day(props.data.current.num_days)}</Text> :
@@ -115,9 +115,9 @@ export default function StreakItem(props: { isFast: boolean, data: any }) {
 
 
         </View>
-        <View style={{ marginTop: rpxToPx(16), flexDirection: 'row', height: rpxToPx(36), overflow: 'hidden' }}>
+        <View style={{ marginTop: rpxToPx(16), flexDirection: 'row', height: rpxToPx(36), overflow: 'hidden',alignItems:'flex-end' }}>
             <Text className='streak_item_note'>{t('feature.track_time_duration.streaks.longest')}</Text>
-            <Text className='streak_item_value' style={{ color: '#fff', opacity: 0.4 }}>{props.data.longest.num_days}</Text>
+            <Text className='streak_item_value' style={{ color: '#fff', opacity: 0.4,marginBottom:-2 }}>{props.data.longest.num_days}</Text>
             <Text className='streak_item_note' style={{ fontWeight: 'bold' }}>{day(props.data.longest.num_days)}</Text>
         </View>
     </View>

+ 72 - 10
src/features/trackTimeDuration/components/Streaks.scss

@@ -1,4 +1,5 @@
-.streaks_title{
+@import '@/utils/common.scss';
+.streaks_title {
     display: flex;
     font-weight: bold;
     font-size: 48px;
@@ -9,7 +10,7 @@
     color: #fff;
 }
 
-.streaks_content{
+.streaks_content {
     margin-left: 46px;
     margin-right: 46px;
     display: flex;
@@ -17,7 +18,7 @@
     justify-content: space-between;
 }
 
-.streaks_item{
+.streaks_item {
     width: 318px;
     background-color: #1C1C1C;
     box-sizing: border-box;
@@ -28,21 +29,21 @@
     padding-bottom: 40px;
 }
 
-.streaks_item_header{
+.streaks_item_header {
     display: flex;
     flex-direction: row;
     justify-content: space-between;
     align-items: center;
 }
 
-.streak_item_type{
+.streak_item_type {
     font-size: 32px;
     line-height: 32px;
     color: #fff;
     opacity: 0.6;
 }
 
-.streak_item_point_bg{
+.streak_item_point_bg {
     display: flex;
     flex-direction: row;
     align-items: center;
@@ -50,7 +51,7 @@
     margin-bottom: 58px;
 }
 
-.scroll_point_bg{
+.scroll_point_bg {
     display: flex;
     flex-direction: row;
     // align-items: center;
@@ -64,7 +65,7 @@
     height: 28px;
 }
 
-.streak_item_point{
+.streak_item_point {
     height: 28px;
     width: 28px;
     border-radius: 14px;
@@ -73,18 +74,79 @@
     flex-shrink: 0;
 }
 
-.streak_item_note{
+.streak_item_note {
     font-size: 24px;
     line-height: 24px;
     color: #fff;
     opacity: 0.4;
 }
 
-.streak_item_value{
+.streak_item_value {
     font-size: 36px;
     line-height: 36px;
     font-weight: bold;
     margin-left: 6px;
     margin-right: 4px;
     height: 36px;
+}
+
+.streaks_countdown_bg {
+    padding-left: 46px;
+    padding-right: 46px;
+    padding-top: 20px;
+    padding-bottom: 20px;
+    display: flex;
+    flex-direction: column;
+}
+
+.streak_countdown_item {
+    height: 32px;
+    line-height: 32px;
+    margin-right: 24px;
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+}
+
+.streak_point {
+    width: 12px;
+    height: 12px;
+    border-radius: 6px;
+    background-color: #fff;
+    opacity: 0.4;
+    margin-right: 10px;
+}
+
+
+/* #ifdef weapp */
+.streak_countdown_title {
+    font-size: 18px;
+    font-weight: bold;
+    background: linear-gradient(90deg, $fastColor 0%, $sleepColor 100%);
+    -webkit-background-clip: text;
+    background-clip: text;
+    color: transparent;
+}
+
+
+/* #endif */
+
+/* #ifdef rn */
+.streak_countdown_title {
+    font-size: 18px;
+    font-weight: bold;
+    // background: linear-gradient(90deg, $fastColor 0%, $sleepColor 100%);
+    -webkit-background-clip: text;
+    background-clip: text;
+    color: transparent;
+}
+
+
+/* #endif */
+
+.streak_countdown_value {
+    color: #fff;
+    opacity: 0.4;
+    font-size: 18px;
+    letter-spacing: 0;
 }

+ 57 - 4
src/features/trackTimeDuration/components/Streaks.tsx

@@ -5,27 +5,55 @@ import StreakItem from './StreakItem'
 import { useEffect, useState } from 'react'
 import { getStreaks } from '@/services/trackTimeDuration'
 import dayjs from 'dayjs'
+import { TimeFormatter } from '@/utils/time_format'
+import { rpxToPx } from '@/utils/tools'
 
-export default function Streaks() {
+let GradientText
+
+if (process.env.TARO_ENV == 'rn') {
+    GradientText = require('@/components/basic/GradientText').default
+}
+
+export default function Streaks(props: { count: number }) {
     const { t } = useTranslation()
-    const [fastStreaks, setFastStreaks] = useState(null)
-    const [sleepStreaks, setSleepStreaks] = useState(null)
+    const [fastStreaks, setFastStreaks] = useState<any>(null)
+    const [sleepStreaks, setSleepStreaks] = useState<any>(null)
+    const [isLoading, setIsLoading] = useState(false)
 
     useEffect(() => {
         getDatas()
     }, [])
 
+    useEffect(() => {
+        if (!isLoading) {
+            var now = new Date().getTime()
+            if (fastStreaks && fastStreaks.current.reset_ts && now >= fastStreaks.current.reset_ts) {
+                getDatas()
+                return
+            }
+            if (sleepStreaks && sleepStreaks.current.reset_ts && now >= sleepStreaks.current.reset_ts) {
+                getDatas()
+            }
+
+        }
+    }, [props.count])
+
     global.refreshStreaks = () => {
         getDatas()
     }
 
     function getDatas() {
+        setIsLoading(true)
         var a = dayjs().format('YYYYMMDD')
-        getStreaks({date:a}).then(res => {
+        getStreaks({ date: a }).then(res => {
+            console.log('streak', res)
             if (res) {
                 setFastStreaks((res as any).fast)
                 setSleepStreaks((res as any).sleep)
             }
+            setIsLoading(false)
+        }).catch(e => {
+            setIsLoading(false)
         })
     }
 
@@ -36,5 +64,30 @@ export default function Streaks() {
             <StreakItem isFast={true} data={fastStreaks} />
             <StreakItem isFast={false} data={sleepStreaks} />
         </View>
+        {
+            (fastStreaks.current.reset_ts || sleepStreaks.current.reset_ts) &&
+            <View className='streaks_countdown_bg'>
+                <View className='streak_countdown_item'>
+                    {
+                        process.env.TARO_ENV == 'weapp' ? <Text className='streak_countdown_title'>{t('feature.track_time_duration.streaks.countdown_title', { name: (fastStreaks.current.reset_ts && sleepStreaks.current.reset_ts) ? 'streaks' : 'streak' })}</Text> :
+                            <GradientText style={{ fontSize: rpxToPx(18), fontWeight: 'bold' }}>{t('feature.track_time_duration.streaks.countdown_title', { name: (fastStreaks.current.reset_ts && sleepStreaks.current.reset_ts) ? 'streaks' : 'streak' })}</GradientText>
+
+                    }
+                </View>
+                {
+                    fastStreaks.current.reset_ts && <View className='streak_countdown_item'>
+                        <View className='streak_point' />
+                        <Text className='streak_countdown_value'>{t('feature.track_time_duration.streaks.countdown_fast', { time: TimeFormatter.countdown(fastStreaks.current.reset_ts) })}</Text>
+                    </View>
+                }
+                {
+                    sleepStreaks.current.reset_ts && <View className='streak_countdown_item'>
+                        <View className='streak_point' />
+                        <Text className='streak_countdown_value'>{t('feature.track_time_duration.streaks.countdown_sleep', { time: TimeFormatter.countdown(sleepStreaks.current.reset_ts) })}</Text>
+                    </View>
+                }
+            </View>
+        }
+
     </View>
 }

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

@@ -60,7 +60,10 @@ export default function Component(props: { data: any, title?: string, subTitle?:
     }
 
     function goSetting() {
-        Linking.openURL('app-settings:notifications')
+        var checkNotification = require('@/utils/native_permission_check').checkNotification;
+        checkNotification()
+        
+        // Linking.openURL('app-settings:notifications')
     }
 
 

+ 1 - 1
src/features/trackTimeDuration/components/TitleView.scss

@@ -1,5 +1,5 @@
 .title_view{
-    height: 172px;
+    // height: 172px;
     box-sizing: border-box;
     width: 750px;
     padding-left: 46px;

+ 51 - 8
src/features/trackTimeDuration/components/WeekCalendar.tsx

@@ -1,4 +1,4 @@
-import { View, ScrollView, Text } from "@tarojs/components";
+import { View, ScrollView, Text, Swiper, SwiperItem } from "@tarojs/components";
 import './WeekCalendar.scss'
 import { useEffect, useState, useMemo, memo, useRef } from "react";
 import { ColorType } from "@/context/themes/color";
@@ -34,7 +34,7 @@ const WeekCalendar = memo(() => {
     const [isLoading, setIsLoading] = useState(false)
     const { t } = useTranslation()
     const ref = useRef(null)
-    const pageSize = 4
+    const pageSize = 40
 
     useEffect(() => {
         // pageIndex = -1
@@ -133,7 +133,7 @@ const WeekCalendar = memo(() => {
 
         // var page = parseInt(x / parseInt(rpxToPx(658) + '') + '')
         var page = Math.round(x / parseInt(rpxToPx(658) + ''))
-        console.log(page,x)
+        console.log(page, x)
 
         if (current != page && page < calendars.length && page >= 0) {
             lastFastValue = calendars[current].summary_stats.fast.avg
@@ -155,6 +155,15 @@ const WeekCalendar = memo(() => {
         // }, 300) as any
     }
 
+    function onChange(e) {
+        var page = e.detail.current
+        lastFastValue = calendars[current].summary_stats.fast.avg
+        lastSleepValue = calendars[current].summary_stats.sleep.avg
+        setCurrent(page)
+        setSummary(calendars[page].summary_stats ? calendars[page].summary_stats : null)
+        setCalendarData(calendars[page])
+    }
+
 
     function getDate(timestamp) {
         var date = new Date(timestamp)
@@ -184,6 +193,19 @@ const WeekCalendar = memo(() => {
         }
     }
 
+    function showWeeklyItem(index){
+        if (process.env.TARO_ENV=='weapp'){
+            if (index >= current - 1 && index <= current + 1){
+                return true
+            }
+            return false
+        }
+        if (index >= current - 2 && index <= current + 2){
+            return true
+        }
+        return false
+    }
+
     if (!calendarData)
         return <View />
     return <View style={{ display: 'flex', flexDirection: 'column' }}>
@@ -237,21 +259,42 @@ const WeekCalendar = memo(() => {
                         width: parseInt(rpxToPx(658) + ''),
                     }} /> :
                         <LinearGradient style={{
-                            position:'absolute',
+                            position: 'absolute',
                             left: parseInt(rpxToPx(46) + ''),
                             right: parseInt(rpxToPx(46) + ''),
                             top: parseInt(rpxToPx(60) + ''),
                             bottom: parseInt(rpxToPx(60) + ''),
                             width: parseInt(rpxToPx(658) + ''),
-                            zIndex:-1
+                            zIndex: -1
                         }}
-                            colors={['#1C1C1C','#000000','#1C1C1C']}
+                            colors={['#1C1C1C', '#000000', '#1C1C1C']}
                             start={{ x: 0, y: 0 }}
                             end={{ x: 0, y: 1 }} />
                 }
 
                 <View>
-                    <ScrollView
+                    <Swiper
+                        current={current}
+                        onChange={onChange}
+                        style={{
+                            marginLeft: parseInt(rpxToPx(46) + ''),
+                            width: parseInt(rpxToPx(658) + ''),
+                            height: parseInt(rpxToPx(520) + ''),
+                            flexDirection: 'row', display: 'flex',
+                        }}>
+                        {
+                            calendars.map((item, index) => {
+                                return <SwiperItem key={index}>
+                                    {
+                                        showWeeklyItem(index) ?
+                                            <WeekCalendarItem data={item} isCurrentWeek={index == calendars.length - 1} /> :
+                                            <View style={{ width: parseInt(rpxToPx(658) + ''), flexShrink: 0 }} />
+                                    }
+                                </SwiperItem>
+                            })
+                        }
+                    </Swiper>
+                    {/* <ScrollView
                         style={{
                             marginLeft: parseInt(rpxToPx(46) + ''),
                             width: parseInt(rpxToPx(658) + ''),
@@ -277,7 +320,7 @@ const WeekCalendar = memo(() => {
                             })
                         }
 
-                    </ScrollView>
+                    </ScrollView> */}
                 </View>
                 <View className="chart_times" style={{ marginTop: parseInt(rpxToPx(60) + ''), marginBottom: parseInt(rpxToPx(60) + '') }}>
                     <Text className="chart_times_txt" style={{ left: 0, top: 0 }}>12:00</Text>

+ 52 - 9
src/features/trackTimeDuration/components/WeekCalendarItem.tsx

@@ -5,6 +5,8 @@ import { useEffect, useState } from "react";
 import { ColorType } from "@/context/themes/color";
 import { TimeFormatter } from "@/utils/time_format";
 import dayjs from 'dayjs'
+import showAlert from "@/components/basic/Alert";
+import { title } from "process";
 
 const utc = require('dayjs/plugin/utc')
 const timezone = require('dayjs/plugin/timezone')
@@ -45,19 +47,53 @@ export default function WeekCalendarItem(props: { data: any, isCurrentWeek: bool
                 fasts,
                 sleeps
             })
-            props.data.list.map((item) => {
+
+
+            props.data.list.map((item, index) => {
                 var isFast = item.scenario == 'FAST'
 
                 var real_start = item.real_start_time
                 var real_end = item.real_end_time
-                if (item.real_end_time_zone_id){
-                    var strEnd = dayjs(real_end).tz(item.real_end_time_zone_id).format('YYYY-MM-DD HH:mm:ss')
-                    var duration = real_end-real_start
-                    real_end = new Date(strEnd)
-                    real_start = real_end-duration
+
+                if (item.real_end_time_zone_id) {
+
+
+                    var strEnd = dayjs(real_end).tz(item.real_end_time_zone_id).format('YYYY-MM-DDTHH:mm:ss')
+                    var duration = real_end - real_start
+                    // if (index = 1) {
+                    //     if (new Date(strEnd)) {
+                    //         // 示例字符串
+                    //         var isoString = '2021-04-01T15:20:00';
+
+                    //         // 将字符串转换为Date对象
+                    //         var date = new Date(strEnd);
+
+                    //         showAlert({
+                    //             title: strEnd,
+                    //             content: date.getTime()+''
+                    //         })
+                    //     }
+                    //     else {
+                    //         showAlert({
+                    //             title: strEnd,
+                    //             content: '转换失败'
+                    //         })
+                    //     }
+
+                    // }
+
+
+                    real_end = new Date(strEnd).getTime()
+                    real_start = real_end - duration
                 }
 
+
+
                 var range = getIntersection(start, end, real_start, real_end)
+
+
+
+
                 if (range) {
                     var begin = (range[0] - start) / (24 * 3600 * 1000)
                     var height = (range[1] - range[0]) / (24 * 3600 * 1000)
@@ -76,6 +112,12 @@ export default function WeekCalendarItem(props: { data: any, isCurrentWeek: bool
             })
         }
         setCharts(array)
+        // if (array.length>0 && props.isCurrentWeek){
+        //     showAlert({
+        //         title:'111',
+        //         content:JSON.stringify(props.data)
+        //     })
+        // }
 
         return () => {
             timer && clearInterval(timer)
@@ -128,6 +170,7 @@ export default function WeekCalendarItem(props: { data: any, isCurrentWeek: bool
             return [intersectionStart, intersectionEnd];
         } else {
             // 不存在相交时间戳
+
             return null;
         }
     }
@@ -174,12 +217,12 @@ export default function WeekCalendarItem(props: { data: any, isCurrentWeek: bool
             <View className="horizontalLine" style={{ top: rpxToPx(300), backgroundColor: '#262626' }} />
             {
                 charts.map((item, index) => {
-                    return <View className="lineContent" key={index*9527} style={{ left: rpxToPx(94 * index) }}>
+                    return <View className="lineContent" key={index * 9527} style={{ left: rpxToPx(94 * index) }}>
                         {
                             (item as any).fasts.length > 0 &&
                             <View className="lineBgView">
                                 {
-                                    (item as any).fasts.map((obj,k) => {
+                                    (item as any).fasts.map((obj, k) => {
                                         return <View key={k} className="detailLine" style={{
                                             backgroundColor: ColorType.fast,
                                             top: rpxToPx(obj.begin * 400),
@@ -194,7 +237,7 @@ export default function WeekCalendarItem(props: { data: any, isCurrentWeek: bool
                             (item as any).sleeps.length > 0 &&
                             <View className="lineBgView">
                                 {
-                                    (item as any).sleeps.map((obj,j) => {
+                                    (item as any).sleeps.map((obj, j) => {
                                         return <View key={j} className="detailLine" style={{
                                             backgroundColor: ColorType.sleep,
                                             top: rpxToPx(obj.begin * 400),

+ 4 - 0
src/pages/account/EditPage.tsx

@@ -40,10 +40,14 @@ export default function Page() {
     useEffect(() => {
         if (process.env.TARO_ENV == 'rn') {
             setValue(router.params.name as any)
+
+            navigation.setOptions({ title: t('page.edit_nickname.title') ?? '' });
+
             return
         }
         setTimeout(() => {
             setValue(router.params.name as any)
+
             // setValue(user.nickname)
         }, 300)
     }, [])

+ 24 - 2
src/pages/account/Profile.tsx

@@ -16,6 +16,7 @@ import Tabbar from "@/components/navigation/TabBar";
 import { getInfoSuccess } from "@/store/user";
 import TitleView from "@/features/trackTimeDuration/components/TitleView";
 import showAlert from "@/components/basic/Alert";
+import { rpxToPx } from "@/utils/tools";
 
 let useNavigation;
 if (process.env.TARO_ENV == 'rn') {
@@ -65,7 +66,7 @@ export default function Page() {
             title: t('feature.common.modal.reset_session_title'),
             content: t('feature.common.modal.reset_session_content'),
             showCancel: false,
-            confirm:()=>{
+            confirm: () => {
                 delSession({ type: 'WX_MP' })
             }
         })
@@ -182,6 +183,27 @@ export default function Page() {
             } */}
 
             {
+                user.isLogin && user.test_user && <View>
+                    <View className="cell_top" onClick={clearF}>
+                        <Text className="cell_title">user_id</Text>
+                        <Text className="cell_value">{user.id.substring(0, 6)}***{user.id.substring(user.id.length - 10, user.id.length)}</Text>
+                        <Image className="cell_arrow" src={require('@/assets/images/arrow3.png')} />
+                    </View>
+                    <View className="cell_line" style={{ marginLeft: rpxToPx(46), marginRight: rpxToPx(46) }}></View>
+                    <View className="cell_center" onClick={reset}>
+                        <Text className="cell_title">session</Text>
+                        <Text className="cell_value">{t('page.more.reset_session')}</Text>
+                        <Image className="cell_arrow" src={require('@/assets/images/arrow3.png')} />
+                    </View>
+                    <View className="cell_line" style={{ marginLeft: rpxToPx(46), marginRight: rpxToPx(46) }}></View>
+                    <View className="cell_bottom">
+                        <Text className="cell_title">{t('page.more.debug_mode')}</Text>
+                        <Switch checked={switchOn} onChange={switchChanged} />
+                    </View>
+                </View>
+            }
+
+            {/* {
                 user.isLogin && user.test_user && <TableCell title="user_id" showArrow={true} onClick={clearF}>
                     <Text style={{ opacity: 0.8 }}>{user.id.substring(0, 6)}***{user.id.substring(user.id.length - 10, user.id.length)}</Text>
                 </TableCell>
@@ -195,7 +217,7 @@ export default function Page() {
                 user.isLogin && user.test_user && <TableCell title={t('page.more.debug_mode')} >
                     <Switch checked={switchOn} onChange={switchChanged} />
                 </TableCell>
-            }
+            } */}
             <View style={{ height: 40 }}></View>
 
             {/* <Text>未更改前的1px线</Text>

+ 4 - 0
src/pages/account/ProfileSetting.tsx

@@ -39,6 +39,10 @@ export default function Page() {
         Taro.setNavigationBarTitle({
             title: t('page.user_profile.title')
         })
+
+        if (process.env.TARO_ENV == 'rn') {
+            navigation.setOptions({ title: t('page.user_profile.title') ?? '' });
+        }
     }, [])
 
     function editNickname() {

+ 18 - 0
src/pages/account/Setting.tsx

@@ -18,6 +18,8 @@ if (process.env.TARO_ENV == 'rn') {
     useNavigation = require("@react-navigation/native").useNavigation
 }
 
+let hasCache = false;
+
 export default function Page() {
     const dispatch = useDispatch();
     const { t } = useTranslation()
@@ -31,6 +33,14 @@ export default function Page() {
         Taro.setNavigationBarTitle({
             title: t('page.setting.title')
         })
+
+        if (process.env.TARO_ENV == 'rn') {
+            navigation.setOptions({ title: t('page.setting.title') ?? '' });
+        }
+
+        Taro.getStorage({ key: 'notification' }).then(res => {
+            hasCache = true;
+        })
     }, [])
     function logoutF() {
 
@@ -41,6 +51,14 @@ export default function Page() {
             confirm: () => {
                 logout().then(res => {
                     dispatch(logoutSuccess())
+
+                    if (hasCache) {
+                        Taro.setStorage({
+                            key: 'notification',
+                            data: true
+                        })
+                    }
+                    
                     if (process.env.TARO_ENV == 'weapp') {
                         Taro.switchTab({
                             url: '/pages/clock/Clock'

+ 3 - 1
src/pages/clock/Clock.scss

@@ -21,7 +21,9 @@
 
 .rn_swiper{
     width: 750px;
-    height: 300px;
+    height: 280px;
+    margin-bottom: 5px;
+    // background-color: oldlace;
     // background-color: red;
     // margin-bottom: 20px;
 }

+ 139 - 44
src/pages/clock/Clock.tsx

@@ -67,6 +67,7 @@ let needScroll = false;
 let showUpdate = false;
 let Linking;
 let JPush;
+let checkNotification, uploadPermissions;
 
 if (process.env.TARO_ENV == 'rn') {
     JPush = require('jpush-react-native').default;
@@ -74,6 +75,8 @@ if (process.env.TARO_ENV == 'rn') {
     AppState = require("react-native").AppState
     GradientText = require('@/components/basic/GradientText').default
     useNavigation = require("@react-navigation/native").useNavigation
+    checkNotification = require('@/utils/native_permission_check').checkNotification;
+    uploadPermissions = require('@/utils/native_permission_check').uploadPermissions;
 }
 
 const defaultValue = `[{"scenario":{"name":"FAST_SLEEP","count":0,"schedule":{"fast":{"start_time":"15:00","end_time":"08:00"},"sleep":{"start_time":"22:00","end_time":"07:00"}}},"current_record":{"scenario":"FAST_SLEEP","status":"WAIT_FOR_START","fast":{"status":"WAIT_FOR_START","target_start_time":1710514800000,"target_end_time":1710576000000},"sleep":{"status":"WAIT_FOR_START","target_start_time":1710540000000,"target_end_time":1710572400000}},"wx_pub_followed":false,"time_input_schema":{"min":60,"max":1380,"step":5},"theme_color":{"fast":"#00FFFF","sleep":"#8183FF"}},{"scenarios":[{"name":"FAST","count":0,"schedule":{"fast":{"start_time":"15:00","end_time":"08:00"}}},{"name":"SLEEP","count":0,"schedule":{"sleep":{"start_time":"22:00","end_time":"07:00"}}},{"name":"FAST_SLEEP","count":0,"schedule":{"fast":{"start_time":"15:00","end_time":"08:00"},"sleep":{"start_time":"22:00","end_time":"07:00"}}}],"select_count":0,"theme_color":{"fast":"#00FFFF","sleep":"#8183FF"}}]`
@@ -137,14 +140,28 @@ export default function Page() {
     }, [])
 
     useEffect(() => {
+
         if (process.env.TARO_ENV == 'weapp') {
             loadWXCache()
         }
         else {
             loadRNCache()
+            // const test = require('@/utils/push').default
+            // test()
         }
 
         if (process.env.TARO_ENV == 'rn') {
+            JPush.setBadge({
+                badge: 0,
+                appBadge: 0
+            })
+            JPush.isNotificationEnabled((res) => {
+                if (res) {
+                    const test = require('@/utils/push').default
+                    test()
+                }
+            })
+
             AppState.addEventListener('change', handleAppStateChange);
         }
 
@@ -154,6 +171,8 @@ export default function Page() {
         getCheckData()
         // global.pauseIndexTimer = !user.isLogin
 
+
+
         if (user.isLogin) {
             uploadUserClient();
             checkAuthorized();
@@ -161,6 +180,7 @@ export default function Page() {
             checkAddToMini();
 
             if (process.env.TARO_ENV == 'rn') {
+                uploadPermissions()
                 JPush.isNotificationEnabled((res) => {
                     if (res) {
                         const test = require('@/utils/push').default
@@ -293,7 +313,22 @@ export default function Page() {
     }
 
     const handleAppStateChange = (nextAppState) => {
+        console.log(nextAppState)
+        if (nextAppState!='active'){
+            return
+        }
         checkTimeZone()
+
+        if (user.isLogin) {
+            uploadPermissions()
+        }
+
+        if (process.env.TARO_ENV == 'rn') {
+            JPush.setBadge({
+                badge: 0,
+                appBadge: 0
+            })
+        }
     };
 
     function checkTimeZone() {
@@ -317,7 +352,7 @@ export default function Page() {
                     //     global.refreshDay()
                     // }
                     if (global.currentStatus != 'WAIT_FOR_START') {
-                        Taro.showModal({
+                        showAlert({
                             title: t('feature.track_time_duration.change_tz_alert.title'),
                             content: t('feature.track_time_duration.change_tz_alert.content', { tz: timeZoneFormatted }),
                             showCancel: false,
@@ -543,60 +578,118 @@ export default function Page() {
     }
 
     global.popScheduleAlert = (scenario, startTime) => {
-        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', { time: startTime }) :
-                    t('feature.track_time_duration.reminders.enable_schedule_sleep_content', { time: startTime }),
-                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) {
+        if (process.env.TARO_ENV == 'weapp') {
+            if (permission.wxPubFollow) {
+                showAlert({
+                    title: t('feature.track_time_duration.reminders.schedule_title'),
+                    content: scenario.name == 'FAST' ?
+                        t('feature.track_time_duration.reminders.enable_schedule_fast_content', { time: startTime }) :
+                        t('feature.track_time_duration.reminders.enable_schedule_sleep_content', { time: startTime }),
+                    showCancel: false,
+                    confirmText: t('feature.track_time_duration.reminders.ok')
+                })
+            }
+            else {
+                showAlert({
+                    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'),
+                    showCancel: true,
+                    confirm: () => {
                         followWxPub()
-                    } else if (res.cancel) {
                     }
+                })
+            }
+        }
+        else {
+            JPush.isNotificationEnabled((res) => {
+                if (res) {
+                    showAlert({
+                        title: t('feature.track_time_duration.reminders.schedule_title'),
+                        content: scenario.name == 'FAST' ?
+                            t('feature.track_time_duration.reminders.enable_schedule_fast_content', { time: startTime }) :
+                            t('feature.track_time_duration.reminders.enable_schedule_sleep_content', { time: startTime }),
+                        showCancel: false,
+                        confirmText: t('feature.track_time_duration.reminders.ok')
+                    })
+                }
+                else {
+                    showAlert({
+                        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'),
+                        showCancel: true,
+                        confirm: () => {
+                            checkNotification()
+                            // Linking.openURL('app-settings:notifications')
+                        }
+                    })
                 }
             })
         }
+
     }
 
     global.popMixScheduleAlert = (time1, time2) => {
-        if (permission.wxPubFollow) {
-            Taro.showModal({
-                title: t('feature.track_time_duration.reminders.schedule_title'),
-                content: t('feature.track_time_duration.reminders.enable_schedule_mix_content', { time1: time1, time2: time2 }),
-                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.schedule_mix_content'),
-                cancelText: t('feature.track_time_duration.reminders.later'),
-                confirmText: t('feature.track_time_duration.reminders.open'),
-                success: function (res) {
-                    if (res.confirm) {
+        if (process.env.TARO_ENV == 'weapp') {
+            if (permission.wxPubFollow) {
+                showAlert({
+                    title: t('feature.track_time_duration.reminders.schedule_title'),
+                    content: t('feature.track_time_duration.reminders.enable_schedule_mix_content', { time1: time1, time2: time2 }),
+                    showCancel: false,
+                    confirmText: t('feature.track_time_duration.reminders.ok')
+                })
+            }
+            else {
+                showAlert({
+                    title: t('feature.track_time_duration.reminders.schedule_title'),
+                    content:
+                        t('feature.track_time_duration.reminders.schedule_mix_content'),
+                    cancelText: t('feature.track_time_duration.reminders.later'),
+                    confirmText: t('feature.track_time_duration.reminders.open'),
+                    showCancel: true,
+                    confirm: () => {
                         followWxPub()
-                    } else if (res.cancel) {
                     }
+
+                })
+
+            }
+        }
+        else {
+            JPush.isNotificationEnabled((res) => {
+                if (res) {
+                    showAlert({
+                        title: t('feature.track_time_duration.reminders.schedule_title'),
+                        content: t('feature.track_time_duration.reminders.enable_schedule_mix_content', { time1: time1, time2: time2 }),
+                        showCancel: false,
+                        confirmText: t('feature.track_time_duration.reminders.ok')
+                    })
                 }
+                else {
+                    showAlert({
+                        title: t('feature.track_time_duration.reminders.schedule_title'),
+                        content:
+                            t('feature.track_time_duration.reminders.schedule_mix_content'),
+                        cancelText: t('feature.track_time_duration.reminders.later'),
+                        confirmText: t('feature.track_time_duration.reminders.open'),
+                        showCancel: true,
+                        confirm: () => {
+                            checkNotification()
+                            // Linking.openURL('app-settings:notifications')
+                        }
 
+                    })
+                }
             })
-
         }
+
     }
 
     function followWxPub() {
@@ -674,9 +767,11 @@ export default function Page() {
     function render() {
         if (!loaded) {
             return <Layout type={TemplateType.customHeader} header={headerView()} title={t('page.clock.title')} titleShowStyle={NaviBarTitleShowType.scrollToShow}>
-                <View style={{ width: rpxToPx(750), height: rpxToPx(900), display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
+                <View style={{ width: rpxToPx(750), height: rpxToPx(900), display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center' }}>
                     <AtActivityIndicator size={40} color="#fff" />
-                    <Tabbar index={0} />
+                    {
+                        process.env.TARO_ENV == 'weapp' && <Tabbar index={0} />
+                    }
                 </View>
             </Layout>
         }
@@ -760,7 +855,7 @@ export default function Page() {
                     </View>
                 }
                 {
-                    user.isLogin && <Streaks />
+                    user.isLogin && <Streaks count={count} />
                 }
 
                 {

+ 12 - 5
src/pages/clock/StreakDetail.tsx

@@ -164,7 +164,14 @@ export default function StreakDetail() {
         return '天'
     }
 
-    function space(){
+    function count(num) {
+        if (global.language == 'en') {
+            return `Total ${num} ${num == 1 ? 'record' : 'records'}`
+        }
+        return `共${num}条记录`
+    }
+
+    function space() {
         if (global.language == 'en') {
             return ' '
         }
@@ -175,8 +182,8 @@ export default function StreakDetail() {
         <View>
             <View className='seg_bg'>
                 <Segment titles={[
-                     `${t('feature.track_time_duration.streaks.current')}${space()}${intro.current.num_days}${space()}${day(intro.current.num_days)}`,
-                     `${t('feature.track_time_duration.streaks.longest')}${space()}${intro.longest.num_days}${space()}${day(intro.longest.num_days)}`,
+                    `${t('feature.track_time_duration.streaks.current')}${space()}${intro.current.num_days}${space()}${day(intro.current.num_days)}`,
+                    `${t('feature.track_time_duration.streaks.longest')}${space()}${intro.longest.num_days}${space()}${day(intro.longest.num_days)}`,
                 ]}
                     subTitles={getSubTitles()}
                     changed={(e) => {
@@ -225,10 +232,10 @@ export default function StreakDetail() {
                 loaded && segmentIndex == 1 && longest.length == 0 && <Text className='empty'>{t('feature.track_time_duration.streaks.no_data')}</Text>
             }
             {
-                loaded && segmentIndex == 0 && currents.length > 0 && <Text className='detail_count'>{currents.length}条记录</Text>
+                loaded && segmentIndex == 0 && currents.length > 0 && <Text className='detail_count'>{count(currents.length)}</Text>
             }
             {
-                loaded && segmentIndex == 1 && longest.length > 0 && <Text className='detail_count'>{longest.length}条记录</Text>
+                loaded && segmentIndex == 1 && longest.length > 0 && <Text className='detail_count'>{count(longest.length)}</Text>
             }
         </View>
     </Layout>

+ 29 - 14
src/pages/common/H5.tsx

@@ -5,30 +5,45 @@ import { useEffect } from "react";
 import { useTranslation } from "react-i18next";
 
 
-let useRoute;
+let useRoute,useNavigation;
 if (process.env.TARO_ENV == 'rn') {
     useRoute = require("@react-navigation/native").useRoute
+    useNavigation = require("@react-navigation/native").useNavigation
     // useNavigation = require("@react-navigation/native").useNavigation
 }
-export default function Page(){
-    const {t} = useTranslation()
+export default function Page() {
+    const { t } = useTranslation()
+
+    let navigation;
+    if (useNavigation) {
+        navigation = useNavigation()
+    }
+
+
     let router;
-    if (process.env.TARO_ENV=='weapp'){
+    if (process.env.TARO_ENV == 'weapp') {
         router = useRouter();
     }
     else {
         router = useRoute()
     }
-    
-
-    useEffect(()=>{
-        Taro.setNavigationBarTitle({
-            title:router.params.title??''
-            // title:t('feature.track_time_duration.follow_wx_pub.title')
-        })
-    },[])
-    
+
+
+    useEffect(() => {
+        
+
+        if (process.env.TARO_ENV == 'rn') {
+            navigation.setOptions({ title: router.params.title ?? '' });
+        }
+        else {
+            Taro.setNavigationBarTitle({
+                title: router.params.title ?? ''
+                // title:t('feature.track_time_duration.follow_wx_pub.title')
+            })
+        }
+    }, [])
+
     return (
-        <WebView style={{display:'flex',flex:1}} src={router.params.url as string} />
+        <WebView style={{ display: 'flex', flex: 1 }} src={router.params.url as string} />
     )
 }

+ 18 - 21
src/pages/common/RecordsHistory.tsx

@@ -17,6 +17,7 @@ import { useTranslation } from "react-i18next";
 import './RecordsHistory.scss'
 import { clearWorkoutRecords, workoutRecords } from "@/services/workout";
 import WorkoutHistory from "@/features/workout/WorkoutHistory";
+import showAlert from "@/components/basic/Alert";
 
 let useRoute;
 let useNavigation;
@@ -36,19 +37,19 @@ export default function Page() {
 
     if (process.env.TARO_ENV == 'rn') {
         router = useRoute()
-        var title = ''
-        if (router.params.type == 'time') {
-            title = t('page.clock.title')
-        }
-        else if (router.params.type == 'metric') {
-            title = t('page.metric.title')
-        }
-        else if (router.params.type == 'workout') {
-            title = t('page.workout.title')
-        }
-        navigation.setOptions({
-            headerBackTitle: title
-        });
+        // var title = ''
+        // if (router.params.type == 'time') {
+        //     title = t('page.clock.title')
+        // }
+        // else if (router.params.type == 'metric') {
+        //     title = t('page.metric.title')
+        // }
+        // else if (router.params.type == 'workout') {
+        //     title = t('page.workout.title')
+        // }
+        // navigation.setOptions({
+        //     headerBackTitle: title
+        // });
     }
     else {
         router = useRouter()
@@ -276,16 +277,12 @@ export default function Page() {
         // var page = Taro.getCurrentPages()[0]
         // debugger
         // page.refresh()
-        Taro.showModal({
+       showAlert({
             title: t('feature.common.modal.delete_all_title'),
             content: t('feature.common.modal.delete_all_content'),
-            success: (res) => {
-                if (res.confirm) {
-
-                    doClear()
-
-
-                }
+            showCancel:true,
+            confirm:()=>{
+                doClear()
             }
         })
 

+ 58 - 34
src/pages/rn/RNMain.tsx

@@ -21,7 +21,6 @@ import WorkoutDetail from '@/pages/workout/WorkoutDetail'
 import Explore from '../explore/Index';
 import StreakDetail from '@/pages/clock/StreakDetail';
 import H5 from '@/pages/common/H5';
-import DemoA from '../clock/demoA';
 import { Image, PixelRatio } from 'react-native';
 // import { View,Image } from '@tarojs/components';
 
@@ -70,36 +69,35 @@ export default function RNMain() {
   const MetricPage = () => <Metric />
   // const WorkoutPage = () => <Workout />
   const ProfilePage = () => <Profile />
-  const DemoAPage = () => <DemoA />
   // const FoodPage = ()=><Food/>
 
   function tabNavigator() {
     return (
-      <Tab.Navigator 
-      
-      screenOptions={({ route }) => ({
-        headerStyle: {
-          backgroundColor: 'black',
-          // borderBottomColor:'#ffffff33',
-          // borderBottomWidth: 1, // 隐藏导航条底部边框
-        },
-        headerTintColor: 'white',
-        tabBarStyle: { backgroundColor: 'black',borderTopColor:'#ffffff22',borderTopWidth:1/PixelRatio.get() }, // tabbar的背景色
-        tabBarActiveTintColor: 'white', // 活动标签的颜色
-        tabBarInactiveTintColor: 'gray', // 非活动标签的颜色
-      })}>
+      <Tab.Navigator
+
+        screenOptions={({ route }) => ({
+          headerStyle: {
+            backgroundColor: 'black',
+            // borderBottomColor:'#ffffff33',
+            // borderBottomWidth: 1, // 隐藏导航条底部边框
+          },
+          headerTintColor: 'white',
+          tabBarStyle: { backgroundColor: 'black', borderTopColor: '#ffffff22', borderTopWidth: 1 / PixelRatio.get() }, // tabbar的背景色
+          tabBarActiveTintColor: 'white', // 活动标签的颜色
+          tabBarInactiveTintColor: 'gray', // 非活动标签的颜色
+        })}>
         <Tab.Screen name="Circadian" component={ClockPage} options={{
           tabBarIcon: ({ size, focused, color }) => {
             return (
               <Image
                 resizeMode='contain'
                 style={{ width: size, height: size }}
-                source={require('@assets/images/test.png')}
+                source={focused ? require('@assets/images/home_focus.png') : require('@assets/images/home_nonfocus.png')}
               />
             );
           },
         }} />
-        <Tab.Screen name="Explore" component={ExplorePage} options={{
+        {/* <Tab.Screen name="Explore" component={ExplorePage} options={{
           tabBarIcon: ({ size, focused, color }) => {
             return (
               <Image
@@ -109,7 +107,7 @@ export default function RNMain() {
               />
             );
           },
-        }} />
+        }} /> */}
         {/* <Tab.Screen name='DemoA' component={DemoAPage} /> */}
         {/* <Tab.Screen name="Food" component={FoodPage} options={{
           tabBarIcon: ({size,focused,color}) => {
@@ -151,7 +149,7 @@ export default function RNMain() {
               <Image
                 resizeMode='contain'
                 style={{ width: size, height: size }}
-                source={require('@assets/images/camera.png')}
+                source={focused ? require('@assets/images/profile_focus.png') : require('@assets/images/profile_nonfocus.png')}
               />
             );
           },
@@ -183,22 +181,48 @@ export default function RNMain() {
         tabBarInactiveTintColor: 'gray', // 非活动标签的颜色
       })}>
         <Stack.Screen name='Main' component={tabNavigator} options={{ headerShown: false }} />
-        <Stack.Screen name='ChooseAuth' component={ChooseAuth} />
-        <Stack.Screen name='Auth' component={Auth} />
-        <Stack.Screen name='Food' component={Food} />
-        <Stack.Screen name='Clock' component={Clock} />
-        <Stack.Screen name='Setting' component={Setting} />
-        <Stack.Screen name='H5' component={H5} />
-        <Stack.Screen name='ChooseScenario' component={ChooseScenario} />
+        <Stack.Screen name='ChooseAuth' component={ChooseAuth} options={{
+          headerBackTitle: ' '
+        }} />
+        <Stack.Screen name='Auth' component={Auth} options={{
+          headerBackTitle: ' '
+        }} />
+        <Stack.Screen name='Food' component={Food} options={{
+          headerBackTitle: ' '
+        }} />
+        <Stack.Screen name='Clock' component={Clock} options={{
+          headerBackTitle: ' '
+        }} />
+        <Stack.Screen name='Setting' component={Setting} options={{
+          headerBackTitle: ' '
+        }} />
+        <Stack.Screen name='H5' component={H5} options={{
+          headerBackTitle: ' '
+        }} />
+        <Stack.Screen name='ChooseScenario' component={ChooseScenario} options={{
+          headerBackTitle: ' '
+        }} />
         <Stack.Screen name='RecordsHistory' component={RecordsHistory} options={{
-          // headerBackTitle:'hello world'
-        }} />
-        <Stack.Screen name='SetSchedule' component={SetSchedule} />
-        <Stack.Screen name='ProfileSetting' component={ProfileSetting} />
-        <Stack.Screen name='EditPage' component={EditPage} />
-        <Stack.Screen name='Working' component={Working} />
-        <Stack.Screen name='WorkoutDetail' component={WorkoutDetail} />
-        <Stack.Screen name='StreakDetail' component={StreakDetail} />
+          headerBackTitle: ' '
+        }} />
+        <Stack.Screen name='SetSchedule' component={SetSchedule} options={{
+          headerBackTitle: ' '
+        }} />
+        <Stack.Screen name='ProfileSetting' component={ProfileSetting} options={{
+          headerBackTitle: ' '
+        }} />
+        <Stack.Screen name='EditPage' component={EditPage} options={{
+          headerBackTitle: ' '
+        }} />
+        <Stack.Screen name='Working' component={Working} options={{
+          headerBackTitle: ' '
+        }} />
+        <Stack.Screen name='WorkoutDetail' component={WorkoutDetail} options={{
+          headerBackTitle: ' '
+        }} />
+        <Stack.Screen name='StreakDetail' component={StreakDetail} options={{
+          headerBackTitle: ' '
+        }} />
       </Stack.Navigator>
     </NavigationContainer>
   )

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

@@ -1,6 +1,6 @@
 let online = process.env.TARO_ENV == 'rn' ? false : true;
 export let baseUrl = online ? 'https://api.fast.liveplus.fun' : 'https://api.fast.dev.liveplus.fun';
-export let APP_VERSION = '2.0.0'
+export let APP_VERSION = '1.0.0'
 export let WX_VERSION = ''
 export let imgUrl = online
     ? 'https://api.fast.liveplus.fun/static/image/'

+ 1 - 1
src/services/http/request.ts

@@ -58,7 +58,7 @@ export async function request<T>(param: RequestParam): Promise<T> {
 
     function performRequest(resolve: (value?: T | PromiseLike<T>) => void, reject: (reason?: any) => void) {
         const { url, method, data } = param;
-        console.log(url)
+        // console.log(url)
         var requestTask: any = null;
         let header: any = {};
 

+ 3 - 3
src/utils/check_authorized.tsx

@@ -2,9 +2,9 @@ import { clientInfo } from "@/services/common";
 import Taro from "@tarojs/taro";
 // import { checkPermissions } from "./native_permission_check";
 
-let checkPermissions
+let uploadPermissions
 if (process.env.TARO_ENV == 'rn') {
-    checkPermissions = require('./native_permission_check').checkPermissions;
+    uploadPermissions = require('./native_permission_check').uploadPermissions;
     // Linking = require('react-native').Linking;
     // AppState = require("react-native").AppState
     // GradientText = require('@/components/basic/GradientText').default
@@ -35,7 +35,7 @@ export function checkAuthorized() {
         })
     }
     else {
-        checkPermissions()
+        uploadPermissions()
     }
 
 

+ 35 - 19
src/utils/native_permission_check.tsx

@@ -1,8 +1,8 @@
 import { clientInfo } from '@/services/common';
 import Taro from '@tarojs/taro';
 import JPush from 'jpush-react-native';
-import { Alert } from 'react-native';
-import { check, PERMISSIONS, RESULTS, checkNotifications, checkMultiple } from 'react-native-permissions';
+import { Alert, Linking } from 'react-native';
+import { check, PERMISSIONS, RESULTS, checkMultiple } from 'react-native-permissions';
 
 
 export const checkLocation = () => {
@@ -40,27 +40,18 @@ export const checkLocation = () => {
 }
 
 
-export const checkPermissions = () => {
-    async function getStorage(key: string) {
-        try {
-            const res = await Taro.getStorage({ key });
-            return res.data;
-        } catch {
-            return '';
-        }
-    }
-
+export const uploadPermissions = () => {
+    debugger
     checkMultiple([PERMISSIONS.IOS.CAMERA,
     PERMISSIONS.IOS.PHOTO_LIBRARY,
+    PERMISSIONS.IOS.LOCATION_WHEN_IN_USE,
     PERMISSIONS.IOS.LOCATION_ALWAYS]).then(statuses => {
         // console.log('Camera', statuses[PERMISSIONS.IOS.CAMERA]);
         // console.log('photos', statuses[PERMISSIONS.IOS.PHOTO_LIBRARY]);
         // console.log('location', statuses[PERMISSIONS.IOS.LOCATION_ALWAYS]);
         // debugger
 
-        debugger
         Taro.getStorage({ key: 'notification' }).then(res => {
-            debugger
             if (res) {
                 JPush.isNotificationEnabled((res) => {
                     console.log(res)
@@ -69,7 +60,8 @@ export const checkPermissions = () => {
                             perm: {
                                 album: statuses[PERMISSIONS.IOS.PHOTO_LIBRARY],
                                 camera: statuses[PERMISSIONS.IOS.CAMERA],
-                                location: statuses[PERMISSIONS.IOS.LOCATION_ALWAYS],
+                                location_always: statuses[PERMISSIONS.IOS.LOCATION_ALWAYS],
+                                location_when_in_use: statuses[PERMISSIONS.IOS.LOCATION_WHEN_IN_USE],
                                 notification: 'allow'
                             }
                         })
@@ -79,7 +71,8 @@ export const checkPermissions = () => {
                             perm: {
                                 album: statuses[PERMISSIONS.IOS.PHOTO_LIBRARY],
                                 camera: statuses[PERMISSIONS.IOS.CAMERA],
-                                location: statuses[PERMISSIONS.IOS.LOCATION_ALWAYS],
+                                location_always: statuses[PERMISSIONS.IOS.LOCATION_ALWAYS],
+                                location_when_in_use: statuses[PERMISSIONS.IOS.LOCATION_WHEN_IN_USE],
                                 notification: 'denied'
                             }
                         })
@@ -91,14 +84,37 @@ export const checkPermissions = () => {
                     perm: {
                         album: statuses[PERMISSIONS.IOS.PHOTO_LIBRARY],
                         camera: statuses[PERMISSIONS.IOS.CAMERA],
-                        location: statuses[PERMISSIONS.IOS.LOCATION_ALWAYS],
+                        location_always: statuses[PERMISSIONS.IOS.LOCATION_ALWAYS],
+                        location_when_in_use: statuses[PERMISSIONS.IOS.LOCATION_WHEN_IN_USE],
                         notification: 'unavailable'
                     }
                 })
             }
-        }).catch(e=>{
-            console.log(e)
+        }).catch(e => {
+            clientInfo({
+                perm: {
+                    album: statuses[PERMISSIONS.IOS.PHOTO_LIBRARY],
+                    camera: statuses[PERMISSIONS.IOS.CAMERA],
+                    location_always: statuses[PERMISSIONS.IOS.LOCATION_ALWAYS],
+                    location_when_in_use: statuses[PERMISSIONS.IOS.LOCATION_WHEN_IN_USE],
+                    notification: 'unavailable'
+                }
+            })
         })
 
     })
+}
+
+export const checkNotification = () => {
+    Taro.getStorage({ key: 'notification' }).then(res => {
+        Linking.openURL('app-settings:notifications')
+    }).catch(e => {
+        const test = require('@/utils/push').default
+        test()
+
+        Taro.setStorage({
+            key: 'notification',
+            data: true
+        })
+    })
 }

+ 7 - 4
src/utils/push.tsx

@@ -1,6 +1,9 @@
 
+import showAlert from '@/components/basic/Alert';
 import { clientId } from '@/services/user';
 import JPush from 'jpush-react-native';
+import { title } from 'process';
+import { uploadPermissions } from './native_permission_check';
 
 export default function jgPush() {
     // const JPush = require('jpush-react-native')
@@ -46,12 +49,12 @@ export default function jgPush() {
     JPush.addMobileNumberListener(mobileNumberListener);
 
     JPush.getRegistrationID(obj => {
-        // alert('register id=' + obj.registerID)
+        uploadPermissions()
         global.registerID = obj.registerID
-        setTimeout(()=>{
+        setTimeout(() => {
             clientId()
-        },3000)
+        }, 3000)
     })
 
-    
+
 }

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