feat(zitare): expand settings with display options

Add toggle switches for show/hide category and source, and a font
size selector (small/normal/large/extra large). Settings are persisted
via the existing settings store and applied to QuoteCard and home page.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Till JS 2026-03-26 20:28:22 +01:00
parent 5bb96dbf2d
commit 6107d572a1
5 changed files with 120 additions and 1 deletions

View file

@ -5,6 +5,7 @@
import { authStore } from '$lib/stores/auth.svelte';
import { ZitareEvents } from '@manacore/shared-utils/analytics';
import { toast } from '$lib/stores/toast.svelte';
import { zitareSettings } from '$lib/stores/settings.svelte';
import { _ } from 'svelte-i18n';
interface Props {
@ -84,6 +85,9 @@
<div
class="quote-card rounded-2xl bg-surface-elevated shadow-lg overflow-hidden {sizeClasses[size]}"
style="font-size: {zitareSettings.fontSizeMultiplier !== 1
? `${zitareSettings.fontSizeMultiplier}em`
: ''}"
>
{#if showCategory}
<div class="mb-4">

View file

@ -115,6 +115,16 @@
"settings": {
"quoteLanguage": "Zitat-Sprache",
"quoteLanguageDescription": "Wähle die Sprache, in der die Zitate angezeigt werden sollen.",
"display": "Anzeige",
"showCategory": "Kategorie anzeigen",
"showCategoryDescription": "Zeigt die Kategorie-Badge auf Zitat-Karten",
"showSource": "Quelle anzeigen",
"showSourceDescription": "Zeigt Quelle und Jahr unter dem Zitat",
"fontSize": "Schriftgröße",
"fontSizeSmall": "Klein",
"fontSizeNormal": "Normal",
"fontSizeLarge": "Groß",
"fontSizeXLarge": "Sehr groß",
"about": "Über Zitare",
"aboutDescription": "Zitare bietet dir täglich inspirierende Zitate von den größten Denkern der Geschichte. Speichere deine Favoriten und erstelle eigene Listen.",
"stats": "{quotes} Zitate · {categories} Kategorien · {languages} Sprachen"

View file

@ -115,6 +115,16 @@
"settings": {
"quoteLanguage": "Quote language",
"quoteLanguageDescription": "Choose the language in which quotes are displayed.",
"display": "Display",
"showCategory": "Show category",
"showCategoryDescription": "Shows the category badge on quote cards",
"showSource": "Show source",
"showSourceDescription": "Shows source and year below the quote",
"fontSize": "Font size",
"fontSizeSmall": "Small",
"fontSizeNormal": "Normal",
"fontSizeLarge": "Large",
"fontSizeXLarge": "Extra large",
"about": "About Zitare",
"aboutDescription": "Zitare offers you daily inspiring quotes from the greatest thinkers in history. Save your favorites and create your own lists.",
"stats": "{quotes} quotes · {categories} categories · {languages} languages"

View file

@ -1,6 +1,7 @@
<script lang="ts">
import { _ } from 'svelte-i18n';
import { quotesStore } from '$lib/stores/quotes.svelte';
import { zitareSettings } from '$lib/stores/settings.svelte';
import { ZitareEvents } from '@manacore/shared-utils/analytics';
import QuoteCard from '$lib/components/QuoteCard.svelte';
@ -30,7 +31,12 @@
<!-- Daily Quote Card -->
{#if quotesStore.currentQuote}
<div class="mb-8 transition-all duration-300 {isRefreshing ? 'opacity-50 scale-95' : ''}">
<QuoteCard quote={quotesStore.currentQuote} size="large" showCategory showSource />
<QuoteCard
quote={quotesStore.currentQuote}
size="large"
showCategory={zitareSettings.showCategory}
showSource={zitareSettings.showSource}
/>
</div>
{/if}

View file

@ -1,6 +1,7 @@
<script lang="ts">
import { _ } from 'svelte-i18n';
import { quotesStore } from '$lib/stores/quotes.svelte';
import { zitareSettings } from '$lib/stores/settings.svelte';
import { ZitareEvents } from '@manacore/shared-utils/analytics';
import type { SupportedLanguage } from '@zitare/content';
import { APP_VERSION } from '$lib/version';
@ -15,12 +16,32 @@
{ value: 'original', label: 'Original' },
];
const fontSizeOptions = [
{ value: 0.85, label: 'settings.fontSizeSmall' },
{ value: 1, label: 'settings.fontSizeNormal' },
{ value: 1.15, label: 'settings.fontSizeLarge' },
{ value: 1.3, label: 'settings.fontSizeXLarge' },
];
function handleLanguageChange(event: Event) {
const select = event.target as HTMLSelectElement;
const lang = select.value as SupportedLanguage;
quotesStore.setLanguage(lang);
ZitareEvents.quoteLanguageChanged(lang);
}
function handleFontSizeChange(event: Event) {
const select = event.target as HTMLSelectElement;
zitareSettings.update({ fontSizeMultiplier: parseFloat(select.value) });
}
function toggleShowCategory() {
zitareSettings.update({ showCategory: !zitareSettings.showCategory });
}
function toggleShowSource() {
zitareSettings.update({ showSource: !zitareSettings.showSource });
}
</script>
<svelte:head>
@ -48,6 +69,74 @@
</select>
</div>
<!-- Display Settings -->
<div class="bg-surface-elevated rounded-2xl p-6">
<h2 class="text-lg font-semibold text-foreground mb-4">{$_('settings.display')}</h2>
<div class="space-y-4">
<!-- Show Category -->
<label class="flex items-center justify-between cursor-pointer">
<div>
<p class="text-foreground font-medium">{$_('settings.showCategory')}</p>
<p class="text-foreground-secondary text-sm">
{$_('settings.showCategoryDescription')}
</p>
</div>
<button
onclick={toggleShowCategory}
class="relative w-11 h-6 rounded-full transition-colors {zitareSettings.showCategory
? 'bg-primary'
: 'bg-border'}"
role="switch"
aria-checked={zitareSettings.showCategory}
>
<span
class="absolute top-0.5 left-0.5 w-5 h-5 bg-white rounded-full shadow transition-transform {zitareSettings.showCategory
? 'translate-x-5'
: ''}"
></span>
</button>
</label>
<!-- Show Source -->
<label class="flex items-center justify-between cursor-pointer">
<div>
<p class="text-foreground font-medium">{$_('settings.showSource')}</p>
<p class="text-foreground-secondary text-sm">
{$_('settings.showSourceDescription')}
</p>
</div>
<button
onclick={toggleShowSource}
class="relative w-11 h-6 rounded-full transition-colors {zitareSettings.showSource
? 'bg-primary'
: 'bg-border'}"
role="switch"
aria-checked={zitareSettings.showSource}
>
<span
class="absolute top-0.5 left-0.5 w-5 h-5 bg-white rounded-full shadow transition-transform {zitareSettings.showSource
? 'translate-x-5'
: ''}"
></span>
</button>
</label>
<!-- Font Size -->
<div>
<p class="text-foreground font-medium mb-2">{$_('settings.fontSize')}</p>
<select
value={zitareSettings.fontSizeMultiplier}
onchange={handleFontSizeChange}
class="w-full p-3 rounded-lg bg-surface border border-border text-foreground"
>
{#each fontSizeOptions as option}
<option value={option.value}>{$_(option.label)}</option>
{/each}
</select>
</div>
</div>
</div>
<!-- About -->
<div class="bg-surface-elevated rounded-2xl p-6">
<h2 class="text-lg font-semibold text-foreground mb-4">{$_('settings.about')}</h2>