From 05bfd110b89889cf0d8f35c1bfa36726f43f39ab Mon Sep 17 00:00:00 2001 From: Admin Date: Sat, 4 Apr 2026 20:35:15 +0500 Subject: [PATCH] refactor: replace floating settings panel with bottom sheet + Reading/Listening tabs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The old vertical dropdown was too tall on mobile — 14 stacked groups required heavy scrolling and had no visual hierarchy. New design: - Full-width bottom sheet slides from screen edge (natural mobile gesture) - Drag handle + dimmed backdrop for clarity - Two tabs split the settings: Reading (typography + layout) and Listening (player style, speed, auto-next, sleep timer) - Each row uses label-on-left + pill-group-on-right layout — saves one line per setting and makes the list scannable at a glance - Settings are grouped into titled cards (Typography, Layout, Player) with dividers between rows instead of floating individual blocks - Gear button moved to bottom-[4.5rem] to clear the mini-player bar --- .../books/[slug]/chapters/[n]/+page.svelte | 483 ++++++++++-------- 1 file changed, 261 insertions(+), 222 deletions(-) diff --git a/ui/src/routes/books/[slug]/chapters/[n]/+page.svelte b/ui/src/routes/books/[slug]/chapters/[n]/+page.svelte index af91f23..876337f 100644 --- a/ui/src/routes/books/[slug]/chapters/[n]/+page.svelte +++ b/ui/src/routes/books/[slug]/chapters/[n]/+page.svelte @@ -20,6 +20,7 @@ // ── Reader settings panel ──────────────────────────────────────────────── const settingsCtx = getContext<{ current: string; fontFamily: string; fontSize: number } | undefined>('theme'); let settingsPanelOpen = $state(false); + let settingsTab = $state<'reading' | 'listening'>('reading'); const READER_THEMES = [ { id: 'amber', label: 'Amber', swatch: '#f59e0b' }, @@ -591,22 +592,14 @@ {/if} - + {#if settingsCtx} - -{#if settingsPanelOpen} - -
(settingsPanelOpen = false)} - >
-{/if} - + - + {#if settingsPanelOpen} -
-

Reader Settings

+ + +
(settingsPanelOpen = false)}>
- -
-

Theme

-
- {#each READER_THEMES as t} +
+ + +
+
+
+ + +
+ + +
+ + +
+ + {#if settingsTab === 'reading'} + + +
+

Typography

+
+ + +
+ Theme +
+ {#each READER_THEMES as t} + + {/each} +
+
+ + +
+ Font +
+ {#each READER_FONTS as f} + + {/each} +
+
+ + +
+ Size +
+ {#each READER_SIZES as s} + + {/each} +
+
+ +
+
+ + +
+

Layout

+
+ + +
+ Mode +
+ {#each ([['scroll', 'Scroll'], ['paginated', 'Pages']] as const) as [mode, lbl]} + + {/each} +
+
+ + +
+ Spacing +
+ {#each ([['compact', 'Tight'], ['normal', 'Normal'], ['relaxed', 'Loose']] as const) as [s, lbl]} + + {/each} +
+
+ + +
+ Width +
+ {#each ([['narrow', 'Narrow'], ['normal', 'Normal'], ['wide', 'Wide']] as const) as [w, lbl]} + + {/each} +
+
+ + +
+ Paragraphs +
+ {#each ([['spaced', 'Spaced'], ['indented', 'Indented']] as const) as [s, lbl]} + + {/each} +
+
+ + - {/each} -
-
- -
-

Font

-
- {#each READER_FONTS as f} +
+
+ + {:else} + + +
+

Player

+
+ + +
+ Style +
+ {#each ([['standard', 'Standard'], ['compact', 'Compact']] as const) as [s, lbl]} + + {/each} +
+
+ + {#if page.data.user} + + +
+ Speed +
+ {#each [0.75, 1, 1.25, 1.5, 2] as s} + + {/each} +
+
+ + - {/each} -
-
- -
-

Text size

-
- {#each READER_SIZES as s} + - {/each} + + {/if} + +
+ + {/if} + +

Changes save automatically

+
- - -
- - -
-

Read mode

-
- {#each ([['scroll', 'Scroll'], ['paginated', 'Pages']] as const) as [mode, label]} - - {/each} -
-
- - -
-

Line spacing

-
- {#each ([['compact', 'Tight'], ['normal', 'Normal'], ['relaxed', 'Loose']] as const) as [s, label]} - - {/each} -
-
- - -
-

Width

-
- {#each ([['narrow', 'Narrow'], ['normal', 'Normal'], ['wide', 'Wide']] as const) as [w, label]} - - {/each} -
-
- - -
-

Paragraphs

-
- {#each ([['spaced', 'Spaced'], ['indented', 'Indented']] as const) as [s, label]} - - {/each} -
-
- - - - - -
-

Listening

- - -
-

Player style

-
- {#each ([['standard', 'Standard'], ['compact', 'Compact']] as const) as [s, label]} - - {/each} -
-
- - {#if page.data.user} - -
-

Speed

-
- {#each [0.75, 1, 1.25, 1.5, 2] as s} - - {/each} -
-
- - - - - - - {/if} - -

Changes save automatically

{/if} {/if}