Files
musicland/App.js
T
2026-08-26 15:19:40 +02:00

224 lines
6.9 KiB
JavaScript

import '@expo/metro-runtime'
import { PortalProvider } from '@gorhom/portal'
import { DefaultTheme, NavigationContainer } from '@react-navigation/native'
import { useFonts } from 'expo-font'
import * as SplashScreen from 'expo-splash-screen'
import { StatusBar } from 'expo-status-bar'
import moment from 'moment'
import 'moment/locale/fr'
import { Platform, Text, TextInput } from 'react-native'
import { GestureHandlerRootView } from 'react-native-gesture-handler'
import React, { setGlobal, useCallback, useEffect, useGlobal, useState } from 'reactn'
import { MainStack, Routes } from './src/navigation'
import { Palette } from './src/styles'
import { navigationRef, reset } from './src/navigation/NavigationService'
import { MenuProvider } from 'react-native-popup-menu'
import initialGlobalState from './src/config/initialGlobalState'
import {
Inter_400Regular,
Inter_400Regular_Italic,
Inter_500Medium,
Inter_600SemiBold,
Inter_700Bold,
} from '@expo-google-fonts/inter'
import firebase from './src/config/firebase'
import Providers from './src/providers'
import { LogBox } from 'react-native'
import CommentsBottomSheet from './src/components/bottomsheets/CommentsBottomSheet'
import ShareQrModalContainer from './src/components/modal/ShareQrModalContainer'
import AppDownloadBanner from './src/components/AppDownloadBanner'
import './src/utils/Sheet'
console.disableYellowBox = true
console.reportErrorsAsExceptions = false
moment.locale('fr')
// Keep typography stable regardless of the user's system font scaling on mobile
if (Platform.OS !== 'web') {
if (Text.defaultProps == null) {
Text.defaultProps = {}
}
if (TextInput.defaultProps == null) {
TextInput.defaultProps = {}
}
Text.defaultProps.allowFontScaling = false
TextInput.defaultProps.allowFontScaling = false
}
setGlobal(initialGlobalState)
SplashScreen.preventAutoHideAsync()
const App = () => {
const [, setCurrentUID] = useGlobal('currentUID')
const [, setCurrentUserRoles] = useGlobal('currentUserRoles')
const [appIsReady, setAppIsReady] = useState(false)
const [isInitializing, setInitializing] = useState(true)
const routeNameRef = React.useRef(null)
const syncActiveRoute = useCallback(() => {
const currentRoute = navigationRef.current?.getCurrentRoute()
const currentName = currentRoute?.name ?? null
if (routeNameRef.current !== currentName) {
routeNameRef.current = currentName
setGlobal({ activeRouteName: currentName })
}
}, [setGlobal])
const handleNavigationReady = useCallback(() => {
syncActiveRoute()
}, [syncActiveRoute])
const handleNavigationStateChange = useCallback(() => {
syncActiveRoute()
}, [syncActiveRoute])
const [loaded] = useFonts({
NewYorkSemibold: require('./src/assets/fonts/NewYork-Semibold.ttf'),
OpenSansRegular: require('./src/assets/fonts/OpenSans-Regular.ttf'),
InterRegular: Inter_400Regular,
InterMedium: Inter_500Medium,
InterSemiBold: Inter_600SemiBold,
InterBold: Inter_700Bold,
InterRegularItalic: Inter_400Regular_Italic,
HelveticaNeueRegular: require('./src/assets/fonts/HelveticaNeueRegular.ttf'),
HelveticaNeueMedium: require('./src/assets/fonts/HelveticaNeueMedium.ttf'),
HelveticaNeueBold: require('./src/assets/fonts/HelveticaNeueBold.ttf'),
OwnersRegular: require('./src/assets/fonts/OwnersRegular.ttf'),
OwnersMedium: require('./src/assets/fonts/OwnersMedium.ttf'),
OwnersBold: require('./src/assets/fonts/OwnersBold.ttf'),
})
useEffect(() => {
if (loaded) {
setAppIsReady(true)
LogBox.ignoreAllLogs()
}
}, [loaded])
const onLayoutRootView = useCallback(async () => {
if (appIsReady) {
await SplashScreen.hideAsync()
}
}, [appIsReady, loaded])
useEffect(() => {
const subscriber = firebase.auth().onAuthStateChanged(onAuthStateChanged)
return subscriber
}, [])
useEffect(() => {
if (Platform.OS === 'web') {
const s = document.createElement('script')
const isCompactViewport = window.innerWidth < 700
s.src = 'https://minuit.app/embed/report-a-problem.js'
s.async = true
s.setAttribute('data-project-id', 'playbackproduction')
s.setAttribute('data-position', isCompactViewport ? 'custom' : 'right')
s.setAttribute('data-offset', isCompactViewport ? '12' : '16')
if (isCompactViewport) {
s.setAttribute('data-top', '72')
}
s.setAttribute('data-primary-color', '#FB68A8')
s.setAttribute('data-bg-primary-color', '#0E0E12')
s.setAttribute('data-bg-secondary-color', '#1D1825')
s.setAttribute('data-text-color', '#F3F0F5')
document.body.appendChild(s)
return () => {
try {
s.remove()
} catch (_) {}
}
}
}, [])
const onAuthStateChanged = async (user) => {
if (isInitializing) {
setInitializing(false)
}
if (user?.uid) {
setCurrentUID(user.uid)
const idTokenResult = await user.getIdTokenResult()
setCurrentUserRoles(idTokenResult?.claims?.roles || [])
} else {
setCurrentUID(null)
setGlobal(initialGlobalState)
reset({
index: 0,
routes: [{ name: Routes.Splash }],
})
}
}
if (!loaded || isInitializing) {
return null
}
return (
<>
<StatusBar style="light" />
<GestureHandlerRootView
onLayout={onLayoutRootView}
style={[
{
flex: 1,
backgroundColor: Platform.OS === 'web' ? 'transparent' : Palette.darkPurple,
},
]}
>
<PortalProvider>
<Providers>
<MenuProvider>
{/* <AppLayout currentUID={currentUID}> */}
<NavigationContainer
theme={{
...DefaultTheme,
colors: {
...DefaultTheme.colors,
background: Platform.OS === 'web' ? 'transparent' : Palette.darkPurple,
},
}}
ref={navigationRef}
onReady={handleNavigationReady}
onStateChange={handleNavigationStateChange}
documentTitle={{
formatter: (options) =>
options?.title ? `${options?.title} - MusicLand` : 'MusicLand',
}}
linking={{
prefixes: ['musicland://', 'https://musicland-one.vercel.app'],
config: {
screens: {
// Add any deep link configurations here if needed
},
},
}}
>
<MainStack />
</NavigationContainer>
<CommentsBottomSheet />
<ShareQrModalContainer />
<AppDownloadBanner />
{/* </AppLayout> */}
</MenuProvider>
</Providers>
</PortalProvider>
</GestureHandlerRootView>
</>
)
}
export default App