feat: full-text event search #33

Merged
makiolaj merged 3 commits from feat/event-search into release/v2.8.0 2026-06-23 09:27:52 +00:00
Owner

Adds a full-text event search reached from a magnifier in each calendar screen's top bar.

  • Data: queries the Events table directly with an escaped LIKE on title / description / location, so search is unbounded in time and filtered provider-side. New SearchProjection + toSearchResult mapper reuse the .ics export's DURATION handling; hidden calendars are filtered out, mirroring instances().
  • Recurring events: shown once (the series master), displaying and sorting by their nearest occurrence — soonest upcoming within ~2 years, else most recent past — resolved via the Instances provider; falls back to the series start when none lies in the window.
  • SearchViewModel: debounces the query (250 ms), needs >= 2 chars, orders results upcoming-ascending then past-descending.
  • SearchScreen: autofocused inline field in the top bar, GroupedRow results (date · time · location) reusing the agenda row style, idle/empty states. Hosted as a CalendarHost overlay below detail/edit so a tapped result's detail draws on top. Clears on reopen; idle/empty message re-centres above the keyboard (imePadding).

Builds clean (compileDebugKotlin / lintDebug / testDebugUnitTest / assembleDebug). Verified on-device (Pixel 10).

Note: touches CalendarHost.kt, which the QS-tile branch (#32) also edits — a small merge may be needed depending on merge order.

Adds a full-text event search reached from a magnifier in each calendar screen's top bar. - **Data**: queries the Events table directly with an escaped LIKE on title / description / location, so search is unbounded in time and filtered provider-side. New SearchProjection + toSearchResult mapper reuse the .ics export's DURATION handling; hidden calendars are filtered out, mirroring instances(). - **Recurring events**: shown once (the series master), displaying and sorting by their nearest occurrence — soonest upcoming within ~2 years, else most recent past — resolved via the Instances provider; falls back to the series start when none lies in the window. - **SearchViewModel**: debounces the query (250 ms), needs >= 2 chars, orders results upcoming-ascending then past-descending. - **SearchScreen**: autofocused inline field in the top bar, GroupedRow results (date · time · location) reusing the agenda row style, idle/empty states. Hosted as a CalendarHost overlay below detail/edit so a tapped result's detail draws on top. Clears on reopen; idle/empty message re-centres above the keyboard (imePadding). Builds clean (compileDebugKotlin / lintDebug / testDebugUnitTest / assembleDebug). Verified on-device (Pixel 10). Note: touches CalendarHost.kt, which the QS-tile branch (#32) also edits — a small merge may be needed depending on merge order.
makiolaj added 3 commits 2026-06-23 09:23:02 +00:00
A magnifier in each calendar screen's top bar opens a search overlay: type a
query and matching events (title, location or description) appear, nearest-to-
today first; tapping a result opens its detail.

- Data: query the Events table directly with a LIKE selection on title /
  description / location (wildcards escaped), so search is unbounded in time and
  filtered provider-side. New SearchProjection + toSearchResult mapper reuse the
  .ics export's DURATION handling for recurring masters. Hidden calendars are
  filtered out, mirroring instances().
- SearchViewModel debounces the query (250 ms), needs >= 2 chars, and orders
  results upcoming-ascending then past-descending.
- SearchScreen: autofocused inline field in the top bar, GroupedRow results
  reusing the agenda row style, idle/empty states. Hosted as a CalendarHost
  overlay below detail/edit so a tapped result's detail draws on top.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A recurring master's DTSTART is the series start, which for long-running series
reads as an old date and sorts into the past. For recurring hits (non-empty
RRULE/RDATE), resolve the occurrence nearest to now via the Instances provider —
the soonest upcoming within ~2 years, else the most recent past — and display
and sort by that. Falls back to the series start when no occurrence lies in the
window.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
fix(search): clear on reopen and centre messages above the keyboard
All checks were successful
Translations / check (pull_request) Successful in 4s
CI / ci (pull_request) Successful in 4m14s
013efef29e
The search ViewModel is activity-scoped and outlives the overlay, so a reopened
search showed the previous query/results — reset the query when the screen
re-enters (peeking a result keeps it, as the screen stays composed under the
detail). Add imePadding so the idle/empty message re-centres in the area above
the keyboard instead of staying centred on the full page behind it.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
makiolaj merged commit 3b5c0be765 into release/v2.8.0 2026-06-23 09:27:52 +00:00
makiolaj deleted branch feat/event-search 2026-06-23 09:27:52 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: makiolaj/calendula#33