diff --git a/ui/src/routes/profile/+page.svelte b/ui/src/routes/profile/+page.svelte index 8fc6add..7a24cf4 100644 --- a/ui/src/routes/profile/+page.svelte +++ b/ui/src/routes/profile/+page.svelte @@ -192,7 +192,6 @@ function markSaved() { saveStatus = 'saving'; clearTimeout(savedTimer); - // Give a tick for layout's effect to fire, then show ✓ Saved savedTimer = setTimeout(() => { saveStatus = 'saved'; savedTimer = setTimeout(() => (saveStatus = 'idle'), 2000) as unknown as number; @@ -218,11 +217,10 @@ } if (!initialized) { initialized = true; return; } - void v; void sp; void an; void ac; void am; // keep subscriptions live + void v; void sp; void an; void ac; void am; markSaved(); }); - // Keep theme/font writes flowing into layout context when changed from selectors $effect(() => { if (settingsCtx) settingsCtx.current = selectedTheme; }); $effect(() => { if (settingsCtx) settingsCtx.fontFamily = selectedFontFamily; }); $effect(() => { if (settingsCtx) settingsCtx.fontSize = selectedFontSize; }); @@ -283,7 +281,6 @@ deleteError = body.message ?? `Delete failed (${res.status}). Please try again.`; return; } - // Server deleted account — submit logout form to clear session cookie const logoutForm = document.getElementById('logout-form') as HTMLFormElement | null; if (logoutForm) logoutForm.submit(); } catch { @@ -331,12 +328,9 @@ {#if justSubscribed} -
- -
-

Welcome to Pro!

-

Your subscription is being activated. Refresh the page in a moment if the Pro badge doesn't appear yet.

-
+
+

Welcome to Pro!

+

Your subscription is being activated. Refresh the page in a moment if the Pro badge doesn't appear yet.

{/if} @@ -353,9 +347,9 @@ Profile {:else}
- - - + + {data.user.username.slice(0, 1).toUpperCase()} +
{/if}
@@ -365,10 +359,7 @@ {:else} - - - - + Edit {/if}
@@ -380,8 +371,7 @@
{data.user.role} {#if data.isPro} - - + {m.profile_plan_pro()} {/if} @@ -440,8 +430,6 @@ class="inline-flex items-center gap-2 px-4 py-2 rounded-lg bg-(--color-brand) text-(--color-surface) font-semibold text-sm hover:bg-(--color-brand-dim) transition-colors disabled:opacity-60 disabled:cursor-wait"> {#if checkoutLoading === 'monthly'} - {:else} - {/if} {m.profile_upgrade_monthly()} @@ -467,9 +455,8 @@

{m.profile_pro_perks()}

- {m.profile_manage_subscription()} - + class="shrink-0 text-sm font-medium text-(--color-brand) hover:underline"> + {m.profile_manage_subscription()} → {/if} @@ -562,7 +549,7 @@
- +

{m.profile_tts_voice()}

{#if !voicesLoaded} @@ -574,7 +561,6 @@ {:else if voices.length === 0}

No voices available.

{:else} - {#each [ { label: 'Kokoro (GPU)', voices: kokoroVoices }, { label: 'Pocket TTS (CPU)', voices: pocketVoices }, @@ -586,7 +572,6 @@ {#each group.voices as v (v.id)} {@const isSelected = audioStore.voice === v.id} {@const isPlaying = samplePlayingVoice === v.id} -
{ audioStore.voice = v.id; }} onkeydown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); audioStore.voice = v.id; } }} class={cn( - 'flex items-center justify-between gap-2 px-3 py-2 rounded-lg border text-sm transition-colors cursor-pointer select-none', + 'flex items-center justify-between gap-2 px-3 py-2.5 rounded-lg border text-sm transition-colors cursor-pointer select-none', isSelected ? 'border-(--color-brand) bg-(--color-brand)/10 text-(--color-brand)' : 'border-(--color-border) bg-(--color-surface-3) text-(--color-text) hover:border-(--color-brand)/40' )} > -
- {#if isSelected} - - - - {:else} - - {/if} - {voiceLabel(v)} -
- + {voiceLabel(v)}
{/each} @@ -654,15 +621,15 @@
- -
+ +

Playback

-
+

{m.profile_auto_advance()}

-

Automatically load the next chapter when audio finishes

+

Load the next chapter automatically when audio ends

- - - + {deleteConfirmOpen ? 'Close' : 'Open'} {#if deleteConfirmOpen} @@ -851,9 +808,6 @@ Deleting… {:else} - - - Delete my account {/if} @@ -871,10 +825,10 @@

Reading Overview

{#each [ - { label: 'Chapters Read', value: data.stats.totalChaptersRead, icon: '📖' }, - { label: 'Completed', value: data.stats.booksCompleted, icon: '✅' }, - { label: 'Reading', value: data.stats.booksReading, icon: '📚' }, - { label: 'Plan to Read', value: data.stats.booksPlanToRead, icon: '🔖' }, + { label: 'Chapters Read', value: data.stats.totalChaptersRead }, + { label: 'Completed', value: data.stats.booksCompleted }, + { label: 'Reading', value: data.stats.booksReading }, + { label: 'Plan to Read', value: data.stats.booksPlanToRead }, ] as stat}

{stat.value}

@@ -888,21 +842,15 @@

Activity

-
-
🔥
-
-

{data.stats.streak}

-

day streak

-
+
+

{data.stats.streak}

+

day streak

-
-
-
-

- {data.stats.avgRatingGiven > 0 ? data.stats.avgRatingGiven.toFixed(1) : '—'} -

-

avg rating given

-
+
+

+ {data.stats.avgRatingGiven > 0 ? data.stats.avgRatingGiven.toFixed(1) : '—'} +

+

avg rating given

@@ -914,12 +862,11 @@
{#each data.stats.topGenres as genre, i} - {#if i === 0}🏆{/if} {genre} {/each} @@ -940,10 +887,7 @@ {#if activeTab === 'history'}
{#if data.history.length === 0} -
- - - +

No reading history yet.

{:else} @@ -956,11 +900,7 @@ {#if item.cover} {item.title} {:else} -
- - - -
+
{/if}