Each recent search now has a trailing close button to remove it from
the history. The view action is logged without its payload so removed
queries don't end up in the logs.
Queries were previously stored whenever a result was selected, which
meant half-typed queries ended up in the history. Now a query is only
recorded when the user submits the search field, while selecting a
result only records the room.
Rooms the user is invited to, or has knocked on, are handled by the chats
list and aren't somewhere search should lead. The search screen now asks
the room summary provider for joined rooms only.
The search screen's empty state now lists the queries the user searched
for and the rooms they opened from the results, newest first, capped at 25
and stored in AppSettings. Tapping a query fills the search field, tapping
a room opens it, and both are reachable with a hardware keyboard.
Rooms are resolved from their identifiers as the room list loads, and
those the user has left or is only invited to are dropped. The history is
cleared on logout.
- Drop the redundant searchService coordinator/view model parameter; derive it from the client proxy.
- Rename the globalSearch avatar size to search.
- Lift the query observation streams out of their tasks.
- Restore the appeared and updateVisibleRange comments.
- Use CompoundIcon defaults and a scaledFrame for media previews.
- Simplify the result mapping with compactMap(makeResult) and drop unsupported events by returning nil.
- Move the preview helpers beneath the previews.
Split global search into Rooms and Messages tabs. The Messages tab lists
matching events with the room's name and avatar, a sender-prefixed preview,
rich media (image/video/audio/file) previews, and a loading indicator, then
paginates as you scroll. Queries are debounced and the previous one is
superseded so late results can't clobber a newer search.
cmd+k jumps to the search tab but left users with no way back. Pressing
escape in the search field now returns to the tab they came from (never
into search itself).
Escape is handled at the search field's pressesBegan, alongside the
existing arrow-key navigation, since the focused UIKit field swallows
SwiftUI keyboard shortcuts.
* Add a developer flag for the search tab
Introduces a globalSearchEnabled user preference (off by default) with a toggle in Developer Options, used to gate the new search experience.
* Support search role tabs in the tab coordinator
Migrates the NavigationTabCoordinator to SwiftUI's value-based Tab API and adds an isSearch option so a tab can adopt the iOS 26 .search role, which detaches it into the trailing search button in the tab bar.
* Moves room search to a new screen
Adds a new screen that filters the alternate room summary provider as you type, shows an empty state, and lists matching rooms with their matrix identifier. Supports hardware keyboard selection (arrow keys to move through results, return to open) by reaching into the system search field.
* Present search in a dedicated tab
Adds the search tab to the chats flow on iOS 26 when the flag is enabled, rendered as the detached .search role button. The Cmd+K shortcut now selects this tab, and the home screen's inline search is hidden while the tab is available.
* Remove the old global search screen
The dedicated search tab replaces the Cmd+K floating window, so the GlobalSearchScreen, its window plumbing in the WindowManager, and its presentation in the chats flow are all removed.