Commit Graph
1249 Commits
Author SHA1 Message Date
john-okeefe 1e7d13dc85 feat(ebook-reader): implement page-based pagination with CFI support
This commit implements true page-based pagination for the ebook reader,
similar to Kindle's approach where content is split into discrete pages
based on viewport size, font settings, and content layout.

Phase 1 - Bug Fixes:
- Fix goToPage to use getScrollPositionForPage instead of treating
  page numbers as spine indices
- Move page calculation to initialize before first render to avoid
  race condition with scroll handler
- Add fallback page calculation when pageCalculationResult is null

Phase 2 - Page Splitting:
- Add new page-splitter.ts module with CFI-based splitting for EPUB
  and height-based fallback for other formats
- Integrate splitContent into page-calculator to generate discrete
  page content for each spine item
- Store pages[] array in ChapterPageInfo for rendering
- Rewrite navigation (nextPage, previousPage, renderSpineItem) to
  use page-based approach with currentPage tracking
- Remove old scroll-based pagination from view-modes.ts
- Update paginated mode CSS for true page clipping

Phase 3 - Progress Display:
- Update progress-indicator to use currentPage directly instead of
  calculating from scroll position
- Fix getCurrentPage in reader-state to return currentPage for ebooks

Phase 4 - Interface Fixes:
- Add currentPage field to UniversalReader interface
- Update sendProgressUpdate to use currentPage directly
- Initialize currentPage to 1 on reader creation

Key features:
- Dynamic page count based on font size, line height, margins
- CFI-based page splitting preserves reading context
- Falls back to height-based splitting for non-EPUB formats
- Progress display updates immediately on page change
- Settings changes trigger page recalculation and re-render
2026-04-06 21:18:29 -04:00
john-okeefe 6805d0b66d fix(ebook-reader): load SVG images and fix progress update ID
- Add SVG image support: process <image xlink:href=...> elements
  in addition to HTML <img> tags for cover pages and embedded images
- Fix progress update: use 'id' from API response instead of
  'media_item_id' which the backend never returns for this endpoint
- Update reader context interfaces to include currentPage field
- Add debug logging for all resource keys to help troubleshoot
  image loading issues in future epubs
2026-04-06 17:01:05 -04:00
john-okeefe b12040c63f fix(book-detail): make Read Now button navigate to reader
The Read Now button now properly navigates to the reader page at
/readers/{book_id} instead of showing a placeholder alert. Also includes
generated template variable adjustments.
2026-04-06 16:02:54 -04:00
john-okeefe 74b485faa7 feat(reader): update reader template for module loading and accessibility
- Change main.js script to use type=module for proper ES module loading
- Add reader-fonts.css link for custom reading fonts
- Add tabindex=0 to reader-content for keyboard accessibility
- Fix metadata.MediaItemID reference in back link
- Add panel editor button for comics/manga
2026-04-06 16:02:48 -04:00
john-okeefe 5da573c007 fix: change script tags from 'defer' to 'type=module' for ES modules
Change script loading from deprecated 'defer' attribute to 'type=module'
for main.js across all templates. This ensures proper ES module loading
and is required for the reader module system to work correctly.
2026-04-06 16:02:45 -04:00
john-okeefe ece77ed1be fix(ebook-reader): improve image loading, keyboard nav, and progress tracking
- Add enhanced image path lookup (findImageInResources) that tries multiple
  path variations: full path, relative path, filename only, without extension,
  and common extensions (.jpg, .jpeg, .gif, .webp, .svg, .png)
- Fix keyboard navigation by focusing container on reader init
- Implement Kindle-style page display using pageCalculationResult for both
  currentPage and totalPages instead of raw spine index
- Store computed currentPage in state during scroll for UI display
- Extend progress API to send character offset, chapter index, and percentage
  for accurate cross-device sync (backend already supports these fields)
