ComicMTL / frontend /app /_layout.tsx
BloodyInside's picture
firsty
947c08e
raw
history blame
5.83 kB
import { useFonts } from 'expo-font';
import { Stack, router, usePathname } from 'expo-router';
import * as SplashScreen from 'expo-splash-screen';
import { useEffect, useState, useContext, createContext, memo } from 'react';
import { useWindowDimensions, View, Text, Pressable } from 'react-native';
import 'react-native-reanimated';
import { SafeAreaView } from 'react-native-safe-area-context';
import Menu from '@/components/menu/menu';
import Storage from '@/constants/module/storage';
import { useColorScheme } from '@/hooks/useColorScheme';
import Toast, { SuccessToast } from 'react-native-toast-message';
import type { BaseToastProps } from 'react-native-toast-message';
import { BaseToast, ErrorToast, InfoToast } from 'react-native-toast-message';
import { AnimatePresence } from 'moti';
import { Platform } from 'react-native';
import CloudflareTurnstile from '@/components/cloudflare_turnstile';
import Theme from '@/constants/theme';
import { CONTEXT } from '@/constants/module/context';
// Prevent the splash screen from auto-hiding before asset loading is complete.
const toastConfig = {
success: (props: BaseToastProps) => (
<SuccessToast {...props} text2NumberOfLines={8} text1NumberOfLines={8}
style={{
maxWidth:"90%",
width:"auto",
height:"auto",
padding:0,
paddingTop:12, paddingBottom:12,
borderLeftColor:"red"
}}
/>
),
error: (props: BaseToastProps) => (
<ErrorToast {...props} text2NumberOfLines={8} text1NumberOfLines={8}
style={{
maxWidth:"90%",
width:"auto",
height:"auto",
padding:0,
paddingTop:12, paddingBottom:12,
borderLeftColor:"red"
}}
/>
),
info: (props: BaseToastProps) => (
<InfoToast {...props} text2NumberOfLines={8} text1NumberOfLines={8}
style={{
maxWidth:"90%",
width:"auto",
height:"auto",
padding:0,
paddingTop:12, paddingBottom:12,
borderLeftColor:"cyan"
}}
/>
),
};
SplashScreen.preventAutoHideAsync();
export default function RootLayout() {
const pathname = usePathname()
const Dimensions = useWindowDimensions();
const [showMenuContext,setShowMenuContext]:any = useState(true)
const [themeTypeContext,setThemeTypeContext]:any = useState("")
const [apiBaseContext, setApiBaseContext]:any = useState("")
const [socketBaseContext, setSocketBaseContext]:any = useState("")
const [widgetContext, setWidgetContext]:any = useState({state:false,component:<></>})
const [showCloudflareTurnstileContext, setShowCloudflareTurnstileContext]:any = useState(false)
const MemoMenu = memo(Menu)
useEffect(() => {
if (Platform.OS === 'web') {
document.title = "ComicMTL";
}
}, [])
const [loaded, error] = useFonts({
SpaceMono: require('@/assets/fonts/SpaceMono-Regular.ttf'),
"roboto-black": require('@/assets/fonts/Roboto-Black.ttf'),
"roboto-bold": require('@/assets/fonts/Roboto-Bold.ttf'),
"roboto-light": require('@/assets/fonts/Roboto-Light.ttf'),
"roboto-medium": require('@/assets/fonts/Roboto-Medium.ttf'),
"roboto-regular": require('@/assets/fonts/Roboto-Regular.ttf'),
"roboto-thin": require('@/assets/fonts/Roboto-Thin.ttf'),
});
useEffect(() => {
if (loaded) {
(async ()=>{
const THEME = await Storage.get("theme")
if (!THEME) await Storage.store("theme","DARK_GREEN")
setThemeTypeContext(`${await Storage.get("theme")}`)
const API_BASE:any = await Storage.get("CUSTOM_API_BASE") || process.env.EXPO_PUBLIC_DEFAULT_API_BASE
await Storage.store("IN_USE_API_BASE", API_BASE)
setApiBaseContext(API_BASE)
const SOCKET_BASE:any = await Storage.get("CUSTOM_SOCKET_BASE") || process.env.EXPO_PUBLIC_DEFAULT_SOCKET_BASE
await Storage.store("IN_USE_SOCKET_BASE", SOCKET_BASE)
setSocketBaseContext(SOCKET_BASE)
SplashScreen.hideAsync();
})()
}
}, [loaded]);
if (!loaded) {
return null;
}
return (<>{loaded && themeTypeContext && apiBaseContext && socketBaseContext && <>
<SafeAreaView style={{flex:1,backgroundColor:Theme[themeTypeContext].background_color}}>
<CONTEXT.Provider value={{
themeTypeContext, setThemeTypeContext,
showMenuContext, setShowMenuContext,
apiBaseContext, setApiBaseContext,
socketBaseContext, setSocketBaseContext,
widgetContext, setWidgetContext,
showCloudflareTurnstileContext, setShowCloudflareTurnstileContext,
}}>
<View style={{width:"100%",height:"100%",backgroundColor: Theme[themeTypeContext].background_color}}>
{showCloudflareTurnstileContext
? <View style={{position:"absolute",width:"100%",height:"100%",display:"flex",justifyContent:"center",alignItems:"center",backgroundColor:Theme[themeTypeContext].background_color}}>
<CloudflareTurnstile
callback={() => {
setShowCloudflareTurnstileContext(false)
}} />
</View>
: <>
<AnimatePresence exitBeforeEnter>
{widgetContext.state &&
<View style={{
width:"100%",
height:"100%",
position:"absolute",
backgroundColor: 'rgba(0, 0, 0, 0.5)',
display:"flex",
justifyContent:"center",
alignItems:"center",
zIndex:1,
padding:15,
}}
>{widgetContext.component}</View>
}
</AnimatePresence>
<View style={{
position:"absolute",
width:"100%",
height:"100%",
display: 'flex',
flex: 1,
flexDirection: Dimensions.width <= 720 ? 'column' : 'row-reverse',
}}>
<Stack screenOptions={{ headerShown: false}}>
<Stack.Screen name="index"/>
<Stack.Screen name="+not-found" />
</Stack>
<AnimatePresence exitBeforeEnter>
{showMenuContext && <MemoMenu/>}
</AnimatePresence>
</View>
</>
}
</View>
<Toast config={toastConfig} />
</CONTEXT.Provider>
</SafeAreaView>
</>}</>);
}