import { NavigationContainer } from '@react-navigation/native'; import AppLoading from 'expo-app-loading'; import 'expo-asset'; import { Asset } from 'expo-asset'; import * as Updates from "expo-updates"; import React, { useEffect, useRef, useState } from 'react'; import { Alert, Keyboard, LogBox, SafeAreaView, StatusBar } from 'react-native'; import 'react-native-gesture-handler'; import { MenuProvider } from 'react-native-popup-menu'; import { SafeAreaProvider } from 'react-native-safe-area-context'; import { QueryClient, QueryClientProvider } from 'react-query'; import { AuthContextProvider } from './src/state/external/auth-provider'; import { PermissionsContextProvider } from './src/permissions-context'; import { navigationRef } from './src/components/navigation/root-navigator'; import Atlas from './src/components/Atlas'; import { colors } from './src/utils/GlobalUtils'; import { LOGGING } from './src/utils/logging'; import { store } from './src/main-store'; const App: React.FC = () => { const updateDismissed = useRef(false) const queryClient = new QueryClient() useEffect(() => { const keyboardDidShowListener = Keyboard.addListener( 'keyboardWillShow', () => { store.global.setKeyboardOpen(true); } ); const keyboardDidHideListener = Keyboard.addListener( 'keyboardWillHide', () => { store.global.setKeyboardOpen(false); } ); return () => { keyboardDidHideListener.remove(); keyboardDidShowListener.remove(); }; }, []); useEffect(() => { LOGGING.log("SYSTEM", 'info', "Launching app...") if (!__DEV__) { LOGGING.log("SYSTEM", 'info', "App is release version, checking for updates...") const timer = setInterval(async () => { const update = await Updates.checkForUpdateAsync() if (update.isAvailable && !updateDismissed.current) { LOGGING.log("SYSTEM", 'info', "Update available, prompting user...") updateDismissed.current = true setTimeout(() => { Alert.alert('Update Available', 'An update is available. Would you like to update now?', [ {"text": "Yes", "onPress": async () => { await Updates.fetchUpdateAsync() await Updates.reloadAsync() }}, {"text": "No", "onPress": () => { Alert.alert('Update Available', 'Update dismissed, you can always revisit it in settings', [ {"text": "OK"} ]) }} ]) }, 1000); } }, 5000) return () => clearInterval(timer) }}, []) LogBox.ignoreAllLogs(); const [loading, setLoading] = useState(false); const _cacheResourcesAsync = async () => { const images = [ require('./assets/logo-white.png'), require('./assets/cover-dark.png'), require('./assets/cover.jpg'), require('./assets/default-pfp.png'), require('./assets/pin-icons/pothole.png'), require('./assets/pin-icons/roadblock.png'), require('./assets/pin-icons/barrier.png'), require('./assets/pin-icons/bump.png'), require('./assets/pin-icons/information.png'), require('./assets/pin-icons/washroom.png'), require('./assets/pin-icons/park.png'), ]; const cacheImages = images.map(image => { return Asset.fromModule(image).downloadAsync(); }); Promise.all(cacheImages); } if (loading) { return ( setLoading(false)} onError={console.warn} /> ); } return ( ); } export default App;