/** * 设置页 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, type AppColors, } from '../../theme'; import { useAuthStore } from '../../stores'; import { Text } from '../../components/common'; import { useResponsive, useResponsiveSpacing } from '../../hooks'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; import * as hrefs from '../../navigation/hrefs'; // 设置卡片最大宽度 const SETTINGS_CARD_MAX_WIDTH = 720; 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: 'verification', title: '身份认证', icon: 'check-decagram', showArrow: true, subtitle: '获得认证标识,解锁更多功能' }, { 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: '推送、震动、提示音' }, { key: 'data_storage', title: '数据与存储', icon: 'database-outline', showArrow: true }, ], }, { 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.paper, }, scrollContent: { paddingVertical: spacing.lg, }, groupContainer: { marginBottom: spacing['2xl'], maxWidth: SETTINGS_CARD_MAX_WIDTH, alignSelf: 'center', width: '100%', }, groupHeader: { paddingHorizontal: spacing['2xl'], marginBottom: spacing.sm, marginTop: spacing.sm, }, groupTitle: { fontWeight: '600', fontSize: fontSizes.sm, color: colors.text.secondary, textTransform: 'uppercase', letterSpacing: 0.5, }, settingItem: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', paddingVertical: 16, paddingHorizontal: spacing['2xl'], borderBottomWidth: StyleSheet.hairlineWidth, borderBottomColor: colors.divider, }, settingItemFirst: {}, settingItemLast: { borderBottomWidth: 0, }, settingItemLeft: { flexDirection: 'row', alignItems: 'center', flex: 1, }, iconContainer: { width: 24, height: 24, justifyContent: 'center', alignItems: 'center', marginRight: spacing.lg, }, dangerIconContainer: {}, settingContent: { flex: 1, }, subtitle: { marginTop: 2, }, logoutButton: { flexDirection: 'row', alignItems: 'center', justifyContent: 'center', marginTop: spacing.lg, marginBottom: spacing['2xl'], paddingVertical: 16, marginHorizontal: spacing['2xl'], borderRadius: 14, gap: spacing.sm, maxWidth: SETTINGS_CARD_MAX_WIDTH, alignSelf: 'center', width: '100%', backgroundColor: colors.error.light + '20', }, logoutText: { fontWeight: '600', }, 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 insets = useSafeAreaInsets(); const { isMobile } = useResponsive(); const responsivePadding = useResponsiveSpacing({ xs: 8, sm: 12, md: 16, lg: 24, xl: 32 }); 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: 'chat_settings', title: '聊天设置', icon: 'message-text-outline', showArrow: true, subtitle: '字号、主题、壁纸', }, { key: 'theme', title: '主题模式', icon: 'theme-light-dark', showArrow: true, subtitle: themeSubtitle, }, ], }, ...SETTINGS_GROUPS_BASE, ]; }, [themePreference]); const handleItemPress = (key: string) => { switch (key) { case 'chat_settings': router.push(hrefs.hrefProfileChatSettings()); break; case 'theme': { Alert.alert( '主题模式', '选择应用界面明暗', [ { text: '取消', style: 'cancel' }, { text: '跟随系统', onPress: () => { void setThemePreference('system'); }, }, { text: '浅色', onPress: () => { void setThemePreference('light'); }, }, { text: '深色', onPress: () => { void setThemePreference('dark'); }, }, ] ); break; } case 'data_storage': router.push(hrefs.hrefProfileDataStorage()); break; case 'about': router.push(hrefs.hrefProfileAbout()); break; case 'help': Alert.alert('帮助与反馈', '帮助中心即将上线!'); break; case 'edit_profile': router.push(hrefs.hrefProfileEdit()); break; case 'verification': router.push(hrefs.hrefProfileVerification()); 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} © 2026 青春之旅电子信息科技(威海)有限公司 ); return ( {renderContent()} ); }; export default SettingsScreen;