Files
digital-pilates/app/index.tsx
richarjiang a228280ca4 feat(onboarding): 添加新用户引导流程
实现了完整的应用引导功能,包括:
- 新增引导页面UI,包含健康数据追踪、轻断食计划和健康挑战三个介绍页面
- 添加引导状态持久化存储,使用AsyncStorage管理用户完成状态
- 修改应用启动逻辑,根据引导状态决定跳转到主页或引导页
- 在开发者选项中添加重置引导状态功能,方便测试
- 更新路由配置和存储键常量,统一管理引导相关配置
2025-11-06 15:22:31 +08:00

77 lines
2.4 KiB
TypeScript

import { ThemedView } from '@/components/ThemedView';
import { ROUTES } from '@/constants/Routes';
import { usePushNotifications } from '@/hooks/usePushNotifications';
import { useThemeColor } from '@/hooks/useThemeColor';
import { preloadUserData } from '@/store/userSlice';
import { router } from 'expo-router';
import React, { useEffect, useState } from 'react';
import { ActivityIndicator, View } from 'react-native';
import AsyncStorage from '@/utils/kvStore';
import { STORAGE_KEYS } from '@/services/api';
const ONBOARDING_COMPLETED_KEY = STORAGE_KEYS.onboardingCompleted;
export default function SplashScreen() {
const backgroundColor = useThemeColor({}, 'background');
const primaryColor = useThemeColor({}, 'primary');
const [isLoading, setIsLoading] = useState(true);
const { initializePushNotifications } = usePushNotifications();
useEffect(() => {
checkOnboardingStatus();
}, []);
const checkOnboardingStatus = async () => {
try {
// 先预加载用户数据,这样进入应用时就有正确的 token 状态
console.log('开始预加载用户数据...');
await preloadUserData();
console.log('用户数据预加载完成');
// 初始化推送通知(不阻塞应用启动)
console.log('开始初始化推送通知...');
initializePushNotifications().catch((error) => {
console.warn('推送通知初始化失败,但不影响应用正常使用:', error);
});
const onboardingCompleted = await AsyncStorage.getItem(ONBOARDING_COMPLETED_KEY);
if (onboardingCompleted === 'true') {
router.replace(ROUTES.TAB_STATISTICS);
} else {
router.replace(ROUTES.ONBOARDING);
}
} catch (error) {
console.error('检查引导状态或预加载用户数据失败:', error);
// 如果出现错误,仍然进入应用,但可能会有状态更新
router.replace(ROUTES.TAB_STATISTICS);
}
setIsLoading(false);
};
if (!isLoading) {
return null;
}
return (
<ThemedView style={{
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor
}}>
<View style={{
width: 80,
height: 80,
borderRadius: 40,
// backgroundColor: primaryColor,
justifyContent: 'center',
alignItems: 'center',
marginBottom: 20,
}}>
</View>
<ActivityIndicator size="large" color={primaryColor} />
</ThemedView>
);
}