import { useEffect, useRef } from 'react'; import { Animated, Dimensions, Image, Text, TouchableOpacity, View } from 'react-native'; import Svg, { Defs, RadialGradient, Rect, Stop } from 'react-native-svg'; import { useRouter } from 'expo-router'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; import { useTranslation } from 'react-i18next'; import { useAuthStore } from '../stores/auth'; const { width: SW, height: SH } = Dimensions.get('window'); export default function LandingScreen() { const router = useRouter(); const insets = useSafeAreaInsets(); const { t } = useTranslation(); // Reaktiver Routing-Fix für „eingeloggt bleiben": wenn beim Cold-Start (oder // nach einem `router.replace('/')` aus dem LockScreen-Sign-Out) bereits eine // gültige Session in AsyncStorage liegt, überspringen wir das Landing und // schicken den User direkt in `(app)`. const session = useAuthStore((s) => s.session); const loading = useAuthStore((s) => s.loading); useEffect(() => { if (!loading && session) { router.replace('/(app)'); } }, [loading, session, router]); const glowTopOpacity = useRef(new Animated.Value(0.5)).current; const glowCenterOpacity = useRef(new Animated.Value(0)).current; const glowCenterScale = useRef(new Animated.Value(0.6)).current; const nameOpacity = useRef(new Animated.Value(0)).current; const nameTranslateY = useRef(new Animated.Value(12)).current; const logoOpacity = useRef(new Animated.Value(0)).current; const logoScale = useRef(new Animated.Value(0.82)).current; const logoTranslateY = useRef(new Animated.Value(8)).current; const logoPulse = useRef(new Animated.Value(1)).current; const taglineOpacity = useRef(new Animated.Value(0)).current; const taglineTranslateY = useRef(new Animated.Value(8)).current; const ctaOpacity = useRef(new Animated.Value(0)).current; const ctaTranslateY = useRef(new Animated.Value(10)).current; const footerOpacity = useRef(new Animated.Value(0)).current; useEffect(() => { Animated.loop( Animated.sequence([ Animated.timing(glowTopOpacity, { toValue: 0.9, duration: 2000, useNativeDriver: true }), Animated.timing(glowTopOpacity, { toValue: 0.5, duration: 2000, useNativeDriver: true }), ]), ).start(); const ease = (toValue: number, duration: number) => ({ toValue, duration, useNativeDriver: true }); Animated.parallel([ Animated.timing(glowCenterOpacity, ease(1, 900)), Animated.timing(glowCenterScale, ease(1, 900)), ]).start(); setTimeout(() => { Animated.parallel([ Animated.timing(nameOpacity, ease(1, 600)), Animated.timing(nameTranslateY, ease(0, 600)), ]).start(); }, 300); setTimeout(() => { Animated.parallel([ Animated.timing(logoOpacity, ease(1, 650)), Animated.spring(logoScale, { toValue: 1, useNativeDriver: true, friction: 6, tension: 80 }), Animated.timing(logoTranslateY, ease(0, 650)), ]).start(); }, 700); setTimeout(() => { Animated.loop( Animated.sequence([ Animated.timing(logoPulse, { toValue: 1.04, duration: 1300, useNativeDriver: true }), Animated.timing(logoPulse, { toValue: 1, duration: 1300, useNativeDriver: true }), ]), ).start(); }, 1100); setTimeout(() => { Animated.parallel([ Animated.timing(taglineOpacity, ease(1, 550)), Animated.timing(taglineTranslateY, ease(0, 550)), ]).start(); }, 1300); setTimeout(() => { Animated.parallel([ Animated.timing(ctaOpacity, ease(1, 500)), Animated.timing(ctaTranslateY, ease(0, 500)), Animated.timing(footerOpacity, ease(1, 600)), ]).start(); }, 1700); }, [ glowTopOpacity, glowCenterOpacity, glowCenterScale, nameOpacity, nameTranslateY, logoOpacity, logoScale, logoTranslateY, logoPulse, taglineOpacity, taglineTranslateY, ctaOpacity, ctaTranslateY, footerOpacity, ]); // Early-return MUSS nach allen Hooks stehen (Rules of Hooks) — sonst wirft // React "Rendered fewer hooks than expected" wenn sich loading/session zwischen // Renders ändert. if (loading || session) return null; return ( {/* Top breathing glow */} {/* Center indigo halo */} {/* Content */} {t('appHeader.appName')} {t('splash.tagline')} router.push('/signin')} activeOpacity={0.85} style={{ backgroundColor: '#6366f1', borderRadius: 16, paddingVertical: 16, alignItems: 'center', }} > {t('auth.signin')} router.push('/signup')} activeOpacity={0.85} style={{ borderWidth: 1.5, borderColor: 'rgba(255,255,255,0.25)', borderRadius: 16, paddingVertical: 16, alignItems: 'center', }} > {t('landing.start')} {/* Footer */} {t('splash.madeInGermany')} ); }