App.tsx 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. import { NavigationContainer } from '@react-navigation/native';
  2. import AppLoading from 'expo-app-loading';
  3. import 'expo-asset';
  4. import { Asset } from 'expo-asset';
  5. import * as Updates from "expo-updates";
  6. import React, { useEffect, useRef, useState } from 'react';
  7. import { Alert, Keyboard, LogBox, SafeAreaView, StatusBar } from 'react-native';
  8. import 'react-native-gesture-handler';
  9. import { MenuProvider } from 'react-native-popup-menu';
  10. import { SafeAreaProvider } from 'react-native-safe-area-context';
  11. import { QueryClient, QueryClientProvider } from 'react-query';
  12. import { AuthContextProvider } from './src/state/external/auth-provider';
  13. import { PermissionsContextProvider } from './src/permissions-context';
  14. import { navigationRef } from './src/components/navigation/root-navigator';
  15. import Atlas from './src/components/Atlas';
  16. import { colors } from './src/utils/GlobalUtils';
  17. import { LOGGING } from './src/utils/logging';
  18. import { store } from './src/main-store';
  19. const App: React.FC = () => {
  20. const updateDismissed = useRef<boolean>(false)
  21. const queryClient = new QueryClient()
  22. useEffect(() => {
  23. const keyboardDidShowListener = Keyboard.addListener(
  24. 'keyboardWillShow',
  25. () => {
  26. store.global.setKeyboardOpen(true);
  27. }
  28. );
  29. const keyboardDidHideListener = Keyboard.addListener(
  30. 'keyboardWillHide',
  31. () => {
  32. store.global.setKeyboardOpen(false);
  33. }
  34. );
  35. return () => {
  36. keyboardDidHideListener.remove();
  37. keyboardDidShowListener.remove();
  38. };
  39. }, []);
  40. useEffect(() => {
  41. LOGGING.log("SYSTEM", 'info', "Launching app...")
  42. if (!__DEV__) {
  43. LOGGING.log("SYSTEM", 'info', "App is release version, checking for updates...")
  44. const timer = setInterval(async () => {
  45. const update = await Updates.checkForUpdateAsync()
  46. if (update.isAvailable && !updateDismissed.current) {
  47. LOGGING.log("SYSTEM", 'info', "Update available, prompting user...")
  48. updateDismissed.current = true
  49. setTimeout(() => {
  50. Alert.alert('Update Available', 'An update is available. Would you like to update now?', [
  51. {"text": "Yes", "onPress": async () => {
  52. await Updates.fetchUpdateAsync()
  53. await Updates.reloadAsync()
  54. }},
  55. {"text": "No", "onPress": () => {
  56. Alert.alert('Update Available', 'Update dismissed, you can always revisit it in settings', [
  57. {"text": "OK"}
  58. ])
  59. }}
  60. ])
  61. }, 1000);
  62. }
  63. }, 5000)
  64. return () => clearInterval(timer)
  65. }}, [])
  66. LogBox.ignoreAllLogs();
  67. const [loading, setLoading] = useState(false);
  68. const _cacheResourcesAsync = async () => {
  69. const images = [
  70. require('./assets/logo-white.png'),
  71. require('./assets/cover-dark.png'),
  72. require('./assets/cover.jpg'),
  73. require('./assets/default-pfp.png'),
  74. require('./assets/pin-icons/pothole.png'),
  75. require('./assets/pin-icons/roadblock.png'),
  76. require('./assets/pin-icons/barrier.png'),
  77. require('./assets/pin-icons/bump.png'),
  78. require('./assets/pin-icons/information.png'),
  79. require('./assets/pin-icons/washroom.png'),
  80. require('./assets/pin-icons/park.png'),
  81. ];
  82. const cacheImages = images.map(image => {
  83. return Asset.fromModule(image).downloadAsync();
  84. });
  85. Promise.all(cacheImages);
  86. }
  87. if (loading) {
  88. return (
  89. <AppLoading
  90. startAsync={_cacheResourcesAsync}
  91. onFinish={() => setLoading(false)}
  92. onError={console.warn}
  93. />
  94. );
  95. }
  96. return (
  97. <SafeAreaProvider>
  98. <QueryClientProvider client={queryClient}>
  99. <MenuProvider>
  100. <SafeAreaView style={{height: '100%', backgroundColor: colors.red}}>
  101. <StatusBar barStyle='light-content' backgroundColor={colors.red}/>
  102. <NavigationContainer ref={navigationRef}>
  103. <AuthContextProvider>
  104. <PermissionsContextProvider>
  105. <Atlas/>
  106. </PermissionsContextProvider>
  107. </AuthContextProvider>
  108. </NavigationContainer>
  109. </SafeAreaView>
  110. </MenuProvider>
  111. </QueryClientProvider>
  112. </SafeAreaProvider>
  113. );
  114. }
  115. export default App;