feat(fasting): add auto-renewal and reset functionality for fasting plans

- Implement auto-renewal logic for completed fasting cycles using dayjs
- Add reset button with information modal in FastingOverviewCard
- Configure iOS push notifications for production environment
- Add expo-media-library and react-native-view-shot dependencies
- Update FastingScheduleOrigin type to include 'auto' origin
This commit is contained in:
richarjiang
2025-10-15 19:06:18 +08:00
parent 039138f7e4
commit d39a32c0d8
9 changed files with 548 additions and 155 deletions

View File

@@ -24,6 +24,7 @@ import {
} from '@/utils/fasting'; } from '@/utils/fasting';
import { useFocusEffect } from '@react-navigation/native'; import { useFocusEffect } from '@react-navigation/native';
import { useRouter } from 'expo-router'; import { useRouter } from 'expo-router';
import dayjs from 'dayjs';
import React, { useCallback, useEffect, useMemo, useState } from 'react'; import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { ScrollView, StyleSheet, Text, View } from 'react-native'; import { ScrollView, StyleSheet, Text, View } from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context'; import { useSafeAreaInsets } from 'react-native-safe-area-context';
@@ -154,6 +155,53 @@ export default function FastingTabScreen() {
} }
}, [notificationsReady, notificationsLoading, notificationError, notificationIds, lastSyncTime, activeSchedule?.startISO, currentPlan?.id]); }, [notificationsReady, notificationsLoading, notificationError, notificationIds, lastSyncTime, activeSchedule?.startISO, currentPlan?.id]);
useEffect(() => {
if (!activeSchedule || !currentPlan) return;
if (phase !== 'completed') return;
const start = dayjs(activeSchedule.startISO);
const end = dayjs(activeSchedule.endISO);
if (!start.isValid() || !end.isValid()) return;
const now = dayjs();
if (now.isBefore(end)) return;
const fastingHours = currentPlan.fastingHours;
const eatingHours = currentPlan.eatingHours;
const cycleHours = fastingHours + eatingHours;
if (fastingHours <= 0 || cycleHours <= 0) return;
let nextStart = start;
let nextEnd = end;
let iterations = 0;
const maxIterations = 60;
while (!now.isBefore(nextEnd)) {
nextStart = nextStart.add(cycleHours, 'hour');
nextEnd = nextStart.add(fastingHours, 'hour');
iterations += 1;
if (iterations >= maxIterations) {
if (__DEV__) {
console.warn('自动续订断食周期失败: 超出最大迭代次数', {
start: activeSchedule.startISO,
end: activeSchedule.endISO,
planId: currentPlan.id,
});
}
return;
}
}
if (iterations === 0) return;
dispatch(rescheduleActivePlan({
start: nextStart.toDate().toISOString(),
origin: 'auto',
}));
}, [dispatch, activeSchedule, currentPlan, phase]);
const handleAdjustStart = () => { const handleAdjustStart = () => {
if (!currentPlan) return; if (!currentPlan) return;
setShowPicker(true); setShowPicker(true);
@@ -213,6 +261,7 @@ export default function FastingTabScreen() {
endTimeLabel={displayWindow.endTimeLabel} endTimeLabel={displayWindow.endTimeLabel}
onAdjustStartPress={handleAdjustStart} onAdjustStartPress={handleAdjustStart}
onViewMealsPress={handleViewMeal} onViewMealsPress={handleViewMeal}
onResetPress={handleResetPlan}
progress={progress} progress={progress}
/> />
)} )}
@@ -233,9 +282,6 @@ export default function FastingTabScreen() {
<Text style={styles.resetHint}> <Text style={styles.resetHint}>
</Text> </Text>
<Text style={styles.resetAction} onPress={handleResetPlan}>
</Text>
</View> </View>
</View> </View>
)} )}
@@ -325,20 +371,10 @@ const styles = StyleSheet.create({
lineHeight: 20, lineHeight: 20,
}, },
resetRow: { resetRow: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
marginTop: 16, marginTop: 16,
}, },
resetHint: { resetHint: {
flex: 1,
fontSize: 12, fontSize: 12,
color: '#8A96A3', color: '#8A96A3',
marginRight: 12,
},
resetAction: {
fontSize: 12,
fontWeight: '600',
color: '#6366F1',
}, },
}); });

View File

