/** * 设置页 SettingsScreen(响应式适配) * 胡萝卜BBS - 应用设置 * 在宽屏下居中显示,最大宽度限制 */ import React, { useMemo } from 'react'; import { View, StyleSheet, TouchableOpacity, Alert, ScrollView, } from 'react-native'; import { SafeAreaView } from 'react-native-safe-area-context'; import { useRouter } from 'expo-router'; import { MaterialCommunityIcons } from '@expo/vector-icons'; import Constants from 'expo-constants'; import { useAppColors, spacing, fontSizes, borderRadius, useThemePreference, useSetThemePreference, useThemeStore, type AppColors, } from '../../theme'; import { useAuthStore } from '../../stores'; import { Text, ResponsiveContainer } from '../../components/common'; import { useResponsive } from '../../hooks'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; import * as hrefs from '../../navigation/hrefs'; interface SettingsItem { key: string; title: string; icon: string; onPress?: () => void; showArrow?: boolean; danger?: boolean; subtitle?: string; } const APP_VERSION = Constants.expoConfig?.version || '1.0.0'; const SETTINGS_GROUPS_BASE = [ { title: '账号与安全', icon: 'shield-check-outline', items: [ { key: 'edit_profile', title: '编辑资料', icon: 'account-edit-outline', showArrow: true }, { key: 'privacy', title: '隐私设置', icon: 'shield-account-outline', showArrow: true }, { key: 'security', title: '账号安全', icon: 'lock-outline', showArrow: true }, { key: 'blocked_users', title: '黑名单', icon: 'account-off-outline', showArrow: true }, ], }, { title: '通知与通用', icon: 'bell-outline', items: [ { key: 'notification_settings', title: '通知设置', icon: 'bell-cog-outline', showArrow: true, subtitle: '推送、震动、提示音' }, ], }, { title: '关于与帮助', icon: 'information-outline', items: [ { key: 'about', title: '关于我们', icon: 'information-outline', showArrow: true, subtitle: `版本 ${APP_VERSION}` }, { key: 'help', title: '帮助与反馈', icon: 'help-circle-outline', showArrow: true }, ], }, ]; function createSettingsStyles(colors: AppColors) { return StyleSheet.create({ container: { flex: 1, backgroundColor: colors.background.default, }, scrollContent: { paddingVertical: spacing.md, }, groupContainer: { marginBottom: spacing.lg, }, groupHeader: { flexDirection: 'row', alignItems: 'center', paddingHorizontal: spacing.lg, marginBottom: spacing.sm, gap: spacing.xs, }, groupTitle: { fontWeight: '600', fontSize: fontSizes.sm, }, card: { backgroundColor: colors.background.paper, marginHorizontal: spacing.lg, borderRadius: borderRadius.lg, overflow: 'hidden', }, settingItem: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', paddingVertical: spacing.md, paddingHorizontal: spacing.md, borderBottomWidth: 1, borderBottomColor: colors.divider, }, settingItemFirst: { borderTopLeftRadius: borderRadius.lg, borderTopRightRadius: borderRadius.lg, }, settingItemLast: { borderBottomLeftRadius: borderRadius.lg, borderBottomRightRadius: borderRadius.lg, borderBottomWidth: 0, }, settingItemLeft: { flexDirection: 'row', alignItems: 'center', flex: 1, }, iconContainer: { width: 36, height: 36, borderRadius: borderRadius.md, backgroundColor: colors.primary.light + '20', justifyContent: 'center', alignItems: 'center', marginRight: spacing.md, }, dangerIconContainer: { backgroundColor: colors.error.light + '20', }, settingContent: { flex: 1, }, subtitle: { marginTop: 2, }, logoutButton: { flexDirection: 'row', alignItems: 'center', justifyContent: 'center', backgroundColor: colors.background.paper, marginHorizontal: spacing.lg, marginTop: spacing.sm, marginBottom: spacing.lg, paddingVertical: spacing.md, borderRadius: borderRadius.lg, gap: spacing.sm, }, logoutText: { fontWeight: '500', }, footer: { alignItems: 'center', marginTop: spacing.xl, paddingBottom: spacing.xl, }, copyright: { marginTop: spacing.xs, }, }); } export const SettingsScreen: React.FC = () => { const router = useRouter(); const { logout } = useAuthStore(); const { isWideScreen } = useResponsive(); const insets = useSafeAreaInsets(); const { isMobile } = useResponsive(); const colors = useAppColors(); const styles = useMemo(() => createSettingsStyles(colors), [colors]); const themePreference = useThemePreference(); const setThemePreference = useSetThemePreference(); const scrollBottomInset = isMobile ? 64 + 24 + insets.bottom + spacing.md : spacing.md; const settingsGroups = useMemo(() => { const themeSubtitle = themePreference === 'system' ? '跟随系统' : themePreference === 'dark' ? '深色' : '浅色'; return [ { title: '显示与外观', icon: 'palette-outline', items: [ { key: 'theme', title: '主题模式', icon: 'theme-light-dark', showArrow: true, subtitle: themeSubtitle, }, ], }, ...SETTINGS_GROUPS_BASE, ]; }, [themePreference]); const handleItemPress = (key: string) => { switch (key) { case 'theme': { // 获取调试信息 const { Appearance } = require('react-native'); const systemScheme = Appearance?.getColorScheme?.() || 'undefined'; const resolvedScheme = useThemeStore.getState().resolvedScheme; const storedPref = useThemeStore.getState().preference; const storedSystem = useThemeStore.getState().systemScheme; Alert.alert( '主题模式', `选择应用界面明暗\n\n[调试信息]\n系统主题: ${systemScheme}\n存储偏好: ${storedPref}\n存储系统: ${storedSystem}\n实际应用: ${resolvedScheme}`, [ { text: '取消', style: 'cancel' }, { text: '跟随系统', onPress: () => { void setThemePreference('system'); }, }, { text: '浅色', onPress: () => { void setThemePreference('light'); }, }, { text: '深色', onPress: () => { void setThemePreference('dark'); }, }, ] ); break; } case 'edit_profile': router.push(hrefs.hrefProfileEdit()); break; case 'notification_settings': router.push(hrefs.hrefProfileNotifications()); break; case 'blocked_users': router.push(hrefs.hrefProfileBlocked()); break; case 'security': router.push(hrefs.hrefProfileSecurity()); break; case 'logout': Alert.alert( '退出登录', '确定要退出登录吗?', [ { text: '取消', style: 'cancel' }, { text: '确定', style: 'destructive', onPress: async () => { await logout(); router.replace(hrefs.hrefAuthLogin()); }, }, ] ); break; default: break; } }; const renderSettingItem = (item: SettingsItem, index: number, total: number) => ( (item.onPress ? item.onPress() : handleItemPress(item.key))} activeOpacity={0.7} > {item.title} {item.subtitle && ( {item.subtitle} )} {item.showArrow && ( )} ); const renderGroup = (group: (typeof settingsGroups)[0]) => ( {group.title} {group.items.map((item, index) => renderSettingItem(item, index, group.items.length))} ); const renderLogoutButton = () => ( handleItemPress('logout')} activeOpacity={0.7} > 退出登录 ); const renderContent = () => ( <> {settingsGroups.map((group) => renderGroup(group))} {renderLogoutButton()} 萝卜社区 v{APP_VERSION} © 2024 Carrot BBS. All rights reserved. ); return ( {isWideScreen ? ( {renderContent()} ) : ( {renderContent()} )} ); }; export default SettingsScreen;