153 lines
7.2 KiB
Markdown
153 lines
7.2 KiB
Markdown
---
|
||
id: ML-176.2
|
||
title: "Presto: add splash screen, search views, and on-screen keyboard"
|
||
status: To Do
|
||
assignee: []
|
||
created_date: "2026-05-10 13:35"
|
||
updated_date: "2026-05-10 13:56"
|
||
labels:
|
||
- presto
|
||
- search
|
||
- micropython
|
||
milestone: m-0
|
||
dependencies:
|
||
- ML-176.1
|
||
references:
|
||
- presto/AGENTS.md
|
||
- presto/README.md
|
||
- >-
|
||
doc-17 -
|
||
Implementation-Plan-ML-176.2-—-Presto-splash-screen-search-views-and-on-screen-keyboard
|
||
modified_files:
|
||
- presto/records_on_the_day.py
|
||
parent_task_id: ML-176
|
||
priority: medium
|
||
---
|
||
|
||
## Description
|
||
|
||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||
|
||
Refactor `presto/records_on_the_day.py` into a unified app with a splash screen, search capability, and the existing calendar. All work is in the single MicroPython file.
|
||
|
||
## New states
|
||
|
||
- `STATE_HOME` (new, default on boot/wake)
|
||
- `STATE_SEARCH_INPUT` (new — search box + on-screen keyboard)
|
||
- `STATE_SEARCH_RESULTS` (new — results list, reuses day-view rendering)
|
||
- `STATE_MONTH` / `STATE_DAY` / `STATE_RECORD` (existing, unchanged logic)
|
||
|
||
## Splash screen (STATE_HOME)
|
||
|
||
- Two large touch targets: "Search Collection" and "Today's Records"
|
||
- "Today's Records" → transitions to existing `STATE_MONTH` / today's records flow
|
||
- "Search Collection" → transitions to `STATE_SEARCH_INPUT`
|
||
- On boot and display wake: always show `STATE_HOME`
|
||
|
||
## On-screen keyboard (part of STATE_SEARCH_INPUT)
|
||
|
||
- 3-row QWERTY layout: qwertyuiop / asdfghjkl / zxcvbnm
|
||
- Bottom row: [123 toggle] [space] [⌫ backspace] [OK]
|
||
- Numbers keyboard: 1234567890 / symbols row / [ABC toggle] [space] [⌫] [OK]
|
||
- Space and ⌫ are shared between both layouts
|
||
- Lowercase only, no shift/caps
|
||
- OK button disabled (dimmed) when query is empty
|
||
- Each key is a rounded rectangle, touch-mapped to append/delete chars
|
||
- Visual feedback on key press (brief highlight)
|
||
- Query buffer displayed in a text field area above the keyboard, max ~50 chars
|
||
|
||
## Search triggering
|
||
|
||
- User types query, presses OK
|
||
- OK calls `fetch_search_results(query)` → API
|
||
- Transitions to `STATE_SEARCH_RESULTS`
|
||
|
||
## Search results (STATE_SEARCH_RESULTS)
|
||
|
||
- Reuses existing `_draw_record_list()`, scroll, and row rendering from day view
|
||
- Header shows "Search: <query>" with Back button
|
||
- Back returns to `STATE_SEARCH_INPUT` (preserving query so user can refine)
|
||
- Tapping a record → `STATE_RECORD` (detail view, unchanged)
|
||
- Back from detail → returns to search results
|
||
- Empty results: "No records found" full-screen message
|
||
- Error: "Could not reach server" with retry-on-tap (same as day view)
|
||
- 20 results per page, no infinite scroll
|
||
|
||
## API client
|
||
|
||
- New `fetch_search_results(query)` function
|
||
- Calls `GET /api/v1/collection?q=<url-encoded-query>&limit=20`
|
||
- Parses `{total, records, ...}` response
|
||
- Returns `(records_list, error_flag)` tuple (same shape as `fetch_records`)
|
||
|
||
## Navigation state
|
||
|
||
- Track previous state to know where "Back" in detail view should go
|
||
- Detail Back → search results when entered from search
|
||
- Detail Back → day view when entered from day
|
||
- Month view and search views both have "Back to Home"
|
||
|
||
## Constraints
|
||
|
||
- Must reuse existing record row rendering (`_draw_record_row`), detail view (`draw_record_detail`), thumbnail fetching, WiFi, NTP, display sleep logic
|
||
- Scroll performance rules from AGENTS.md still apply
|
||
- Memory: no large buffers, keep GC pressure low
|
||
<!-- SECTION:DESCRIPTION:END -->
|
||
|
||
## Acceptance Criteria
|
||
|
||
<!-- AC:BEGIN -->
|
||
|
||
- [ ] #1 On boot, splash screen shows with 'Search Collection' and 'Today's Records' buttons
|
||
- [ ] #2 Tapping 'Today's Records' opens the existing month calendar (unchanged behavior)
|
||
- [ ] #3 Tapping 'Search Collection' opens search input view with on-screen QWERTY keyboard
|
||
- [ ] #4 Keyboard: tapping letter keys builds query string shown in input field
|
||
- [ ] #5 Keyboard: backspace removes last character
|
||
- [ ] #6 Keyboard: 123/ABC toggle switches between QWERTY and numbers keyboard layouts
|
||
- [ ] #7 Keyboard: OK button is visually disabled (dimmed) when query is empty
|
||
- [ ] #8 Keyboard: OK button triggers API search when query is non-empty
|
||
- [ ] #9 Search results display using same record row layout as day view (cover, title, artist, format, year)
|
||
- [ ] #10 Search results: Back button returns to search input view with query preserved
|
||
- [ ] #11 Search results: tapping a record opens detail view
|
||
- [ ] #12 Detail view Back returns to search results when entered from search
|
||
- [ ] #13 Detail view Back returns to day view when entered from day
|
||
- [ ] #14 Empty results show 'No records found' full-screen message
|
||
- [ ] #15 API error shows 'Could not reach server' with retry-on-tap
|
||
- [ ] #16 Display sleep/wake always returns to splash screen
|
||
- [ ] #17 Scroll in search results works identically to day view scroll
|
||
- [ ] #18 Keyboard renders correctly at 720×720: all keys visible and tappable
|
||
- [ ] #19 Back-to-Home navigation available from month view and search views
|
||
<!-- AC:END -->
|
||
|
||
## Implementation Notes
|
||
|
||
<!-- SECTION:NOTES:BEGIN -->
|
||
|
||
## Implementation Plan
|
||
|
||
Full plan: `doc-17 - Implementation Plan: ML-176.2 — Presto splash screen, search views, and on-screen keyboard`
|
||
|
||
### Summary
|
||
|
||
11-step plan, all within `records_on_the_day.py`:
|
||
|
||
1. **State constants + globals** — Add `STATE_HOME` (4), `STATE_SEARCH_INPUT` (5), `STATE_SEARCH_RESULTS` (6). Remove `STATE_STARTUP`. Add `search_query`, `search_results`, `keyboard_mode`, `previous_state` globals.
|
||
2. **`fetch_search_results()`** — New API client calling `GET /api/v1/collection?q=<encoded>&limit=20`. Returns `(records_list, error_flag)`. Depends on ML-176.1 for the backend `q` parameter.
|
||
3. **Splash screen (`STATE_HOME`)** — `draw_home_screen()` with two large buttons: "Search Collection" and "Today's Records".
|
||
4. **On-screen keyboard (`STATE_SEARCH_INPUT`)** — `draw_search_input()` with 3-row QWERTY + numbers keyboard. Hit-test via `_keyboard_hit_test()`. Touch handler `handle_search_input_touch()`. Visual key-press feedback. OK button dimmed when query empty.
|
||
5. **Search results (`STATE_SEARCH_RESULTS`)** — Reuses `_draw_record_row()`. Own scroll state (`search_scroll_offset`, `_search_content_height`). `prepare_records_for_display(recs=None)` made generic to support both `records` and `search_results`. Empty/error states.
|
||
6. **Navigation tracking** — `previous_state` tracks whether detail was entered from day or search. Back from detail returns to correct origin.
|
||
7. **Back-to-Home** — Home button added to month header. `wake_display()` sets `state = STATE_HOME`. `redraw_current_view()` updated for new states.
|
||
8. **Boot flow** — Starts at `STATE_HOME`, no auto-fetch. User taps "Today's Records" → month view.
|
||
9. **Main loop dispatch** — Added handlers for all new states. `handle_home_touch()`. Search results drag-scroll mirrors day view.
|
||
10. **Cleanup** — Remove all `STATE_STARTUP` references.
|
||
11. **Deploy** — Verify ML-176.1 deployed → `mise run presto` → manual verification on device.
|
||
|
||
### Key design decisions
|
||
|
||
- "Today's Records" navigates to month view (with today highlighted), not directly to day — preserves calendar context
|
||
- Keyboard: fixed layout, lowercase only, no shift/caps, max 50 chars
|
||
- Search results: 20 per page, no infinite scroll. Own scroll state per AGENTS.md rules.
|
||
- `prepare_records_for_display()` parameterized to accept optional list — avoids duplicating the entire display-prep pipeline
|
||
<!-- SECTION:NOTES:END -->
|