/**
* 设置页 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: '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: 'language', title: '语言设置', icon: 'translate', 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 },
{ key: 'terms', title: '用户协议', icon: 'file-document-outline', showArrow: true },
{ key: 'privacy_policy', title: '隐私政策', icon: 'shield-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,
maxWidth: SETTINGS_CARD_MAX_WIDTH,
alignSelf: 'center',
width: '100%',
},
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,
maxWidth: SETTINGS_CARD_MAX_WIDTH,
alignSelf: 'center',
width: '100%',
},
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 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 'language': {
Alert.alert(
'语言设置',
'选择应用显示语言',
[
{ text: '取消', style: 'cancel' },
{ text: '简体中文', onPress: () => {} },
{ text: '繁體中文', onPress: () => {} },
{ text: 'English', onPress: () => {} },
]
);
break;
}
case 'data_storage': {
Alert.alert('数据与存储', '缓存清理功能即将上线!');
break;
}
case 'terms': {
Alert.alert('用户协议', '用户协议页面即将上线!');
break;
}
case 'privacy_policy': {
Alert.alert('隐私政策', '隐私政策页面即将上线!');
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 (
{renderContent()}
);
};
export default SettingsScreen;