# Parse and Display All Available EPUB Metadata Fields + Cleanup Refactor ## Task 1. Extend the OPF parser, metadata cache, Epub accessors, i18n, and BookInfo screen to parse and display all standard Dublin Core metadata fields plus Calibre rating. 2. Refactor for code quality: consolidate duplicate static blank strings, add `getMetadata()` accessor, and simplify `buildLayout` to accept `BookMetadata` struct. ## Changes Made ### 1. ContentOpfParser (`lib/Epub/Epub/parsers/ContentOpfParser.h/.cpp`) - Added 6 new `ParserState` entries: `IN_BOOK_PUBLISHER`, `IN_BOOK_DATE`, `IN_BOOK_SUBJECT`, `IN_BOOK_RIGHTS`, `IN_BOOK_CONTRIBUTOR`, `IN_BOOK_IDENTIFIER` - Added 7 new public string members: `publisher`, `date`, `subjects`, `rights`, `contributor`, `identifier`, `rating` - Added `identifierIsIsbn` flag for preferring ISBN identifiers over generic ones - `startElement`: handles `dc:publisher`, `dc:date`, `dc:subject` (multi-tag, comma-separated), `dc:rights`, `dc:contributor` (multi-tag, comma-separated), `dc:identifier` (prefers `opf:scheme="ISBN"`), and `calibre:rating` meta tag - `characterData`: appends text for all new states - `endElement`: transitions back to `IN_METADATA` for all new `dc:*` elements ### 2. BookMetadataCache (`lib/Epub/Epub/BookMetadataCache.h/.cpp`) - Added 7 new fields to `BookMetadata` struct - Bumped `BOOK_CACHE_VERSION` from 6 to 7 - Updated `metadataSize` calculation (8 → 15 string fields) - Added `writeString`/`readString` calls for all new fields in serialization/deserialization ### 3. Epub Accessors (`lib/Epub/Epub.h/.cpp`) - Added 7 new accessor methods: `getPublisher()`, `getDate()`, `getSubjects()`, `getRights()`, `getContributor()`, `getIdentifier()`, `getRating()` - Added `getMetadata()` returning full `BookMetadataCache::BookMetadata` const ref - Consolidated 13 duplicate `static std::string blank` locals into single file-scope `kBlank` (saves ~384 bytes DRAM) - Propagated new fields from `opfParser` to `bookMetadata` in `parseContentOpf()` ### 4. I18n (`lib/I18n/translations/english.yaml`, `lib/I18n/I18nKeys.h`) - Added 7 new translation keys: `STR_PUBLISHER`, `STR_DATE`, `STR_SUBJECTS`, `STR_RATING`, `STR_ISBN`, `STR_RIGHTS`, `STR_CONTRIBUTOR` - Regenerated I18n headers ### 5. BookInfoActivity (`src/activities/home/BookInfoActivity.h/.cpp`) - Refactored `buildLayout()` from 14 individual parameters to single `BookMetadataCache::BookMetadata` struct + `fileSize` - `onEnter()` EPUB path uses `epub.getMetadata()` directly; XTC path builds a local `BookMetadata` - Display order: Title, Author, Series, Publisher, Date, Subjects, Rating (N/5), Language, ISBN, Contributor, File Size, Rights, Description - Rating displayed as `N / 5` (Calibre stores 0-10, divided by 2) ### 6. BookInfoActivity UI Integration (`src/activities/home/BookInfoActivity.cpp`) - Added `GUI.drawHeader()` call to show the standard header bar (clock, battery, "Book Info" title) - Replaced hardcoded `MARGIN = 20` with theme metrics (`contentSidePadding`, `topPadding`, `headerHeight`, etc.) - Content now starts below the header bar using `metrics.topPadding + metrics.headerHeight + metrics.verticalSpacing` - Y-culling stops content above button hints using `pageH - metrics.buttonHintsHeight - metrics.verticalSpacing` - `contentHeight` includes bottom padding for button hints so scrolling accounts for the reserved hint area ## Commits - `8025e6f` — `feat: parse and display all available EPUB metadata fields` - `efa727e` — `refactor: consolidate Epub blank strings, simplify BookInfo buildLayout` - (pending) — `fix: add header bar and fix bottom spacing in BookInfo` ## Follow-up - Existing book caches will auto-invalidate (version 6 → 7) and regenerate on next load - Users must delete `.crosspoint/` or let it regenerate to see new metadata for previously cached books - Hardware testing needed to verify rendering of all new fields in all orientations