- Remove legacy database.ts, LocalDataSource.ts, and MessageRepository.ts - Create new src/database/ module with messageRepository, userCacheRepository, conversationRepository, and groupCacheRepository - Update all consumers to import from @/database instead of services/database - Add web platform blur handling for modal components to fix focus issues - Flatten SystemMessageItem and NotificationsScreen styles for consistent design - Add draggable slider in ChatSettingsScreen and dynamic font size support - Introduce 9 new chat color themes - Add profile screens for about, terms, and privacy policy with navigation routes - Add policy links to login and registration screens - Fix post share URL format from /posts/ to /post/
328 lines
7.4 KiB
TypeScript
328 lines
7.4 KiB
TypeScript
/**
|
|
* 聊天设置 Store
|
|
* 持久化存储用户的聊天样式偏好设置
|
|
*/
|
|
|
|
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
import { create } from 'zustand';
|
|
import { persist, createJSONStorage } from 'zustand/middleware';
|
|
import { useShallow } from 'zustand/react/shallow';
|
|
|
|
// 主题配置 - 扩展包含更多颜色
|
|
export const CHAT_THEMES = [
|
|
{
|
|
id: 'default',
|
|
name: '默认绿',
|
|
primary: '#4CAF50',
|
|
secondary: '#E8F5E9',
|
|
bubble: '#DCF8C6',
|
|
icon: '🏠',
|
|
// 扩展颜色
|
|
card: '#FFFFFF', // 卡片背景
|
|
inputBg: '#FFFFFF', // 输入框背景
|
|
panelBg: '#F5F5F5', // 面板背景
|
|
headerBg: '#FFFFFF', // 头部背景
|
|
textPrimary: '#1A1A1A', // 主要文字
|
|
textSecondary: '#666666', // 次要文字
|
|
},
|
|
{
|
|
id: 'yellow',
|
|
name: '活力黄',
|
|
primary: '#FFC107',
|
|
secondary: '#FFF8E1',
|
|
bubble: '#FFECB3',
|
|
icon: '🐥',
|
|
card: '#FFFFFF',
|
|
inputBg: '#FFFFFF',
|
|
panelBg: '#FFFDE7',
|
|
headerBg: '#FFFFFF',
|
|
textPrimary: '#1A1A1A',
|
|
textSecondary: '#666666',
|
|
},
|
|
{
|
|
id: 'blue',
|
|
name: '清新蓝',
|
|
primary: '#2196F3',
|
|
secondary: '#E3F2FD',
|
|
bubble: '#BBDEFB',
|
|
icon: '☃️',
|
|
card: '#FFFFFF',
|
|
inputBg: '#FFFFFF',
|
|
panelBg: '#E1F5FE',
|
|
headerBg: '#FFFFFF',
|
|
textPrimary: '#1A1A1A',
|
|
textSecondary: '#666666',
|
|
},
|
|
{
|
|
id: 'purple',
|
|
name: '梦幻紫',
|
|
primary: '#9C27B0',
|
|
secondary: '#F3E5F5',
|
|
bubble: '#E1BEE7',
|
|
icon: '💎',
|
|
card: '#FFFFFF',
|
|
inputBg: '#FFFFFF',
|
|
panelBg: '#F3E5F5',
|
|
headerBg: '#FFFFFF',
|
|
textPrimary: '#1A1A1A',
|
|
textSecondary: '#666666',
|
|
},
|
|
{
|
|
id: 'teal',
|
|
name: '自然青',
|
|
primary: '#009688',
|
|
secondary: '#E0F2F1',
|
|
bubble: '#B2DFDB',
|
|
icon: '🦁',
|
|
card: '#FFFFFF',
|
|
inputBg: '#FFFFFF',
|
|
panelBg: '#E0F2F1',
|
|
headerBg: '#FFFFFF',
|
|
textPrimary: '#1A1A1A',
|
|
textSecondary: '#666666',
|
|
},
|
|
{
|
|
id: 'coral',
|
|
name: '珊瑚橙',
|
|
primary: '#FF6B6B',
|
|
secondary: '#FFF0F0',
|
|
bubble: '#FFD4D4',
|
|
icon: '🐠',
|
|
card: '#FFFFFF',
|
|
inputBg: '#FFFFFF',
|
|
panelBg: '#FFF5F5',
|
|
headerBg: '#FFFFFF',
|
|
textPrimary: '#1A1A1A',
|
|
textSecondary: '#666666',
|
|
},
|
|
{
|
|
id: 'rose',
|
|
name: '玫瑰粉',
|
|
primary: '#E91E63',
|
|
secondary: '#FCE4EC',
|
|
bubble: '#F8BBD9',
|
|
icon: '🌹',
|
|
card: '#FFFFFF',
|
|
inputBg: '#FFFFFF',
|
|
panelBg: '#FCE4EC',
|
|
headerBg: '#FFFFFF',
|
|
textPrimary: '#1A1A1A',
|
|
textSecondary: '#666666',
|
|
},
|
|
{
|
|
id: 'indigo',
|
|
name: '靛蓝紫',
|
|
primary: '#3F51B5',
|
|
secondary: '#E8EAF6',
|
|
bubble: '#C5CAE9',
|
|
icon: '🐉',
|
|
card: '#FFFFFF',
|
|
inputBg: '#FFFFFF',
|
|
panelBg: '#E8EAF6',
|
|
headerBg: '#FFFFFF',
|
|
textPrimary: '#1A1A1A',
|
|
textSecondary: '#666666',
|
|
},
|
|
{
|
|
id: 'mint',
|
|
name: '薄荷绿',
|
|
primary: '#00BCD4',
|
|
secondary: '#E0F7FA',
|
|
bubble: '#B2EBF2',
|
|
icon: '🧊',
|
|
card: '#FFFFFF',
|
|
inputBg: '#FFFFFF',
|
|
panelBg: '#E0F7FA',
|
|
headerBg: '#FFFFFF',
|
|
textPrimary: '#1A1A1A',
|
|
textSecondary: '#666666',
|
|
},
|
|
{
|
|
id: 'cherry',
|
|
name: '樱桃红',
|
|
primary: '#D32F2F',
|
|
secondary: '#FFEBEE',
|
|
bubble: '#FFCDD2',
|
|
icon: '🍒',
|
|
card: '#FFFFFF',
|
|
inputBg: '#FFFFFF',
|
|
panelBg: '#FFEBEE',
|
|
headerBg: '#FFFFFF',
|
|
textPrimary: '#1A1A1A',
|
|
textSecondary: '#666666',
|
|
},
|
|
{
|
|
id: 'lavender',
|
|
name: '薰衣草',
|
|
primary: '#7E57C2',
|
|
secondary: '#EDE7F6',
|
|
bubble: '#D1C4E9',
|
|
icon: '💜',
|
|
card: '#FFFFFF',
|
|
inputBg: '#FFFFFF',
|
|
panelBg: '#EDE7F6',
|
|
headerBg: '#FFFFFF',
|
|
textPrimary: '#1A1A1A',
|
|
textSecondary: '#666666',
|
|
},
|
|
{
|
|
id: 'sunset',
|
|
name: '落日橙',
|
|
primary: '#FF5722',
|
|
secondary: '#FBE9E7',
|
|
bubble: '#FFCCBC',
|
|
icon: '🌅',
|
|
card: '#FFFFFF',
|
|
inputBg: '#FFFFFF',
|
|
panelBg: '#FBE9E7',
|
|
headerBg: '#FFFFFF',
|
|
textPrimary: '#1A1A1A',
|
|
textSecondary: '#666666',
|
|
},
|
|
{
|
|
id: 'ocean',
|
|
name: '深海蓝',
|
|
primary: '#006064',
|
|
secondary: '#B2EBF2',
|
|
bubble: '#80DEEA',
|
|
icon: '🌊',
|
|
card: '#FFFFFF',
|
|
inputBg: '#FFFFFF',
|
|
panelBg: '#E0F7FA',
|
|
headerBg: '#FFFFFF',
|
|
textPrimary: '#1A1A1A',
|
|
textSecondary: '#666666',
|
|
},
|
|
{
|
|
id: 'forest',
|
|
name: '森林绿',
|
|
primary: '#1B5E20',
|
|
secondary: '#C8E6C9',
|
|
bubble: '#A5D6A7',
|
|
icon: '🌳',
|
|
card: '#FFFFFF',
|
|
inputBg: '#FFFFFF',
|
|
panelBg: '#E8F5E9',
|
|
headerBg: '#FFFFFF',
|
|
textPrimary: '#1A1A1A',
|
|
textSecondary: '#666666',
|
|
},
|
|
] as const;
|
|
|
|
export type ChatThemeId = typeof CHAT_THEMES[number]['id'];
|
|
|
|
export interface ChatSettings {
|
|
// 消息字号 (12-24)
|
|
fontSize: number;
|
|
// 消息圆角 (0-30)
|
|
messageRadius: number;
|
|
// 选中的主题索引
|
|
themeIndex: number;
|
|
// 夜间模式
|
|
nightMode: boolean;
|
|
// 聊天壁纸 (可选)
|
|
wallpaper?: string | null;
|
|
// 名称颜色 (可选)
|
|
nameColor?: string | null;
|
|
}
|
|
|
|
const DEFAULT_SETTINGS: ChatSettings = {
|
|
fontSize: 16,
|
|
messageRadius: 12,
|
|
themeIndex: 0,
|
|
nightMode: false,
|
|
wallpaper: null,
|
|
nameColor: null,
|
|
};
|
|
|
|
interface ChatSettingsState extends ChatSettings {
|
|
// 获取当前主题
|
|
getCurrentTheme: () => typeof CHAT_THEMES[number];
|
|
// 更新设置
|
|
updateSettings: (settings: Partial<ChatSettings>) => void;
|
|
// 重置为默认
|
|
resetSettings: () => void;
|
|
// 设置字号
|
|
setFontSize: (size: number) => void;
|
|
// 设置圆角
|
|
setMessageRadius: (radius: number) => void;
|
|
// 设置主题
|
|
setTheme: (index: number) => void;
|
|
// 切换夜间模式
|
|
toggleNightMode: () => void;
|
|
}
|
|
|
|
const STORAGE_KEY = 'chat_settings';
|
|
|
|
export const useChatSettingsStore = create<ChatSettingsState>()(
|
|
persist(
|
|
(set, get) => ({
|
|
...DEFAULT_SETTINGS,
|
|
|
|
getCurrentTheme: () => {
|
|
const { themeIndex } = get();
|
|
return CHAT_THEMES[themeIndex] ?? CHAT_THEMES[0];
|
|
},
|
|
|
|
updateSettings: (settings) => {
|
|
set((state) => ({ ...state, ...settings }));
|
|
},
|
|
|
|
resetSettings: () => {
|
|
set(DEFAULT_SETTINGS);
|
|
},
|
|
|
|
setFontSize: (fontSize) => {
|
|
set({ fontSize: Math.max(12, Math.min(24, fontSize)) });
|
|
},
|
|
|
|
setMessageRadius: (messageRadius) => {
|
|
set({ messageRadius: Math.max(0, Math.min(30, messageRadius)) });
|
|
},
|
|
|
|
setTheme: (themeIndex) => {
|
|
set({ themeIndex: Math.max(0, Math.min(CHAT_THEMES.length - 1, themeIndex)) });
|
|
},
|
|
|
|
toggleNightMode: () => {
|
|
set((state) => ({ nightMode: !state.nightMode }));
|
|
},
|
|
}),
|
|
{
|
|
name: STORAGE_KEY,
|
|
storage: createJSONStorage(() => AsyncStorage),
|
|
}
|
|
)
|
|
);
|
|
|
|
// 导出便捷 hooks
|
|
export function useChatFontSize() {
|
|
return useChatSettingsStore((s) => s.fontSize);
|
|
}
|
|
|
|
export function useChatMessageRadius() {
|
|
return useChatSettingsStore((s) => s.messageRadius);
|
|
}
|
|
|
|
export function useChatTheme() {
|
|
const themeIndex = useChatSettingsStore((s) => s.themeIndex);
|
|
return CHAT_THEMES[themeIndex];
|
|
}
|
|
|
|
export function useChatNightMode() {
|
|
return useChatSettingsStore((s) => s.nightMode);
|
|
}
|
|
|
|
export function useChatSettingsActions() {
|
|
return useChatSettingsStore(
|
|
useShallow((s) => ({
|
|
setFontSize: s.setFontSize,
|
|
setMessageRadius: s.setMessageRadius,
|
|
setTheme: s.setTheme,
|
|
toggleNightMode: s.toggleNightMode,
|
|
updateSettings: s.updateSettings,
|
|
resetSettings: s.resetSettings,
|
|
}))
|
|
);
|
|
}
|