Fix @mention search performance and refactor search functionality
Fixed issue #506
This is a remastered version of the PR #550 .
- Add a lightweight
cpu_workerthread that stays alive for the app lifetime and runsCPU-boundjobs (currently the room-member search);App::handle_startupinitializes it and widgets enqueue work viacpu_worker::spawn_cpu_job. - Rework
MentionableTextInputinto an explicit state machine with search IDs, cancellation tokens, loading/empty UI states, and streaming updates that arrive over the background worker channel. - Replace the old
MatrixRequest::SearchRoomMemberspath:sliding_syncnow fetches joined-member lists directly, emits RoomMembersListFetched, and RoomScreen caches those members plus precomputed sort data for downstream widgets. - Refactor room/member_search.rs to support batched streaming, cancellation, richer match heuristics, optional precomputed sort reuse, and add unit tests for the new helpers.
There are three related issues that still need to be fixed.
@alanpoon & @tyreseluo, can you please give this a review before I dig in? Thanks.
@alanpoon & @tyreseluo, can you please give this a review before I dig in? Thanks.
yep, i will.
Review suggestions: • Select a large room (thousands or tens of thousands of members), @ a user, and search. • Continue testing in rooms with more than 50 members. • Continue testing in rooms with fewer than 50 members. • Close large/small rooms, reopen them, and continue testing. • Logout, then login again, and rerun the above four steps.
@kevinaboos
Current PR progress:
- Fix the issue where remote sync of members does not work after logout-login - Previously, after logging out and then logging back in, remote synchronization of room members failed to trigger properly - The relevant state reset logic has been corrected
- Remove the behavior of automatically deleting the local members cache after closing a tab - This behavior is considered unnecessary and harms the user experience - In the future, a setting can be added to manually clear local cached data
- Optimize the member list loading experience - Automatically check local cached members; if a cache exists, render the user list immediately without waiting for remote data - Each room performs remote synchronization only once per application session - During synchronization, show a loading animation at the bottom of the user list; it will disappear automatically after sync completes
- Fix the issue where the cursor disappears after clicking to select a mention user with the mouse - Previously, after clicking to select a user in the mention popup, the cursor would blink and then disappear, making it impossible to continue typing - Resolved by retrying the focus restoration mechanism in draw_walk
- Fix duplicate room tabs after app restart or logout-login
- Previously, restoring rooms could create duplicate tabs
- Avoided by looking up existing tabs based on
room_id
Remote sync room_members trigger conditions:
Remote member synchronization (SyncRoomMemberList) is triggered in the following cases:
- First time opening a room after the application starts
- Login again after Logout
- Switching to a new room that has never been loaded
Note: Within the same application session, closing a room tab and reopening it will not trigger remote synchronization again.
The current code still needs another review; functional testing can proceed first.
Summary
This PR comprehensively refactors the @mention member search functionality to address performance issues in large rooms (#506).
Key Architectural Changes
-
CPU Worker Module - A lightweight background thread handles CPU-bound member search operations, keeping the UI responsive during searches in large rooms.
-
State Machine Design -
MentionableTextInputnow uses an explicit state machine (MentionSearchState) with four states:Idle,WaitingForMembers,Searching, andJustCancelled. This replaces multiple boolean flags and reduces race conditions. -
Streaming Search Results - Results are sent via MPSC channel in batches of 10, enabling progressive UI updates. Each search has a unique ID and cancellation token support.
-
Precomputed Sort Data -
PrecomputedMemberSortcaches sort keys and indices, making empty searches O(1) and avoiding repeated computation. -
Local-First Rendering - Member lists render immediately from local cache while remote sync continues in background.
Bug Fixes
- @room in DMs: Block @room mentions in direct message rooms
-
Duplicate Tabs: Fix duplicate room tabs on restore by using
find_open_room_live_id()lookup -
Focus Loss: Restore text input focus after mention selection via
pending_draw_focus_restore - Logout/Login: Clear Matrix SDK database on logout to prevent stale data
Duplicate Tabs
Security Fix
- Add
validate_path_within_app_data()to prevent arbitrary directory deletion when clearing app state.
The database path from session files is now validated to be strictly within the app data directory before deletion.
Documentation
- Added comprehensive module documentation with ASCII diagrams for state machine and background thread flow
- Documented duplicate tab prevention mechanism
- Documented database cleanup rationale and security measures
Test Plan
- [ ] Verify @mention search is responsive in large rooms (1000+ members)
- [ ] Verify @room option does not appear in direct messages
- [ ] Verify no duplicate tabs when clicking already-open rooms
- [ ] Verify focus remains in text input after selecting a mention
- [ ] Verify logout and re-login shows fresh data without stale cache
- [ ] Verify ESC cancels mention search and prevents immediate re-trigger