188 lines
4.8 KiB
TypeScript
188 lines
4.8 KiB
TypeScript
import { useState, useEffect } from 'react';
|
||
import { StyleSheet, TouchableOpacity, Alert, ActivityIndicator } from 'react-native';
|
||
import * as Updates from 'expo-updates';
|
||
|
||
import { Text, View } from '@/components/Themed';
|
||
|
||
export default function TabOneScreen() {
|
||
const [isChecking, setIsChecking] = useState(false);
|
||
const [updateInfo, setUpdateInfo] = useState<string>('');
|
||
|
||
const checkForUpdates = async () => {
|
||
if (__DEV__) {
|
||
Alert.alert('提示', '开发模式下无法检查更新,请使用生产构建测试热更新功能');
|
||
return;
|
||
}
|
||
|
||
setIsChecking(true);
|
||
setUpdateInfo('正在检查更新...');
|
||
|
||
try {
|
||
const update = await Updates.checkForUpdateAsync();
|
||
|
||
if (update.isAvailable) {
|
||
setUpdateInfo('发现新版本,正在下载...');
|
||
await Updates.fetchUpdateAsync();
|
||
|
||
Alert.alert('更新完成', '新版本已下载完成,是否立即重启应用?', [
|
||
{
|
||
text: '稍后',
|
||
style: 'cancel',
|
||
onPress: () => setUpdateInfo('更新已下载,稍后重启应用即可应用'),
|
||
},
|
||
{
|
||
text: '立即重启',
|
||
onPress: async () => {
|
||
await Updates.reloadAsync();
|
||
},
|
||
},
|
||
]);
|
||
} else {
|
||
setUpdateInfo('当前已是最新版本');
|
||
}
|
||
} catch (error) {
|
||
setUpdateInfo('检查更新失败: ' + (error as Error).message);
|
||
Alert.alert('错误', '检查更新失败,请稍后重试');
|
||
} finally {
|
||
setIsChecking(false);
|
||
}
|
||
};
|
||
|
||
const getUpdateInfo = () => {
|
||
const { isEmbeddedLaunch, isEmergencyLaunch, updateId, channel, runtimeVersion } =
|
||
Updates.useUpdates();
|
||
|
||
return `
|
||
运行模式: ${__DEV__ ? '开发模式' : '生产模式'}
|
||
是否为内嵌启动: ${isEmbeddedLaunch ? '是' : '否'}
|
||
是否为紧急启动: ${isEmergencyLaunch ? '是' : '否'}
|
||
更新 ID: ${updateId || '无'}
|
||
更新通道: ${channel || '无'}
|
||
运行时版本: ${runtimeVersion || '无'}
|
||
`.trim();
|
||
};
|
||
|
||
useEffect(() => {
|
||
console.log('=== TabOneScreen 组件已渲染 ===');
|
||
}, []);
|
||
|
||
return (
|
||
<View style={styles.container}>
|
||
<Text style={styles.title}>🚀 热更新演示</Text>
|
||
<View style={styles.separator} lightColor="#eee" darkColor="rgba(255,255,255,0.1)" />
|
||
|
||
<View style={styles.infoContainer}>
|
||
<Text style={styles.infoTitle}>当前版本信息:</Text>
|
||
<Text style={styles.infoText}>{getUpdateInfo()}</Text>
|
||
</View>
|
||
|
||
<TouchableOpacity
|
||
style={[styles.button, isChecking && styles.buttonDisabled]}
|
||
onPress={checkForUpdates}
|
||
disabled={isChecking}
|
||
>
|
||
{isChecking ? (
|
||
<ActivityIndicator color="#fff" />
|
||
) : (
|
||
<Text style={styles.buttonText}>检查更新</Text>
|
||
)}
|
||
</TouchableOpacity>
|
||
|
||
{updateInfo ? (
|
||
<View style={styles.updateInfoContainer}>
|
||
<Text style={styles.updateInfoText}>{updateInfo}</Text>
|
||
</View>
|
||
) : null}
|
||
|
||
<View style={styles.instructionsContainer}>
|
||
<Text style={styles.instructionsTitle}>📝 使用说明:</Text>
|
||
<Text style={styles.instructionsText}>
|
||
1. 使用 EAS Build 构建生产版本{'\n'}
|
||
2. 修改代码后运行 eas update 发布更新{'\n'}
|
||
3. 打开应用点击"检查更新"按钮{'\n'}
|
||
4. 应用会自动下载并提示重启
|
||
</Text>
|
||
</View>
|
||
</View>
|
||
);
|
||
}
|
||
|
||
const styles = StyleSheet.create({
|
||
container: {
|
||
flex: 1,
|
||
alignItems: 'center',
|
||
justifyContent: 'center',
|
||
padding: 20,
|
||
},
|
||
title: {
|
||
fontSize: 28,
|
||
fontWeight: 'bold',
|
||
marginBottom: 10,
|
||
},
|
||
separator: {
|
||
marginVertical: 20,
|
||
height: 1,
|
||
width: '80%',
|
||
},
|
||
infoContainer: {
|
||
backgroundColor: 'rgba(0, 122, 255, 0.1)',
|
||
padding: 15,
|
||
borderRadius: 10,
|
||
marginBottom: 20,
|
||
width: '100%',
|
||
},
|
||
infoTitle: {
|
||
fontSize: 16,
|
||
fontWeight: 'bold',
|
||
marginBottom: 10,
|
||
},
|
||
infoText: {
|
||
fontSize: 12,
|
||
fontFamily: 'monospace',
|
||
lineHeight: 18,
|
||
},
|
||
button: {
|
||
backgroundColor: '#007AFF',
|
||
paddingHorizontal: 30,
|
||
paddingVertical: 15,
|
||
borderRadius: 10,
|
||
marginBottom: 20,
|
||
minWidth: 200,
|
||
alignItems: 'center',
|
||
},
|
||
buttonDisabled: {
|
||
backgroundColor: '#999',
|
||
},
|
||
buttonText: {
|
||
color: '#fff',
|
||
fontSize: 16,
|
||
fontWeight: 'bold',
|
||
},
|
||
updateInfoContainer: {
|
||
backgroundColor: 'rgba(52, 199, 89, 0.1)',
|
||
padding: 15,
|
||
borderRadius: 10,
|
||
marginBottom: 20,
|
||
width: '100%',
|
||
},
|
||
updateInfoText: {
|
||
fontSize: 14,
|
||
textAlign: 'center',
|
||
},
|
||
instructionsContainer: {
|
||
backgroundColor: 'rgba(255, 149, 0, 0.1)',
|
||
padding: 15,
|
||
borderRadius: 10,
|
||
width: '100%',
|
||
},
|
||
instructionsTitle: {
|
||
fontSize: 16,
|
||
fontWeight: 'bold',
|
||
marginBottom: 10,
|
||
},
|
||
instructionsText: {
|
||
fontSize: 13,
|
||
lineHeight: 20,
|
||
},
|
||
});
|