diff --git a/app/(tabs)/goals.tsx b/app/(tabs)/goals.tsx index 6257c3a..79427a9 100644 --- a/app/(tabs)/goals.tsx +++ b/app/(tabs)/goals.tsx @@ -512,7 +512,7 @@ export default function GoalsScreen() { text: '每日目标通知', onPress: async () => { try { - const userName = userProfile?.name || '小海豹'; + const userName = userProfile?.name || ''; const notificationIds = await GoalNotificationHelpers.scheduleGoalNotifications( { title: '每日运动目标', @@ -533,7 +533,7 @@ export default function GoalsScreen() { text: '每周目标通知', onPress: async () => { try { - const userName = userProfile?.name || '小海豹'; + const userName = userProfile?.name || ''; const notificationIds = await GoalNotificationHelpers.scheduleGoalNotifications( { title: '每周运动目标', @@ -557,7 +557,7 @@ export default function GoalsScreen() { text: '目标达成通知', onPress: async () => { try { - const userName = userProfile?.name || '小海豹'; + const userName = userProfile?.name || ''; await GoalNotificationHelpers.sendGoalAchievementNotification(userName, '每日运动目标'); Alert.alert('成功', '目标达成通知已发送'); } catch (error) { diff --git a/app/(tabs)/personal.tsx b/app/(tabs)/personal.tsx index d1597e9..ec9d66f 100644 --- a/app/(tabs)/personal.tsx +++ b/app/(tabs)/personal.tsx @@ -6,12 +6,14 @@ import { useAppDispatch, useAppSelector } from '@/hooks/redux'; import { useAuthGuard } from '@/hooks/useAuthGuard'; import { useNotifications } from '@/hooks/useNotifications'; import { DEFAULT_MEMBER_NAME, fetchActivityHistory, fetchMyProfile } from '@/store/userSlice'; +import { getItem, setItem } from '@/utils/kvStore'; import { log } from '@/utils/logger'; import { getNotificationEnabled, setNotificationEnabled as saveNotificationEnabled } from '@/utils/userPreferences'; -import { getItem, setItem } from '@/utils/kvStore'; +import { Button, Host, Text as SwiftText } from '@expo/ui/swift-ui'; +import { frame, glassEffect } from '@expo/ui/swift-ui/modifiers'; import { Ionicons } from '@expo/vector-icons'; - import { useFocusEffect } from '@react-navigation/native'; +import { isLiquidGlassAvailable } from 'expo-glass-effect'; import { Image } from 'expo-image'; import { LinearGradient } from 'expo-linear-gradient'; import React, { useEffect, useMemo, useRef, useState } from 'react'; @@ -25,6 +27,7 @@ export default function PersonalScreen() { const { confirmLogout, confirmDeleteAccount, isLoggedIn, pushIfAuthedElseLogin } = useAuthGuard(); const insets = useSafeAreaInsets(); + const isLgAvaliable = isLiquidGlassAvailable() // 推送通知相关 const { @@ -212,9 +215,35 @@ export default function PersonalScreen() { {displayName} - pushIfAuthedElseLogin('/profile/edit')}> + {isLgAvaliable ? + + : pushIfAuthedElseLogin('/profile/edit')}> 编辑 - + } + + @@ -381,7 +410,7 @@ export default function PersonalScreen() { transition={200} cachePolicy="memory-disk" /> */} - 鱼干记录 + 能量记录 {menuSections.map((section, index) => ( diff --git a/app/voice-record.tsx b/app/voice-record.tsx index d07bdcd..4cad8d2 100644 --- a/app/voice-record.tsx +++ b/app/voice-record.tsx @@ -9,7 +9,7 @@ import { Ionicons } from '@expo/vector-icons'; import Voice from '@react-native-voice/voice'; import { BlurView } from 'expo-blur'; import { router, useLocalSearchParams } from 'expo-router'; -import React, { useEffect, useRef, useState } from 'react'; +import React, { useCallback, useEffect, useRef, useState } from 'react'; import { Alert, Animated, @@ -33,6 +33,10 @@ export default function VoiceRecordScreen() { const [isListening, setIsListening] = useState(false); const [analysisProgress, setAnalysisProgress] = useState(0); + // 用于跟踪组件是否已卸载,防止在组件卸载后设置状态 + const isMountedRef = useRef(true); + const progressIntervalRef = useRef | null>(null); + // 动画相关 const scaleAnimation = useRef(new Animated.Value(1)).current; const pulseAnimation = useRef(new Animated.Value(1)).current; @@ -108,50 +112,78 @@ export default function VoiceRecordScreen() { progressAnimation.setValue(0); }; - // 语音识别回调 - const onSpeechStart = () => { + // 语音识别回调 - 使用 useCallback 避免每次渲染重新创建 + const onSpeechStart = useCallback(() => { + console.log('语音开始'); + if (!isMountedRef.current) return; + setIsListening(true); setRecordState('listening'); startPulseAnimation(); startWaveAnimation(); - }; + }, []); - const onSpeechRecognized = () => { + const onSpeechRecognized = useCallback(() => { console.log('语音识别中...'); - }; + }, []); + + const onSpeechEnd = useCallback(() => { + console.log('语音结束'); + if (!isMountedRef.current) return; - const onSpeechEnd = () => { setIsListening(false); setRecordState('processing'); stopAnimations(); - }; + }, []); - const onSpeechError = (error: any) => { + const onSpeechError = useCallback((error: any) => { console.log('语音识别错误:', error); + if (!isMountedRef.current) return; + setIsListening(false); setRecordState('idle'); stopAnimations(); - }; - const onSpeechResults = (event: any) => { + // 显示更友好的错误信息 + if (error.error?.code === '7') { + Alert.alert('提示', '没有检测到语音输入,请重试'); + } else if (error.error?.code === '2') { + Alert.alert('提示', '网络连接异常,请检查网络后重试'); + } else { + Alert.alert('提示', '语音识别出现问题,请重试'); + } + }, []); + + const onSpeechResults = useCallback((event: any) => { + console.log('语音识别结果:', event); + if (!isMountedRef.current) return; + const text = event.value?.[0] || ''; - setRecognizedText(text); - setRecordState('result'); + if (text.trim()) { + setRecognizedText(text); + setRecordState('result'); + } else { + setRecordState('idle'); + Alert.alert('提示', '未识别到有效内容,请重新录音'); + } stopAnimations(); - }; + }, []); + + const onSpeechPartialResults = useCallback((event: any) => { + if (!isMountedRef.current) return; - const onSpeechPartialResults = (event: any) => { const text = event.value?.[0] || ''; setRecognizedText(text); - }; + }, []); + + const onSpeechVolumeChanged = useCallback((event: any) => { + if (!isMountedRef.current) return; - const onSpeechVolumeChanged = (event: any) => { // 根据音量调整动画 const volume = event.value || 0; const scale = 1 + (volume * 0.1); scaleAnimation.setValue(Math.min(scale, 1.5)); - }; - + }, []); useEffect(() => { // 初始化语音识别 @@ -164,57 +196,91 @@ export default function VoiceRecordScreen() { Voice.onSpeechVolumeChanged = onSpeechVolumeChanged; return () => { - Voice.destroy().then(Voice.removeAllListeners); + // 标记组件已卸载 + isMountedRef.current = false; + + // 清理进度定时器 + if (progressIntervalRef.current) { + clearInterval(progressIntervalRef.current); + } + + // 清理语音识别资源 + const cleanup = async () => { + try { + await Voice.stop(); + await Voice.destroy(); + Voice.removeAllListeners(); + } catch (error) { + console.log('清理语音识别资源失败:', error); + } + }; + cleanup(); }; }, [onSpeechStart, onSpeechRecognized, onSpeechEnd, onSpeechError, onSpeechResults, onSpeechPartialResults, onSpeechVolumeChanged]); - // 开始录音 const startRecording = async () => { try { + // 重置状态 setRecognizedText(''); + setRecordState('idle'); triggerHapticFeedback('impactMedium'); - await Voice.start('zh-CN'); // 设置为中文识别 + // 确保之前的识别已停止 + await Voice.stop(); + + // 添加短暂延迟确保资源清理完成 + await new Promise(resolve => setTimeout(resolve, 100)); + + // 启动新的语音识别 + await Voice.start('zh-CN'); + } catch (error) { console.log('启动语音识别失败:', error); setRecordState('idle'); - Alert.alert('录音失败', '无法启动语音识别,请检查权限设置'); + setIsListening(false); + Alert.alert('录音失败', '无法启动语音识别,请检查麦克风权限设置'); } }; // 停止录音 const stopRecording = async () => { try { + console.log('停止录音'); + setIsListening(false); await Voice.stop(); triggerHapticFeedback('impactLight'); } catch (error) { console.log('停止语音识别失败:', error); + setIsListening(false); + setRecordState('idle'); } }; // 重新录音 const retryRecording = async () => { - // 停止所有动画 - stopAnimations(); - - // 重置所有状态 - setRecognizedText(''); - setAnalysisProgress(0); - setIsListening(false); - setRecordState('idle'); - - // 确保语音识别已停止 try { - await Voice.stop(); - } catch { - // 忽略停止错误,可能已经停止了 - } + // 停止所有动画 + stopAnimations(); - // 延迟一点再开始新的录音,确保状态完全重置 - setTimeout(() => { - startRecording(); - }, 100); + // 重置所有状态 + setRecognizedText(''); + setAnalysisProgress(0); + setIsListening(false); + setRecordState('idle'); + + // 确保语音识别已停止 + await Voice.stop(); + + // 延迟一点再开始新的录音,确保状态完全重置 + setTimeout(() => { + startRecording(); + }, 200); + } catch (error) { + console.log('重新录音失败:', error); + setRecordState('idle'); + setIsListening(false); + } }; // 确认并分析食物文本 @@ -233,10 +299,19 @@ export default function VoiceRecordScreen() { startAnalysisAnimation(); // 模拟进度更新 - const progressInterval = setInterval(() => { + progressIntervalRef.current = setInterval(() => { + if (!isMountedRef.current) { + if (progressIntervalRef.current) { + clearInterval(progressIntervalRef.current); + } + return; + } + setAnalysisProgress(prev => { if (prev >= 90) { - clearInterval(progressInterval); + if (progressIntervalRef.current) { + clearInterval(progressIntervalRef.current); + } return prev; } return prev + Math.random() * 15; @@ -248,7 +323,12 @@ export default function VoiceRecordScreen() { const result = await analyzeFoodFromText({ text: recognizedText }); // 清理进度定时器 - clearInterval(progressInterval); + if (progressIntervalRef.current) { + clearInterval(progressIntervalRef.current); + } + + if (!isMountedRef.current) return; + setAnalysisProgress(100); // 生成识别结果ID并保存到Redux @@ -272,8 +352,17 @@ export default function VoiceRecordScreen() { } catch (error) { console.error('食物分析失败:', error); + + // 清理进度定时器 + if (progressIntervalRef.current) { + clearInterval(progressIntervalRef.current); + } + + if (!isMountedRef.current) return; + stopAnimations(); setRecordState('result'); + dispatch(setLoading(false)); const errorMessage = error instanceof Error ? error.message : '分析失败,请重试'; dispatch(setError(errorMessage)); @@ -281,11 +370,24 @@ export default function VoiceRecordScreen() { } }; - const handleBack = () => { - if (isListening) { - stopRecording(); + const handleBack = async () => { + try { + // 如果正在录音,先停止 + if (isListening) { + await stopRecording(); + } + + // 停止所有动画 + stopAnimations(); + + // 确保语音识别完全停止 + await Voice.stop(); + + router.back(); + } catch (error) { + console.log('返回时清理资源失败:', error); + router.back(); } - router.back(); }; // 获取状态对应的UI文本 diff --git a/assets/images/icons/icon-blood-oxygen.png b/assets/images/icons/icon-blood-oxygen.png new file mode 100644 index 0000000..62a91ce Binary files /dev/null and b/assets/images/icons/icon-blood-oxygen.png differ diff --git a/assets/images/icons/icon-fire.png b/assets/images/icons/icon-fire.png index 865bbb3..9aeb27a 100644 Binary files a/assets/images/icons/icon-fire.png and b/assets/images/icons/icon-fire.png differ diff --git a/assets/images/icons/icon-healthy-diet.png b/assets/images/icons/icon-healthy-diet.png new file mode 100644 index 0000000..31086e3 Binary files /dev/null and b/assets/images/icons/icon-healthy-diet.png differ diff --git a/assets/images/icons/icon-mood.png b/assets/images/icons/icon-mood.png new file mode 100644 index 0000000..f79514e Binary files /dev/null and b/assets/images/icons/icon-mood.png differ diff --git a/assets/images/icons/icon-pressure.png b/assets/images/icons/icon-pressure.png new file mode 100644 index 0000000..a0e45b6 Binary files /dev/null and b/assets/images/icons/icon-pressure.png differ diff --git a/assets/images/icons/icon-sleep.png b/assets/images/icons/icon-sleep.png new file mode 100644 index 0000000..a333320 Binary files /dev/null and b/assets/images/icons/icon-sleep.png differ diff --git a/assets/images/icons/icon-step.png b/assets/images/icons/icon-step.png new file mode 100644 index 0000000..8b3a600 Binary files /dev/null and b/assets/images/icons/icon-step.png differ diff --git a/assets/images/icons/icon-weight.png b/assets/images/icons/icon-weight.png new file mode 100644 index 0000000..350f79b Binary files /dev/null and b/assets/images/icons/icon-weight.png differ diff --git a/components/ActivityHeatMap.tsx b/components/ActivityHeatMap.tsx index 2902c9b..630a5b6 100644 --- a/components/ActivityHeatMap.tsx +++ b/components/ActivityHeatMap.tsx @@ -184,23 +184,23 @@ const ActivityHeatMap = () => { > - 小鱼干可以用来与小海豹进行对话 + 能量值的积攒后续可以用来兑换 AI 相关权益 获取说明 - 1. 每日登录获得小鱼干+1 + 1. 每日登录获得能量值+1 - 2. 每日记录心情获得小鱼干+1 + 2. 每日记录心情获得能量值+1 - 3. 记饮食获得小鱼干+1 + 3. 记饮食获得能量值+1 - 4. 完成一次目标获得小鱼干+1 + 4. 完成一次目标获得能量值+1 diff --git a/components/BasalMetabolismCard.tsx b/components/BasalMetabolismCard.tsx index 7dfc2fd..e20cdf1 100644 --- a/components/BasalMetabolismCard.tsx +++ b/components/BasalMetabolismCard.tsx @@ -1,4 +1,5 @@ import { AnimatedNumber } from '@/components/AnimatedNumber'; +import { Image } from 'expo-image'; import React from 'react'; import { StyleSheet, Text, View } from 'react-native'; @@ -35,6 +36,10 @@ export function BasalMetabolismCard({ value, resetToken, style }: BasalMetabolis {/* 头部区域 */} + 基础代谢 @@ -117,6 +122,12 @@ const styles = StyleSheet.create({ title: { fontSize: 14, color: '#0F172A', + fontWeight: '600', + }, + titleIcon: { + width: 16, + height: 16, + marginRight: 4, }, statusBadge: { paddingHorizontal: 8, diff --git a/components/MoodCard.tsx b/components/MoodCard.tsx index 981c16a..2f24104 100644 --- a/components/MoodCard.tsx +++ b/components/MoodCard.tsx @@ -2,7 +2,7 @@ import { MoodCheckin, getMoodConfig } from '@/services/moodCheckins'; import dayjs from 'dayjs'; import LottieView from 'lottie-react-native'; import React, { useEffect, useRef } from 'react'; -import { StyleSheet, Text, TouchableOpacity, View } from 'react-native'; +import { Image, StyleSheet, Text, TouchableOpacity, View } from 'react-native'; interface MoodCardProps { moodCheckin: MoodCheckin | null; @@ -23,7 +23,13 @@ export function MoodCard({ moodCheckin, onPress }: MoodCardProps) { return ( - 心情 + + + 心情 + - 饮食分析 + + + 饮食分析 + 更新: {dayjs(nutritionSummary?.updatedAt).format('MM-DD HH:mm')} @@ -292,9 +298,20 @@ const styles = StyleSheet.create({ alignItems: 'center', marginBottom: 8, }, + titleContainer: { + flexDirection: 'row', + alignItems: 'center', + }, + titleIcon: { + width: 16, + height: 16, + marginRight: 6, + resizeMode: 'contain', + }, cardTitle: { fontSize: 14, color: '#192126', + fontWeight: '600' }, cardSubtitle: { fontSize: 10, diff --git a/components/StepsCard.tsx b/components/StepsCard.tsx index 5e639f2..8311d25 100644 --- a/components/StepsCard.tsx +++ b/components/StepsCard.tsx @@ -10,9 +10,10 @@ import { import { fetchHourlyStepSamples, fetchStepCount, HourlyStepData } from '@/utils/health'; import { logger } from '@/utils/logger'; +import dayjs from 'dayjs'; +import { Image } from 'expo-image'; import { useRouter } from 'expo-router'; import { AnimatedNumber } from './AnimatedNumber'; -import dayjs from 'dayjs'; // 使用原生View来替代SVG,避免导入问题 // import Svg, { Rect } from 'react-native-svg'; @@ -110,6 +111,10 @@ const StepsCard: React.FC = ({ <> {/* 标题和步数显示 */} + 步数 @@ -213,12 +218,19 @@ const styles = StyleSheet.create({ }, header: { flexDirection: 'row', - justifyContent: 'space-between', + justifyContent: 'flex-start', alignItems: 'center', }, + titleIcon: { + width: 16, + height: 16, + marginRight: 6, + resizeMode: 'contain', + }, title: { fontSize: 14, color: '#192126', + fontWeight: '600' }, footprintIcons: { flexDirection: 'row', @@ -228,6 +240,7 @@ const styles = StyleSheet.create({ chartContainer: { flex: 1, justifyContent: 'center', + marginTop: 6 }, chartWrapper: { width: '100%', diff --git a/components/StressMeter.tsx b/components/StressMeter.tsx index cad2bd6..97b6d68 100644 --- a/components/StressMeter.tsx +++ b/components/StressMeter.tsx @@ -1,5 +1,6 @@ import { fetchHRVForDate } from '@/utils/health'; import dayjs from 'dayjs'; +import { Image } from 'expo-image'; import { LinearGradient } from 'expo-linear-gradient'; import React, { useEffect, useState } from 'react'; import { StyleSheet, Text, TouchableOpacity, View } from 'react-native'; @@ -96,6 +97,10 @@ export function StressMeter({ curDate }: StressMeterProps) { {/* 头部区域 */} + 压力 {/* {updateTime && ( @@ -172,9 +177,16 @@ const styles = StyleSheet.create({ justifyContent: 'center', marginRight: 6, }, + titleIcon: { + width: 16, + height: 16, + marginRight: 6, + resizeMode: 'contain', + }, title: { fontSize: 14, color: '#192126', + fontWeight: '600' }, valueSection: { flexDirection: 'row', diff --git a/components/WaterIntakeCard.tsx b/components/WaterIntakeCard.tsx index de8963f..6f7d3f7 100644 --- a/components/WaterIntakeCard.tsx +++ b/components/WaterIntakeCard.tsx @@ -4,6 +4,7 @@ import { getQuickWaterAmount } from '@/utils/userPreferences'; import { useFocusEffect } from '@react-navigation/native'; import dayjs from 'dayjs'; import * as Haptics from 'expo-haptics'; +import { Image } from 'expo-image'; import { useRouter } from 'expo-router'; import LottieView from 'lottie-react-native'; import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; @@ -185,7 +186,16 @@ const WaterIntakeCard: React.FC = ({ {/* 标题和加号按钮 */} - 喝水 + + + 喝水 + {isToday && ( + {quickWaterAmount}ml @@ -291,10 +301,16 @@ const styles = StyleSheet.create({ marginBottom: 4, minHeight: 22, }, + titleIcon: { + width: 16, + height: 16, + marginRight: 6, + resizeMode: 'contain', + }, title: { fontSize: 14, color: '#192126', - fontWeight: '500', + fontWeight: '600', }, addButton: { borderRadius: 16, diff --git a/components/statistic/HealthDataCard.tsx b/components/statistic/HealthDataCard.tsx index 41996e1..1d95959 100644 --- a/components/statistic/HealthDataCard.tsx +++ b/components/statistic/HealthDataCard.tsx @@ -1,3 +1,4 @@ +import { Image } from 'expo-image'; import React from 'react'; import { StyleSheet, Text, View } from 'react-native'; import Animated, { FadeIn, FadeOut } from 'react-native-reanimated'; @@ -22,7 +23,17 @@ const HealthDataCard: React.FC = ({ style={[styles.card, style]} > - {title} + + + {title} + {value} {unit} @@ -51,10 +62,16 @@ const styles = StyleSheet.create({ flex: 1, justifyContent: 'center', }, + titleIcon: { + width: 16, + height: 16, + marginRight: 6, + resizeMode: 'contain', + }, title: { fontSize: 14, color: '#192126', - marginBottom: 14, + fontWeight: '600', }, valueContainer: { flexDirection: 'row', diff --git a/components/statistic/SleepCard.tsx b/components/statistic/SleepCard.tsx index 517630a..b60ed1d 100644 --- a/components/statistic/SleepCard.tsx +++ b/components/statistic/SleepCard.tsx @@ -1,4 +1,5 @@ import { fetchCompleteSleepData, formatSleepTime } from '@/utils/sleepHealthKit'; +import { Image } from 'expo-image'; import React, { useEffect, useState } from 'react'; import { StyleSheet, Text, TouchableOpacity, View } from 'react-native'; @@ -39,6 +40,10 @@ const SleepCard: React.FC = ({ const CardContent = ( + 睡眠 @@ -65,11 +70,18 @@ const styles = StyleSheet.create({ cardHeaderRow: { flexDirection: 'row', alignItems: 'center', - justifyContent: 'space-between', + justifyContent: 'flex-start', + }, + titleIcon: { + width: 16, + height: 16, + marginRight: 6, + resizeMode: 'contain', }, cardTitle: { fontSize: 14, color: '#192126', + fontWeight: '600', }, sleepValue: { fontSize: 16, diff --git a/components/weight/WeightHistoryCard.tsx b/components/weight/WeightHistoryCard.tsx index fff2275..e61aebb 100644 --- a/components/weight/WeightHistoryCard.tsx +++ b/components/weight/WeightHistoryCard.tsx @@ -6,6 +6,7 @@ import { useColorScheme } from '@/hooks/useColorScheme'; import { fetchWeightHistory } from '@/store/userSlice'; import { BMI_CATEGORIES } from '@/utils/bmi'; import { Ionicons } from '@expo/vector-icons'; +import { Image } from 'expo-image'; import { LinearGradient } from 'expo-linear-gradient'; import React, { useEffect, useState } from 'react'; import { @@ -72,6 +73,10 @@ export function WeightHistoryCard() { return ( + 体重记录 @@ -156,6 +161,10 @@ export function WeightHistoryCard() { return ( + 体重记录 (s as any)?.user?.token as string | null); - console.log('useAuthGuard!!!token', token); - const isLoggedIn = !!token; const ensureLoggedIn = useCallback(async (options?: EnsureOptions): Promise => { diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 00c79bd..a0c038b 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -179,8 +179,8 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - PurchasesHybridCommon (16.2.2): - - RevenueCat (= 5.34.0) + - PurchasesHybridCommon (17.7.0): + - RevenueCat (= 5.39.0) - RCT-Folly (2024.11.18.00): - boost - DoubleConversion @@ -2545,7 +2545,7 @@ PODS: - React-perflogger (= 0.81.4) - React-utils (= 0.81.4) - SocketRocket - - RevenueCat (5.34.0) + - RevenueCat (5.39.0) - RNAppleHealthKit (1.7.0): - React - RNCAsyncStorage (2.2.0): @@ -2690,8 +2690,8 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - RNPurchases (9.2.2): - - PurchasesHybridCommon (= 16.2.2) + - RNPurchases (9.4.3): + - PurchasesHybridCommon (= 17.7.0) - React-Core - RNReanimated (4.1.0): - boost @@ -3463,7 +3463,7 @@ SPEC CHECKSUMS: libwebp: 02b23773aedb6ff1fd38cec7a77b81414c6842a8 lottie-ios: a881093fab623c467d3bce374367755c272bdd59 lottie-react-native: 86fa7488b1476563f41071244aa73d5b738faf19 - PurchasesHybridCommon: 62f852419aae7041792217593998f7ac3f8b567d + PurchasesHybridCommon: 6bc96162fb0c061e1980f474be618c088cfd1428 RCT-Folly: 846fda9475e61ec7bcbf8a3fe81edfcaeb090669 RCTDeprecation: c0ed3249a97243002615517dff789bf4666cf585 RCTRequired: 58719f5124f9267b5f9649c08bf23d9aea845b23 @@ -3531,7 +3531,7 @@ SPEC CHECKSUMS: ReactAppDependencyProvider: 433ddfb4536948630aadd5bd925aff8a632d2fe3 ReactCodegen: 1d05923ad119796be9db37830d5e5dc76586aa00 ReactCommon: 394c6b92765cf6d211c2c3f7f6bc601dffb316a6 - RevenueCat: eb2aa042789d9c99ad5172bd96e28b96286d6ada + RevenueCat: 4743a5eee0004e1c03eabeb3498818f902a5d622 RNAppleHealthKit: 86ef7ab70f762b802f5c5289372de360cca701f9 RNCAsyncStorage: 29f0230e1a25f36c20b05f65e2eb8958d6526e82 RNCMaskedView: 5ef8c95cbab95334a32763b72896a7b7d07e6299 @@ -3539,7 +3539,7 @@ SPEC CHECKSUMS: RNDateTimePicker: cda4c045beca864cebb3209ef9cc4094f974864c RNDeviceInfo: d863506092aef7e7af3a1c350c913d867d795047 RNGestureHandler: 3a73f098d74712952870e948b3d9cf7b6cae9961 - RNPurchases: 7993b33416e67d5863140b5c62c682b34719f475 + RNPurchases: 1bc60e3a69af65d9cfe23967328421dd1df1763c RNReanimated: 9de34f0313c4177a34c079ca9fce6f1f278bff24 RNScreens: 0bbf16c074ae6bb1058a7bf2d1ae017f4306797c RNSentry: f2c39f1113e22413c9bb6e3faa6b27f110d95eaf diff --git a/package-lock.json b/package-lock.json index 1cd96a8..2c236a0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -58,7 +58,7 @@ "react-native-markdown-display": "^7.0.2", "react-native-modal-datetime-picker": "^18.0.0", "react-native-popover-view": "^6.1.0", - "react-native-purchases": "^9.2.2", + "react-native-purchases": "^9.4.3", "react-native-reanimated": "~4.1.0", "react-native-render-html": "^6.3.4", "react-native-safe-area-context": "~5.6.0", @@ -3967,24 +3967,24 @@ } }, "node_modules/@revenuecat/purchases-js": { - "version": "1.11.1", - "resolved": "https://mirrors.tencent.com/npm/@revenuecat/purchases-js/-/purchases-js-1.11.1.tgz", - "integrity": "sha512-P0jxwUBWOIFSZQ1/NIMpbOXG3brraNDGYoCnES1r5w97yonhAw1brpKwhFKUhlq+DvAUDCG1q1d8FdTzI+MgXg==", + "version": "1.14.0", + "resolved": "https://mirrors.tencent.com/npm/@revenuecat/purchases-js/-/purchases-js-1.14.0.tgz", + "integrity": "sha512-SotJ9MznBZoq91nSxLl1Oqw42k6A3JU0d73/WFbppv1IG770Q8KhuAUo1SgZC62ERCuCHme5fEdER1ZI4x8y7A==", "license": "MIT" }, "node_modules/@revenuecat/purchases-js-hybrid-mappings": { - "version": "16.2.1", - "resolved": "https://mirrors.tencent.com/npm/@revenuecat/purchases-js-hybrid-mappings/-/purchases-js-hybrid-mappings-16.2.1.tgz", - "integrity": "sha512-TXYw6lh5rg/kGI44kayU4TGSXKDcc35TdB0vBuZfllSokY1tnyYmP8Pm2eZamLN8ycrTuCysoPxknW2Klh1H1g==", + "version": "17.7.0", + "resolved": "https://mirrors.tencent.com/npm/@revenuecat/purchases-js-hybrid-mappings/-/purchases-js-hybrid-mappings-17.7.0.tgz", + "integrity": "sha512-254jmgsCxn7Om49gdRQmh8rNVPsEjpMcKmrIwiR8D4Yfcch4bWUK23bDNvFR29Ygen9ctBkGc+CklmmKNQMQYw==", "license": "MIT", "dependencies": { - "@revenuecat/purchases-js": "1.11.1" + "@revenuecat/purchases-js": "1.14.0" } }, "node_modules/@revenuecat/purchases-typescript-internal": { - "version": "16.2.1", - "resolved": "https://mirrors.tencent.com/npm/@revenuecat/purchases-typescript-internal/-/purchases-typescript-internal-16.2.1.tgz", - "integrity": "sha512-g7FhNA6nxr9686klimlfueMQqQl34pHUHXeCKXqeuaPJOOsFc7qcOGhGZdyLGulIAgpkctrvcAbeDyBk7t5QRg==", + "version": "17.7.0", + "resolved": "https://mirrors.tencent.com/npm/@revenuecat/purchases-typescript-internal/-/purchases-typescript-internal-17.7.0.tgz", + "integrity": "sha512-CGyNcupvNEnyiZTRsD98VOLRxsp6cr1NYIL8XKDO2EoSDBaDuDXyHTADbPEf0lRW2qYqwmQKZFJ61Vwl+0YiWw==", "license": "MIT" }, "node_modules/@rtsao/scc": { @@ -12673,17 +12673,17 @@ } }, "node_modules/react-native-purchases": { - "version": "9.2.2", - "resolved": "https://mirrors.tencent.com/npm/react-native-purchases/-/react-native-purchases-9.2.2.tgz", - "integrity": "sha512-j376mva8G6SLA2HPTROpUGoivfLMZVWPM7mj2bcgTS8y6NzbyQJ20Npe8V3nWc0N5YFTuknTF8pl0tWc6FqYbA==", + "version": "9.4.3", + "resolved": "https://mirrors.tencent.com/npm/react-native-purchases/-/react-native-purchases-9.4.3.tgz", + "integrity": "sha512-7M8/tjZY2iZISBOqXIxxzkt7fxt86WGF2ZW/qcsEfXVaZv2UvDLs+GuYKjf0Bz+2hOuYwoJK/LF++jpUi6CRng==", "license": "MIT", "workspaces": [ "examples/purchaseTesterTypescript", "react-native-purchases-ui" ], "dependencies": { - "@revenuecat/purchases-js-hybrid-mappings": "16.2.1", - "@revenuecat/purchases-typescript-internal": "16.2.1" + "@revenuecat/purchases-js-hybrid-mappings": "17.7.0", + "@revenuecat/purchases-typescript-internal": "17.7.0" }, "peerDependencies": { "react": ">= 16.6.3", diff --git a/package.json b/package.json index 40d64dd..0736536 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,7 @@ "react-native-markdown-display": "^7.0.2", "react-native-modal-datetime-picker": "^18.0.0", "react-native-popover-view": "^6.1.0", - "react-native-purchases": "^9.2.2", + "react-native-purchases": "^9.4.3", "react-native-reanimated": "~4.1.0", "react-native-render-html": "^6.3.4", "react-native-safe-area-context": "~5.6.0", @@ -82,4 +82,4 @@ "typescript": "~5.9.2" }, "private": true -} +} \ No newline at end of file diff --git a/store/userSlice.ts b/store/userSlice.ts index b0c10fd..af2e60f 100644 --- a/store/userSlice.ts +++ b/store/userSlice.ts @@ -92,7 +92,7 @@ export type UserState = { activityHistory: ActivityHistoryItem[]; }; -export const DEFAULT_MEMBER_NAME = '小海豹'; +export const DEFAULT_MEMBER_NAME = ''; const getInitialState = (): UserState => { const preloaded = getPreloadedUserData();