123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- import 'react-native-gesture-handler';
- import 'expo-splash-screen';
- import { QueryClientProvider } from '@tanstack/react-query';
- import { NavigationContainer } from '@react-navigation/native';
- import { queryClient } from 'src/utils/queryClient';
- import * as Sentry from '@sentry/react-native';
- import Route from './Route';
- import { ConnectionProvider } from 'src/contexts/ConnectionContext';
- import ConnectionBanner from 'src/components/ConnectionBanner/ConnectionBanner';
- import { RegionProvider } from 'src/contexts/RegionContext';
- import { ErrorProvider, useError } from 'src/contexts/ErrorContext';
- import { useEffect, useState } from 'react';
- import { setupInterceptors } from 'src/utils/request';
- import { ErrorModal, WarningModal } from 'src/components';
- import React from 'react';
- import { Linking, Platform } from 'react-native';
- import { API_HOST, API_URL, APP_VERSION } from 'src/constants';
- import axios from 'axios';
- import { API } from 'src/types';
- import { storage, StoreType } from 'src/storage';
- const IOS_STORE_URL = 'https://apps.apple.com/app/id6502843543';
- const ANDROID_STORE_URL =
- 'https://play.google.com/store/apps/details?id=com.nomadmania.presentation';
- const userId = (storage.get('uid', StoreType.STRING) as string) ?? 'not_logged_in';
- const routingInstrumentation = Sentry.reactNavigationIntegration({
- enableTimeToInitialDisplay: true
- });
- Sentry.init({
- dsn: 'https://c9b37005f4be22a17a582603ebc17598@o4507781200543744.ingest.de.sentry.io/4507781253824592',
- integrations: [Sentry.reactNativeTracingIntegration({ routingInstrumentation })],
- debug: false,
- ignoreErrors: ['Network Error', 'ECONNABORTED', 'timeout of 10000ms exceeded'],
- beforeSend(event, hint) {
- if (userId) {
- event.user = {
- ...event.user,
- userId: userId
- };
- }
- const isNonError = hint?.originalException instanceof Error === false;
- if (isNonError || event.message?.match(/Non-Error exception captured/)) {
- return {
- ...event,
- message: `Processed Non-Error: ${event.message || 'No message'}`,
- level: 'warning',
- contexts: {
- ...event.contexts,
- non_error: {
- type: typeof hint?.originalException,
- value: JSON.stringify(hint?.originalException)
- }
- }
- };
- }
- return event;
- }
- });
- const linking = {
- prefixes: [API_HOST, 'nomadmania://'],
- config: {
- screens: {
- publicProfileView: '/profile/:userId'
- }
- }
- };
- const App = () => {
- return (
- <QueryClientProvider client={queryClient}>
- <ErrorProvider>
- <InnerApp />
- </ErrorProvider>
- </QueryClientProvider>
- );
- };
- const InnerApp = () => {
- const errorContext = useError();
- const navigation = React.useRef(null);
- const [isUpdateAvailable, setIsUpdateAvailable] = useState(false);
- useEffect(() => {
- setupInterceptors(errorContext);
- }, [errorContext]);
- useEffect(() => {
- const checkLatestVersion = async () => {
- try {
- const response = await axios.get(API_URL + '/' + API.LATEST_VERSION, {
- headers: {
- 'App-Version': APP_VERSION,
- Platform: Platform.OS
- }
- });
- const { version } = response.data;
- const formatVersion = (versionString: string) => {
- return parseInt(versionString.replace(/\./g, ''), 10);
- };
- const currentVersionInt = formatVersion(APP_VERSION);
- const latestVersionInt = formatVersion(version);
- if (latestVersionInt > currentVersionInt) {
- setIsUpdateAvailable(true);
- }
- } catch (error) {
- console.error('Failed to check latest version:', error);
- }
- };
- checkLatestVersion();
- }, []);
- const handleUpdatePress = () => {
- const storeUrl = Platform.OS === 'ios' ? IOS_STORE_URL : ANDROID_STORE_URL;
- Linking.openURL(storeUrl).catch((err) => console.error('Failed to open store URL:', err));
- };
- return (
- <ConnectionProvider>
- <RegionProvider>
- <NavigationContainer
- ref={navigation}
- onReady={() => {
- routingInstrumentation.registerNavigationContainer(navigation);
- }}
- linking={linking}
- >
- <Route />
- <ConnectionBanner />
- <ErrorModal />
- <WarningModal
- isVisible={isUpdateAvailable}
- type="success"
- title="Update Available"
- message="A new version of the NomadMania app is available. Please update to the latest version."
- action={handleUpdatePress}
- onClose={() => setIsUpdateAvailable(false)}
- />
- </NavigationContainer>
- </RegionProvider>
- </ConnectionProvider>
- );
- };
- export default Sentry.wrap(App);
|