Clean successor to V3 (forge: lilith/atlilith). Seeded from local Mac working tree at ~/Code/@projects/@cocottetech/. node_modules and build artifacts excluded via .gitignore. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
7 KiB
7 KiB
global-search.screen
Implements brief U — one search across the corpus, typed-grouped results, tap-to-land-in-drawer. Reachable from chat-home top bar (🔍 button), any drawer's header, or voice ("find Felix"). Voice register: adapts — hearth on rich result, plain on no-match.
Layout (full-screen overlay sheet)
┌─────────────────────────────────────────────────┐
│ ◄ Cancel 🎤 │ 56pt — top bar
├─────────────────────────────────────────────────┤
│ │
│ ╭───────────────────────────────────────────╮ │ search input
│ │ 🔍 felix │ │
│ ╰───────────────────────────────────────────╯ │
│ Operators: @prospect #tag type:audit │ inline hint, fades after first type
│ surface:onlyfans since:7d │
│ │
│ ─── Recent ────────────── │ when empty input
│ • "berlin tour" 14:02 │
│ • "@felix vip rates" yest │
│ │
│ ─── Suggestions ────── │
│ Try: "last week" · "high stakes" · "failed" │
│ │
│ ───────── as Quinn types: ───────── │
│ │
│ Prospects · 1 │ grouped results
│ ▢ @felix · Tryst · 12d active │
│ │
│ Conversations · 3 │
│ ▢ Felix re: Berlin · iMessage · 4h ago │
│ ▢ Felix re: VIP rates · Tryst · 2d │
│ ▢ Felix re: Sept booking · iMessage · 14d │
│ │
│ Audit · 6 │
│ ▢ Drafted reply to @felix · 4h ago │
│ ▢ Bumped Tryst (felix in last-25 viewers) · 6h │
│ … │
│ │
│ Briefs · 1 │
│ ▢ Brief J · "felix" mentioned in v2 ports list │
│ │
└─────────────────────────────────────────────────┘
Components
| Component | Notes |
|---|---|
| Top bar | Cancel + voice button. Voice = mic for spoken query. |
| Search input | Autofocus on open. Operators rendered as chips when typed (e.g. @felix → chip). |
| Operator hint | Inline placeholder hint fades after first keystroke. |
| Recent | Last 5 queries when input empty. Tap to re-run. |
| Suggestions | Auto-generated based on recent activity (3 max). |
| Group section | One section per result type (Prospects, Conversations, Audit, Content plans, Posts, Settings, Tour legs, Hotels, Specialists, Briefs). Each section: count + top 3 results inline + "See all N" footer if more. |
| Result row | Type-specific icon + title + 1-line context + timestamp + tap target. |
States
- Empty input — recent + suggestions.
- Typing (0–2 chars) — recent + suggestions still; no live results yet (avoids noise).
- Typing (3+ chars) — live grouped results stream in per section; top groups first.
- Operator chip active (e.g.
type:audit) — only matching group shown; other groups collapsed with counts. - Voice query in flight — mic pulsing; partial transcription shown in input.
- No results — single line per group: "No prospects matching 'xyz'." Plain register on empty.
- Streaming partial — sections appear as their indices return; small "still searching" caret below.
- Search complete — caret disappears; counts finalize.
- Filter applied from drawer entry — when search is opened from a drawer (e.g. audit), the drawer's existing filter pre-applies as an operator chip.
- Index degraded (per M) — banner: "Some results may be missing. The search index is rebuilding." Doesn't block.
- VoiceOver — sections announced as headings; result rows have hint "double-tap to open."
Operators (supported)
@<handle>— prospect / conversation scoped to a handle.#<tag>— content plan / asset tag.type:<group>— restrict to one group (audit, posts, prospects, etc.).surface:<id>— scoped to one surface (onlyfans / tryst / etc.).since:<duration>—since:7d/since:yesterday/since:2026-05-01.specialist:<id>— audit rows from one specialist.
Operators are tappable chips once detected; remove via × on the chip.
Interactions
- Tap a result row → open the originating drawer scoped to that item (prospect → prospect detail; audit → audit-row-detail; etc.).
- Tap "See all N" footer → open the originating drawer with the active query as its filter.
- Tap recent or suggestion → re-run query.
- Long-press a recent → "Remove from history" / "Pin to top."
- Mic → voice query; on accept, runs as if typed.
- Swipe-down → dismiss; query and results discarded unless pinned.
Edge cases
- Coop hash result (per N PII hashing) — result shows hash, not original PII. Tap routes to coop-drawer scoped to that hash.
- Briefs in search results (Quinn-as-power-user) — these are markdown files; opening one loads a read-only doc viewer with anchor-jump to the matching section.
- Two prospects with same handle on different surfaces — both shown; surface chip disambiguates.
- Encrypted attachment content (per N N7b) — NOT indexed; search doesn't reveal attachment bodies.
- Voice query mis-transcribed — quick "use my last typed query instead" affordance.
- Reduced motion — streaming animation replaced by snap-in.
Related
- Brief U — parent design.
- chat-home.screen.md — 🔍 top-bar entry point.
- Brief I, Brief P, Brief T — drawers this search lands into.
- Brief N §N7a — PII hashing constraint on coop results.
Out of scope
- Semantic / embedding-based search (P3+; v1 is keyword + operators).
- Cross-tenant search (search is scoped to
user_id = current Quinn). - Search history syncing across devices (defer).