添加主题切换、多语言支持
This commit is contained in:
193
app/profile.tsx
Normal file
193
app/profile.tsx
Normal file
@@ -0,0 +1,193 @@
|
||||
import { Image } from "expo-image";
|
||||
import { Stack } from "expo-router";
|
||||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { ScrollView, StyleSheet, TouchableOpacity, View } from "react-native";
|
||||
|
||||
import { ThemedText } from "@/components/themed-text";
|
||||
import { IconSymbol } from "@/components/ui/icon-symbol";
|
||||
import { useTheme } from "@/context/ThemeContext";
|
||||
import { changeLanguage } from "@/i18n";
|
||||
|
||||
export default function ProfileScreen() {
|
||||
const { theme, toggleTheme, setTheme, isSystemTheme, useSystemTheme } =
|
||||
useTheme();
|
||||
const { t, i18n } = useTranslation();
|
||||
const isDark = theme === "dark";
|
||||
|
||||
const currentLanguage = i18n.language;
|
||||
|
||||
const toggleLanguage = () => {
|
||||
const nextLang = currentLanguage.startsWith("en") ? "zh" : "en";
|
||||
changeLanguage(nextLang);
|
||||
};
|
||||
|
||||
const iconColor = isDark ? "#FFFFFF" : "#000000";
|
||||
const textColor = isDark ? "#FFFFFF" : "#000000";
|
||||
const subTextColor = isDark ? "#AAAAAA" : "#666666";
|
||||
|
||||
return (
|
||||
<>
|
||||
<Stack.Screen
|
||||
options={{
|
||||
title: t("profile.title"),
|
||||
headerShown: true,
|
||||
// Ensure header matches theme to avoid white flash
|
||||
headerStyle: {
|
||||
backgroundColor: isDark ? "#000" : "#f2f2f7",
|
||||
},
|
||||
headerTintColor: textColor,
|
||||
headerShadowVisible: false,
|
||||
// Present the screen as a normal card and slide from right
|
||||
presentation: "card",
|
||||
animation: "slide_from_right",
|
||||
// Set the scene/content background to match theme during transition
|
||||
contentStyle: { backgroundColor: isDark ? "#000" : "#f2f2f7" },
|
||||
}}
|
||||
/>
|
||||
<ScrollView
|
||||
style={[
|
||||
styles.container,
|
||||
{ backgroundColor: isDark ? "#000" : "#f2f2f7" },
|
||||
]}
|
||||
>
|
||||
{/* User Info Section */}
|
||||
<View
|
||||
style={[
|
||||
styles.section,
|
||||
{ backgroundColor: isDark ? "#1c1c1e" : "#fff" },
|
||||
]}
|
||||
>
|
||||
<View style={styles.profileHeader}>
|
||||
<Image
|
||||
source={{ uri: "https://via.placeholder.com/100" }}
|
||||
style={styles.avatar}
|
||||
contentFit="cover"
|
||||
/>
|
||||
<View style={styles.profileInfo}>
|
||||
<ThemedText type="title">{t("profile.name")}</ThemedText>
|
||||
<ThemedText style={{ color: subTextColor }}>
|
||||
user@example.com
|
||||
</ThemedText>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* Settings Section */}
|
||||
<ThemedText style={styles.sectionTitle}>
|
||||
{t("settings.title")}
|
||||
</ThemedText>
|
||||
|
||||
<View
|
||||
style={[
|
||||
styles.section,
|
||||
{ backgroundColor: isDark ? "#1c1c1e" : "#fff" },
|
||||
]}
|
||||
>
|
||||
{/* Theme Setting */}
|
||||
<View style={styles.settingItem}>
|
||||
<View style={styles.settingLabel}>
|
||||
<IconSymbol
|
||||
name="sunny"
|
||||
size={20}
|
||||
color={iconColor}
|
||||
style={{ marginRight: 10 }}
|
||||
/>
|
||||
<ThemedText>{t("settings.theme")}</ThemedText>
|
||||
</View>
|
||||
<View style={styles.settingControl}>
|
||||
<TouchableOpacity onPress={toggleTheme} style={styles.button}>
|
||||
<ThemedText>
|
||||
{theme === "light" ? t("settings.light") : t("settings.dark")}
|
||||
</ThemedText>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* Language Setting */}
|
||||
<View
|
||||
style={[
|
||||
styles.settingItem,
|
||||
{
|
||||
borderTopWidth: StyleSheet.hairlineWidth,
|
||||
borderTopColor: isDark ? "#38383a" : "#c6c6c8",
|
||||
},
|
||||
]}
|
||||
>
|
||||
<View style={styles.settingLabel}>
|
||||
<IconSymbol
|
||||
name="globe"
|
||||
size={20}
|
||||
color={iconColor}
|
||||
style={{ marginRight: 10 }}
|
||||
/>
|
||||
<ThemedText>{t("settings.language")}</ThemedText>
|
||||
</View>
|
||||
<View style={styles.settingControl}>
|
||||
<TouchableOpacity onPress={toggleLanguage} style={styles.button}>
|
||||
<ThemedText>
|
||||
{currentLanguage.startsWith("zh")
|
||||
? t("settings.chinese")
|
||||
: t("settings.english")}
|
||||
</ThemedText>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</ScrollView>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
},
|
||||
section: {
|
||||
marginTop: 20,
|
||||
paddingVertical: 10,
|
||||
paddingHorizontal: 16,
|
||||
borderRadius: 10, // iOS style groups
|
||||
marginHorizontal: 16,
|
||||
},
|
||||
sectionTitle: {
|
||||
marginLeft: 32,
|
||||
marginTop: 20,
|
||||
marginBottom: 5,
|
||||
fontSize: 13,
|
||||
textTransform: "uppercase",
|
||||
opacity: 0.6,
|
||||
},
|
||||
profileHeader: {
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
paddingVertical: 10,
|
||||
},
|
||||
avatar: {
|
||||
width: 60,
|
||||
height: 60,
|
||||
borderRadius: 30,
|
||||
backgroundColor: "#ccc",
|
||||
},
|
||||
profileInfo: {
|
||||
marginLeft: 15,
|
||||
},
|
||||
settingItem: {
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
justifyContent: "space-between",
|
||||
paddingVertical: 12,
|
||||
},
|
||||
settingLabel: {
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
},
|
||||
settingControl: {
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
},
|
||||
button: {
|
||||
paddingHorizontal: 10,
|
||||
paddingVertical: 5,
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user