2026-04-06 16:02:25 -04:00
john-okeefe ba8c53cf4b fix: resolve progress update errors and use dynamic page calculation
- reader-navigation.ts: add fallback for mediaItemId from page URL
- reader-navigation.ts: use getCurrentPageFromScroll for accurate page tracking
- reader-navigation.ts: use pageCalculationResult.totalPages for total
- reader-services.ts: validate mediaItemId before API call
- reader-services.ts: avoid double body consumption by checking response.ok
2026-04-05 21:35:57 -04:00
john-okeefe 4cb9bdbac1 fix: resolve TypeScript errors in reader module
- reader-context.ts: fix event type to use ReaderEventType instead of string
- page-calculator.ts: add pagesInChapter property to ChapterPageInfo interface
- reader-navigation.ts: remove unused getScrollPositionForPage import
2026-04-05 21:30:16 -04:00
john-okeefe 35acf87faa fix: implement viewport-based page navigation for EPUBs
- Replace spine-only navigation with scroll-based page navigation
- nextPage: scroll down within chapter, only jump to next spine at chapter end
- previousPage: scroll up within chapter, only jump to previous spine at chapter start
- Use viewportHeight - 120 for accurate page height calculation
- Fallback to spine-only navigation when page calculation not available
2026-04-05 21:23:30 -04:00
john-okeefe 7d4c6ac142 fix: use dynamic import instead of require for browser compatibility
- Replace require() with await import() for ES module compatibility
- Add async to setTimeout callback for dynamic import support
2026-04-05 21:16:49 -04:00
john-okeefe b455f54d3c refactor: export getDefaultSettings for reader module use
- Export getDefaultSettings function for use in reader-navigation
- Minor formatting improvements in settings-manager.ts
- Add tabindex and ebook-content class to reader-content in template
2026-04-05 21:15:07 -04:00
john-okeefe ceab60e3d1 feat: initialize page calculation on reader load
- Add pageCalculationResult and currentScrollPosition to UniversalReader type
- Add settings:changed event type for settings change notifications
- Call initializePageCalculation after reader ready in reader-shell.ts
- Add tabindex to reader-content for keyboard navigation focus
2026-04-05 21:14:58 -04:00
john-okeefe caacf12003 feat: update progress indicator to use dynamic page calculation
- Import getCurrentPageFromScroll for viewport-based page calculation
- Replace spine index with actual calculated page numbers when available
- Fix bug where currentPage was assigned to itself (no-op)
- Add fallback to estimated pages while calculation is in progress
2026-04-05 21:14:44 -04:00
john-okeefe edc733947b feat: integrate page calculator with reader navigation
- Add page calculation state and initialization function
- Import page calculator functions for dynamic page tracking
- Update nextPage/previousPage to use getScrollPositionForPage for chapter navigation
- Add scroll tracking in renderSpineItem for real-time page updates
- Emit progressUpdated with dynamic page count instead of spine index
- Fix applyReaderTheme to use classList.add instead of className overwrite
- Remove unused state variables from applyReaderTheme/applyTypography
2026-04-05 21:14:42 -04:00
john-okeefe 26c0a2d001 feat: add viewport-based dynamic page calculation for EPUBs
- Create page-calculator.ts module with viewport-based pagination
- Implement calculatePagesForEbook to measure rendered content
- Add getCurrentPageFromScroll for scroll position to page mapping
- Add getScrollPositionForPage for page to scroll position mapping
- Include calculateProgressPercentage for progress tracking
- Create documentation with full implementation spec
2026-04-05 21:14:38 -04:00
john-okeefe 4574885dcd fix: EPUB spine extraction and image resource path resolution
- Fix spine item parsing to properly extract all chapters from EPUB manifest
- Add resource path fallback lookup to handle relative paths like 'image/1.png'
- Store multiple path keys in resources Map for flexible image lookup
- Simplify resource loading logic to handle OEBPS/ prefix paths
2026-04-05 21:14:31 -04:00
john-okeefe ea718b663d Reader progress display fix and dependency updates
- Add readerReady event listener to progress-indicator.ts to ensure
  progress displays correctly when reader finishes loading
