Commit Graph
5 Commits
Author SHA1 Message Date
john-okeefe d38804e910 fix(progress): correct percentage display and add format-aware progress
Fix two bugs in progress display across book detail, progress page, reader,
and sync modal templates:

1. Percentage was stored as 0.0-1.0 fraction but displayed as-if 0-100
   (showing 0.5% instead of 50%). Multiply by 100 at the data source in
   both GetAllProgress and GetAllProgressData handlers, and in the reader
   route's ReadingProgress construction.

2. Progress bar width was never evaluated — { expr } inside style=".."
   was rendered as literal text by templ, resulting in 0% width bars for
   all items. Fixed by using templ's style={ expr } attribute syntax
   which evaluates the Go expression (uses SanitizeStyleAttributeValues).

Also add format-aware progress display:
- Reader template: shows "45% · Page 89/196" for reflowable (estimated
  pages), "127/342" for comics/PDFs (actual pages)
- Progress page: shows "Page X of Y (est.)" for reflowable, "X / Y"
  for fixed layout
- Add FormatGroup and EstimatedPages to ProgressWithMedia struct
- Remove hardcoded totalPages=200 fallback in progress handler (now 0)
- Add fmt import to progress.templ for string formatting
2026-04-24 14:03:03 -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 562ca53d6e feat: implement comic/manga metadata display on book detail page
Implement comprehensive comic metadata display features on the SSR book detail
page, supporting all 8 metadata fields from ComicInfo.xml and other sources.

## Template Changes (book_detail.templ)

### Step 1: Reading Direction Badge
- Display directional badge (RTL, LTR, VERTICAL) for manga/comics
- Uses 📖 icon with uppercase direction text
- Auto-hides when direction is "auto" (default)
- Styled with accent color for visibility

### Step 2: Community Rating Display
- Show pre-existing community rating from metadata (0.0-10.0 scale)
- Distinct from user ratings with visual differentiation
- Uses renderStars() helper for visual star display
- Shows both stars and numeric score (e.g., "★★★★☆ 8.5 / 10")
- Smaller, subtler styling than user rating

### Step 3: Comic-Specific Badges
- Age Rating: Content maturity indicator
- Black & White: Visual style badge
- Story Arc: Narrative arc name with 📚 icon
- Badges styled as pills with subtle borders
- Only display when values are present

### Step 4: Universal Series Info
- Series Count: Total items in series
- Volume: Volume/omnibus number
- Imprint: Publisher imprint (e.g., Vertigo)

### Step 5: Comic-Specific Metadata
- Manga Type: Raw/Comic/Manga classification
- Scan Information: Scanner group, resolution
- Alternate Series: Different series numbering

### Step 6: Summary Section
- Display ComicInfo.xml summary when present
- Separate from description field
- Sanitized HTML output with bluemonday
- Scrollable container for long summaries

### Step 7: Metadata Notes
- Technical notes from metadata files
- Internal/useful information (scanner, source, etc.)
- Card-style display with clear typography

### Step 8: Web URL Link
- External link to info sources (Goodreads, ComicVine, etc.)
- Opens in new tab with security attributes
- Displays clean domain name

## Utils Changes (templates/utils.go)

Added helper functions:
- getAlternateSeries(): Extract alternate series from JSONB
- getDomainName(): Extract clean domain for display
- formatAlternateInfo(): Format readable alternate series string

## Implementation Plan

Updated FRONTEND_IMPLEMENTATION_PLAN_COMIC_METADATA.md with:
- Disabled markdownlint for MD013 (line length)
- Added spacing for readability

## Technical Details

- All fields use pgtype.Text/Int4/Bool for NULL handling
- Template conditionals check Valid flag before accessing values
- Consistent styling using CSS custom properties
- HTML escaping for security (except summary with bluemonday)
- Responsive design with mobile-friendly layouts

Related: Database schema already supports all metadata fields
2026-03-31 17:09:25 -04:00
john-okeefe e89ed4dbc6 feat: enhance book detail star rating display with visual half-stars
Improve star rating display on book detail page to show always-visible
5-star rating scale with theme-aware colors and visual half-star rendering.

Changes:

Enhanced renderStars() function:
- Always displays 5 stars (0/5 now shows 5 grey stars instead of empty)
- Filled stars use var(--accent) color (theme-aware highlight)
- Empty stars use var(--text-secondary) (theme-aware grey, adapts to light/dark themes)
- Half-stars use CSS linear-gradient (90deg) to split star vertically:
  - Left half: var(--accent) (filled, color)
  - Right half: var(--text-secondary) (empty, grey)
- Uses webkit-background-clip and text-fill-color transparent for gradient effect

Added getBookRating() helper function:
- Returns rating value or 0 if book.Rating is nil
- Allows unrated books to display 0/5 (5 grey stars)
- Makes rating section always visible instead of hiding when nil

Template changes:
- Updated rating display to always show (no conditionals)
- Removed text-yellow-400 class (colors now inline with theme vars)
- Added templ.Raw() wrapper for HTML rendering (prevents escaping)
- Simplified rating display logic

Benefits:
- Users can now see rating scale even when book isn't rated
- Visual half-star is much more intuitive than ½ text character
- Theme-aware colors adapt to light/dark mode automatically
- Follows existing patterns ( UnsafeHTML, CSS variables, etc.)

This makes the rating section more discoverable and user-friendly.
2026-03-29 00:26:50 -04:00
john-okeefe eb349cbc95 feat: add book detail page with comprehensive metadata display
Implement SSR-first book detail page at /media/:uuid with complete
book information, progress tracking, and interactivity.

Features:
- Cover image (256x384px) with responsive layout
- Complete metadata: title, author, description, publisher, ISBN,
  language, edition, page count, genre, copyright year, format
- External service links (Goodreads, Open Library, Google Books, Amazon)
  with smart URL fallback: ID → ISBN → Title+Author
- Reading progress display with device sources (web/kobo/koreader)
- Sync progress modal for conflict resolution
- Collections display as clickable badges
- Notes/highlights counter with placeholder modal
- Rating display (1-10 scale with star rendering)
- HTML sanitization for book descriptions using bluemonday

Data Structure:
- handlers.MediaDetail embeds database.MediaItems for zero duplication
- Uses existing database queries (GetMediaItem, GetMediaRating, etc.)
- Follows project pattern: no parallel type systems

Frontend:
- TypeScript modal triggers (book-detail.ts)
- Alpine.js for modal interactions
- TailwindCSS styling with theme variables
- Responsive: cover-left layout, mobile stacks vertically

Backend:
- Route: GET /media/:uuid (protected)
- Handler: inline function in frontend.go following existing pattern
- Template: SSR-first with progressive enhancement
- Returns HTML only (API uses separate /api/media-items/:id endpoint)

Files created:
- internal/handlers/media_detail.go
- templates/book_detail.templ
- templates/book_detail_modals.templ
- web/src/book-detail.ts

Files modified:
- internal/router/frontend.go (add route)
- web/src/main.ts (import module)
2026-03-28 23:54:39 -04:00