114 lines
No EOL
4.3 KiB
TypeScript
114 lines
No EOL
4.3 KiB
TypeScript
import React, { useState, useEffect } from 'react';
|
||
import { View, ActivityIndicator } from 'react-native';
|
||
import { tw, theme, MyText, MyTouchableOpacity , BottomDialog } from 'common-ui';
|
||
import { trpc, trpcClient } from '@/src/trpc-client';
|
||
import { useGetEssentialConsts } from '@/src/api-hooks/essential-consts.api';
|
||
import Constants from 'expo-constants';
|
||
import * as Linking from 'expo-linking';
|
||
|
||
interface HealthTestWrapperProps {
|
||
children: React.ReactNode;
|
||
}
|
||
|
||
const HealthTestWrapper: React.FC<HealthTestWrapperProps> = ({ children }) => {
|
||
const { data, isLoading, error, refetch } = trpc.common.healthCheck.useQuery();
|
||
const { data: backendConsts } = useGetEssentialConsts();
|
||
|
||
const versionFromBackend = backendConsts?.versionNum;
|
||
const appUrl = backendConsts?.playStoreUrl;
|
||
|
||
const [showUpdateDialog, setShowUpdateDialog] = useState(false);
|
||
|
||
// Version comparison logic
|
||
useEffect(() => {
|
||
const version = Constants.expoConfig?.version;
|
||
if (!version || !versionFromBackend) return;
|
||
|
||
// Parse local version
|
||
const versionParts = version.split('.');
|
||
const versionNum1 = parseInt(versionParts[0]);
|
||
const versionNum2 = parseInt(versionParts[1]);
|
||
const versionNum3 = parseInt(versionParts[2]);
|
||
|
||
if (isNaN(versionNum1) || isNaN(versionNum2) || isNaN(versionNum3)) return;
|
||
|
||
// Parse backend version
|
||
const backendVersionParts = versionFromBackend.split('.');
|
||
const backendVersionNum1 = parseInt(backendVersionParts[0]);
|
||
const backendVersionNum2 = parseInt(backendVersionParts[1]);
|
||
const backendVersionNum3 = parseInt(backendVersionParts[2]);
|
||
|
||
if (isNaN(backendVersionNum1) || isNaN(backendVersionNum2) || isNaN(backendVersionNum3)) return;
|
||
|
||
// Compare versions
|
||
const needsUpdate = versionNum1 < backendVersionNum1 ||
|
||
(versionNum1 === backendVersionNum1 && versionNum2 < backendVersionNum2);
|
||
|
||
if (needsUpdate) {
|
||
setShowUpdateDialog(true);
|
||
}
|
||
}, [versionFromBackend]);
|
||
|
||
// Log app version
|
||
console.log('App Version:', Constants.expoConfig?.version);
|
||
console.log('Backend Version:', versionFromBackend);
|
||
if (isLoading) {
|
||
return (
|
||
<View style={tw`flex-1 justify-center items-center bg-gray-50`}>
|
||
<ActivityIndicator size="large" color={theme.colors.brand500} />
|
||
<MyText style={tw`text-gray-500 mt-4 font-medium`}>Checking service status...</MyText>
|
||
</View>
|
||
);
|
||
}
|
||
|
||
if (error || data?.status !== "ok") {
|
||
return (
|
||
<View style={tw`flex-1 justify-center items-center bg-gray-50 p-6`}>
|
||
<View style={tw`w-16 h-16 bg-red-100 rounded-full items-center justify-center mb-4`}>
|
||
<MyText style={tw`text-red-600 text-2xl`}>⚠️</MyText>
|
||
</View>
|
||
<MyText style={tw`text-xl font-bold text-gray-900 mb-2`}>Service Unavailable</MyText>
|
||
<MyText style={tw`text-gray-600 text-center mb-6 leading-5`}>
|
||
Please check your connection and try again.
|
||
</MyText>
|
||
<MyTouchableOpacity
|
||
onPress={() => refetch()}
|
||
style={tw`bg-brand500 px-8 py-3 rounded-xl shadow-md`}
|
||
activeOpacity={0.8}
|
||
>
|
||
<MyText style={tw`text-white font-bold text-base`}>Retry</MyText>
|
||
</MyTouchableOpacity>
|
||
</View>
|
||
);
|
||
}
|
||
|
||
return (
|
||
<>
|
||
{children}
|
||
{showUpdateDialog && appUrl && (
|
||
<BottomDialog open={showUpdateDialog} onClose={() => setShowUpdateDialog(false)} enableDismiss={false}>
|
||
<View style={{ padding: 20 }}>
|
||
<MyText style={{ fontSize: 18, fontWeight: 'bold', marginBottom: 16 }}>
|
||
Update Available
|
||
</MyText>
|
||
<MyText style={{ marginBottom: 24 }}>
|
||
A new version ({versionFromBackend}) is available. Your current version is {Constants.expoConfig?.version}. Please update to continue using the app.
|
||
</MyText>
|
||
<MyTouchableOpacity
|
||
onPress={() => {
|
||
if (appUrl) {
|
||
Linking.openURL(appUrl);
|
||
}
|
||
}}
|
||
style={{ backgroundColor: theme.colors.brand500, padding: 12, borderRadius: 8, alignItems: 'center' }}
|
||
>
|
||
<MyText style={{ color: 'white', fontWeight: 'bold' }}>Update Now</MyText>
|
||
</MyTouchableOpacity>
|
||
</View>
|
||
</BottomDialog>
|
||
)}
|
||
</>
|
||
);
|
||
};
|
||
|
||
export default HealthTestWrapper; |