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();