Fix: Dropdown in Settings

This commit is contained in:
Youwes09
2026-04-20 11:35:41 -05:00
parent 044c93a790
commit e41e8011be
9 changed files with 122 additions and 60 deletions
@@ -1,12 +1,17 @@
<script lang="ts">
import { store, updateSettings } from "@store/state.svelte";
import { selectPortal } from "@core/actions/selectPortal";
interface Props {
selectOpen: string | null;
onToggleSelect: (id: string) => void;
closingSelect: string | null;
toggleSelect: (id: string) => void;
anims: boolean;
}
let { selectOpen, onToggleSelect }: Props = $props();
let { selectOpen, closingSelect, toggleSelect, anims }: Props = $props();
let triggerIdleTimeout: HTMLButtonElement;
</script>
<div class="s-panel">
@@ -54,15 +59,15 @@
<div class="s-section-body">
<div class="s-row">
<div class="s-row-info"><span class="s-label">Idle screen timeout</span><span class="s-desc">Show the Moku idle splash after this much inactivity</span></div>
<div class="s-select" id="idle-timeout">
<button class="s-select-btn" onclick={() => onToggleSelect("idle-timeout")}>
<div class="s-select">
<button bind:this={triggerIdleTimeout} class="s-select-btn" onclick={() => toggleSelect("idle-timeout")}>
<span>{{ "0":"Never","1":"1 minute","2":"2 minutes","5":"5 minutes","10":"10 minutes","15":"15 minutes","30":"30 minutes" }[String(store.settings.idleTimeoutMin ?? 5)] ?? `${store.settings.idleTimeoutMin} min`}</span>
<svg class="s-select-caret" class:open={selectOpen === "idle-timeout"} width="10" height="6" viewBox="0 0 10 6"><path d="M0 0l5 6 5-6" fill="currentColor"/></svg>
</button>
{#if selectOpen === "idle-timeout"}
<div class="s-select-menu">
{#if selectOpen === "idle-timeout" || closingSelect === "idle-timeout"}
<div class="s-select-menu" class:anims class:closing={closingSelect === "idle-timeout"} {@attach selectPortal(triggerIdleTimeout)}>
{#each [["0","Never"],["1","1 minute"],["2","2 minutes"],["5","5 minutes"],["10","10 minutes"],["15","15 minutes"],["30","30 minutes"]] as [v, l]}
<button class="s-select-option" class:active={String(store.settings.idleTimeoutMin ?? 5) === v} onclick={() => { updateSettings({ idleTimeoutMin: Number(v) }); onToggleSelect("idle-timeout"); }}>{l}</button>
<button class="s-select-option" class:active={String(store.settings.idleTimeoutMin ?? 5) === v} onclick={() => { updateSettings({ idleTimeoutMin: Number(v) }); toggleSelect("idle-timeout"); }}>{l}</button>
{/each}
</div>
{/if}
@@ -1,13 +1,17 @@
<script lang="ts">
import { store, updateSettings, clearHistory, wipeAllData } from "@store/state.svelte";
import type { Settings } from "@types/settings";
import { selectPortal } from "@core/actions/selectPortal";
interface Props {
selectOpen: string | null;
onToggleSelect: (id: string) => void;
toggleSelect: (id: string) => void;
anims: boolean;
}
let { selectOpen, onToggleSelect }: Props = $props();
let { selectOpen, toggleSelect, anims }: Props = $props();
let triggerSortDir: HTMLButtonElement;
</script>
<div class="s-panel">
@@ -31,15 +35,15 @@
<div class="s-section-body">
<div class="s-row">
<div class="s-row-info"><span class="s-label">Default sort direction</span><span class="s-desc">Initial chapter list order when opening a manga</span></div>
<div class="s-select" id="sort-dir">
<button class="s-select-btn" onclick={() => onToggleSelect("sort-dir")}>
<div class="s-select">
<button bind:this={triggerSortDir} class="s-select-btn" onclick={() => toggleSelect("sort-dir")}>
<span>{{ "desc":"Newest first","asc":"Oldest first" }[store.settings.chapterSortDir]}</span>
<svg class="s-select-caret" class:open={selectOpen === "sort-dir"} width="10" height="6" viewBox="0 0 10 6"><path d="M0 0l5 6 5-6" fill="currentColor"/></svg>
</button>
{#if selectOpen === "sort-dir"}
<div class="s-select-menu">
<div class="s-select-menu" class:anims {@attach selectPortal(triggerSortDir)}>
{#each [["desc","Newest first"],["asc","Oldest first"]] as [v, l]}
<button class="s-select-option" class:active={store.settings.chapterSortDir === v} onclick={() => { updateSettings({ chapterSortDir: v as Settings["chapterSortDir"] }); onToggleSelect("sort-dir"); }}>{l}</button>
<button class="s-select-option" class:active={store.settings.chapterSortDir === v} onclick={() => { updateSettings({ chapterSortDir: v as Settings["chapterSortDir"] }); toggleSelect("sort-dir"); }}>{l}</button>
{/each}
</div>
{/if}
@@ -1,13 +1,19 @@
<script lang="ts">
import { store, updateSettings } from "@store/state.svelte";
import type { Settings, FitMode } from "@types/settings";
import { selectPortal } from "@core/actions/selectPortal";
interface Props {
selectOpen: string | null;
onToggleSelect: (id: string) => void;
toggleSelect: (id: string) => void;
anims: boolean;
}
let { selectOpen, onToggleSelect }: Props = $props();
let { selectOpen, toggleSelect, anims }: Props = $props();
let triggerPageStyle: HTMLButtonElement;
let triggerReadingDir: HTMLButtonElement;
let triggerFitMode: HTMLButtonElement;
</script>
<div class="s-panel">
@@ -17,15 +23,15 @@
<div class="s-section-body">
<div class="s-row">
<div class="s-row-info"><span class="s-label">Default layout</span><span class="s-desc">How chapters open by default</span></div>
<div class="s-select" id="page-style">
<button class="s-select-btn" onclick={() => onToggleSelect("page-style")}>
<div class="s-select">
<button bind:this={triggerPageStyle} class="s-select-btn" onclick={() => toggleSelect("page-style")}>
<span>{{ "single":"Single page","longstrip":"Long strip" }[store.settings.pageStyle === "double" ? "single" : store.settings.pageStyle]}</span>
<svg class="s-select-caret" class:open={selectOpen === "page-style"} width="10" height="6" viewBox="0 0 10 6"><path d="M0 0l5 6 5-6" fill="currentColor"/></svg>
</button>
{#if selectOpen === "page-style"}
<div class="s-select-menu">
<div class="s-select-menu" class:anims {@attach selectPortal(triggerPageStyle)}>
{#each [["single","Single page"],["longstrip","Long strip"]] as [v, l]}
<button class="s-select-option" class:active={(store.settings.pageStyle === "double" ? "single" : store.settings.pageStyle) === v} onclick={() => { updateSettings({ pageStyle: v as Settings["pageStyle"] }); onToggleSelect("page-style"); }}>{l}</button>
<button class="s-select-option" class:active={(store.settings.pageStyle === "double" ? "single" : store.settings.pageStyle) === v} onclick={() => { updateSettings({ pageStyle: v as Settings["pageStyle"] }); toggleSelect("page-style"); }}>{l}</button>
{/each}
</div>
{/if}
@@ -33,15 +39,15 @@
</div>
<div class="s-row">
<div class="s-row-info"><span class="s-label">Reading direction</span><span class="s-desc">Left-to-right for most manga, right-to-left for Japanese</span></div>
<div class="s-select" id="reading-dir">
<button class="s-select-btn" onclick={() => onToggleSelect("reading-dir")}>
<div class="s-select">
<button bind:this={triggerReadingDir} class="s-select-btn" onclick={() => toggleSelect("reading-dir")}>
<span>{{ "ltr":"Left to right","rtl":"Right to left" }[store.settings.readingDirection]}</span>
<svg class="s-select-caret" class:open={selectOpen === "reading-dir"} width="10" height="6" viewBox="0 0 10 6"><path d="M0 0l5 6 5-6" fill="currentColor"/></svg>
</button>
{#if selectOpen === "reading-dir"}
<div class="s-select-menu">
<div class="s-select-menu" class:anims {@attach selectPortal(triggerReadingDir)}>
{#each [["ltr","Left to right"],["rtl","Right to left"]] as [v, l]}
<button class="s-select-option" class:active={store.settings.readingDirection === v} onclick={() => { updateSettings({ readingDirection: v as Settings["readingDirection"] }); onToggleSelect("reading-dir"); }}>{l}</button>
<button class="s-select-option" class:active={store.settings.readingDirection === v} onclick={() => { updateSettings({ readingDirection: v as Settings["readingDirection"] }); toggleSelect("reading-dir"); }}>{l}</button>
{/each}
</div>
{/if}
@@ -67,15 +73,15 @@
<div class="s-section-body">
<div class="s-row">
<div class="s-row-info"><span class="s-label">Default fit mode</span><span class="s-desc">How pages are scaled to fill the reader on open</span></div>
<div class="s-select" id="fit-mode">
<button class="s-select-btn" onclick={() => onToggleSelect("fit-mode")}>
<div class="s-select">
<button bind:this={triggerFitMode} class="s-select-btn" onclick={() => toggleSelect("fit-mode")}>
<span>{{ "width":"Fit width","height":"Fit height","screen":"Fit screen","original":"Original (1:1)" }[store.settings.fitMode ?? "width"]}</span>
<svg class="s-select-caret" class:open={selectOpen === "fit-mode"} width="10" height="6" viewBox="0 0 10 6"><path d="M0 0l5 6 5-6" fill="currentColor"/></svg>
</button>
{#if selectOpen === "fit-mode"}
<div class="s-select-menu">
<div class="s-select-menu" class:anims {@attach selectPortal(triggerFitMode)}>
{#each [["width","Fit width"],["height","Fit height"],["screen","Fit screen"],["original","Original (1:1)"]] as [v, l]}
<button class="s-select-option" class:active={(store.settings.fitMode ?? "width") === v} onclick={() => { updateSettings({ fitMode: v as FitMode }); onToggleSelect("fit-mode"); }}>{l}</button>
<button class="s-select-option" class:active={(store.settings.fitMode ?? "width") === v} onclick={() => { updateSettings({ fitMode: v as FitMode }); toggleSelect("fit-mode"); }}>{l}</button>
{/each}
</div>
{/if}