Files
music_library/backlog/tasks/ml-176.2 - Presto-add-splash-screen-search-views-and-on-screen-keyboard.md
T
2026-05-10 15:07:06 +01:00

153 lines
7.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
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 -->