Leon 1 rok pred
rodič
commit
df5057b913

+ 4 - 2
ios/AppDelegate.mm

@@ -38,6 +38,8 @@ static NSString *const kRNConcurrentRoot = @"concurrentRoot";
   //  NSString *url = UIApplicationOpenNotificationSettingsURLString;
   // APNS
   //  BOOL isLocation = [CLLocationManager locationServicesEnabled];
+  UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
+  [center removeAllPendingNotificationRequests];
   self.rnLoaded = NO;
   NSDate *date = [NSDate date];
   //zone为当前时区信息  在我的程序中打印的是@"Asia/Shanghai"
@@ -57,7 +59,7 @@ static NSString *const kRNConcurrentRoot = @"concurrentRoot";
   
   RCTBridge *bridge = [self.reactDelegate createBridgeWithDelegate:self launchOptions:launchOptions];
   
-  UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
+//  UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
   center.delegate = self;
   
   
@@ -130,7 +132,7 @@ static NSString *const kRNConcurrentRoot = @"concurrentRoot";
 - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
 {
 //  return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
-#if DEBUGaaa
+#if DEBUG
   return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"];
 #else
   return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];

+ 1 - 78
ios/NativeBridge.m

@@ -317,7 +317,7 @@ RCT_EXPORT_METHOD(addSunPush:(id)array){
       UNCalendarNotificationTrigger *trigger = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:dateComponents repeats:YES];
       
       
-      NSString * identifier = message_id;
+      NSString * identifier = [NSString stringWithFormat:@"REMINDER_FS_%@",message_id];
       UNNotificationRequest * request = [UNNotificationRequest requestWithIdentifier:identifier content:content trigger:trigger];
       [[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
         
@@ -362,83 +362,6 @@ RCT_EXPORT_METHOD(addLocalPush:(id)array){
   });
 }
 
-RCT_EXPORT_METHOD(addLocalPush3:(id)detail){
-  dispatch_async(dispatch_get_main_queue(), ^{
-    //设置通知内容
-    UNMutableNotificationContent * content = [[UNMutableNotificationContent alloc] init];
-    content.title = detail[@"title"];
-    content.body = detail[@"body"];
-    
-    NSString *category_id = detail[@"category_id"];
-    NSString *message_id = detail[@"id"];
-    NSString *mode = detail[@"mode"];
-    
-    NSArray *actions;
-    if ([category_id isEqualToString:@"REMINDER_FS_START_FAST"]||[category_id isEqualToString:@"REMINDER_FS_START_SLEEP"]){
-      //消息的处理按钮
-      UNNotificationAction *action1 = [UNNotificationAction actionWithIdentifier:@"START_TIMER_NOW" title:@"Start timer now with 1-tap" options:UNNotificationActionOptionForeground];
-      
-      UNNotificationAction *action2 = [UNNotificationAction actionWithIdentifier:@"PICK_EARLIER_START" title:@"Pick an earlier start" options:UNNotificationActionOptionForeground];
-      
-      UNNotificationAction *action3 = [UNNotificationAction actionWithIdentifier:@"SKIP" title:@"Skip" options:UNNotificationActionOptionAuthenticationRequired];
-      
-      actions = @[action1,action2,action3];
-    }
-    else if([category_id isEqualToString:@"REMINDER_FS_END_FAST"]||[category_id isEqualToString:@"REMINDER_FS_END_SLEEP"]){
-      //消息的处理按钮
-      UNNotificationAction *action1 = [UNNotificationAction actionWithIdentifier:@"END_TIMER_NOW" title:@"End timer now with 1-tap" options:UNNotificationActionOptionForeground];
-      
-      UNNotificationAction *action2 = [UNNotificationAction actionWithIdentifier:@"PICK_EARLIER_END" title:@"Pick an earlier end" options:UNNotificationActionOptionForeground];
-      
-      UNNotificationAction *action3 = [UNNotificationAction actionWithIdentifier:@"SKIP" title:@"Skip" options:UNNotificationActionOptionAuthenticationRequired];
-      
-      actions = @[action1,action2,action3];
-    }
-    
-    UNNotificationCategory *categroy = [UNNotificationCategory categoryWithIdentifier:category_id actions:actions intentIdentifiers:@[] options:UNNotificationCategoryOptionCustomDismissAction];
-    
-    [[UNUserNotificationCenter currentNotificationCenter] setNotificationCategories:[NSSet setWithObject:categroy]];
-    content.categoryIdentifier = category_id;
-    
-    if ([mode isEqualToString:@"RECURRING"]){
-      //设置推送的触发机制
-      NSArray *timeArray = [detail[@"recurring"][@"time"] componentsSeparatedByString:@":"];
-      NSInteger hour = [[timeArray objectAtIndex:0] integerValue];
-      NSInteger minute = [[timeArray objectAtIndex:1] integerValue];
-      NSInteger second = [[timeArray objectAtIndex:2] integerValue];
-      
-      // 2. 设置触发条件
-      NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
-      dateComponents.hour = hour;
-      dateComponents.minute = minute;
-      dateComponents.second = second;
-      UNCalendarNotificationTrigger *trigger = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:dateComponents repeats:YES];
-      
-      
-      NSString * identifier = message_id;
-      UNNotificationRequest * request = [UNNotificationRequest requestWithIdentifier:identifier content:content trigger:trigger];
-      [[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
-        
-      }];
-    }
-    else {
-      NSTimeInterval timestamp = [detail[@"once"] doubleValue]/1000; // 毫秒级时间戳
-      // 获取当前时间
-      NSDate *currentDate = [NSDate date];
-      // 计算当前时间与给定时间戳之间的时间差(秒)
-      NSTimeInterval timeInterval = timestamp - [currentDate timeIntervalSince1970];
-      
-      UNTimeIntervalNotificationTrigger * trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:timeInterval repeats:NO];
-      NSString * identifier = message_id;
-      UNNotificationRequest * request = [UNNotificationRequest requestWithIdentifier:identifier content:content trigger:trigger];
-      [[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
-        
-      }];
-    }
-    
-    
-  });
-}
 
 @end
 

