@@ -7,7 +7,7 @@ import { EnhancedStore } from '@reduxjs/toolkit'
77import React , { useEffect , useState } from 'react'
88import { I18nextProvider } from 'react-i18next'
99import { Provider } from 'react-redux'
10- import { MaintenanceScreen , LoadingScreen } from '@/components'
10+ import { MaintenanceScreen , LoadingScreen , AppUpdatePopup } from '@/components'
1111// eslint-disable-next-line camelcase
1212import { useFonts , Inter_400Regular } from '@expo-google-fonts/inter'
1313import RootContainer from '@/components/RootContainer'
@@ -18,6 +18,9 @@ import { isRunningInExpoGo } from 'expo'
1818import { Platform , StatusBar , useColorScheme } from 'react-native'
1919import { getThemeStyle } from '@/utils'
2020import { KeyboardProvider } from 'react-native-keyboard-controller'
21+ import ApiService from '@/services/ApiService'
22+ import { AppVersionCheckResponse } from '@/types'
23+ import * as Application from 'expo-application'
2124
2225const navigationIntegration = Sentry . reactNavigationIntegration ( {
2326 enableTimeToInitialDisplay : ! isRunningInExpoGo ( ) ,
@@ -58,6 +61,8 @@ const RootLayout = () => {
5861 // Capture the NavigationContainer ref and register it with the integration
5962 const ref = useNavigationContainerRef ( )
6063 const colorScheme = useColorScheme ( )
64+ const [ appVersionStatus , setAppVersionStatus ] = useState < AppVersionCheckResponse | null > ( null )
65+ const [ appUpdatePopupVisible , setAppUpdatePopupVisible ] = useState ( false )
6166
6267 useEffect ( ( ) => {
6368 if ( ref ?. current ) {
@@ -78,11 +83,45 @@ const RootLayout = () => {
7883 } )
7984 } , [ ] )
8085
86+ // Check app version
87+ useEffect ( ( ) => {
88+ async function checkAppVersion ( ) {
89+ try {
90+ const apiService = new ApiService ( )
91+
92+ // Get native app version and build version
93+ let appVersion = '1.0.0'
94+ let buildVersion = '1'
95+
96+ if ( Platform . OS === 'ios' || Platform . OS === 'android' ) {
97+ appVersion = Application . nativeApplicationVersion !
98+ buildVersion = Application . nativeBuildVersion !
99+ }
100+
101+ const appVersionCheckResults = await apiService . checkAppVersion (
102+ Platform . OS , // Pass Platform.OS directly (web, ios, android)
103+ appVersion ,
104+ buildVersion ,
105+ )
106+
107+ setAppVersionStatus ( appVersionCheckResults )
108+ setAppUpdatePopupVisible (
109+ appVersionCheckResults . force_update_required || appVersionCheckResults . update_available ,
110+ )
111+ } catch ( error ) {
112+ console . error ( 'Failed to check app version:' , error )
113+ }
114+ }
115+
116+ checkAppVersion ( )
117+ } , [ ] )
118+
81119 if ( ! reduxStore || ! fontsLoaded ) {
82120 return < LoadingScreen />
83121 }
84122
85- if ( process . env . EXPO_PUBLIC_MAINTENANCE_MODE === 'true' ) {
123+ // Maintenance mode check from API response
124+ if ( appVersionStatus && appVersionStatus . maintenance_mode ) {
86125 return < MaintenanceScreen />
87126 }
88127
@@ -94,6 +133,14 @@ const RootLayout = () => {
94133 < I18nextProvider i18n = { i18n } >
95134 < Provider store = { reduxStore } >
96135 < RootContainer >
136+ { appVersionStatus && (
137+ < AppUpdatePopup
138+ isForced = { appVersionStatus . force_update_required }
139+ visible = { appUpdatePopupVisible }
140+ onDismiss = { appVersionStatus . force_update_required ? undefined : ( ) => setAppUpdatePopupVisible ( false ) }
141+ />
142+ ) }
143+
97144 < Stack
98145 screenOptions = { {
99146 headerShown : false ,
0 commit comments