App.tsx 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. import 'react-native-gesture-handler';
  2. import 'expo-splash-screen';
  3. import { QueryClientProvider } from '@tanstack/react-query';
  4. import { NavigationContainer } from '@react-navigation/native';
  5. import { queryClient } from 'src/utils/queryClient';
  6. import * as Sentry from '@sentry/react-native';
  7. import Route from './Route';
  8. import { ConnectionProvider } from 'src/contexts/ConnectionContext';
  9. import ConnectionBanner from 'src/components/ConnectionBanner/ConnectionBanner';
  10. import { RegionProvider } from 'src/contexts/RegionContext';
  11. import { ErrorProvider, useError } from 'src/contexts/ErrorContext';
  12. import { useEffect, useState } from 'react';
  13. import { setupInterceptors } from 'src/utils/request';
  14. import { ErrorModal, WarningModal } from 'src/components';
  15. import React from 'react';
  16. import { Linking, Platform } from 'react-native';
  17. import { API_HOST, API_URL, APP_VERSION } from 'src/constants';
  18. import axios from 'axios';
  19. import { API } from 'src/types';
  20. const IOS_STORE_URL = 'https://apps.apple.com/app/id6502843543';
  21. const ANDROID_STORE_URL =
  22. 'https://play.google.com/store/apps/details?id=com.nomadmania.presentation';
  23. const routingInstrumentation = Sentry.reactNavigationIntegration({
  24. enableTimeToInitialDisplay: true
  25. });
  26. Sentry.init({
  27. dsn: 'https://c9b37005f4be22a17a582603ebc17598@o4507781200543744.ingest.de.sentry.io/4507781253824592',
  28. integrations: [Sentry.reactNativeTracingIntegration({ routingInstrumentation })],
  29. debug: false,
  30. ignoreErrors: ['Network Error', 'ECONNABORTED', 'timeout of 10000ms exceeded']
  31. });
  32. const linking = {
  33. prefixes: [API_HOST, 'nomadmania://'],
  34. config: {
  35. screens: {
  36. publicProfileView: 'profile/:userId'
  37. }
  38. }
  39. };
  40. const App = () => {
  41. return (
  42. <QueryClientProvider client={queryClient}>
  43. <ErrorProvider>
  44. <InnerApp />
  45. </ErrorProvider>
  46. </QueryClientProvider>
  47. );
  48. };
  49. const InnerApp = () => {
  50. const errorContext = useError();
  51. const navigation = React.useRef(null);
  52. const [isUpdateAvailable, setIsUpdateAvailable] = useState(false);
  53. useEffect(() => {
  54. setupInterceptors(errorContext);
  55. }, [errorContext]);
  56. useEffect(() => {
  57. const checkLatestVersion = async () => {
  58. try {
  59. const response = await axios.get(API_URL + '/' + API.LATEST_VERSION, {
  60. headers: {
  61. 'App-Version': APP_VERSION,
  62. Platform: Platform.OS
  63. }
  64. });
  65. const { version } = response.data;
  66. const formatVersion = (versionString: string) => {
  67. return parseInt(versionString.replace(/\./g, ''), 10);
  68. };
  69. const currentVersionInt = formatVersion(APP_VERSION);
  70. const latestVersionInt = formatVersion(version);
  71. if (latestVersionInt > currentVersionInt) {
  72. setIsUpdateAvailable(true);
  73. }
  74. } catch (error) {
  75. console.error('Failed to check latest version:', error);
  76. }
  77. };
  78. checkLatestVersion();
  79. }, []);
  80. const handleUpdatePress = () => {
  81. const storeUrl = Platform.OS === 'ios' ? IOS_STORE_URL : ANDROID_STORE_URL;
  82. Linking.openURL(storeUrl).catch((err) => console.error('Failed to open store URL:', err));
  83. };
  84. return (
  85. <ConnectionProvider>
  86. <RegionProvider>
  87. <NavigationContainer
  88. ref={navigation}
  89. onReady={() => {
  90. routingInstrumentation.registerNavigationContainer(navigation);
  91. }}
  92. linking={linking}
  93. >
  94. <Route />
  95. <ConnectionBanner />
  96. <ErrorModal />
  97. <WarningModal
  98. isVisible={isUpdateAvailable}
  99. type="success"
  100. title="Update Available"
  101. message="A new version of the NomadMania app is available. Please update to the latest version."
  102. action={handleUpdatePress}
  103. onClose={() => setIsUpdateAvailable(false)}
  104. />
  105. </NavigationContainer>
  106. </RegionProvider>
  107. </ConnectionProvider>
  108. );
  109. };
  110. export default Sentry.wrap(App);