feat(web): sync-conflict banner at top of media item page + end-time help row
Release / build-and-push (push) Successful in 3m9s

- A progress sync conflict used to be flagged only inside the progress
  card, far down a long page. An unresolved conflict now also renders
  a full-width warning strip at the very top (under the app bar) that
  opens the same resolution modal on click. Rendered from the same
  ActiveConflict the progress section uses — absent when clean.
- Shortcuts dialog Mouse section gains an 'End time' row: click to
  cycle total → book left → chapter left (§10's toggle was
  undiscoverable).
This commit is contained in:
John O'Keefe committed 2026-10-23 12:30:12 -04:00
1 parent f8de17723a
commit 9d0ae2bcc4
3 files changed
+492 -457

No files matched your search

+17
View File
@@ -52,6 +52,23 @@ templ BookDetail(user User, book handlers.MediaDetail, errorMessage string, tomb
data-conflict-winner={ conflictWinnerSource(book.ActiveConflict) } data-conflict-winner={ conflictWinnerSource(book.ActiveConflict) }
> >
@Header(user, "/media/{ uuidToString(book.ID) }") @Header(user, "/media/{ uuidToString(book.ID) }")
if book.ActiveConflict != nil {
<!-- Sync-conflict banner (user request): the progress
card's warning sits far down a long page — this
strip is unmissable at the very top, and clicking
it opens the same resolution modal. -->
<button
type="button"
@click="showProgressSyncModal()"
class="w-full flex items-center gap-3 px-4 sm:px-6 lg:px-8 py-3 text-left"
style="background-color: color-mix(in srgb, var(--status-warning) 14%, transparent); border-bottom: 1px solid var(--status-warning);"
>
@Icon("alert", "h-5 w-5 shrink-0")
<span class="text-sm" style="color: var(--text-primary);">
Progress sync conflict detected on this item — click to review and resolve.
</span>
</button>
}
<!-- Hero with blurred cover backdrop --> <!-- Hero with blurred cover backdrop -->
<div class="relative overflow-hidden"> <div class="relative overflow-hidden">
if book.CoverImagePath.Valid && book.CoverImagePath.String != "" { if book.CoverImagePath.Valid && book.CoverImagePath.String != "" {
File diff suppressed because it is too large. Load diff
+4
View File
@@ -232,6 +232,10 @@ export const MOUSE_GUIDE: readonly PointerGuideRow[] = [
{ label: "Shift + click", description: "Jump to the nearest chapter line" }, { label: "Shift + click", description: "Jump to the nearest chapter line" },
{ label: "Shift + drag", description: "Precision rail (±5 min) around the nearest line" }, { label: "Shift + drag", description: "Precision rail (±5 min) around the nearest line" },
{ label: "Wheel", description: "Nudge ±5s (Shift: ±60s)" }, { label: "Wheel", description: "Nudge ±5s (Shift: ±60s)" },
{
label: "End time",
description: "Click to cycle the −label: total → book left → chapter left",
},
]; ];
export const TOUCH_GUIDE: readonly PointerGuideRow[] = [ export const TOUCH_GUIDE: readonly PointerGuideRow[] = [