feat: replace compact player with draggable floating overlay
Some checks failed
Release / Test backend (push) Successful in 40s
Release / Check ui (push) Failing after 32s
Release / Docker (push) Has been skipped
Release / Gitea Release (push) Has been skipped

- Remove compact player mode (seekable bar inline was undifferentiated
  from standard; didn't have voice/chapter/warm-up controls)
- Add 'float' player style: a fixed, draggable mini-overlay positioned
  above the bottom mini-bar (bottom-right corner, z-55)
  · Seek bar, skip ±15/30s, play/pause, time, speed indicator
  · Drag handle (pointer capture) to reposition anywhere on screen
  · Animated playing pulse dot in the title row
  · Suppresses the standard non-idle inline block when active so
    there is no duplicate UI
- PlayerStyle type: 'standard' | 'float' (was 'compact')
- Bump localStorage key to reader_layout_v2 so old 'compact' pref
  does not pollute the new default
- Listening tab Style row now shows Standard / Float
This commit is contained in:
root
2026-04-08 20:28:47 +05:00
parent e399b1ce01
commit 956594ae7b
2 changed files with 130 additions and 128 deletions

View File

@@ -52,7 +52,7 @@
type LineSpacing = 'compact' | 'normal' | 'relaxed';
type ReadWidth = 'narrow' | 'normal' | 'wide';
type ParaStyle = 'spaced' | 'indented';
type PlayerStyle = 'standard' | 'compact';
type PlayerStyle = 'standard' | 'float';
/** Controls how many lines fit on a page by adjusting the container height offset. */
type PageLines = 'less' | 'normal' | 'more';
@@ -66,7 +66,7 @@
pageLines: PageLines;
}
const LAYOUT_KEY = 'reader_layout_v1';
const LAYOUT_KEY = 'reader_layout_v2';
const LINE_HEIGHTS: Record<LineSpacing, number> = { compact: 1.55, normal: 1.85, relaxed: 2.2 };
const READ_WIDTHS: Record<ReadWidth, string> = { narrow: '58ch', normal: '72ch', wide: 'min(90ch, 100%)' };
/**
@@ -950,7 +950,7 @@
<div class="flex items-center gap-3 px-3 py-2.5">
<span class="text-xs text-(--color-muted) w-14 shrink-0">Style</span>
<div class="flex gap-1.5 flex-1">
{#each ([['standard', 'Standard'], ['compact', 'Compact']] as const) as [s, lbl]}
{#each ([['standard', 'Standard'], ['float', 'Float']] as const) as [s, lbl]}
<button
type="button"
onclick={() => setLayout('playerStyle', s)}