Files
physical-expo/app/profile.tsx
2026-01-12 15:31:47 +08:00

194 lines
5.4 KiB
TypeScript

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,
},
});