Files
mindfulness/client/app/(splash)/splash.tsx
2026-01-29 19:09:36 +08:00

164 lines
4.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import React, { useEffect, useState } from 'react';
import { View, Text, Image, StyleSheet, TouchableOpacity, Dimensions, Platform, Alert } from 'react-native';
import { LinearGradient } from 'expo-linear-gradient';
import { useRouter } from 'expo-router';
import * as WebBrowser from 'expo-web-browser';
import { useTranslation } from 'react-i18next';
import { SafeAreaView } from 'react-native-safe-area-context';
import { setConsentAccepted, getConsentAccepted } from '../../src/storage/appStorage';
const { width, height } = Dimensions.get('window');
export default function SplashScreen() {
const router = useRouter();
const { t } = useTranslation();
const [showConsent, setShowConsent] = useState(false);
useEffect(() => {
checkConsent();
}, []);
const checkConsent = async () => {
const accepted = await getConsentAccepted();
setShowConsent(!accepted);
if (accepted) {
// 如果已经同意过,直接跳转到首页分发
// 注意:这里需要与 app/index.tsx 配合,如果 app/index.tsx 已经判断了 consent=true 不会跳过来,
// 那么这里其实是防守。
// 但如果用户是通过 deep link 或其他方式强制进入 splash这个逻辑会把他们送走。
router.replace('/');
}
};
const handleAgree = async () => {
await setConsentAccepted(true);
setShowConsent(false);
router.replace('/');
};
const openLink = async (url: string) => {
try {
await WebBrowser.openBrowserAsync(url);
} catch (error) {
Alert.alert(t('common.error'), t('common.openLinkError'));
}
};
return (
<View style={styles.container}>
<Image
source={require('../../assets/images/index/index_flowers.png')}
style={styles.image}
resizeMode="contain"
/>
<View style={styles.contentContainer}>
<Text style={styles.title}>{t('consent.title')}</Text>
<Text style={styles.subtitle}>{t('consent.subtitle')}</Text>
</View>
<SafeAreaView style={styles.bottomContainer} edges={['bottom']}>
{showConsent && (
<>
<TouchableOpacity onPress={handleAgree} activeOpacity={0.8}>
<LinearGradient
colors={['#F69F7B', '#F99CC0']}
start={{ x: 0, y: 0 }}
end={{ x: 1, y: 0 }}
style={styles.button}
>
<Text style={styles.buttonText}>{t('consent.agree')}</Text>
</LinearGradient>
</TouchableOpacity>
<View style={styles.linksContainer}>
<TouchableOpacity onPress={() => openLink('https://example.com/privacy')}>
<Text style={styles.linkText}>{t('consent.privacy')}</Text>
</TouchableOpacity>
<View style={styles.divider} />
<TouchableOpacity onPress={() => openLink('https://example.com/terms')}>
<Text style={styles.linkText}>{t('consent.terms')}</Text>
</TouchableOpacity>
</View>
</>
)}
</SafeAreaView>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#FFF9F0', // 假设的背景色,根据图片调整
alignItems: 'center',
},
image: {
width: width * 0.8,
height: height * 0.5,
marginTop: height * 0.1,
},
contentContainer: {
alignItems: 'center',
marginTop: 20,
paddingHorizontal: 30,
},
title: {
fontSize: 24,
fontWeight: 'bold',
color: '#4A3427', // 深褐色
marginBottom: 10,
textAlign: 'center',
fontFamily: Platform.OS === 'ios' ? 'Georgia' : 'serif', // 尝试匹配衬线体
},
subtitle: {
fontSize: 18,
fontWeight: 'bold',
color: '#4A3427', // 深褐色
textAlign: 'center',
lineHeight: 24,
fontFamily: Platform.OS === 'ios' ? 'Georgia' : 'serif',
},
bottomContainer: {
position: 'absolute',
bottom: 0,
width: '100%',
alignItems: 'center',
paddingBottom: 20,
},
button: {
width: width * 0.8,
paddingVertical: 16,
borderRadius: 30,
alignItems: 'center',
justifyContent: 'center',
marginBottom: 20,
shadowColor: '#F69F7B',
shadowOffset: { width: 0, height: 4 },
shadowOpacity: 0.3,
shadowRadius: 8,
elevation: 5,
},
buttonText: {
color: '#FFF',
fontSize: 18,
fontWeight: '600',
},
linksContainer: {
flexDirection: 'row',
alignItems: 'center',
marginBottom: 10,
},
linkText: {
fontSize: 12,
color: '#999',
textDecorationLine: 'underline',
},
divider: {
width: 1,
height: 12,
backgroundColor: '#CCC',
marginHorizontal: 15,
},
});