feat(search): polish the room-header search UI/UX (LC-699) #665
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/LC-699-search-polish"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Polishes the room-header search popover (LC-699). Presentation + result-row enrichment only: no change to the FTS/semantic ranking, operator grammar, access gates, or the save-search mechanism.
search.jscombobox keyboard-nav and therole="listbox"/role="option"contract are untouched.What changed
[data-lc-embeddings]gate already ANDs the runtime AI toggle, so it already vanishes when AI is off or embeddings are unconfigured; only the styling changed.@usernamebyline, context label, timestamp, and the snippet with matched terms wrapped in<mark>. Names are resolved via the existing username cache (one lookup per distinct author).Safety of the highlight
The snippet is HTML-escaped first, then matched on an ASCII-lowercased copy so byte offsets stay aligned with the original (ASCII lowercasing never changes byte length). Multi-byte UTF-8 is never sliced mid-character. The rendered snippet is safe pre-escaped HTML (
|safe).Tests
Two integration assertions (
routes_search_room,routes_related_search) updated because the matched term is now wrapped in<mark>; they assert on the unhighlighted tail of the snippet. Fulljust testgreen (195 binaries, 1634 tests), clippy clean under bothstandaloneandsaas,cargo fmt --checkclean. en/es locale parity keys added.Scope
partials/room_header.html,search/results.html,views/search.rs(SearchResultgainsauthor_name+author_id; snippet is safe HTML),routes/search.rs(author resolution +<mark>highlight helper),assets/main.css(authored.lc-search-*classes),locales/en+es. No DB migration, no route or access-gate changes.🤖 Generated with Claude Code
https://claude.ai/code/session_016ufqbuN7mjyt4ms5NEygMy
Presentation and result-row enrichment for the room-header search popover; no change to the FTS/semantic ranking, the operator grammar, the access gates, or the save-search mechanism. Input: the leading magnifier stays inside the field and a clear (x) button appears once you type (CSS :placeholder-shown), with a small in-flight "Searching..." indicator wired via the htmx-indicator pattern (useful for semantic search, which hits the embedding model). Semantic toggle: the bare checkbox becomes a labelled toggle with a one-line hint ("Find by meaning, not exact words. Slower.") so users understand what it does. Its existing [data-lc-embeddings] visibility gate already ANDs the runtime AI toggle (embeddings_available = ai_flag_on && state.embeddings_available() && ai_privileged), so it already vanishes when AI is off; only the styling changed. Result rows: each hit now shows the author avatar (/avatars/{user_id}) and resolved @username byline, the room/DM context label, the timestamp, and the snippet with the matched query terms wrapped in <mark>. Author names are resolved in render_results through the existing username cache (one lookup per distinct id). Highlighting HTML-escapes the body first and matches on an ASCII-lowercased copy so byte offsets stay aligned and multi-byte UTF-8 is never sliced mid-character; the snippet is therefore safe pre-rendered HTML (|safe). Popover: a scope header ("This room"), consistent padding, a scrollable max-height results area, the existing empty state, and a clearer, iconned "Save search" footer. New styling is authored in main.css (.lc-search-*) so it renders without a Tailwind rebuild. Two integration assertions updated because the matched term is now wrapped in <mark> (they now assert on the unhighlighted tail of the snippet). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016ufqbuN7mjyt4ms5NEygMy