fix: player float mode now works; add minimal player style
Float mode was broken because AudioPlayer was unmounted the moment audioStore.active became true — exactly when the float overlay needs to render. Fix: keep AudioPlayer mounted in float and minimal modes regardless of audioStore.active; only standard mode shows the 'Controls below' message. Adds a third 'minimal' style: a compact single-row bar (skip ±, play/pause, seek, time) with no voice picker or chapter browser. Voice picker and chapter button are hidden in the idle pill too. Settings UI updated to show all three options with a live description of what each style does.
This commit is contained in:
@@ -52,7 +52,7 @@
|
||||
type LineSpacing = 'compact' | 'normal' | 'relaxed';
|
||||
type ReadWidth = 'narrow' | 'normal' | 'wide';
|
||||
type ParaStyle = 'spaced' | 'indented';
|
||||
type PlayerStyle = 'standard' | 'float';
|
||||
type PlayerStyle = 'standard' | 'minimal' | 'float';
|
||||
/** Controls how many lines fit on a page by adjusting the container height offset. */
|
||||
type PageLines = 'less' | 'normal' | 'more';
|
||||
|
||||
@@ -596,27 +596,27 @@
|
||||
</button>
|
||||
{#if audioExpanded}
|
||||
<div class="border border-t-0 border-(--color-border) rounded-b-lg overflow-hidden">
|
||||
{#if audioStore.slug === data.book.slug && audioStore.chapter === data.chapter.number && audioStore.active}
|
||||
<!-- Mini-player is already playing this chapter — don't duplicate controls -->
|
||||
<div class="px-4 py-3 flex items-center gap-2 text-sm text-(--color-muted)">
|
||||
<svg class="w-4 h-4 text-(--color-brand) shrink-0" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path d="M12 3v10.55A4 4 0 1014 17V7h4V3h-6z"/>
|
||||
</svg>
|
||||
<span>Controls are in the player bar below.</span>
|
||||
</div>
|
||||
{:else}
|
||||
<AudioPlayer
|
||||
slug={data.book.slug}
|
||||
chapter={data.chapter.number}
|
||||
chapterTitle={cleanTitle}
|
||||
bookTitle={data.book.title}
|
||||
cover={data.book.cover}
|
||||
nextChapter={data.next}
|
||||
chapters={data.chapters}
|
||||
voices={data.voices}
|
||||
playerStyle={layout.playerStyle}
|
||||
wordCount={wordCount}
|
||||
onProRequired={() => { audioProRequired = true; }}
|
||||
{#if audioStore.slug === data.book.slug && audioStore.chapter === data.chapter.number && audioStore.active && layout.playerStyle === 'standard'}
|
||||
<!-- Mini-player is already playing this chapter — don't duplicate controls (standard/minimal mode) -->
|
||||
<div class="px-4 py-3 flex items-center gap-2 text-sm text-(--color-muted)">
|
||||
<svg class="w-4 h-4 text-(--color-brand) shrink-0" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path d="M12 3v10.55A4 4 0 1014 17V7h4V3h-6z"/>
|
||||
</svg>
|
||||
<span>Controls are in the player bar below.</span>
|
||||
</div>
|
||||
{:else}
|
||||
<AudioPlayer
|
||||
slug={data.book.slug}
|
||||
chapter={data.chapter.number}
|
||||
chapterTitle={cleanTitle}
|
||||
bookTitle={data.book.title}
|
||||
cover={data.book.cover}
|
||||
nextChapter={data.next}
|
||||
chapters={data.chapters}
|
||||
voices={data.voices}
|
||||
playerStyle={layout.playerStyle}
|
||||
wordCount={wordCount}
|
||||
onProRequired={() => { audioProRequired = true; }}
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
@@ -1169,7 +1169,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'], ['float', 'Float']] as const) as [s, lbl]}
|
||||
{#each ([['standard', 'Standard'], ['minimal', 'Minimal'], ['float', 'Float']] as const) as [s, lbl]}
|
||||
<button
|
||||
type="button"
|
||||
onclick={() => setLayout('playerStyle', s)}
|
||||
@@ -1182,6 +1182,17 @@
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
<div class="px-3 pb-2.5">
|
||||
<p class="text-[11px] text-(--color-muted)/70 leading-snug">
|
||||
{#if layout.playerStyle === 'standard'}
|
||||
Full panel with voice picker and chapter browser.
|
||||
{:else if layout.playerStyle === 'minimal'}
|
||||
Compact bar: play/pause, seek, and time only.
|
||||
{:else}
|
||||
Draggable overlay — stays visible while you read.
|
||||
{/if}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Speed -->
|
||||
<div class="flex items-center gap-3 px-3 py-2.5">
|
||||
|
||||
Reference in New Issue
Block a user