You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
156 lines
3.9 KiB
156 lines
3.9 KiB
// 国家选择 |
|
import React, { useState, useEffect } from 'react'; |
|
import { |
|
View, |
|
Text, |
|
FlatList, |
|
TouchableOpacity, |
|
StyleSheet, |
|
SafeAreaView, |
|
StatusBar, |
|
} from 'react-native'; |
|
import { useTranslation } from 'react-i18next'; |
|
import { Country, countries } from '../constants/countries'; |
|
import Constants from 'expo-constants'; |
|
import AsyncStorage from '@react-native-async-storage/async-storage'; |
|
import { useNavigation } from '@react-navigation/native'; |
|
import type { NativeStackNavigationProp } from '@react-navigation/native-stack'; |
|
import { RootStackParamList } from '../types/navigation'; |
|
|
|
const SELECTED_COUNTRY_KEY = '@selected_country'; |
|
|
|
export const CountrySelect = () => { |
|
const { t } = useTranslation(); |
|
const [selectedCountry, setSelectedCountry] = useState<string>(''); |
|
const navigation = useNavigation<NativeStackNavigationProp<RootStackParamList>>(); |
|
|
|
useEffect(() => { |
|
checkSelectedCountry(); |
|
}, []); |
|
|
|
const checkSelectedCountry = async () => { |
|
try { |
|
const savedCountry = await AsyncStorage.getItem(SELECTED_COUNTRY_KEY); |
|
if (savedCountry) { |
|
// 如果已经选择过国家,直接导航到主页面 |
|
// 只有在非清除语言选择的情况下才导航 |
|
const isCleared = await AsyncStorage.getItem('languageCleared'); |
|
if (!isCleared) { |
|
navigation.replace('MainTabs'); |
|
} |
|
} |
|
} catch (error) { |
|
console.error('Error checking selected country:', error); |
|
} |
|
}; |
|
|
|
const handleCountrySelect = async (country: Country) => { |
|
try { |
|
await AsyncStorage.setItem(SELECTED_COUNTRY_KEY, JSON.stringify(country)); |
|
// 清除清除标记 |
|
await AsyncStorage.removeItem('languageCleared'); |
|
// 选择国家后导航到主页面 |
|
navigation.replace('MainTabs'); |
|
} catch (error) { |
|
console.error('Error saving selected country:', error); |
|
} |
|
}; |
|
|
|
const renderCountryItem = ({ item }: { item: Country }) => ( |
|
<TouchableOpacity |
|
style={[ |
|
styles.countryItem, |
|
selectedCountry === item.code && styles.selectedItem |
|
]} |
|
onPress={() => handleCountrySelect(item)} |
|
> |
|
<Text style={styles.flag}>{item.flag}</Text> |
|
<Text style={[ |
|
styles.countryName, |
|
selectedCountry === item.code && styles.selectedText |
|
]}>{item.name}</Text> |
|
{selectedCountry === item.code && ( |
|
<Text style={styles.checkmark}>✓</Text> |
|
)} |
|
</TouchableOpacity> |
|
); |
|
|
|
return ( |
|
<View style={styles.container}> |
|
<StatusBar |
|
backgroundColor="#fff" |
|
barStyle="dark-content" |
|
/> |
|
<SafeAreaView style={styles.safeArea}> |
|
<View style={styles.header}> |
|
<Text style={styles.title}>{t('selectCountry')}</Text> |
|
<Text style={styles.subtitle}>{t('subtitle')}</Text> |
|
</View> |
|
<FlatList |
|
data={countries} |
|
renderItem={renderCountryItem} |
|
keyExtractor={(item) => item.code} |
|
style={styles.list} |
|
showsVerticalScrollIndicator={false} |
|
/> |
|
</SafeAreaView> |
|
</View> |
|
); |
|
}; |
|
|
|
const styles = StyleSheet.create({ |
|
container: { |
|
flex: 1, |
|
backgroundColor: '#fff', |
|
paddingTop: Constants.statusBarHeight, |
|
}, |
|
safeArea: { |
|
flex: 1, |
|
}, |
|
header: { |
|
padding: 20, |
|
backgroundColor: '#fff', |
|
}, |
|
title: { |
|
fontSize: 24, |
|
fontWeight: 'bold', |
|
marginBottom: 8, |
|
color: '#000', |
|
}, |
|
subtitle: { |
|
fontSize: 14, |
|
color: '#666', |
|
marginBottom: 20, |
|
lineHeight: 20, |
|
}, |
|
list: { |
|
flex: 1, |
|
}, |
|
countryItem: { |
|
flexDirection: 'row', |
|
alignItems: 'center', |
|
padding: 16, |
|
borderBottomWidth: 1, |
|
borderBottomColor: '#f0f0f0', |
|
}, |
|
selectedItem: { |
|
backgroundColor: '#f8f8f8', |
|
}, |
|
flag: { |
|
fontSize: 24, |
|
marginRight: 16, |
|
}, |
|
countryName: { |
|
flex: 1, |
|
fontSize: 16, |
|
color: '#333', |
|
}, |
|
selectedText: { |
|
color: '#007AFF', |
|
fontWeight: '500', |
|
}, |
|
checkmark: { |
|
fontSize: 20, |
|
color: '#007AFF', |
|
}, |
|
});
|