Files
mindfulness/client/app/(splash)/splash.tsx
2026-01-30 16:34:40 +08:00

158 lines
4.3 KiB
TypeScript

import React, { useEffect, useState } from 'react';
import { View, Text, Image, StyleSheet, TouchableOpacity, Dimensions, Platform, Alert } from 'react-native';
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';
import FlowersBg from '../../assets/images/index/flowers_endbg.svg';
import WelcomeBtn from '../../assets/images/index/welcome_btn.svg';
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) {
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}>
{/* Top Image Area - No white card, placed below SVG */}
<View style={styles.imageContainer}>
<Image
source={require('../../assets/images/index/index_flowers.png')}
style={styles.mainImage}
resizeMode="contain"
/>
</View>
{/* Background Flower SVG - Placed above the image */}
<View style={styles.bgFlowerContainer}>
<FlowersBg width={width} height={height * 0.6} />
</View>
{/* Content Area */}
<View style={styles.contentContainer}>
<Text style={styles.title}>
You are perfect.{"\n"}
Everything{"\n"}
will be better.
</Text>
</View>
{/* Bottom Actions */}
<SafeAreaView style={styles.bottomContainer} edges={['bottom']}>
{showConsent && (
<>
<TouchableOpacity onPress={handleAgree} activeOpacity={0.8} style={styles.welcomeBtnWrapper}>
<WelcomeBtn width={87} height={57} />
</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: '#F5D3B5',
alignItems: 'center',
},
imageContainer: {
marginTop: 60,
width: width,
height: height * 0.5,
alignItems: 'center',
justifyContent: 'center',
zIndex: 1, // 放在底层
},
mainImage: {
width: width * 0.85,
height: '100%',
},
bgFlowerContainer: {
position: 'absolute',
bottom: -height * 0.05, // 向下移动屏幕高度的 5%
left: 0,
right: 0,
zIndex: 2, // 放在图片上层
},
contentContainer: {
marginTop: 40,
paddingHorizontal: 30,
zIndex: 3,
},
title: {
fontSize: 30,
lineHeight: 42,
color: '#772F00',
textAlign: 'center',
fontWeight: '600',
fontFamily: Platform.OS === 'ios' ? 'STIX Two Text' : 'serif',
},
bottomContainer: {
position: 'absolute',
bottom: 40,
width: '100%',
alignItems: 'center',
zIndex: 4,
},
welcomeBtnWrapper: {
marginBottom: 30,
},
linksContainer: {
flexDirection: 'row',
alignItems: 'center',
},
linkText: {
fontSize: 12,
color: 'rgba(119, 47, 0, 0.5)', // 配合整体色调的半透明褐色
textDecorationLine: 'underline',
},
divider: {
width: 1,
height: 12,
backgroundColor: 'rgba(119, 47, 0, 0.2)',
marginHorizontal: 15,
},
});