- Update bruno environment variable values for testing
- Move bluemonday from indirect to direct dependency in go.mod
- Clean up unused indirect dependencies in go.sum
2026-04-04 22:49:16 -04:00
john-okeefe 83ba24e31a Expose library_type_name in API and remove redundant empty fields
- Add library_type_name to GetMediaItem handler response in media.go
- Remove empty LibraryName and LibraryTypeName fields from:
  - ListMediaItemsRow in collections.go handler
  - ListMediaItemsRow in dashboard_service.go
- These fields are now populated at the database level via trigger

The library_type_name is now automatically populated in the database
when a media item is created, so we remove the manual empty string
assignments and expose the actual value in the API response.
2026-04-04 22:49:12 -04:00
john-okeefe cf8c690474 Add library_type_name column to media_items with auto-population trigger
- Add library_type_name VARCHAR(50) column to media_items table in schema.sql
- Create PostgreSQL trigger 'set_library_type_name_on_insert' that automatically
  populates library_type_name by joining libraries table with library_types on insert
- Add library_type_name parameter to CreateMediaItem SQL query
- Update Go models (models.go) to include LibraryTypeName field
- Add UpdateMediaItemChapterMetadata query method to querier.go
- Regenerate queries.sql.go with sqlc

This allows media items to store their library type (e.g., 'Books', 'Comics', 'Manga')
at the database level, enabling filtering and display without needing additional joins.
2026-04-04 22:49:07 -04:00
john-okeefe 0697fc3b12 changed vite basedir
- Vite Base Dir changed to /static/
2026-04-04 21:43:35 -04:00
john-okeefe be7ff3f1c9 reader: implement Feature Registration Pattern infrastructure
- Add Feature Registry system in reader-shell.ts to track features
- Update format detection to use format_group with switch statement
- Add manga detection via library_type_name or manga_type fields
- Import and register features via init() functions on load
- Fix parser imports in parser-manager.ts (add missing function imports)
- Simplify epub-parsers and fb2-parser by removing unused imports
2026-04-04 18:17:20 -04:00
john-okeefe 2b22d7b255 reader: convert feature modules to Feature Registration Pattern
- Add init(context) exported function to each feature module
- Store module-level context reference for event handlers
- Fix gestures.ts to use library_type_name instead of library_type
- Features: gestures, keyboard-shortcuts, navigator-panel, offline-manager,
  panel-dock-system, progress-indicator, reading-speed-tracker