+ 2 - 2
ios/hola.xcodeproj/project.pbxproj

@@ -576,7 +576,7 @@
 				CODE_SIGN_ENTITLEMENTS = hola/hola.entitlements;
 				CODE_SIGN_IDENTITY = "Apple Development";
 				CODE_SIGN_STYLE = Automatic;
-				CURRENT_PROJECT_VERSION = 76;
+				CURRENT_PROJECT_VERSION = 81;
 				DEVELOPMENT_TEAM = GPMXAZ9G5N;
 				ENABLE_BITCODE = NO;
 				INFOPLIST_FILE = hola/Info.plist;
@@ -609,7 +609,7 @@
 				CODE_SIGN_ENTITLEMENTS = hola/hola.entitlements;
 				CODE_SIGN_IDENTITY = "Apple Development";
 				CODE_SIGN_STYLE = Automatic;
-				CURRENT_PROJECT_VERSION = 76;
+				CURRENT_PROJECT_VERSION = 81;
 				DEVELOPMENT_TEAM = GPMXAZ9G5N;
 				INFOPLIST_FILE = hola/Info.plist;
 				LD_RUNPATH_SEARCH_PATHS = (

+ 1 - 1
ios/hola/Info.plist

@@ -32,7 +32,7 @@
 		</dict>
 	</array>
 	<key>CFBundleVersion</key>
-	<string>76</string>
+	<string>81</string>
 	<key>ITSAppUsesNonExemptEncryption</key>
 	<false/>
 	<key>LSApplicationCategoryType</key>

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 1 - 1
ios/main.jsbundle


+ 37 - 21
src/features/trackTimeDuration/components/IndexConsole.tsx

@@ -224,14 +224,14 @@ export default function IndexConsole(props: { record: any, count: number }) {
             return
         }
         if (status != 'ONGOING1' && props.record.scenario.name == 'FAST_SLEEP') {
-            if (status == 'WAIT_FOR_START') {
-                Taro.showToast({
-                    title: t('feature.track_time_duration.console.lock_fast_tip'),
-                    icon: 'none'
-                })
-            }
-
-            vibrate()
+            // if (status == 'WAIT_FOR_START') {
+            //     Taro.showToast({
+            //         title: t('feature.track_time_duration.console.lock_fast_tip'),
+            //         icon: 'none'
+            //     })
+            // }
+
+            // vibrate()
             setMutiEvent('start_sleep')
             setShowMutiPicker(true);
             return;
@@ -284,12 +284,12 @@ export default function IndexConsole(props: { record: any, count: number }) {
         }
         if (status != 'ONGOING2' && status != 'ONGOING') {
 
-            Taro.showToast({
-                title: t('feature.track_time_duration.console.lock_sleep_tip'),
-                icon: 'none'
-            })
+            // Taro.showToast({
+            //     title: t('feature.track_time_duration.console.lock_sleep_tip'),
+            //     icon: 'none'
+            // })
 
-            vibrate()
+            // vibrate()
             setMutiEvent('end_sleep')
             setShowMutiPicker(true);
             return;
@@ -337,11 +337,11 @@ export default function IndexConsole(props: { record: any, count: number }) {
             return
         }
         if (status == 'WAIT_FOR_START') {
-            Taro.showToast({
-                title: t('feature.track_time_duration.console.lock_fast_tip'),
-                icon: 'none'
-            })
-            vibrate()
+            // Taro.showToast({
+            //     title: t('feature.track_time_duration.console.lock_fast_tip'),
+            //     icon: 'none'
+            // })
+            // vibrate()
             setMutiEvent('end_fast')
             setShowMutiPicker(true);
             return;
@@ -833,7 +833,7 @@ export default function IndexConsole(props: { record: any, count: number }) {
 
     function mutiPickerContent() {
         global.set_time = new Date().getTime()
-        return <IndexConsoleMuti status={status} event={mutiEvent} close={() => setShowMutiPicker(false)} />
+        return <IndexConsoleMuti status={status} event={mutiEvent} scenario={props.record.scenario.name} close={() => setShowMutiPicker(false)} />
     }
 
     function single() {
@@ -842,7 +842,7 @@ export default function IndexConsole(props: { record: any, count: number }) {
                 {
                     status == 'WAIT_FOR_START' &&
                     <View onClick={tapStartFast} className='console_btn'>
-                        <Text style={{ fontWeight: 'bold', color: ColorType.black }}>{t('feature.track_time_duration.common.start_fast')}</Text>
+                        <Text style={{ fontWeight: 'bold', fontSize: rpxToPx(32), color: ColorType.black }}>{t('feature.track_time_duration.common.start_fast')}</Text>
                     </View>
                 }
                 {/* {
@@ -850,12 +850,28 @@ export default function IndexConsole(props: { record: any, count: number }) {
                 } */}
                 {
                     status == 'ONGOING' && <View onClick={tapEndFast} className={status == 'ONGOING' ? 'console_btn' : 'console_btn btn_disable'}>
-                        <Text style={{ fontWeight: 'bold', color: ColorType.black }}>{t('feature.track_time_duration.common.end_fast')}</Text>
+                        <Text style={{ fontWeight: 'bold', fontSize: rpxToPx(32), color: ColorType.black }}>{t('feature.track_time_duration.common.end_fast')}</Text>
+                    </View>
+                }
+                {
+                    status == 'WAIT_FOR_START' && <View>
+                        {
+                            !expand && <Text className='expand' onClick={() => { setExpand(true) }}>{expandBtnText()}</Text>
+                        }
+                    </View>
+                }
+                {expand && <View className='btn_line' />}
+                {
+                    expand && <View onClick={tapEndFast} className={status == 'ONGOING3' ? 'console_btn' : 'console_btn btn_disable'}>
+                        <Text style={{ fontWeight: 'bold', fontSize: rpxToPx(32), color: ColorType.black }}>{t('feature.track_time_duration.common.end_fast')}</Text>
                     </View>
                 }
                 {
                     showTimePicker && modalContent()
                 }
+                {
+                    showMutiPicker && mutiContent()
+                }
             </View>
         }
         else if (props.record.scenario.name == 'SLEEP') {

+ 3 - 3
src/features/trackTimeDuration/components/IndexConsoleMuti.tsx

@@ -16,7 +16,7 @@ import { TimeFormatter } from "@/utils/time_format";
 let min = 0
 let max = 0
 let defaultTimestamp = 0
-export default function IndexConsoleMuti(props: { status: string, event: string, close: Function }) {
+export default function IndexConsoleMuti(props: { status: string, event: string, close: Function,scenario:string }) {
     const { t } = useTranslation();
     const isLoading = false;
     var color = ColorType.fast;
@@ -351,10 +351,10 @@ export default function IndexConsoleMuti(props: { status: string, event: string,
                 props.event == 'end_fast' && props.status == 'WAIT_FOR_START' && startFastCell()
             }
             {
-                props.event == 'end_fast' && (props.status == 'ONGOING1' || props.status == 'WAIT_FOR_START') && startSleepCell()
+                props.event == 'end_fast' && props.scenario=='FAST_SLEEP' && (props.status == 'ONGOING1' || props.status == 'WAIT_FOR_START') && startSleepCell()
             }
             {
-                props.event == 'end_fast' && (props.status == 'ONGOING1' || props.status == 'ONGOING2' || props.status == 'WAIT_FOR_START') && endSleepCell()
+                props.event == 'end_fast' && props.scenario=='FAST_SLEEP' && (props.status == 'ONGOING1' || props.status == 'ONGOING2' || props.status == 'WAIT_FOR_START') && endSleepCell()
             }
             {
                 props.event == 'end_fast' && endFastCell()

+ 0 - 1
src/pages/clock/SetGoal.tsx

@@ -359,7 +359,6 @@ export default function SetGoal() {
     }
 
     function popRNAlert() {
-        debugger
         if (target.isMixed) {
             popMixScheduleAlert(fastTarget.start_time, sleepTarget.start_time)
         }

+ 8 - 0
src/pages/notification/setting.tsx

@@ -10,6 +10,8 @@ import { getNotifySettings, postNotifySettings } from "@/services/notifications"
 import { ColorType } from "@/context/themes/color";
 import { getLocalPush } from "@/features/trackTimeDuration/actions/TrackTimeActions";
 import { useSelector } from "react-redux";
+import ProductList from "../store/product_list";
+import { jumpPage } from "@/features/trackTimeDuration/hooks/Common";
 
 let useNavigation;
 let AppState;
@@ -166,8 +168,14 @@ export default function Page() {
         </View>
     }
 
+    function iap(){
+        jumpPage('','ProductList',navigation)
+    }
+
     function pro() {
         return <ScrollView style={{ flex: 1 }}>
+            {/* <ProductList /> */}
+            <Text style={{fontSize:30,color:'#fff'}} onClick={iap}>iap test</Text>
             <View className="setting_container">
                 <View className="setting_section">
                     <Text className="setting_section_title">Fasting with/or Sleep</Text>

+ 4 - 0
src/pages/rn/RNMain.tsx

@@ -25,6 +25,7 @@ import StreakDetail from '@/pages/clock/StreakDetail';
 import H5 from '@/pages/common/H5';
 import NotificationSetting from '@/pages/notification/setting';
 import { Image, PixelRatio } from 'react-native';
+import ProductList from '../store/product_list';
 // import { View,Image } from '@tarojs/components';
 
 // 创建底部 Tab 导航器
@@ -243,6 +244,9 @@ export default function RNMain() {
         <Stack.Screen name='SetGoal' component={SetGoal} options={{
           headerBackTitle: ' '
         }} />
+        <Stack.Screen name='ProductList' component={ProductList} options={{
+          headerBackTitle: ' '
+        }} />
         {/* <Stack.Screen name='NotificationSetting' component={NotificationSetting} options={{
           headerBackTitle: ' '
         }} /> */}

+ 0 - 0
src/pages/store/product_list.scss


+ 93 - 0
src/pages/store/product_list.tsx

@@ -0,0 +1,93 @@
+import { payInfo } from "@/services/common";
+import { kIsAndroid, kIsIOS } from "@/utils/tools";
+import { View, Text } from "@tarojs/components";
+import { useEffect, useState } from "react";
+import { FlatList, Pressable } from "react-native";
+import Purchases from 'react-native-purchases'
+
+export default function ProductList() {
+
+    const [packages, setPackages] = useState([]);
+
+    // - State for displaying an overlay view
+    const [isPurchasing, setIsPurchasing] = useState(false);
+
+    useEffect(() => {
+        if (process.env.TARO_ENV == 'rn') {
+            if (kIsIOS) {
+                Purchases.configure({ apiKey: 'appl_FNFYDLwHZlXzqrKJFlErWXUHGwx' })
+            }
+            else if (kIsAndroid) {
+                Purchases.configure({ apiKey: 'goog_cyJSYOsnZpNqsUbCsHSdhqQdQwe' })
+            }
+            // console.log('aaaa')
+            // setTimeout(() => {
+            //     getProducts();
+            //     hi()
+            // }, 2000)
+
+        }
+    }, [])
+
+    async function getProducts() {
+        try {
+            const offerings = await Purchases.getOfferings();
+            console.log((offerings as any).current.availablePackages)
+            if (offerings.current !== null && offerings.current.availablePackages.length !== 0) {
+                setPackages((offerings as any).current.availablePackages);
+            }
+        } catch (e) {
+            console.log(e.message)
+        }
+    }
+
+
+    async function hi(item) {
+        try {
+            // 启动购买流程
+            const purchaseResult = await Purchases.purchaseProduct('pro_lifelong_test');
+            console.log(purchaseResult);
+            // 检查购买是否成功
+            // setIsSubscribed(purchaseResult.purchaserInfo.activeSubscriptions.length > 0);
+        } catch (error) {
+            console.error('Purchase error:', error);
+        }
+    }
+
+    async function pay(item:any) {
+        setIsPurchasing(true);
+        try {
+            const { customerInfo } = await Purchases.purchasePackage(item);
+            payInfo(customerInfo);
+            console.log('result',customerInfo)
+          } catch (e) {
+            debugger
+            if (e.code === Purchases.PURCHASES_ERROR_CODE.PURCHASE_CANCELLED_ERROR) {
+
+            }
+          } finally {
+            setIsPurchasing(false);
+          }
+    }
+
+    return <View>
+        <Text style={{ color: '#fff', fontSize: 30 }} onClick={getProducts}>点击获取产品列表</Text>
+        <FlatList
+            data={packages}
+            renderItem={({ item }) => <Pressable onPress={()=>{}} style={{flexDirection:'column',marginTop:20,marginBottom:20}}>
+            <View>
+              <Text style={{color:'#fff',fontSize:20,fontWeight:'bold'}}>{(item as any).product.title}</Text>
+              <Text style={{color:'#fff',fontSize:16,marginTop:5,marginBottom:5}}>{(item as any).product.description}</Text>
+            </View>
+            <Text style={{color:'red'}}>{(item as any).product.priceString}</Text>
+            <Text style={{color:'green',fontSize:30,fontWeight:'bold'}} onClick={()=>pay(item)}>Pay</Text>
+          </Pressable>}
+            keyExtractor={(item) => (item as any).identifier}
+
+        />
+
+        {
+            isPurchasing && <Text style={{color:'#fff',fontSize:40}}>正在付款</Text>
+        }
+    </View>
+}

+ 18 - 1
src/services/common.tsx

@@ -1,5 +1,5 @@
 import { setResources, setConfigs } from "@/store/common";
-import { API_CONFIGS, API_DEL_SESSION, API_GLOBAL_CONFIGS, API_STATIC_RESOURCES, API_SYSTEM_VERSION, API_UPLOAD_SESSION, API_USER_CLIENT, API_USER_LOCATION, APP_VERSION } from "./http/api";
+import { API_CONFIGS, API_DEL_SESSION, API_GLOBAL_CONFIGS, API_PAY_UPLOAD, API_STATIC_RESOURCES, API_SYSTEM_VERSION, API_UPLOAD_SESSION, API_USER_CLIENT, API_USER_LOCATION, APP_VERSION } from "./http/api";
 import { request } from "./http/request";
 import Taro from "@tarojs/taro";
 import { kIsIOS } from "@/utils/tools";
@@ -97,4 +97,21 @@ export const delSession = (params) => {
             duration: 2000
         })
     })
+}
+
+export const payInfo = (params) => {
+    debugger
+    return new Promise((resolve, reject) => {
+        request({
+            url: API_PAY_UPLOAD, method: 'POST', data: {
+                ...params
+            }
+        }).then(res => {
+            resolve(res)
+            // dispatch(loginSuccess(res));
+        }).catch(e => {
+            reject(e)
+        })
+    })
+
 }

+ 3 - 0
src/services/http/api.js

@@ -80,3 +80,6 @@ export const API_WX_PUB_FOLLOWED = `${baseUrl}/api/fast/user/wx-pub-followed`
 //notification
 export const API_LOCAL_PUSHES = `${baseUrl}/api/user/local-pushes`
 export const API_NOTIFY_SETTINGS = `${baseUrl}/api/user/notify-settings`
+
+//store
+export const API_PAY_UPLOAD = `${baseUrl}/api/pay/rc-result`

Niektoré súbory nie sú zobrazené, pretože je v týchto rozdielových dátach zmenené mnoho súborov