Search and filter the library #13

Merged
365DevNet merged 0 commits from refs/pull/13/head into main 2026-08-13 16:22:29 +02:00
365DevNet commented 2026-08-13 16:11:58 +02:00 (Migrated from codeberg.org)

Summary

Finding a book meant paging through covers until you saw it. This adds a Find
screen reached from the bottom bar: search by title or author, and filter by
read state, on-device status and collection.

Costs no extra requests — every field it matches on is already in memory
from the browse the app does at startup.

Scope came from the data, not from guesswork

Surveyed the live library first:

Field Series with data
Writers 27 / 29
Language 26 / 29
Release year 18 / 29
Summary 11 / 29
Genres 6 / 29
Tags 0 / 29

Genre filtering is deliberately excluded: 23 of 29 books have none, what
exists is mostly publisher junk scraped from EPUB metadata (febtradepromo,
givewell, sel021000), and it would cost 29 extra HTTP requests at startup —
one Series/metadata call per series — to filter on data most books lack.

What changed

  • core/BookFilter (new, pure) — all matching rules, 14 host tests using the
    real library as fixtures, because those titles are what break naive matchers:
    "Calvin and Hobbes" appears twice, "Habit" twice, and one title is Dutch.
  • ui/FindScreen (new) — the form and its hit-testing, sharing rectangle
    helpers so a control is tappable exactly where it was drawn.
  • Bottom bar gains Find, and shows Find * 12 of 29 - Page 1 / 2 whenever a
    filter is active, so a filtered shelf can never be mistaken for a shrinking
    library.
  • main.cpp pages the gallery over a g_visible index list.

The one real hazard

g_visible holds indices into g_entries. Only the gallery's page
arithmetic works in filtered space; details, load, unload and sync all stay in
real-entry space and convert at exactly one place. Getting that wrong would
open — or unload — the wrong book.

Notes

  • Filter is in memory only and resets on relaunch. A filter that survives a
    restart and silently hides books is a "where did my library go?" trap.
  • KBD_SCREENTOP + KBD_NO_SELFCLOSE_ON_OK would allow refine-in-place
    searching. Left as a future device experiment — this firmware has departed
    from documented PocketBook behaviour before.

Test plan

  • 134 host tests pass
  • Clean ARM cross-build
  • On device: search narrows the shelf; filters work; empty state escapable
  • On device: tapping a cover in a filtered shelf opens that book — the
    index-mapping hazard above

🤖 Generated with Claude Code

## Summary Finding a book meant paging through covers until you saw it. This adds a Find screen reached from the bottom bar: search by title or author, and filter by read state, on-device status and collection. Costs **no extra requests** — every field it matches on is already in memory from the browse the app does at startup. ## Scope came from the data, not from guesswork Surveyed the live library first: | Field | Series with data | |---|---| | **Writers** | **27 / 29** | | Language | 26 / 29 | | Release year | 18 / 29 | | Summary | 11 / 29 | | **Genres** | **6 / 29** | | **Tags** | **0 / 29** | Genre filtering is deliberately **excluded**: 23 of 29 books have none, what exists is mostly publisher junk scraped from EPUB metadata (`febtradepromo`, `givewell`, `sel021000`), and it would cost 29 extra HTTP requests at startup — one `Series/metadata` call per series — to filter on data most books lack. ## What changed - `core/BookFilter` (new, pure) — all matching rules, 14 host tests using the real library as fixtures, because those titles are what break naive matchers: "Calvin and Hobbes" appears twice, "Habit" twice, and one title is Dutch. - `ui/FindScreen` (new) — the form and its hit-testing, sharing rectangle helpers so a control is tappable exactly where it was drawn. - Bottom bar gains `Find`, and shows `Find * 12 of 29 - Page 1 / 2` whenever a filter is active, so a filtered shelf can never be mistaken for a shrinking library. - `main.cpp` pages the gallery over a `g_visible` index list. ## The one real hazard `g_visible` holds **indices into `g_entries`**. Only the gallery's page arithmetic works in filtered space; details, load, unload and sync all stay in real-entry space and convert at exactly one place. Getting that wrong would open — or unload — the wrong book. ## Notes - Filter is in memory only and resets on relaunch. A filter that survives a restart and silently hides books is a "where did my library go?" trap. - `KBD_SCREENTOP` + `KBD_NO_SELFCLOSE_ON_OK` would allow refine-in-place searching. Left as a future device experiment — this firmware has departed from documented PocketBook behaviour before. ## Test plan - [x] 134 host tests pass - [x] Clean ARM cross-build - [x] On device: search narrows the shelf; filters work; empty state escapable - [x] On device: **tapping a cover in a filtered shelf opens that book** — the index-mapping hazard above 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
365DevNet/PocketBook_Kavita_sync!13
No description provided.