2026-04-04 18:17:16 -04:00
john-okeefe 4abc814c1b types: add format_group, library_type_name, manga_type to ReaderMetadata
- Move ReaderMetadata from api.ts to reader.d.ts as global type
- Add format_group field for format detection (reflowable/fixed_layout/comic_archive)
- Add library_type_name for library type (ebooks/comics/manga/pdf)
- Add manga_type for manga-specific reading direction metadata
- Remove duplicate mime_type field and fix typo (unkown -> unknown)
2026-04-04 18:17:11 -04:00
john-okeefe f1b1eebc0b templates: update script tags for ES modules and reader link
- Change script tags from 'defer' to 'type=module' for ES module support
- Add reader.js script to reader.templ for the reader bundle
- Update book_detail.templ 'Read Now' button to link to /readers/{id}
- Remove trailing blank line from register.templ
2026-04-04 18:17:06 -04:00
john-okeefe 99d6c9a5d1 build: configure multi-entry Vite build for reader
- Add reader.ts as second entry point alongside main.ts in vite.config.ts
- Set assetsDir to empty string to output chunks to /static/ root
- Remove reader-shell import from main.ts (loaded separately via reader.js)
- Update .gitignore to exclude web/static/assets/*.js chunks
- Update Bruno environment with new test IDs
2026-04-04 18:17:03 -04:00
john-okeefe 779f34d4f5 refactor: Remove duplicate feature files from reader root
Delete old versions of features that are now in /reader/features/:
- offline-manager.ts (moved to features/)
- reading-speed-tracker.ts (moved to features/)
- panel-dock-system.ts (replaced by converted version in features/)
- navigator-panel.ts (replaced by converted version in features/)

All imports now use the /reader/features/ directory. This eliminates
duplication and makes it clear which files are the active ones.
2026-04-04 14:24:08 -04:00
john-okeefe e04eb90d53 fix: Rename duplicate extractFB2Metadata in fb2-parser
Fix infinite recursion bug where exported function called itself.
Renamed to getFB2Metadata to avoid duplicate declaration.
2026-04-04 14:22:34 -04:00
john-okeefe c1477659c1 fix: Remove duplicate functions in epub-parsers.ts
Clean up duplicate implementations of resolvePath and
calculateTotalCharacters that were causing syntax errors.
2026-04-04 14:22:16 -04:00
john-okeefe 3e48989e83 fix: Rename duplicate extractHTMLMetadata in html-parser
Fix infinite recursion bug where exported function called itself.
Renamed to getHTMLMetadata to avoid duplicate declaration.
2026-04-04 14:21:54 -04:00
john-okeefe bf455dbf97 fix: Rename duplicate extractTXTMetadata in txt-parser
Fix infinite recursion bug where exported function called itself.
Renamed to getTXTMetadata to avoid duplicate declaration.
2026-04-04 14:21:35 -04:00
john-okeefe 7eee7c8e39 fix: Rename image-parter.ts to image-parser.ts
Reader shell expects image-parser module. Renamed file to match
import expectations.
2026-04-04 14:21:04 -04:00
john-okeefe bb586984d1 feat: Add missing feature files for build
Create panel-dock-system.ts and navigator-panel.ts in features/
directory with proper init() implementations. Copy offline-manager
and reading-speed-tracker to features/ as well.
2026-04-04 14:20:48 -04:00
john-okeefe 6649d0526d fix: Store context at module level in gestures.ts
Fix bug where context parameter was unused in init() but referenced
throughout the file. Now properly stored as module-level variable
so all gesture handler functions can access it.
2026-04-04 14:16:24 -04:00
john-okeefe 4b2b7ee66a feat: Add ebook view modes with Feature Registration Pattern
Convert view-modes.ts to init(context) pattern with:
- Paginated mode with pagination controls
- Scrolled mode for continuous reading
- Single and double column layouts
- Event-based navigation and mode switching
2026-04-04 13:48:47 -04:00
john-okeefe d03ac20f66 refactor: Convert all reader features to Feature Registration Pattern
Complete the Feature Registration Pattern refactoring across all reader
modules. Each feature now exports an init(context) function and uses the
event-based architecture for loose coupling.

## Comic Features (6 files)
- background-color.ts: Background color picker with toggle
- chapter-markers.ts: Visual chapter indicators
- page-cache.ts: 5-page ahead prefetch with cleanup
- page-order.ts: Auto-detect Japanese vs Western order
- page-scrubber.ts: Quick navigation slider
- panel-gap.ts: Adjustable panel gap controls

## Ebook Features (6 files)
- copy-handler.ts: Text copying with citation
- dictionary-popup.ts: Word lookup integration
- font-loader.ts: 8 bundled libre fonts
- search.ts: Full-text search across spine
- typography-engine.ts: Font rendering and hyphenation

## Manga Features (4 files)
- reading-direction.ts: RTL/LTR/vertical detection
- rtl-navigator.ts: Reversed page turn direction
- settings.ts: Webtoon mode and transitions
- vertical-scroll-mode.ts: Infinite scroll with lazy loading

## PDF Features (3 files)
- pdf-navigation.ts: Page turning, zoom, fit modes
- pdf-text-selection.ts: Highlight creation via backend
- annotation-layer.ts: Render highlights and notes

## Root-Level Features (3 files)
- offline-manager.ts: PWA service worker and sync
- reading-speed-tracker.ts: Pages/words per minute tracking
- settings-manager.ts: Per-user settings with localStorage fallback

## Core Infrastructure (1 file)
- parser-manager.ts: Fixed import paths for all parsers

## Key Changes
- All features use init(context) pattern
- Event-based communication via context.events.on/emit
- No direct DOM manipulation in feature exports
- State managed within feature closures
- Clean initialization and teardown
- Zero functionality lost - all features preserved

Total: 23 files converted to unified architecture
2026-04-04 13:48:18 -04:00
john-okeefe c3cf4717db refactor(reader): remove old callback-based feature files
- Delete gestures.ts: replaced by features/gestures.ts
- Delete keyboard-shortcuts.ts: replaced by features/keyboard-shortcuts.ts
- Delete progress-indicator.ts: replaced by features/progress-indicator.ts
- Old files used callback pattern, new files use init(context) pattern
2026-04-04 13:38:28 -04:00
john-okeefe 7fd8ccb129 feat(reader): add reader JavaScript loading and backend support
- templates/reader.templ: add script tag to load main.js
- Enables reader shell and Alpine components to initialize
- internal/handlers/reader.go: add GetMediaReadingProgress handler
- Backend now supports fetching reading progress via API
- GET /api/media-items/:id/progress returns current progress
2026-04-04 13:38:23 -04:00
john-okeefe 13347a9eed feat(reader): add reader module to main bundle
- Import reader/reader-shell to load reader functionality
- Ensures reader JavaScript is included in main.js bundle
- Reader features and Alpine components are now initialized
2026-04-04 13:38:19 -04:00
john-okeefe 08564ed8b1 refactor(reader): implement unified reader shell with feature orchestration
- Replace callback-based architecture with Feature Registration Pattern
- Add feature registry for modular feature initialization
- Create createNavigationAPI() for unified page/chapter navigation
- Implement renderCurrentPage() for PDF/comic/manga rendering
- Add updateProgress() to sync reading progress to backend
- Support ebook, PDF, comic, and manga readers in single interface
- Remove 600+ lines of callback wiring code
- reader-shell now acts as lightweight orchestrator
- Delegates specific functionality to feature modules
- Parse ebooks using parser-manager with format routing
- Initialize readers based on library type from metadata
2026-04-04 13:38:14 -04:00
john-okeefe f51749243a feat(reader): add PDF reader implementation
- Update pdfjs-wrapper.ts: add initializePDFReader() function
- Configure PDF.js worker, standard fonts, and cmaps
- Load PDF documents and extract metadata
- Implement page rendering with canvas
- Support PDF page navigation and zoom
- Return PDFReader with current page tracking
- Integrates with feature-based reader architecture
2026-04-04 13:38:09 -04:00
john-okeefe 6e41e5c33f feat(reader): add ebook reader features
- Update copy-handler.ts: export enableContextMenuCopy for text selection
- Update typography-engine.ts: export applyTypography and getFontStack
- Update view-modes.ts: export setViewMode and getCurrentViewMode
- Enable text copying with citation for ebooks
- Add typography engine with font loading and text formatting
- Add view mode support (paginated, scrolled, single/dual column)
- These features integrate with settings-manager for customization
2026-04-04 13:38:06 -04:00
john-okeefe 3c9a661941 feat(reader): implement comic and manga reader support
- Add image-parser.ts: CBZ archive parser for comics/manga
- Add image-parter.ts: image splitting utility for comic pages
- Update panel-detector.ts: export Panel interface
- Update panel-editor.ts: export functions for panel editing
- Implement initializeComicReader() and initializeMangaReader()
- Support page navigation for image-based readers
- Parse comic archives using JSZip with natural sort order
2026-04-04 13:38:01 -04:00
john-okeefe 6c876c3e19 feat(reader): add reader API integration
- Add getReaderMetadata() to fetch media item metadata
- Add updateReadingProgress() to sync reading progress to backend
- Export ReaderMetadata and ReadingProgress types
- Enable reader to communicate with Go backend
2026-04-04 13:37:56 -04:00
john-okeefe e076b0d0b2 feat(reader): implement gestures and keyboard-shortcuts as feature modules
- Move gestures.ts to features/ with init(context) pattern
- Move keyboard-shortcuts.ts to features/ with init(context) pattern
- Remove callback-based architecture
- Features now subscribe to events via ReaderContext
- Support touch gestures (swipe, tap, double-tap, pinch-to-zoom)
- Support keyboard shortcuts (navigation, zoom, fullscreen, bookmarks)
- Add panel-aware navigation for comics/manga
- Keyboard shortcuts include chapter navigation
2026-04-04 13:37:52 -04:00
john-okeefe 96d90db036 feat(reader): add core infrastructure for feature-based architecture
- Add reader-context.ts: defines ReaderContext interface and factory
- Add reader-events.ts: event bus for feature communication
- Add reader-state.ts: centralized state management
- Add reader-navigation.ts: unified navigation and rendering API
- Add reader-services.ts: shared services (progress, chapters)
- Establishes foundation for Feature Registration Pattern
2026-04-04 13:37:47 -04:00
john-okeefe 3162d9b7ee docs: add Feature Registration Pattern refactor plan
- Add comprehensive implementation guide for feature-based architecture
- Define core infrastructure components (context, events, state, navigation)
- Establish pattern for feature modules with init(context) functions
- Include migration checklist and code examples
2026-04-04 13:37:44 -04:00
john-okeefe 1d4195ba5e Add panel detection implementation plan documentation
- Document multi-tier detection pipeline: OpenCV → ML (COCO-SSD) → Grid → Manual Editor
- Include dependency details with bundle sizes (OpenCV ~500KB, TensorFlow.js ~2MB)
- Add architecture overview and fallback chain explanation
2026-04-04 01:01:14 -04:00
john-okeefe 0c199963b9 Add universal reader features: gestures, keyboard, navigator, offline
- gestures.ts: Touch gesture controls (swipe, pinch, tap, double-tap)
- keyboard-shortcuts.ts: Keyboard navigation (arrows, space, page up/down, etc)
- navigator-panel.ts: Affinity-style minimap for page navigation
- offline-manager.ts: Service worker registration and online status
- reading-speed-tracker.ts: Track and sync reading speed to database
- Add web manifest.json for PWA support
2026-04-04 01:01:08 -04:00
john-okeefe 2046960563 Add ebook reader features: view modes, dictionary, copy handler
- view-modes.ts: Paginated, scrolled, single-column, double-column modes
- dictionary-popup.ts: Dictionary lookup with popup definitions
- copy-handler.ts: Copy text with automatic citation formatting
- Add en-US.json dictionary for offline word lookups
2026-04-04 01:01:01 -04:00
john-okeefe c94679ec1e Add comprehensive PDF reader enhancements
- pdf-page-sizes.ts: Dynamic page sizing and layout detection
- pdf-rotation.ts: Page rotation with orientation detection
- pdf-minimap.ts: Thumbnail minimap for navigation
- pdf-dual-page.ts: Dual page spread support
- pdf-links.ts: Clickable link handling
- pdf-clipbooard.ts: Copy to clipboard functionality
- pdf-bookmarks.ts: Bookmark management
- pdf-outline.ts: Document outline/TOC integration
- pdf-text-selection.ts: Text selection and highlighting
- page-cache.ts: PDF page caching system
- pdf-search.ts: Full-text search within PDF
- pdf-navigation.ts: Navigation controls and history
- annotation-layer.ts: PDF annotation rendering
- text-layer-renderer.ts: Text layer overlay rendering
- pdfjs-wrapper.ts: PDF.js wrapper with utilities
2026-04-04 01:00:49 -04:00