feat(performance): migrate FlatList to FlashList and add animations
Replace FlatList with FlashList across all message screens (ChatScreen, MessageListScreen, NotificationsScreen, HomeScreen) for improved list virtualization performance. Use `drawDistance={250}` instead of manual pagination. Simplify React.memo comparisons in MessageBubble and SegmentRenderer by removing function prop checks to prevent unnecessary re-renders.
Add AsyncStorage persistence for lastSystemMessageAt to avoid showing current time on first render. Include enter animations (fade and slide) for CreateGroupScreen and modernize UI styling to flat design.
BREAKING CHANGE: Upgrade @shopify/flash-list from 2.0.2 to ^2.3.1
This commit is contained in:
@@ -25,7 +25,7 @@ import { MessageSyncService } from './services/MessageSyncService';
|
||||
import { WSMessageHandler } from './services/WSMessageHandler';
|
||||
|
||||
// 导入 store
|
||||
import { useMessageStore, normalizeConversationId } from './store';
|
||||
import { useMessageStore, normalizeConversationId, loadPersistedLastSystemMessageAt } from './store';
|
||||
|
||||
// 重新导出类型,保持兼容性
|
||||
export type {
|
||||
@@ -146,6 +146,9 @@ class MessageManager {
|
||||
|
||||
this.wsHandler.setBootstrapping(true);
|
||||
|
||||
// 从本地缓存恢复最后系统通知时间(避免首次渲染显示当前时间)
|
||||
await loadPersistedLastSystemMessageAt();
|
||||
|
||||
// 初始化SSE监听
|
||||
this.wsHandler.connect();
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ export {
|
||||
useMessageStore,
|
||||
normalizeConversationId,
|
||||
mergeMessagesById,
|
||||
loadPersistedLastSystemMessageAt,
|
||||
} from './store';
|
||||
export type { MessageState, MessageActions, MessageStore } from './store';
|
||||
|
||||
|
||||
@@ -9,11 +9,14 @@
|
||||
*/
|
||||
|
||||
import { create } from 'zustand';
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
import type {
|
||||
ConversationResponse,
|
||||
MessageResponse,
|
||||
} from '../../types/dto';
|
||||
|
||||
const LAST_SYSTEM_MESSAGE_AT_KEY = 'last_system_message_at';
|
||||
|
||||
// ==================== 状态接口 ====================
|
||||
|
||||
/**
|
||||
@@ -322,6 +325,11 @@ export const useMessageStore = create<MessageStore>((set, get) => ({
|
||||
|
||||
setLastSystemMessageAt: (time: string | null) => {
|
||||
set({ lastSystemMessageAt: time });
|
||||
if (time) {
|
||||
AsyncStorage.setItem(LAST_SYSTEM_MESSAGE_AT_KEY, time).catch(() => {});
|
||||
} else {
|
||||
AsyncStorage.removeItem(LAST_SYSTEM_MESSAGE_AT_KEY).catch(() => {});
|
||||
}
|
||||
},
|
||||
|
||||
setSSEConnected: (connected: boolean) => {
|
||||
@@ -380,6 +388,14 @@ export const useMessageStore = create<MessageStore>((set, get) => ({
|
||||
typingUsersMap: new Map(),
|
||||
mutedStatusMap: new Map(),
|
||||
});
|
||||
AsyncStorage.removeItem(LAST_SYSTEM_MESSAGE_AT_KEY).catch(() => {});
|
||||
},
|
||||
}));
|
||||
|
||||
export async function loadPersistedLastSystemMessageAt(): Promise<void> {
|
||||
const time = await AsyncStorage.getItem(LAST_SYSTEM_MESSAGE_AT_KEY);
|
||||
if (time) {
|
||||
useMessageStore.setState({ lastSystemMessageAt: time });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user