Commit Graph
21 Commits
Author SHA1 Message Date
john-okeefe 4119a5e38e fix(reader): use proper templ expression for back link href and clean up formatting
The back link in ReaderChrome used literal curly braces inside the href
attribute string (href="/media-items/{ metadata.MediaItemID }") which
doesn't interpolate the variable in templ. Changed to use the correct
templ expression syntax: href={ "/media/" + metadata.MediaItemID }.

Also fixed minor formatting issues:
- Normalize whitespace in comment after closing div
- Collapse empty navigator-viewport div to single line
2026-04-23 17:01:01 -04:00
john-okeefe ba502ec750 refactor(reader): remove test font, move settings panel to right sidebar
- Remove Playwrite NZ Guides test font and all references (FONT_MAP,
  FONT_FILES, reader-fonts.css, dropdown option, font files)
- Move settings panel from left sidebar to right sidebar (left sidebar
  now only contains TOC)
- Move Restore Defaults button from top bar icon to a styled button
  inside the settings panel, side by side with Done button
2026-04-19 21:42:19 -04:00
john-okeefe 9ca8e2aa44 fix(reader): use blob URLs for fonts to bypass sandboxed iframe restrictions
The paginator renders inside a sandboxed iframe that blocks @font-face
URL fetches. Fonts were never loading — all font-family rules fell back
to the generic 'serif' system font, making every reading font identical.

Fix: fetch font files on the parent page, create blob: URLs via
URL.createObjectURL(), and use those blob URLs in the @font-face rules
injected into the iframe via setStyles(). Blob URLs are always
same-origin with the creating document, so the sandboxed iframe can
access them with allow-same-origin.

Also added Playwrite NZ Guides as a test font for verifying font
switching works.
2026-04-19 21:36:19 -04:00
john-okeefe 0007b4d1d0 fix(reader): inject reader-fonts.css into iframe, remove foliate-themes.css
Fonts weren't loading because the paginator renders inside a sandboxed
iframe. @font-face declarations in the parent page's CSS are invisible
to the iframe's document. Even injecting @font-face rules via
setStyles() may not trigger font loading in sandboxed iframes.

Fix: inject a <link> to reader-fonts.css directly into the iframe's
document on each section load, so @font-face declarations are parsed
in the iframe's own document context where font-family rules can
reference them.

Also:
- Remove foliate-themes.css entirely (no longer needed)
- Set viewport background color directly via JS using THEME_COLORS map
- Remove reading theme CSS classes from viewport element
2026-04-19 21:23:55 -04:00
john-okeefe 95202f1e28 fix(reader): remove Comic Sans test font (system font not available on Linux)
Comic Sans MS is a system font not available on Linux. The cursive
fallback rendered as a script font, giving false negatives. All 8
loaded reading fonts are serif fonts loaded via @font-face, so they
intentionally look similar — font switching is confirmed working.
2026-04-19 21:12:20 -04:00
john-okeefe d68879a6c6 fix(reader): add test font, expand ranges, fix colors, add restore defaults
- Add Comic Sans MS as a test font option to verify font switching works
- Add !important to background-color and color in getCSS() to prevent
  book CSS from overriding user's reading theme colors
- Expand font size range from 12-24px to 10-40px, bump default to 18px
- Expand line height range from 1.0-2.5 to 0.8-3.0
- Add restoreDefaults() method that resets reading theme, font, size,
  line height, and justify/hyphenate to sensible defaults
- Add ↩️ restore defaults button in top bar underneath the settings gear
2026-04-19 20:51:02 -04:00
john-okeefe 863c0fd9af fix(reader): scope reading theme to viewport, wire up font/size/line-height to shadow DOM
Two root causes fixed:

1. Reading theme CSS variables were on document.body, leaking font/color
   into chrome UI. Now scoped to #reader-viewport so chrome keeps its own
   theme (system font, --text-primary colors) while the reading area uses
   reading theme colors/background.

2. getCSS() never received font family, font size, or line height settings.
   The settings UI (dropdowns, sliders) saved values but they were never
   injected into the book's shadow DOM. Now getCSS() accepts all four
   settings and generates proper CSS rules for them.

Changes:
- Wrap foliate-view in #reader-viewport div (absolute positioned between
  chrome bars)
