XuqmGroup-RNChatDemo/src/utils/storage.ts
徐勤民 e5adc00b44 feat: complete production chat demo — all screens, real media, SDK remote init
- App.tsx: replaced dev console with AuthProvider + AppNavigator
- Auth: Login, Register, ResetPassword screens via demo-service
- Conversations: reactive WatermelonDB subscription with user profile enrichment
- Chat: SingleChat + GroupChat with full media (image/video/audio/file), revoke, pull-up load more
- Contacts: local contacts list + UserSearch with debounced fuzzy search
- Groups: GroupList, CreateGroup (fuzzy member picker), GroupMembers, GroupSettings
- Profile: view + EditProfile (nickname, gender)
- MessageSearch: local DB full-text search across conversations
- ChatInput: text, 20-emoji picker, image/video/audio/file send, tap-to-record audio
- DisconnectBanner: connection status with reconnect
- AuthContext: uses await XuqmSDK.initialize({ appId, serverUrl }) for remote config

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-25 16:41:54 +08:00

27 行
785 B
TypeScript

import AsyncStorage from '@react-native-async-storage/async-storage'
export const K = {
DEMO_TOKEN: '@xuqm:demoToken',
IM_TOKEN: '@xuqm:imToken',
PROFILE: '@xuqm:profile',
CONTACTS: '@xuqm:contacts',
} as const
export async function save(key: string, value: unknown): Promise<void> {
await AsyncStorage.setItem(key, JSON.stringify(value))
}
export async function load<T>(key: string): Promise<T | null> {
const raw = await AsyncStorage.getItem(key)
if (!raw) return null
try { return JSON.parse(raw) as T } catch { return null }
}
export async function remove(key: string): Promise<void> {
await AsyncStorage.removeItem(key)
}
export async function clearSession(): Promise<void> {
await AsyncStorage.multiRemove([K.DEMO_TOKEN, K.IM_TOKEN, K.PROFILE])
}