- Add pending/failed message status to track send state
- Implement optimistic UI: show message immediately, update on server response
- Add retry functionality for failed messages via tap-to-retry
- Change send button from icon to text "发送" for clarity
- Add MessageSendService with temp ID generation to prevent collisions
feat(notification): add JPush notification deduplication and clear on tap
- Deduplicate notificationArrived events from dual JPush/vendor channels
- Clear all notifications on tap (QQ-style behavior)
feat(post): add client-side idempotency key for post creation
- Generate client_request_id per publish intent to prevent duplicates on retry
- Pass idempotency key through to postService and voteService
Refactor the messaging subsystem to enhance data consistency, prevent race conditions during WebSocket reconnection, and ensure accurate unread counts.
- **WebSocket Reliability**: Implement `client_msg_id` for precise message ACK matching, preventing incorrect pending message resolution in high-frequency scenarios.
- **Sync Logic**: Update `WSMessageHandler` and `MessageManager` to use a bootstrapping state, ensuring buffered SSE events are flushed only after the initial synchronization is complete.
- **State Consistency**:
- Introduce atomic unread count increments to prevent lost updates.
- Implement conditional rollback for optimistic read receipts, ensuring that failed API calls do not overwrite newer, valid read states.
- **Resource Management**: Add reference counting to `useMessages` hook to prevent premature clearing of loading states during rapid conversation switching or React StrictMode double-invocations.
- **Data Integrity**: Update `UserCacheService` to re-read the latest message list before applying sender info enrichment, ensuring new messages arriving during the async process are correctly processed.
Refactor the message management system to address synchronization issues and improve performance through request deduplication and enhanced lifecycle management.
- Implement in-flight promise tracking in `MessageSyncService` to prevent redundant network requests for conversations and messages.
- Enhance `useMessages` hook with `useFocusEffect` to trigger automatic synchronization when a chat screen regains focus.
- Add `forceSync` capability to `MessageManager` and `MessageSyncService` to allow manual overrides of loading states during re-entry.
- Consolidate WebSocket synchronization logic in `WSMessageHandler` using a throttled and deduplicated trigger mechanism.
- Clean up unused styles and deprecated hooks (`baseHooks.ts`, `bubbleStyles.ts`, `inputStyles.ts`).
- Update `metro.config.js` and `package.json` to include `@expo/ui` and optimize resolver settings.
Implement `removeMessage` in `useMessageStore` to allow for atomic message deletion from the state. Improve `useChatScreen` loading logic to prevent layout jumps and ensure consistent UI state during initial message loading. Additionally, add type safety for WebSocket sequence numbers and optimize message selector stability.
- Add `removeMessage` action to `useMessageStore` for state-consistent deletions
- Refine `useChatScreen` loading state logic to prevent FlashList layout issues
- Ensure `useMessages` hook returns a stable `EMPTY_MESSAGES` constant
- Cast WebSocket `seq` to integer to ensure consistent numeric comparison
- Update `useChatScreen` to use `useMessageStore` for immediate local deletion feedback
Improve application stability and performance by optimizing Zustand store usage, implementing memoization patterns, and introducing persistent authentication.
- **State Management**:
- Refactor Zustand selectors to use `useShallow` and `getState()` to prevent unnecessary re-renders and infinite loops in hooks.
- Implement `persist` middleware for `authStore` to maintain user sessions across restarts.
- Introduce `buildStateCached` in `themeStore` to reduce redundant theme object computations.
- **Performance & Rendering**:
- Implement `useMemo` for stable object/array references in `ImageGallery` and list components to prevent expensive re-renders.
- Replace inline arrow functions with `useCallback` in complex screens like `ChatScreen` and `MessageListScreen`.
- Optimize `FlashList` usage by providing stable `key` and `extraData` props.
- **Architecture**:
- Decouple unread count fetching by introducing `useUnreadCountQuery` (React Query) for better caching and synchronization.
- Add `useChannels` hook to centralize channel data fetching.
- Refine `SessionGate` logic to allow immediate rendering of authenticated users while verifying in the background.
Remove custom SubscriptionManager class and adopt Zustand's built-in
selector mechanism for reactive state updates. This simplifies the
architecture by eliminating manual subscription management and relying
on Zustand's automatic dependency tracking for component re-renders.
Key changes:
- Remove SubscriptionManager class from store.ts
- Replace all notifySubscribers calls with direct store updates
- Update hooks to use Zustand selectors with useShallow for complex data
- Remove subscribe/unsubscribe patterns from MessageManager
- Simplify EmbeddedChat to use selector instead of local state
- Rename requestConversationListRefresh to refreshConversations
- Remove MessageStateManager wrapper layer in favor of direct zustand store
- Move service modules to services/ subdirectory (ConversationOperations, MessageDeduplication, MessageSendService, MessageSyncService, ReadReceiptManager, UserCacheService, WSMessageHandler)
- Add new zustand-based store with subscriptionManager for event handling
- Introduce React hooks for message state (useConversations, useMessages, useUnreadCount, etc.)
- Update exports in index.ts to reflect new module structure
- Deprecate messageManager.ts entry point in favor of message/index.ts
- Maintain backward compatibility with existing MessageManager API