import { Stack, usePathname, useSegments } from 'expo-router';
import { ActivityIndicator, View, StyleSheet } from 'react-native';
import { useAuth } from '~/features/auth';
import LocationTracker from '~/features/location/LocationTracker';
import { useRecordingStore } from '~/features/audioRecordingV2/store/recordingStore';
import RecordingBar from '~/components/molecules/RecordingBar';
import Header from '~/features/menus/Header';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { HeaderProvider, useHeader } from '~/features/menus/HeaderContext';
import { useTranslation } from 'react-i18next';
import { useTheme } from '~/features/theme/ThemeProvider';
import colors from '~/tailwind.config.js';
import InsufficientCreditsModal from '~/components/molecules/InsufficientCreditsModal';
import { useInsufficientCreditsInterceptor } from '~/features/credits/hooks/useInsufficientCreditsInterceptor';
import { RatingPromptModal } from '~/features/rating/components/RatingPromptModal';
import { useRatingPrompt } from '~/features/rating/hooks/useRatingPrompt';
import { useEffect, useMemo } from 'react';
import PageOnboardingModal from '~/features/onboarding/components/PageOnboardingModal';
import { OnboardingProvider, usePageOnboarding } from '~/features/onboarding/contexts/OnboardingContext';
// Komponente, die den Header mit der Konfiguration aus dem HeaderContext verbindet
const HeaderWithConfig = () => {
const { config } = useHeader();
const { t } = useTranslation();
const pathname = usePathname();
// Bestimme, ob die aktuelle Seite die Homepage ist
// Pfad endet mit '/' oder '/index'
const isHomePage = pathname === '/' || pathname.endsWith('/index');
// Bestimme, ob es sich um eine Memo-Detail-Seite handelt
// In Expo Router werden die Route-Gruppen wie (memo) nicht in der URL angezeigt
// Stattdessen schauen wir nach dem Muster /memo/[id] oder direkt nach einer UUID
const isMemoDetailPage = pathname.match(/^\/[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/) !== null;
// Übersetze den Titel, falls es ein einfacher String ist
const translatedTitle = typeof config.title === 'string'
? t(config.title, config.title) // Fallback auf den Original-Titel
: config.title;
return (
);
};
export default function ProtectedLayout() {
const { isAuthenticated, loading } = useAuth();
const pathname = usePathname();
const segments = useSegments();
const isRecording = useRecordingStore((state) => state.isRecording);
const insets = useSafeAreaInsets();
const { t } = useTranslation();
// Use the insufficient credits interceptor
const {
modalVisible,
requiredCredits,
availableCredits,
operation,
closeModal
} = useInsufficientCreditsInterceptor();
// Use the rating prompt hook
const { showPromptModal, closePrompt, triggerPromptCheck } = useRatingPrompt();
// Check for rating prompt on home page with a slight delay
// This gives time for the memo to be created and the store to be updated
useEffect(() => {
const isHomePage = pathname === '/' || pathname.endsWith('/index');
if (isHomePage) {
const timer = setTimeout(() => {
triggerPromptCheck();
}, 2000); // 2 second delay after landing on home page
return () => clearTimeout(timer);
}
}, [pathname, triggerPromptCheck]);
// Bestimme, ob die RecordingBar angezeigt werden soll
// Nicht auf der Home-Page anzeigen (Pfad endet mit '/' oder '/index')
const isHomePage = pathname === '/' || pathname.endsWith('/index');
const shouldShowRecordingBar = isRecording && !isHomePage;
// Get theme colors - memoize to prevent recalculation
const { isDark, themeVariant } = useTheme();
const menuBackgroundColor = useMemo(() => {
return isDark
? (colors.theme?.extend?.colors?.dark as any)?.[themeVariant]?.menuBackground
: (colors.theme?.extend?.colors as any)?.[themeVariant]?.menuBackground;
}, [isDark, themeVariant]);
// Memoize styles to prevent recreation on every render
const styles = useMemo(() => StyleSheet.create({
container: {
flex: 1,
position: 'relative',
backgroundColor: menuBackgroundColor,
},
content: {
flex: 1,
backgroundColor: menuBackgroundColor,
},
headerContainer: {
width: '100%',
zIndex: 1001,
backgroundColor: menuBackgroundColor,
},
recordingBarContainer: {
width: '100%',
zIndex: 1000,
}
}), [menuBackgroundColor]);
// Show loading indicator while checking authentication
if (loading) {
return (
);
}
// If not authenticated, return null and let root layout handle navigation
if (!isAuthenticated) {
return null;
}
// User is authenticated, show protected content
return (
{shouldShowRecordingBar && (
{
// Hier könnten wir zur Memo-Seite navigieren oder die UI aktualisieren
console.debug(t('recording.completed'), { result, title, spaceId, blueprintId });
}}
/>
)}
{/* Global Insufficient Credits Modal */}
{/* Global Rating Prompt Modal */}
);
}
// Separate component to access OnboardingContext
const OnboardingModalWrapper = () => {
const { pageOnboardingModal, closePageOnboardingModal } = usePageOnboarding();
return (
);
};