- getCSS() reads computed style from #reader-viewport, not document.body
- getCSS() params expanded: fontFamily, fontSize, lineHeight, justify,
  hyphenate (removed unused 'spacing')
- Added FONT_MAP to translate setting keys to CSS font-family values
- applyTheme() targets #reader-viewport instead of document.body
- Removed dead #reader-viewport typography rules from foliate-themes.css
  (shadow DOM doesn't inherit outer styles), kept only background-color
2026-04-19 20:36:18 -04:00
john-okeefe 96effde421 fix(reader): inset foliate-view between chrome bars and remove base typography
- Position foliate-view with absolute inset-x-0 top-[52px] bottom-[52px]
  so book content renders between the fixed header and footer bars instead
  of behind them
- Confirmed removal of foliate-themes.css base typography was correct:
  body color now comes from chrome theme's --text-primary (light for
  dark chrome themes like tokyo-night)
2026-04-19 20:19:35 -04:00
john-okeefe 36de7cfa2f fix(reader): dark text on dark themes and add toggle icons
Two fixes:

1. Remove base typography block from foliate-themes.css. The html/body
   rules were unlayered CSS that overrode the chrome theme's layered
   body styles, causing dark reading theme text colors (--reader-text)
   to apply to the outer chrome UI on dark backgrounds. These styles
   are only meant for the shadow DOM, which getCSS() already handles.

2. Move missing typography rules (img, blockquote, a, p orphans/widows)
   into getCSS() so the shadow DOM still gets them.

3. Add sun/moon emoji indicators to the light/dark toggle switch.
2026-04-19 20:12:34 -04:00
john-okeefe 48a8716a25 feat(reader): add light/dark mode toggle for reading themes
Add explicit light/dark mode toggle switch to the reading theme settings.
The reading mode defaults based on the chrome theme (dark chrome themes
like tokyo-night default to dark reading mode).

- Add readingMode property to readerShell Alpine component
- Add toggleReadingMode() method that toggles dark class on body
- Add detectChromeDarkMode() to infer default from chrome theme
- Update applyTheme() to add/remove dark class and persist reading_mode
- Add toggle switch UI in settings panel (blue pill style, next to
  Reading Theme heading)
- Add reading_mode to default settings in settings-manager
2026-04-19 20:05:42 -04:00
john-okeefe b983f2cd2e fix(reader): restore emoji icons on reading theme optgroup labels 2026-04-19 19:51:48 -04:00
john-okeefe 0589157b57 feat(reader): wire up TOC, bookmarks, and navigator panels with Alpine.js bindings
Replace dead data-action attributes with Alpine.js @click handlers and
x-ref references across all reader panels:

- TOC panel: replaced static <nav> with x-for loop over tocItems array,
  added goToTOCItem() click handler, window-shade toggle via .tocPanel
- Bookmarks panel: replaced data-action with @click.prevent handlers,
  added goToBookmarkTarget() using data-cfi attributes for navigation,
  window-shade toggle via .bookmarksPanel
- Navigator panel: replaced data-action with @click window-shade toggle
  via .navigatorPanel
- Added goToBookmarkTarget() and toggleWindowShade() methods to reader.ts
- Removed unused panel-lock buttons (lock feature not yet implemented)
- Regenerated reader_templ.go, rebuilt CSS and JS bundles
2026-04-19 18:17:42 -04:00
john-okeefe 88c8fbc89d fix(reader): add viewport sizing for foliate-view and remove unused CSS
The foliate-view custom element had no height, causing its shadow DOM
content to collapse to 0px. Books were loading but invisible.

- Add h-screen overflow-hidden to body for full viewport height
- Add block w-full h-full to foliate-view element
- Replace flex-grow with Tailwind grow class on progress slider
- Remove #progress-slider CSS rule from inline style block
  (replaced by Tailwind grow utility)
2026-04-19 18:08:51 -04:00
john-okeefe afeb3f5b45 refactor(reader): rewrite reader module for foliate-js pan/zoom integration
Major rewrite of the web reader to properly interface with
@bookhoard/foliate-js, replacing the abandoned panel-detection
architecture with direct pan and zoom support built into the
foliate-js FixedLayout renderer.

Template (reader.templ):
- Fix critical bug: x-init config was using literal strings
  '{ readerData.X }' inside a quoted attribute, which templ
  treated as raw text and never interpolated. Values were never
  actually passed to JavaScript. Now uses fmt.Sprintf() with
  templ's expression attribute syntax ={ }.