@@ -2,9 +2,13 @@ import { CircularRing } from '@/components/CircularRing';
import { Colors } from '@/constants/Colors'; import { Colors } from '@/constants/Colors';
import type { FastingPlan } from '@/constants/Fasting'; import type { FastingPlan } from '@/constants/Fasting';
import { useColorScheme } from '@/hooks/useColorScheme'; import { useColorScheme } from '@/hooks/useColorScheme';
import { Ionicons } from '@expo/vector-icons';
import { GlassView, isLiquidGlassAvailable } from 'expo-glass-effect';
import { LinearGradient } from 'expo-linear-gradient'; import { LinearGradient } from 'expo-linear-gradient';
import React from 'react'; import React, { useState } from 'react';
import { import {
Modal,
Pressable,
StyleSheet, StyleSheet,
Text, Text,
TouchableOpacity, TouchableOpacity,
@@ -22,6 +26,7 @@ type FastingOverviewCardProps = {
endTimeLabel: string; endTimeLabel: string;
onAdjustStartPress: () => void; onAdjustStartPress: () => void;
onViewMealsPress: () => void; onViewMealsPress: () => void;
onResetPress: () => void;
progress: number; progress: number;
}; };
@@ -36,93 +41,149 @@ export function FastingOverviewCard({
endTimeLabel, endTimeLabel,
onAdjustStartPress, onAdjustStartPress,
onViewMealsPress, onViewMealsPress,
onResetPress,
progress, progress,
}: FastingOverviewCardProps) { }: FastingOverviewCardProps) {
const theme = useColorScheme() ?? 'light'; const theme = useColorScheme() ?? 'light';
const colors = Colors[theme]; const colors = Colors[theme];
const themeColors = plan?.theme; const themeColors = plan?.theme;
const [showResetInfo, setShowResetInfo] = useState(false);
const isGlassAvailable = isLiquidGlassAvailable();
return ( return (
<LinearGradient <>
colors={[ <LinearGradient
themeColors?.accentSecondary ?? colors.heroSurfaceTint, colors={[
themeColors?.backdrop ?? colors.pageBackgroundEmphasis, themeColors?.accentSecondary ?? colors.heroSurfaceTint,
]} themeColors?.backdrop ?? colors.pageBackgroundEmphasis,
style={styles.container} ]}
> style={styles.container}
<View style={styles.headerRow}> >
<View> <View style={styles.headerRow}>
<Text style={styles.planLabel}></Text> <View>
{plan?.id && ( <Text style={styles.planLabel}></Text>
<View style={styles.planTag}> {plan?.id && (
<Text style={[styles.planTagText, { color: themeColors?.accent ?? colors.primary }]}> <View style={styles.planTag}>
{plan.id} <Text style={[styles.planTagText, { color: themeColors?.accent ?? colors.primary }]}>
{plan.id}
</Text>
</View>
)}
</View>
{plan?.badge && (
<View style={[styles.badge, { backgroundColor: `${themeColors?.accent ?? colors.primary}20` }]}>
<Text style={[styles.badgeText, { color: themeColors?.accent ?? colors.primary }]}>
{plan.badge}
</Text> </Text>
</View> </View>
)} )}
</View> </View>
{plan?.badge && (
<View style={[styles.badge, { backgroundColor: `${themeColors?.accent ?? colors.primary}20` }]}> <View style={styles.scheduleRow}>
<Text style={[styles.badgeText, { color: themeColors?.accent ?? colors.primary }]}> <View style={styles.scheduleCell}>
{plan.badge} <Text style={styles.scheduleLabel}></Text>
<Text style={styles.scheduleDay}>{startDayLabel}</Text>
<Text style={styles.scheduleTime}>{startTimeLabel}</Text>
</View>
<View style={styles.separator} />
<View style={styles.scheduleCell}>
<Text style={styles.scheduleLabel}></Text>
<Text style={styles.scheduleDay}>{endDayLabel}</Text>
<Text style={styles.scheduleTime}>{endTimeLabel}</Text>
</View>
</View>
<View style={styles.statusRow}>
<View style={styles.ringContainer}>
<CircularRing
size={168}
strokeWidth={14}
progress={progress}
progressColor={themeColors?.ringProgress ?? colors.primary}
trackColor={themeColors?.ringTrack ?? 'rgba(0,0,0,0.05)'}
showCenterText={false}
startAngleDeg={-90}
resetToken={phaseLabel}
/>
<View style={styles.ringContent}>
<Text style={styles.phaseText}>{phaseLabel}</Text>
<Text style={styles.countdownLabel}>{countdownLabel}</Text>
<Text style={styles.countdownValue}>{countdownValue}</Text>
</View>
</View>
</View>
<View style={styles.actionsRow}>
<TouchableOpacity
style={[styles.secondaryButton, { borderColor: themeColors?.accent ?? colors.primary }]}
onPress={onAdjustStartPress}
activeOpacity={0.85}
>
<Text style={[styles.secondaryButtonText, { color: themeColors?.accent ?? colors.primary }]}>
</Text> </Text>
</View> </TouchableOpacity>
)}
</View>
<View style={styles.scheduleRow}> <TouchableOpacity
<View style={styles.scheduleCell}> style={[styles.secondaryButton, { borderColor: themeColors?.accent ?? colors.primary }]}
<Text style={styles.scheduleLabel}></Text> onPress={onResetPress}
<Text style={styles.scheduleDay}>{startDayLabel}</Text> activeOpacity={0.85}
<Text style={styles.scheduleTime}>{startTimeLabel}</Text> >
</View> <Text style={[styles.secondaryButtonText, { color: themeColors?.accent ?? colors.primary }]}>
<View style={styles.separator} />
<View style={styles.scheduleCell}> </Text>
<Text style={styles.scheduleLabel}></Text> </TouchableOpacity>
<Text style={styles.scheduleDay}>{endDayLabel}</Text>
<Text style={styles.scheduleTime}>{endTimeLabel}</Text>
</View>
</View>
<View style={styles.statusRow}> {isGlassAvailable ? (
<View style={styles.ringContainer}> <GlassView
<CircularRing style={styles.infoButton}
size={168} glassEffectStyle="regular"
strokeWidth={14} isInteractive={true}
progress={progress} >
progressColor={themeColors?.ringProgress ?? colors.primary} <TouchableOpacity onPress={() => setShowResetInfo(true)} style={styles.infoButtonInner}>
trackColor={themeColors?.ringTrack ?? 'rgba(0,0,0,0.05)'} <Ionicons name="information-circle-outline" size={20} color={themeColors?.accent ?? colors.primary} />
showCenterText={false} </TouchableOpacity>
startAngleDeg={-90} </GlassView>
resetToken={phaseLabel} ) : (
/> <TouchableOpacity
<View style={styles.ringContent}> onPress={() => setShowResetInfo(true)}
<Text style={styles.phaseText}>{phaseLabel}</Text> style={[styles.infoButton, styles.fallbackInfoButton]}
<Text style={styles.countdownLabel}>{countdownLabel}</Text> >
<Text style={styles.countdownValue}>{countdownValue}</Text> <Ionicons name="information-circle-outline" size={20} color={themeColors?.accent ?? colors.primary} />
</View> </TouchableOpacity>
)}
</View> </View>
</View> </LinearGradient>
<View style={styles.actionsRow}> <Modal
<TouchableOpacity transparent
style={[styles.secondaryButton, { borderColor: themeColors?.accent ?? colors.primary }]} visible={showResetInfo}
onPress={onAdjustStartPress} animationType="fade"
activeOpacity={0.85} onRequestClose={() => setShowResetInfo(false)}
>
<Pressable
style={styles.infoModalOverlay}
onPress={() => setShowResetInfo(false)}
> >
<Text style={[styles.secondaryButtonText, { color: themeColors?.accent ?? colors.primary }]}> <Pressable style={styles.infoModalContent} onPress={() => { }}>
<View style={styles.infoModalHandle} />
</Text> <Text style={styles.infoModalTitle}></Text>
</TouchableOpacity> <Text style={styles.infoModalText}>
{/* <TouchableOpacity
style={[styles.primaryButton, { backgroundColor: themeColors?.accent ?? colors.primary }]} </Text>
onPress={onViewMealsPress} <Text style={styles.infoModalText}>
activeOpacity={0.9}
> </Text>
<Text style={styles.primaryButtonText}>查看食谱</Text> <TouchableOpacity
</TouchableOpacity> */} style={[styles.infoModalButton, { backgroundColor: themeColors?.accent ?? colors.primary }]}
</View> onPress={() => setShowResetInfo(false)}
</LinearGradient> >
<Text style={styles.infoModalButtonText}></Text>
</TouchableOpacity>
</Pressable>
</Pressable>
</Modal>
</>
); );
} }
@@ -258,6 +319,70 @@ const styles = StyleSheet.create({
fontSize: 15, fontSize: 15,
fontWeight: '600', fontWeight: '600',
}, },
infoButton: {
width: 36,
height: 36,
borderRadius: 18,
alignItems: 'center',
justifyContent: 'center',
marginLeft: 8,
},
infoButtonInner: {
width: '100%',
height: '100%',
alignItems: 'center',
justifyContent: 'center',
},
fallbackInfoButton: {
backgroundColor: 'rgba(255,255,255,0.3)',
},
infoModalOverlay: {
flex: 1,
backgroundColor: 'rgba(0,0,0,0.5)',
justifyContent: 'flex-end',
},
infoModalContent: {
backgroundColor: 'white',
borderTopLeftRadius: 24,
borderTopRightRadius: 24,
paddingVertical: 24,
paddingHorizontal: 20,
paddingBottom: 40,
},
infoModalHandle: {
width: 36,
height: 4,
backgroundColor: '#E5E7EB',
borderRadius: 2,
alignSelf: 'center',
marginBottom: 16,
},
infoModalTitle: {
fontSize: 18,
fontWeight: '700',
color: '#2E3142',
marginBottom: 16,
textAlign: 'center',
},
infoModalText: {
fontSize: 15,
color: '#4A5460',
lineHeight: 22,
marginBottom: 12,
},
infoModalButton: {
paddingVertical: 14,
paddingHorizontal: 24,
borderRadius: 24,
alignItems: 'center',
justifyContent: 'center',
marginTop: 8,
},
infoModalButtonText: {
fontSize: 15,
fontWeight: '600',
color: '#FFFFFF',
},
primaryButton: { primaryButton: {
flex: 1, flex: 1,
borderRadius: 24, borderRadius: 24,

View File

@@ -261,6 +261,7 @@
"${PODS_CONFIGURATION_BUILD_DIR}/EXNotifications/ExpoNotifications_privacy.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/EXNotifications/ExpoNotifications_privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/EXTaskManager/ExpoTaskManager_privacy.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/EXTaskManager/ExpoTaskManager_privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/ExpoFileSystem/ExpoFileSystem_privacy.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/ExpoFileSystem/ExpoFileSystem_privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/ExpoMediaLibrary/ExpoMediaLibrary_privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/ExpoSystemUI/ExpoSystemUI_privacy.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/ExpoSystemUI/ExpoSystemUI_privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/PurchasesHybridCommon/PurchasesHybridCommon.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/PurchasesHybridCommon/PurchasesHybridCommon.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/RNCAsyncStorage/RNCAsyncStorage_resources.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/RNCAsyncStorage/RNCAsyncStorage_resources.bundle",
@@ -282,6 +283,7 @@
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoNotifications_privacy.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoNotifications_privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoTaskManager_privacy.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoTaskManager_privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoFileSystem_privacy.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoFileSystem_privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoMediaLibrary_privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoSystemUI_privacy.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoSystemUI_privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/PurchasesHybridCommon.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/PurchasesHybridCommon.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNCAsyncStorage_resources.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNCAsyncStorage_resources.bundle",

View File

@@ -80,6 +80,7 @@
<key>UIBackgroundModes</key> <key>UIBackgroundModes</key>
<array> <array>
<string>fetch</string> <string>fetch</string>
<string>remote-notification</string>
</array> </array>
<key>UILaunchStoryboardName</key> <key>UILaunchStoryboardName</key>
<string>SplashScreen</string> <string>SplashScreen</string>

View File

@@ -3,7 +3,7 @@
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>aps-environment</key> <key>aps-environment</key>
<string>development</string> <string>production</string>
<key>com.apple.developer.applesignin</key> <key>com.apple.developer.applesignin</key>
<array> <array>
<string>Default</string> <string>Default</string>

View File

@@ -71,6 +71,9 @@ PODS:
- ExpoModulesCore - ExpoModulesCore
- ExpoLinking (8.0.8): - ExpoLinking (8.0.8):
- ExpoModulesCore - ExpoModulesCore
- ExpoMediaLibrary (18.2.0):
- ExpoModulesCore
- React-Core
- ExpoModulesCore (3.0.21): - ExpoModulesCore (3.0.21):
- hermes-engine - hermes-engine
- RCTRequired - RCTRequired
@@ -104,7 +107,7 @@ PODS:
- ExpoModulesCore - ExpoModulesCore
- ExpoSystemUI (6.0.7): - ExpoSystemUI (6.0.7):
- ExpoModulesCore - ExpoModulesCore
- ExpoUI (0.2.0-beta.4): - ExpoUI (0.2.0-beta.7):
- ExpoModulesCore - ExpoModulesCore
- ExpoWebBrowser (15.0.8): - ExpoWebBrowser (15.0.8):
- ExpoModulesCore - ExpoModulesCore
@@ -1508,9 +1511,31 @@ PODS:
- ReactCommon/turbomodule/core - ReactCommon/turbomodule/core
- ReactNativeDependencies - ReactNativeDependencies
- Yoga - Yoga
- react-native-view-shot (4.0.3):
- hermes-engine
- RCTRequired
- RCTTypeSafety
- React-Core
- React-Core-prebuilt
- React-debug
- React-Fabric
- React-featureflags
- React-graphics
- React-ImageManager
- React-jsi
- React-NativeModulesApple
- React-RCTFabric
- React-renderercss
- React-rendererdebug
- React-utils
- ReactCodegen
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- ReactNativeDependencies
- Yoga
- react-native-voice (3.2.4): - react-native-voice (3.2.4):
- React-Core - React-Core
- react-native-webview (13.16.0): - react-native-webview (13.15.0):
- hermes-engine - hermes-engine
- RCTRequired - RCTRequired
- RCTTypeSafety - RCTTypeSafety
@@ -1927,7 +1952,7 @@ PODS:
- ReactCommon/turbomodule/core - ReactCommon/turbomodule/core
- ReactNativeDependencies - ReactNativeDependencies
- Yoga - Yoga
- RNCPicker (2.11.2): - RNCPicker (2.11.1):
- hermes-engine - hermes-engine
- RCTRequired - RCTRequired
- RCTTypeSafety - RCTTypeSafety
@@ -1949,7 +1974,7 @@ PODS:
- ReactCommon/turbomodule/core - ReactCommon/turbomodule/core
- ReactNativeDependencies - ReactNativeDependencies
- Yoga - Yoga
- RNDateTimePicker (8.4.5): - RNDateTimePicker (8.4.4):
- hermes-engine - hermes-engine
- RCTRequired - RCTRequired
- RCTTypeSafety - RCTTypeSafety
@@ -2119,7 +2144,7 @@ PODS:
- ReactCommon/turbomodule/core - ReactCommon/turbomodule/core
- ReactNativeDependencies - ReactNativeDependencies
- Yoga - Yoga
- RNSentry (7.1.0): - RNSentry (7.2.0):
- hermes-engine - hermes-engine
- RCTRequired - RCTRequired
- RCTTypeSafety - RCTTypeSafety
@@ -2141,9 +2166,9 @@ PODS:
- ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core - ReactCommon/turbomodule/core
- ReactNativeDependencies - ReactNativeDependencies
- Sentry/HybridSDK (= 8.56.0) - Sentry/HybridSDK (= 8.56.1)
- Yoga - Yoga
- RNSVG (15.14.0): - RNSVG (15.12.1):
- hermes-engine - hermes-engine
- RCTRequired - RCTRequired
- RCTTypeSafety - RCTTypeSafety
@@ -2164,9 +2189,9 @@ PODS:
- ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core - ReactCommon/turbomodule/core
- ReactNativeDependencies - ReactNativeDependencies
- RNSVG/common (= 15.14.0) - RNSVG/common (= 15.12.1)
- Yoga - Yoga
- RNSVG/common (15.14.0): - RNSVG/common (15.12.1):
- hermes-engine - hermes-engine
- RCTRequired - RCTRequired
- RCTTypeSafety - RCTTypeSafety
@@ -2270,7 +2295,7 @@ PODS:
- SDWebImageWebPCoder (0.14.6): - SDWebImageWebPCoder (0.14.6):
- libwebp (~> 1.0) - libwebp (~> 1.0)
- SDWebImage/Core (~> 5.17) - SDWebImage/Core (~> 5.17)
- Sentry/HybridSDK (8.56.0) - Sentry/HybridSDK (8.56.1)
- UMAppLoader (6.0.7) - UMAppLoader (6.0.7)
- Yoga (0.0.0) - Yoga (0.0.0)
- ZXingObjC/Core (3.6.9) - ZXingObjC/Core (3.6.9)
@@ -2300,6 +2325,7 @@ DEPENDENCIES:
- ExpoKeepAwake (from `../node_modules/expo-keep-awake/ios`) - ExpoKeepAwake (from `../node_modules/expo-keep-awake/ios`)
- ExpoLinearGradient (from `../node_modules/expo-linear-gradient/ios`) - ExpoLinearGradient (from `../node_modules/expo-linear-gradient/ios`)
- ExpoLinking (from `../node_modules/expo-linking/ios`) - ExpoLinking (from `../node_modules/expo-linking/ios`)
- ExpoMediaLibrary (from `../node_modules/expo-media-library/ios`)
- ExpoModulesCore (from `../node_modules/expo-modules-core`) - ExpoModulesCore (from `../node_modules/expo-modules-core`)
- ExpoQuickActions (from `../node_modules/expo-quick-actions/ios`) - ExpoQuickActions (from `../node_modules/expo-quick-actions/ios`)
- ExpoSplashScreen (from `../node_modules/expo-splash-screen/ios`) - ExpoSplashScreen (from `../node_modules/expo-splash-screen/ios`)
@@ -2348,6 +2374,7 @@ DEPENDENCIES:
- React-microtasksnativemodule (from `../node_modules/react-native/ReactCommon/react/nativemodule/microtasks`) - React-microtasksnativemodule (from `../node_modules/react-native/ReactCommon/react/nativemodule/microtasks`)
- react-native-render-html (from `../node_modules/react-native-render-html`) - react-native-render-html (from `../node_modules/react-native-render-html`)
- react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`) - react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`)
- react-native-view-shot (from `../node_modules/react-native-view-shot`)
- "react-native-voice (from `../node_modules/@react-native-voice/voice`)" - "react-native-voice (from `../node_modules/@react-native-voice/voice`)"
- react-native-webview (from `../node_modules/react-native-webview`) - react-native-webview (from `../node_modules/react-native-webview`)
- React-NativeModulesApple (from `../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios`) - React-NativeModulesApple (from `../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios`)
@@ -2452,6 +2479,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/expo-linear-gradient/ios" :path: "../node_modules/expo-linear-gradient/ios"
ExpoLinking: ExpoLinking:
:path: "../node_modules/expo-linking/ios" :path: "../node_modules/expo-linking/ios"
ExpoMediaLibrary:
:path: "../node_modules/expo-media-library/ios"
ExpoModulesCore: ExpoModulesCore:
:path: "../node_modules/expo-modules-core" :path: "../node_modules/expo-modules-core"
ExpoQuickActions: ExpoQuickActions:
@@ -2547,6 +2576,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native-render-html" :path: "../node_modules/react-native-render-html"
react-native-safe-area-context: react-native-safe-area-context:
:path: "../node_modules/react-native-safe-area-context" :path: "../node_modules/react-native-safe-area-context"
react-native-view-shot:
:path: "../node_modules/react-native-view-shot"
react-native-voice: react-native-voice:
:path: "../node_modules/@react-native-voice/voice" :path: "../node_modules/@react-native-voice/voice"
react-native-webview: react-native-webview:
@@ -2663,13 +2694,14 @@ SPEC CHECKSUMS:
ExpoKeepAwake: 1a2e820692e933c94a565ec3fbbe38ac31658ffe ExpoKeepAwake: 1a2e820692e933c94a565ec3fbbe38ac31658ffe
ExpoLinearGradient: a464898cb95153125e3b81894fd479bcb1c7dd27 ExpoLinearGradient: a464898cb95153125e3b81894fd479bcb1c7dd27
ExpoLinking: f051f28e50ea9269ff539317c166adec81d9342d ExpoLinking: f051f28e50ea9269ff539317c166adec81d9342d
ExpoMediaLibrary: 641a6952299b395159ccd459bd8f5f6764bf55fe
ExpoModulesCore: 3a6eb12a5f4d67b2f5fc7d0bc4777b18348f2d7a ExpoModulesCore: 3a6eb12a5f4d67b2f5fc7d0bc4777b18348f2d7a
ExpoQuickActions: 31a70aa6a606128de4416a4830e09cfabfe6667f ExpoQuickActions: 31a70aa6a606128de4416a4830e09cfabfe6667f
ExpoSplashScreen: cbb839de72110dea1851dd3e85080b7923af2540 ExpoSplashScreen: cbb839de72110dea1851dd3e85080b7923af2540
ExpoSQLite: 7fa091ba5562474093fef09be644161a65e11b3f ExpoSQLite: 7fa091ba5562474093fef09be644161a65e11b3f
ExpoSymbols: 1ae04ce686de719b9720453b988d8bc5bf776c68 ExpoSymbols: 1ae04ce686de719b9720453b988d8bc5bf776c68
ExpoSystemUI: 6cd74248a2282adf6dec488a75fa532d69dee314 ExpoSystemUI: 6cd74248a2282adf6dec488a75fa532d69dee314
ExpoUI: 5e44b62e2589b7bc8a6123943105a230c693d000 ExpoUI: b99a1d1ef5352a60bebf4f4fd3a50d2f896ae804
ExpoWebBrowser: d04a0d6247a0bea4519fbc2ea816610019ad83e0 ExpoWebBrowser: d04a0d6247a0bea4519fbc2ea816610019ad83e0
EXTaskManager: cf225704fab8de8794a6f57f7fa41a90c0e2cd47 EXTaskManager: cf225704fab8de8794a6f57f7fa41a90c0e2cd47
FBLazyVector: 9e0cd874afd81d9a4d36679daca991b58b260d42 FBLazyVector: 9e0cd874afd81d9a4d36679daca991b58b260d42
@@ -2715,8 +2747,9 @@ SPEC CHECKSUMS:
React-microtasksnativemodule: 76905804171d8ccbe69329fc84c57eb7934add7f React-microtasksnativemodule: 76905804171d8ccbe69329fc84c57eb7934add7f
react-native-render-html: 5afc4751f1a98621b3009432ef84c47019dcb2bd react-native-render-html: 5afc4751f1a98621b3009432ef84c47019dcb2bd
react-native-safe-area-context: 42a1b4f8774b577d03b53de7326e3d5757fe9513 react-native-safe-area-context: 42a1b4f8774b577d03b53de7326e3d5757fe9513
react-native-view-shot: fb3c0774edb448f42705491802a455beac1502a2
react-native-voice: 908a0eba96c8c3d643e4f98b7232c6557d0a6f9c react-native-voice: 908a0eba96c8c3d643e4f98b7232c6557d0a6f9c
react-native-webview: 3e303e80cadb5f17118c8c1502aa398e9287e415 react-native-webview: b29007f4723bca10872028067b07abacfa1cb35a
React-NativeModulesApple: a9464983ccc0f66f45e93558671f60fc7536e438 React-NativeModulesApple: a9464983ccc0f66f45e93558671f60fc7536e438
React-oscompat: 73db7dbc80edef36a9d6ed3c6c4e1724ead4236d React-oscompat: 73db7dbc80edef36a9d6ed3c6c4e1724ead4236d
React-perflogger: 123272debf907cc423962adafcf4513320e43757 React-perflogger: 123272debf907cc423962adafcf4513320e43757
@@ -2751,21 +2784,21 @@ SPEC CHECKSUMS:
RevenueCat: a51003d4cb33820cc504cf177c627832b462a98e RevenueCat: a51003d4cb33820cc504cf177c627832b462a98e
RNCAsyncStorage: 3a4f5e2777dae1688b781a487923a08569e27fe4 RNCAsyncStorage: 3a4f5e2777dae1688b781a487923a08569e27fe4
RNCMaskedView: d2578d41c59b936db122b2798ba37e4722d21035 RNCMaskedView: d2578d41c59b936db122b2798ba37e4722d21035
RNCPicker: ddce382c4b42ea2ee36dd588066f0c6d5a240707 RNCPicker: a7170edbcbf8288de8edb2502e08e7fc757fa755
RNDateTimePicker: 7dda2673bd2a6022ea8888fe669d735b2eac0b2d RNDateTimePicker: be0e44bcb9ed0607c7c5f47dbedd88cf091f6791
RNDeviceInfo: bcce8752b5043a623fe3c26789679b473f705d3c RNDeviceInfo: bcce8752b5043a623fe3c26789679b473f705d3c
RNGestureHandler: 2914750df066d89bf9d8f48a10ad5f0051108ac3 RNGestureHandler: 2914750df066d89bf9d8f48a10ad5f0051108ac3
RNPurchases: 2569675abdc1dbc739f2eec0fa564a112cf860de RNPurchases: 2569675abdc1dbc739f2eec0fa564a112cf860de
RNReanimated: 3895a29fdf77bbe2a627e1ed599a5e5d1df76c29 RNReanimated: 3895a29fdf77bbe2a627e1ed599a5e5d1df76c29
RNScreens: d8d6f1792f6e7ac12b0190d33d8d390efc0c1845 RNScreens: d8d6f1792f6e7ac12b0190d33d8d390efc0c1845
RNSentry: dbee413744aec703b8763b620b14ed7a1e2db095 RNSentry: 41979b419908128847ef662cc130a400b7576fa9
RNSVG: 6c534e37eaaefe882b3f55294d0d607de20562dc RNSVG: 31d6639663c249b7d5abc9728dde2041eb2a3c34
RNWorklets: 54d8dffb7f645873a58484658ddfd4bd1a9a0bc1 RNWorklets: 54d8dffb7f645873a58484658ddfd4bd1a9a0bc1
SDWebImage: 16309af6d214ba3f77a7c6f6fdda888cb313a50a SDWebImage: 16309af6d214ba3f77a7c6f6fdda888cb313a50a
SDWebImageAVIFCoder: afe194a084e851f70228e4be35ef651df0fc5c57 SDWebImageAVIFCoder: afe194a084e851f70228e4be35ef651df0fc5c57
SDWebImageSVGCoder: 15a300a97ec1c8ac958f009c02220ac0402e936c SDWebImageSVGCoder: 15a300a97ec1c8ac958f009c02220ac0402e936c
SDWebImageWebPCoder: e38c0a70396191361d60c092933e22c20d5b1380 SDWebImageWebPCoder: e38c0a70396191361d60c092933e22c20d5b1380
Sentry: 3d82977434c80381cae856c40b99c39e4be6bc11 Sentry: b3ec44d01708fce73f99b544beb57e890eca4406
UMAppLoader: e1234c45d2b7da239e9e90fc4bbeacee12afd5b6 UMAppLoader: e1234c45d2b7da239e9e90fc4bbeacee12afd5b6
Yoga: 051f086b5ccf465ff2ed38a2cf5a558ae01aaaa1 Yoga: 051f086b5ccf465ff2ed38a2cf5a558ae01aaaa1
ZXingObjC: 8898711ab495761b2dbbdec76d90164a6d7e14c5 ZXingObjC: 8898711ab495761b2dbbdec76d90164a6d7e14c5

280
package-lock.json generated
View File

@@ -9,18 +9,18 @@
"version": "1.0.2", "version": "1.0.2",
"dependencies": { "dependencies": {
"@expo/metro-runtime": "~6.1.2", "@expo/metro-runtime": "~6.1.2",
"@expo/ui": "~0.2.0-beta.4", "@expo/ui": "~0.2.0-beta.7",
"@expo/vector-icons": "^15.0.2", "@expo/vector-icons": "^15.0.2",
"@react-native-async-storage/async-storage": "^2.2.0", "@react-native-async-storage/async-storage": "^2.2.0",
"@react-native-community/datetimepicker": "8.4.5", "@react-native-community/datetimepicker": "8.4.4",
"@react-native-masked-view/masked-view": "^0.3.2", "@react-native-masked-view/masked-view": "^0.3.2",
"@react-native-picker/picker": "2.11.2", "@react-native-picker/picker": "2.11.1",
"@react-native-voice/voice": "^3.2.4", "@react-native-voice/voice": "^3.2.4",
"@react-navigation/bottom-tabs": "^7.4.7", "@react-navigation/bottom-tabs": "^7.4.0",
"@react-navigation/elements": "^2.6.4", "@react-navigation/elements": "^2.6.4",
"@react-navigation/native": "^7.1.17", "@react-navigation/native": "^7.1.8",
"@reduxjs/toolkit": "^2.9.0", "@reduxjs/toolkit": "^2.9.0",
"@sentry/react-native": "~7.1.0", "@sentry/react-native": "~7.2.0",
"@types/lodash": "^4.17.20", "@types/lodash": "^4.17.20",
"dayjs": "^1.11.18", "dayjs": "^1.11.18",
"expo": "^54.0.13", "expo": "^54.0.13",
@@ -36,6 +36,7 @@
"expo-image-picker": "~17.0.8", "expo-image-picker": "~17.0.8",
"expo-linear-gradient": "~15.0.7", "expo-linear-gradient": "~15.0.7",
"expo-linking": "~8.0.8", "expo-linking": "~8.0.8",
"expo-media-library": "^18.2.0",
"expo-notifications": "~0.32.12", "expo-notifications": "~0.32.12",
"expo-quick-actions": "^6.0.0", "expo-quick-actions": "^6.0.0",
"expo-router": "~6.0.12", "expo-router": "~6.0.12",
@@ -63,10 +64,11 @@
"react-native-render-html": "^6.3.4", "react-native-render-html": "^6.3.4",
"react-native-safe-area-context": "~5.6.1", "react-native-safe-area-context": "~5.6.1",
"react-native-screens": "~4.16.0", "react-native-screens": "~4.16.0",
"react-native-svg": "^15.13.0", "react-native-svg": "15.12.1",
"react-native-toast-message": "^2.3.3", "react-native-toast-message": "^2.3.3",
"react-native-view-shot": "^4.0.3",
"react-native-web": "^0.21.1", "react-native-web": "^0.21.1",
"react-native-webview": "13.16.0", "react-native-webview": "13.15.0",
"react-native-wheel-picker-expo": "^0.5.4", "react-native-wheel-picker-expo": "^0.5.4",
"react-redux": "^9.2.0" "react-redux": "^9.2.0"
}, },
@@ -2224,9 +2226,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/@expo/ui": { "node_modules/@expo/ui": {
"version": "0.2.0-beta.4", "version": "0.2.0-beta.7",
"resolved": "https://mirrors.tencent.com/npm/@expo/ui/-/ui-0.2.0-beta.4.tgz", "resolved": "https://mirrors.tencent.com/npm/@expo/ui/-/ui-0.2.0-beta.7.tgz",
"integrity": "sha512-49DoNCQ5jyLFvnTZpVU1aMSbfgRtX4QQtnX7WM97A7dJhocvaF7g7MA3LBeoZ07MMVKuuwfcIBM2F/f52S+6zw==", "integrity": "sha512-oz2HEpwll+yMFUKbryZ84IgxjLx7RPxxMDVKpCEsK0OhETrLF5NxHlpCkKjdLuQL3QiVSvj5kn6hBFknco3aCw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"sf-symbols-typescript": "^2.1.0" "sf-symbols-typescript": "^2.1.0"
@@ -3031,9 +3033,9 @@
} }
}, },
"node_modules/@react-native-community/datetimepicker": { "node_modules/@react-native-community/datetimepicker": {
"version": "8.4.5", "version": "8.4.4",
"resolved": "https://mirrors.tencent.com/npm/@react-native-community/datetimepicker/-/datetimepicker-8.4.5.tgz", "resolved": "https://mirrors.tencent.com/npm/@react-native-community/datetimepicker/-/datetimepicker-8.4.4.tgz",
"integrity": "sha512-vvVOJAHjU8TFBzTUjQzANCL6C3pZSE2zjfutCATk790uz7ASEc2tOBD+EIG4BTelWtP2G9jqvXp2L7XGdhEBRg==", "integrity": "sha512-bc4ZixEHxZC9/qf5gbdYvIJiLZ5CLmEsC3j+Yhe1D1KC/3QhaIfGDVdUcid0PdlSoGOSEq4VlB93AWyetEyBSQ==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"invariant": "^2.2.4" "invariant": "^2.2.4"
@@ -3064,9 +3066,9 @@
} }
}, },
"node_modules/@react-native-picker/picker": { "node_modules/@react-native-picker/picker": {
"version": "2.11.2", "version": "2.11.1",
"resolved": "https://mirrors.tencent.com/npm/@react-native-picker/picker/-/picker-2.11.2.tgz", "resolved": "https://mirrors.tencent.com/npm/@react-native-picker/picker/-/picker-2.11.1.tgz",
"integrity": "sha512-2zyFdW4jgHjF+NeuDZ4nl3hJ+8suey69bI3yljqhNyowfklW2NwNrdDUaJ2iwtPCpk2pt7834aPF8TI6iyZRhA==", "integrity": "sha512-ThklnkK4fV3yynnIIRBkxxjxR4IFbdMNJVF6tlLdOJ/zEFUEFUEdXY0KmH0iYzMwY8W4/InWsLiA7AkpAbnexA==",
"license": "MIT", "license": "MIT",
"workspaces": [ "workspaces": [
"example" "example"
@@ -3717,9 +3719,9 @@
} }
}, },
"node_modules/@sentry/cli": { "node_modules/@sentry/cli": {
"version": "2.53.0", "version": "2.55.0",
"resolved": "https://mirrors.tencent.com/npm/@sentry/cli/-/cli-2.53.0.tgz", "resolved": "https://mirrors.tencent.com/npm/@sentry/cli/-/cli-2.55.0.tgz",
"integrity": "sha512-n2ZNb+5Z6AZKQSI0SusQ7ZzFL637mfw3Xh4C3PEyVSn9LiF683fX0TTq8OeGmNZQS4maYfS95IFD+XpydU0dEA==", "integrity": "sha512-cynvcIM2xL8ddwELyFRSpZQw4UtFZzoM2rId2l9vg7+wDREPDocMJB9lEQpBIo3eqhp9JswqUT037yjO6iJ5Sw==",
"hasInstallScript": true, "hasInstallScript": true,
"license": "BSD-3-Clause", "license": "BSD-3-Clause",
"dependencies": { "dependencies": {
@@ -3736,20 +3738,20 @@
"node": ">= 10" "node": ">= 10"
}, },
"optionalDependencies": { "optionalDependencies": {
"@sentry/cli-darwin": "2.53.0", "@sentry/cli-darwin": "2.55.0",
"@sentry/cli-linux-arm": "2.53.0", "@sentry/cli-linux-arm": "2.55.0",
"@sentry/cli-linux-arm64": "2.53.0", "@sentry/cli-linux-arm64": "2.55.0",
"@sentry/cli-linux-i686": "2.53.0", "@sentry/cli-linux-i686": "2.55.0",
"@sentry/cli-linux-x64": "2.53.0", "@sentry/cli-linux-x64": "2.55.0",
"@sentry/cli-win32-arm64": "2.53.0", "@sentry/cli-win32-arm64": "2.55.0",
"@sentry/cli-win32-i686": "2.53.0", "@sentry/cli-win32-i686": "2.55.0",
"@sentry/cli-win32-x64": "2.53.0" "@sentry/cli-win32-x64": "2.55.0"
} }
}, },
"node_modules/@sentry/cli-darwin": { "node_modules/@sentry/cli-darwin": {
"version": "2.53.0", "version": "2.55.0",
"resolved": "https://mirrors.tencent.com/npm/@sentry/cli-darwin/-/cli-darwin-2.53.0.tgz", "resolved": "https://mirrors.tencent.com/npm/@sentry/cli-darwin/-/cli-darwin-2.55.0.tgz",
"integrity": "sha512-NNPfpILMwKgpHiyJubHHuauMKltkrgLQ5tvMdxNpxY60jBNdo5VJtpESp4XmXlnidzV4j1z61V4ozU6ttDgt5Q==", "integrity": "sha512-jGHE7SHHzqXUmnsmRLgorVH6nmMmTjQQXdPZbSL5tRtH8d3OIYrVNr5D72DSgD26XAPBDMV0ibqOQ9NKoiSpfA==",
"license": "BSD-3-Clause", "license": "BSD-3-Clause",
"optional": true, "optional": true,
"os": [ "os": [
@@ -3759,6 +3761,128 @@
"node": ">=10" "node": ">=10"
} }
}, },
"node_modules/@sentry/cli-linux-arm": {
"version": "2.55.0",
"resolved": "https://mirrors.tencent.com/npm/@sentry/cli-linux-arm/-/cli-linux-arm-2.55.0.tgz",
"integrity": "sha512-ATjU0PsiWADSPLF/kZroLZ7FPKd5W9TDWHVkKNwIUNTei702LFgTjNeRwOIzTgSvG3yTmVEqtwFQfFN/7hnVXQ==",
"cpu": [
"arm"
],
"license": "BSD-3-Clause",
"optional": true,
"os": [
"linux",
"freebsd",
"android"
],
"engines": {
"node": ">=10"
}
},
"node_modules/@sentry/cli-linux-arm64": {
"version": "2.55.0",
"resolved": "https://mirrors.tencent.com/npm/@sentry/cli-linux-arm64/-/cli-linux-arm64-2.55.0.tgz",
"integrity": "sha512-jNB/0/gFcOuDCaY/TqeuEpsy/k52dwyk1SOV3s1ku4DUsln6govTppeAGRewY3T1Rj9B2vgIWTrnB8KVh9+Rgg==",
"cpu": [
"arm64"
],
"license": "BSD-3-Clause",
"optional": true,
"os": [
"linux",
"freebsd",
"android"
],
"engines": {
"node": ">=10"
}
},
"node_modules/@sentry/cli-linux-i686": {
"version": "2.55.0",
"resolved": "https://mirrors.tencent.com/npm/@sentry/cli-linux-i686/-/cli-linux-i686-2.55.0.tgz",
"integrity": "sha512-8LZjo6PncTM6bWdaggscNOi5r7F/fqRREsCwvd51dcjGj7Kp1plqo9feEzYQ+jq+KUzVCiWfHrUjddFmYyZJrg==",
"cpu": [
"x86",
"ia32"
],
"license": "BSD-3-Clause",
"optional": true,
"os": [
"linux",
"freebsd",
"android"
],
"engines": {
"node": ">=10"
}
},
"node_modules/@sentry/cli-linux-x64": {
"version": "2.55.0",
"resolved": "https://mirrors.tencent.com/npm/@sentry/cli-linux-x64/-/cli-linux-x64-2.55.0.tgz",
"integrity": "sha512-5LUVvq74Yj2cZZy5g5o/54dcWEaX4rf3myTHy73AKhRj1PABtOkfexOLbF9xSrZy95WXWaXyeH+k5n5z/vtHfA==",
"cpu": [
"x64"
],
"license": "BSD-3-Clause",
"optional": true,
"os": [
"linux",
"freebsd",
"android"
],
"engines": {
"node": ">=10"
}
},
"node_modules/@sentry/cli-win32-arm64": {
"version": "2.55.0",
"resolved": "https://mirrors.tencent.com/npm/@sentry/cli-win32-arm64/-/cli-win32-arm64-2.55.0.tgz",
"integrity": "sha512-cWIQdzm1pfLwPARsV6dUb8TVd6Y3V1A2VWxjTons3Ift6GvtVmiAe0OWL8t2Yt95i8v61kTD/6Tq21OAaogqzA==",
"cpu": [
"arm64"
],
"license": "BSD-3-Clause",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=10"
}
},
"node_modules/@sentry/cli-win32-i686": {
"version": "2.55.0",
"resolved": "https://mirrors.tencent.com/npm/@sentry/cli-win32-i686/-/cli-win32-i686-2.55.0.tgz",
"integrity": "sha512-ldepCn2t9r4I0wvgk7NRaA7coJyy4rTQAzM66u9j5nTEsUldf66xym6esd5ZZRAaJUjffqvHqUIr/lrieTIrVg==",
"cpu": [
"x86",
"ia32"
],
"license": "BSD-3-Clause",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=10"
}
},
"node_modules/@sentry/cli-win32-x64": {
"version": "2.55.0",
"resolved": "https://mirrors.tencent.com/npm/@sentry/cli-win32-x64/-/cli-win32-x64-2.55.0.tgz",
"integrity": "sha512-4hPc/I/9tXx+HLTdTGwlagtAfDSIa2AoTUP30tl32NAYQhx9a6niUbPAemK2qfxesiufJ7D2djX83rCw6WnJVA==",
"cpu": [
"x64"
],
"license": "BSD-3-Clause",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=10"
}
},
"node_modules/@sentry/cli/node_modules/agent-base": { "node_modules/@sentry/cli/node_modules/agent-base": {
"version": "6.0.2", "version": "6.0.2",
"resolved": "https://mirrors.tencent.com/npm/agent-base/-/agent-base-6.0.2.tgz", "resolved": "https://mirrors.tencent.com/npm/agent-base/-/agent-base-6.0.2.tgz",
@@ -3811,14 +3935,14 @@
} }
}, },
"node_modules/@sentry/react-native": { "node_modules/@sentry/react-native": {
"version": "7.1.0", "version": "7.2.0",
"resolved": "https://mirrors.tencent.com/npm/@sentry/react-native/-/react-native-7.1.0.tgz", "resolved": "https://mirrors.tencent.com/npm/@sentry/react-native/-/react-native-7.2.0.tgz",
"integrity": "sha512-Nhs/1j+w7cl9Q+FmaBl0+nByeAKpZttWFz1R0YkZJsg01b+4g63pepI3WMwUSq2QrvYIAu/5PiUoTa2dx9HK6g==", "integrity": "sha512-rjqYgEjntPz1sPysud78wi4B9ui7LBVPsG6qr8s/htLMYho9GPGFA5dF+eqsQWqMX8NDReAxNkLTC4+gCNklLQ==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@sentry/babel-plugin-component-annotate": "4.3.0", "@sentry/babel-plugin-component-annotate": "4.3.0",
"@sentry/browser": "10.12.0", "@sentry/browser": "10.12.0",
"@sentry/cli": "2.53.0", "@sentry/cli": "2.55.0",
"@sentry/core": "10.12.0", "@sentry/core": "10.12.0",
"@sentry/react": "10.12.0", "@sentry/react": "10.12.0",
"@sentry/types": "10.12.0" "@sentry/types": "10.12.0"
@@ -5052,6 +5176,15 @@
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/base64-arraybuffer": {
"version": "1.0.2",
"resolved": "https://mirrors.tencent.com/npm/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz",
"integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==",
"license": "MIT",
"engines": {
"node": ">= 0.6.0"
}
},
"node_modules/base64-js": { "node_modules/base64-js": {
"version": "1.5.1", "version": "1.5.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
@@ -5819,6 +5952,14 @@
"hyphenate-style-name": "^1.0.3" "hyphenate-style-name": "^1.0.3"
} }
}, },
"node_modules/css-line-break": {
"version": "2.1.0",
"resolved": "https://mirrors.tencent.com/npm/css-line-break/-/css-line-break-2.1.0.tgz",
"integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==",
"dependencies": {
"utrie": "^1.0.2"
}
},
"node_modules/css-select": { "node_modules/css-select": {
"version": "5.2.2", "version": "5.2.2",
"resolved": "https://mirrors.tencent.com/npm/css-select/-/css-select-5.2.2.tgz", "resolved": "https://mirrors.tencent.com/npm/css-select/-/css-select-5.2.2.tgz",
@@ -7174,6 +7315,16 @@
"react-native": "*" "react-native": "*"
} }
}, },
"node_modules/expo-media-library": {
"version": "18.2.0",
"resolved": "https://mirrors.tencent.com/npm/expo-media-library/-/expo-media-library-18.2.0.tgz",
"integrity": "sha512-aIYLIqmU8LFWrQcfZdwg9f/iWm0wC8uhZ7HiUiTnrigtxf417cVvNokX9afXpIOKBHAHRjVIbcs1nN8KZDE2Fw==",
"license": "MIT",
"peerDependencies": {
"expo": "*",
"react-native": "*"
}
},
"node_modules/expo-modules-autolinking": { "node_modules/expo-modules-autolinking": {
"version": "3.0.15", "version": "3.0.15",
"resolved": "https://mirrors.tencent.com/npm/expo-modules-autolinking/-/expo-modules-autolinking-3.0.15.tgz", "resolved": "https://mirrors.tencent.com/npm/expo-modules-autolinking/-/expo-modules-autolinking-3.0.15.tgz",
@@ -8487,6 +8638,19 @@
"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
"license": "ISC" "license": "ISC"
}, },
"node_modules/html2canvas": {
"version": "1.4.1",
"resolved": "https://mirrors.tencent.com/npm/html2canvas/-/html2canvas-1.4.1.tgz",
"integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==",
"license": "MIT",
"dependencies": {
"css-line-break": "^2.1.0",
"text-segmentation": "^1.0.3"
},
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/htmlparser2": { "node_modules/htmlparser2": {
"version": "7.2.0", "version": "7.2.0",
"resolved": "https://mirrors.tencent.com/npm/htmlparser2/-/htmlparser2-7.2.0.tgz", "resolved": "https://mirrors.tencent.com/npm/htmlparser2/-/htmlparser2-7.2.0.tgz",
@@ -11526,8 +11690,7 @@
"node_modules/proxy-from-env": { "node_modules/proxy-from-env": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://mirrors.tencent.com/npm/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "resolved": "https://mirrors.tencent.com/npm/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
"license": "MIT"
}, },
"node_modules/punycode": { "node_modules/punycode": {
"version": "2.3.1", "version": "2.3.1",
@@ -11952,9 +12115,9 @@
} }
}, },
"node_modules/react-native-svg": { "node_modules/react-native-svg": {
"version": "15.14.0", "version": "15.12.1",
"resolved": "https://mirrors.tencent.com/npm/react-native-svg/-/react-native-svg-15.14.0.tgz", "resolved": "https://mirrors.tencent.com/npm/react-native-svg/-/react-native-svg-15.12.1.tgz",
"integrity": "sha512-B3gYc7WztcOT4N54AtUutbe0Nuqqh/nkresY0fAXzUHYLsWuIu/yGiCCD3DKfAs6GLv5LFtWTu7N333Q+e3bkg==", "integrity": "sha512-vCuZJDf8a5aNC2dlMovEv4Z0jjEUET53lm/iILFnFewa15b4atjVxU6Wirm6O9y6dEsdjDZVD7Q3QM4T1wlI8g==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"css-select": "^5.1.0", "css-select": "^5.1.0",
@@ -11976,6 +12139,19 @@
"react-native": "*" "react-native": "*"
} }
}, },
"node_modules/react-native-view-shot": {
"version": "4.0.3",
"resolved": "https://mirrors.tencent.com/npm/react-native-view-shot/-/react-native-view-shot-4.0.3.tgz",
"integrity": "sha512-USNjYmED7C0me02c1DxKA0074Hw+y/nxo+xJKlffMvfUWWzL5ELh/TJA/pTnVqFurIrzthZDPtDM7aBFJuhrHQ==",
"license": "MIT",
"dependencies": {
"html2canvas": "^1.4.1"
},
"peerDependencies": {
"react": "*",
"react-native": "*"
}
},
"node_modules/react-native-web": { "node_modules/react-native-web": {
"version": "0.21.1", "version": "0.21.1",
"resolved": "https://registry.npmjs.org/react-native-web/-/react-native-web-0.21.1.tgz", "resolved": "https://registry.npmjs.org/react-native-web/-/react-native-web-0.21.1.tgz",
@@ -12009,9 +12185,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/react-native-webview": { "node_modules/react-native-webview": {
"version": "13.16.0", "version": "13.15.0",
"resolved": "https://mirrors.tencent.com/npm/react-native-webview/-/react-native-webview-13.16.0.tgz", "resolved": "https://mirrors.tencent.com/npm/react-native-webview/-/react-native-webview-13.15.0.tgz",
"integrity": "sha512-Nh13xKZWW35C0dbOskD7OX01nQQavOzHbCw9XoZmar4eXCo7AvrYJ0jlUfRVVIJzqINxHlpECYLdmAdFsl9xDA==", "integrity": "sha512-Vzjgy8mmxa/JO6l5KZrsTC7YemSdq+qB01diA0FqjUTaWGAGwuykpJ73MDj3+mzBSlaDxAEugHzTtkUQkQEQeQ==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"escape-string-regexp": "^4.0.0", "escape-string-regexp": "^4.0.0",
@@ -13634,6 +13810,15 @@
"url": "https://github.com/sponsors/isaacs" "url": "https://github.com/sponsors/isaacs"
} }
}, },
"node_modules/text-segmentation": {
"version": "1.0.3",
"resolved": "https://mirrors.tencent.com/npm/text-segmentation/-/text-segmentation-1.0.3.tgz",
"integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==",
"license": "MIT",
"dependencies": {
"utrie": "^1.0.2"
}
},
"node_modules/thenify": { "node_modules/thenify": {
"version": "3.3.1", "version": "3.3.1",
"resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
@@ -14210,6 +14395,15 @@
"node": ">= 0.4.0" "node": ">= 0.4.0"
} }
}, },
"node_modules/utrie": {
"version": "1.0.2",
"resolved": "https://mirrors.tencent.com/npm/utrie/-/utrie-1.0.2.tgz",
"integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==",
"license": "MIT",
"dependencies": {
"base64-arraybuffer": "^1.0.2"
}
},
"node_modules/uuid": { "node_modules/uuid": {
"version": "7.0.3", "version": "7.0.3",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz", "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz",

View File

@@ -10,18 +10,18 @@
}, },
"dependencies": { "dependencies": {
"@expo/metro-runtime": "~6.1.2", "@expo/metro-runtime": "~6.1.2",
"@expo/ui": "~0.2.0-beta.4", "@expo/ui": "~0.2.0-beta.7",
"@expo/vector-icons": "^15.0.2", "@expo/vector-icons": "^15.0.2",
"@react-native-async-storage/async-storage": "^2.2.0", "@react-native-async-storage/async-storage": "^2.2.0",
"@react-native-community/datetimepicker": "8.4.5", "@react-native-community/datetimepicker": "8.4.4",
"@react-native-masked-view/masked-view": "^0.3.2", "@react-native-masked-view/masked-view": "^0.3.2",
"@react-native-picker/picker": "2.11.2", "@react-native-picker/picker": "2.11.1",
"@react-native-voice/voice": "^3.2.4", "@react-native-voice/voice": "^3.2.4",
"@react-navigation/bottom-tabs": "^7.4.7", "@react-navigation/bottom-tabs": "^7.4.0",
"@react-navigation/elements": "^2.6.4", "@react-navigation/elements": "^2.6.4",
"@react-navigation/native": "^7.1.17", "@react-navigation/native": "^7.1.8",
"@reduxjs/toolkit": "^2.9.0", "@reduxjs/toolkit": "^2.9.0",
"@sentry/react-native": "~7.1.0", "@sentry/react-native": "~7.2.0",
"@types/lodash": "^4.17.20", "@types/lodash": "^4.17.20",
"dayjs": "^1.11.18", "dayjs": "^1.11.18",
"expo": "^54.0.13", "expo": "^54.0.13",
@@ -37,6 +37,7 @@
"expo-image-picker": "~17.0.8", "expo-image-picker": "~17.0.8",
"expo-linear-gradient": "~15.0.7", "expo-linear-gradient": "~15.0.7",
"expo-linking": "~8.0.8", "expo-linking": "~8.0.8",
"expo-media-library": "^18.2.0",
"expo-notifications": "~0.32.12", "expo-notifications": "~0.32.12",
"expo-quick-actions": "^6.0.0", "expo-quick-actions": "^6.0.0",
"expo-router": "~6.0.12", "expo-router": "~6.0.12",
@@ -64,10 +65,11 @@
"react-native-render-html": "^6.3.4", "react-native-render-html": "^6.3.4",
"react-native-safe-area-context": "~5.6.1", "react-native-safe-area-context": "~5.6.1",
"react-native-screens": "~4.16.0", "react-native-screens": "~4.16.0",
"react-native-svg": "^15.13.0", "react-native-svg": "15.12.1",
"react-native-toast-message": "^2.3.3", "react-native-toast-message": "^2.3.3",
"react-native-view-shot": "^4.0.3",
"react-native-web": "^0.21.1", "react-native-web": "^0.21.1",
"react-native-webview": "13.16.0", "react-native-webview": "13.15.0",
"react-native-wheel-picker-expo": "^0.5.4", "react-native-wheel-picker-expo": "^0.5.4",
"react-redux": "^9.2.0" "react-redux": "^9.2.0"
}, },
@@ -79,4 +81,4 @@
"typescript": "~5.9.2" "typescript": "~5.9.2"
}, },
"private": true "private": true
} }

View File

@@ -4,7 +4,7 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import type { RootState } from './index'; import type { RootState } from './index';
export type FastingScheduleOrigin = 'manual' | 'recommended' | 'quick-start'; export type FastingScheduleOrigin = 'manual' | 'recommended' | 'quick-start' | 'auto';
export type FastingSchedule = { export type FastingSchedule = {
planId: string; planId: string;