Files
crosspoint-reader-mod/chat-summaries/2026-02-12_20-00-summary.md
cottongin dfbc931c14 mod: Phase 1 - bring forward mod-exclusive files with ActivityManager migration
Brings ~55 mod-exclusive files to the upstream-based mod/master-resync branch:

Activities (migrated to new ActivityManager pattern):
- Clock/Time: SetTimeActivity, SetTimezoneOffsetActivity, NtpSyncActivity
- Dictionary: DictionaryDefinitionActivity, DictionarySuggestionsActivity,
  DictionaryWordSelectActivity, LookedUpWordsActivity
- Bookmark: EpubReaderBookmarkSelectionActivity
- Book management: BookManageMenuActivity, EndOfBookMenuActivity
- OPDS: OpdsServerListActivity, OpdsSettingsActivity
- Utility: DirectoryPickerActivity, NumericStepperActivity

Utilities (unchanged):
- BookManager, BookSettings, BookmarkStore, BootNtpSync
- Dictionary, LookupHistory, TimeSync, OpdsServerStore

Libraries: PlaceholderCover, TableData, ChapterXPathIndexer
Scripts: inject_mod_version, generate_book_icon, preview_placeholder_cover
Docs: KOReader sync XPath mapping

Migration changes:
- ActivityWithSubactivity -> Activity base class
- Callback constructors -> finish()/setResult() pattern
- enterNewActivity() -> startActivityForResult()
- Activity::RenderLock&& -> RenderLock&&

These files won't compile yet - they reference mod settings and I18n
strings that will be added in subsequent phases.

Made-with: Cursor
2026-03-07 15:10:00 -05:00

3.4 KiB

Bookmark Feature Implementation

Task

Implement bookmark functionality for the e-reader, replacing existing "Coming soon" stubs with full add/remove bookmark, visual page indicator, and bookmark navigation features.

Changes Made

New Files Created

  • src/util/BookmarkStore.h / src/util/BookmarkStore.cpp - Bookmark persistence utility. Stores bookmarks as binary data (bookmarks.bin) per-book in the epub cache directory on SD card. Each bookmark is a (spineIndex, pageNumber) pair (4 bytes). Provides static methods: load, save, addBookmark, removeBookmark, hasBookmark.

  • src/activities/reader/EpubReaderBookmarkSelectionActivity.h / .cpp - New activity for the "Go to Bookmark" list UI, modeled on the existing chapter selection activity. Shows bookmark entries as "Chapter Title - Page N" with ButtonNavigator for scrolling. Selecting a bookmark navigates to that spine/page.

Edited Files

  • src/activities/reader/EpubReaderMenuActivity.h - Added REMOVE_BOOKMARK to MenuAction enum. Changed buildMenuItems() to accept isBookmarked parameter; dynamically shows "Remove Bookmark" or "Add Bookmark" as the first menu item.

  • src/activities/reader/EpubReaderActivity.cpp - Main integration point:

    • Added includes for BookmarkStore.h and EpubReaderBookmarkSelectionActivity.h
    • Menu creation now computes isBookmarked state and passes it through
    • ADD_BOOKMARK handler: calls BookmarkStore::addBookmark(), shows "Bookmark added" popup
    • REMOVE_BOOKMARK handler (new): calls BookmarkStore::removeBookmark(), shows "Bookmark removed" popup
    • GO_TO_BOOKMARK handler: loads bookmarks, opens EpubReaderBookmarkSelectionActivity if any exist, falls back to Table of Contents if no bookmarks but TOC exists, otherwise returns to reader
    • renderContents(): draws a small bookmark ribbon (fillPolygon, 5-point shape) in the top-right corner when the current page is bookmarked

Follow-up Changes (same session)

Force half refresh on menu exit

  • onReaderMenuBack(): sets pagesUntilFullRefresh = 1 so the next render uses HALF_REFRESH to clear menu/popup ghosting artifacts from the e-ink display.
  • ADD_BOOKMARK / REMOVE_BOOKMARK handlers: also set pagesUntilFullRefresh = 1 after their popups.

Bookmark snippet (first sentence)

  • Bookmark struct now includes a snippet string field storing the first sentence from the bookmarked page.
  • BookmarkStore binary format upgraded to v2: version marker byte (0xFF) + count + entries with variable-length snippet. Backward-compatible: reads v1 files (no snippets) gracefully.
  • addBookmark() now accepts an optional snippet parameter (max 120 chars).
  • EpubReaderActivity::onReaderMenuConfirm(ADD_BOOKMARK): extracts the first sentence from the page by iterating PageLine elements and their TextBlock words, stopping at sentence-ending punctuation (.!?:).
  • EpubReaderBookmarkSelectionActivity::getBookmarkLabel(): displays bookmark as "Chapter Title - First sentence here - Page N".

Follow-up Items

  • Test on device to verify bookmark ribbon sizing/positioning looks good across orientations
  • Consider caching bookmark state in memory to avoid SD reads on every page render (currently hasBookmark reads from SD each time in renderContents)
  • The bookmark selection list could potentially support deleting bookmarks directly from the list in a future iteration