- Pass fileUrl from server so foliate-js can open books directly.
- Redesign bottom bar with foliate-js parity: left/right navigation
  buttons, progress slider with tick marks, and zoom controls
  (zoom out, percentage display, zoom in, magnifier, pan/select
  mode toggle for PDFs).
- Remove panel editor button and enablePanelDetection config.
- Add SVG icon styles for consistent reader controls.

Go types (templates/types.go):
- Expand ReaderMetadata with FormatGroup, MangaType,
  ReadingDirection, FileURL, and LibraryID fields needed by
  the reader frontend.

Router (internal/router/reader.go):
- Populate new ReaderMetadata fields from database values.
- Construct FileURL from library ID and file path for the
  /uploads/library-{id}/* file serving route.

Reader JS (reader.ts):
- Full rewrite modeled on foliate-js Reader class, adapted for
  Alpine.js. Opens books via view.open(fileUrl), accesses
  view.renderer for zoom/pan/navigation, and wires up keyboard
  shortcuts (+/-/0 for zoom, arrows for nav, Escape for magnifier).
- Uses view.isFixedLayout instead of importing FixedLayout class,
  avoiding a TypeScript module resolution issue with the Vite alias.

Settings manager (settings-manager.ts):
- Remove dependency on deleted ReaderContext event bus.
- Export loadSettings/saveSettings/syncSettings directly as
  standalone async functions.

Cleanup:
- Delete reader-context.ts and reader-events.ts (over-engineered
  event system replaced by direct function calls).
- Remove panel_zoom_enabled from ReaderSettings type.
2026-04-19 14:27:56 -04:00
john-okeefe 08054ccc76 feat(reader): Update reader template for panel detection config
- Update reader initialization to pass panel detection configuration
- Include enablePanelDetection, libraryType, formatGroup params
- Add mangaType and readingDirection for proper manga rendering
- Change theme class to theme-tokyo-night for consistent styling
2026-04-12 20:43:58 -04:00
john-okeefe db4de823f3 feat: Update reader template for foliate-js integration
Update reader page template to use foliate-js custom element and add theme selector UI.

Template Changes:
1. Add foliate-js integration:
   - Load foliate-themes.css for reading theme system
   - Load foliate-js/view.js to register <foliate-view> custom element
   - Replace <main id="reader-content"> with <foliate-view id="reader-view">
   - Foliate auto-initializes from the custom element

2. Add Reading Theme selector:
   - New section in settings panel (before Typography)
   - Single dropdown with 18 themes organized by category using <optgroup>
   - Categories: Classic Reading, Sky & Atmosphere, Sunset & Warmth, Nature & Earth, High Performance
   - Each theme shows descriptive name
   - Themes organized for easy discovery (grouped by mood/use case)

3. Remove broken references:
   - Remove ebook-content class (tied to broken CSS columns approach)
   - Clean up old reader-specific CSS class references

Reader Template Structure:
- Chrome (top/bottom bars): Back button, title, settings gear
- Bottom bar: Progress display, TOC/bookmarks/notes buttons, panel editor (comics)
- Settings panel: Chrome behavior, progress mode, reading themes, typography (fonts, spacing)
- TOC panel: Table of contents navigation
- Navigator panel: Page thumbnail with draggable viewport
- Bookmarks panel: User bookmarks with add button
- Dictionary popup: Word definition popup

Template Generator:
- Regenerated reader_templ.go via go generate
- Syncs template changes with Go backend
2026-04-12 12:09:56 -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 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 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 2eddc1b92b Add font loader and update reader template for font loading
- Add font-loader.ts for managing 8 reading fonts with preload optimization
- Include fonts: Literata, Crimson Text, Source Serif 4, EB Garamond,
  Libertinus Serif, Noto Serif, Charis SIL, IBM Plex Serif
- Update reader.templ to include reader-fonts.css stylesheet
2026-04-04 01:00:23 -04:00
john-okeefe afbe7f7220 feat: add reader.templ source file for templ code generation
- Add templates/reader.templ with Go templ syntax
- Contains Reader component with dockable panels
- Panel components: ReaderChrome, Settings, TOC, Navigator, Bookmarks, DictionaryPopup
2026-04-03 17:20:40 -04:00