{ if (e.target === e.currentTarget) close(); }} on:keydown={(e) => { if (e.key === "Escape") close(); }}>

Settings

{#each TABS as t} {/each}

{TABS.find((t) => t.id === tab)?.label}

{#if tab === "general"}

Interface Scale

updateSettings({ uiScale: Number(e.currentTarget.value) })} class="scale-slider" /> {$settings.uiScale}%

{#each [70,80,90,100,110,125,150] as v} {/each}

Server

Server URLBase URL of your Suwayomi instance
updateSettings({ serverUrl: e.currentTarget.value })} placeholder="http://localhost:4567" spellcheck="false" />
Server binaryPath or command to launch tachidesk-server
updateSettings({ serverBinary: e.currentTarget.value })} placeholder="tachidesk-server" spellcheck="false" />

Inactivity

Idle screen timeoutShow the Moku idle splash after this much inactivity.
{#if selectOpen === "idle-timeout"}
{#each [["0","Never"],["1","1 minute"],["2","2 minutes"],["5","5 minutes"],["10","10 minutes"],["15","15 minutes"],["30","30 minutes"]] as [v, l]} {/each}
{/if}
{:else if tab === "appearance"}

Theme

{#each THEMES as theme} {@const active = ($settings.theme ?? "dark") === theme.id} {/each}
{:else if tab === "reader"}

Page Layout

Default layoutHow chapters open by default
{#if selectOpen === "page-style"}
{#each [["single","Single page"],["longstrip","Long strip"]] as [v, l]} {/each}
{/if}
Reading directionLeft-to-right for most manga, right-to-left for Japanese
{#if selectOpen === "reading-dir"}
{#each [["ltr","Left to right"],["rtl","Right to left"]] as [v, l]} {/each}
{/if}

Fit & Zoom

Default fit modeHow pages are sized to fit the screen
{#if selectOpen === "fit-mode"}
{#each [["width","Fit width"],["height","Fit height"],["screen","Fit screen"],["original","Original (1:1)"]] as [v, l]} {/each}
{/if}
Max page widthPixel cap for fit-width mode.
{$settings.maxPageWidth ?? 900}px

Behaviour

{#if !($settings.autoNextChapter ?? false)} {/if}
Pages to preloadImages loaded ahead of the current page
{$settings.preloadPages}
{:else if tab === "library"}

Display

Chapters

Default sort direction
{#if selectOpen === "sort-dir"}
{#each [["desc","Newest first"],["asc","Oldest first"]] as [v, l]} {/each}
{/if}

History

Reading history{$history.length} entries stored
{:else if tab === "performance"}

Render Limit

Items per page Library and Search render this many items before showing a "Load more" button. Lower = faster scrolling on large libraries.
{$settings.renderLimit ?? 48}

{#each [12, 24, 48, 96, 200] as v} {/each}

Rendering

Idle / Splash Screen

Interface

Session Cache

Cache entries In-memory request cache for this session (library, sources, genre pages). Cleared on restart.
{perfSnapshot?.cacheEntries ?? 0} entries
{#if perfSnapshot && perfSnapshot.cacheEntries > 0}
Oldest entry
{fmtAge(perfSnapshot.oldestEntryMs)}
Newest entry
{fmtAge(perfSnapshot.newestEntryMs)}
Cached keys {perfSnapshot.cacheKeys.join(", ")}
{/if}
{:else if tab === "keybinds"}

Keyboard shortcuts

Click a key to rebind, then press the new combination.

{#each Object.keys(KEYBIND_LABELS) as key} {@const k = key as keyof Keybinds} {@const isListening = listeningKey === k} {@const isDefault = $settings.keybinds[k] === DEFAULT_KEYBINDS[k]}
{KEYBIND_LABELS[k]}
{/each}
{:else if tab === "storage"}

Disk Usage

{#if storageLoading}

Reading filesystem…

{:else if storageError}

{storageError}

{:else if storageInfo} {@const mangaBytes = storageInfo.manga_bytes} {@const totalBytes = storageInfo.total_bytes} {@const freeBytes = storageInfo.free_bytes} {@const limitGb = $settings.storageLimitGb ?? null} {@const limitBytes = limitGb !== null ? limitGb * 1024 ** 3 : null} {@const available = mangaBytes + freeBytes} {@const cap = limitBytes !== null ? Math.min(limitBytes, available) : available} {@const pctUsed = cap > 0 ? Math.min(100, (mangaBytes / cap) * 100) : 0}
90} class:warn={pctUsed > 75 && pctUsed <= 90} style="width:{pctUsed}%">
{fmtBytes(mangaBytes)} used {fmtBytes(Math.max(0, cap - mangaBytes))} free
Downloaded manga{fmtBytes(mangaBytes)}
Drive free{fmtBytes(freeBytes)}
Drive total{fmtBytes(totalBytes)}

{storageInfo.path}

{/if}

Cache

Image cacheCached page images stored by the webview

Storage Limit

Limit download storage {$settings.storageLimitGb === null ? "No limit — uses full drive capacity" : `Warn when downloads exceed ${$settings.storageLimitGb} GB`}
{#if $settings.storageLimitGb === null} {:else}
{ const n = parseFloat(e.currentTarget.value); if (!isNaN(n) && n > 0) updateSettings({ storageLimitGb: n }); }} /> GB
{/if}
{:else if tab === "folders"}

Manage Folders

Assign manga to folders from the series detail page.

e.key === "Enter" && createFolder()} style="flex:1;width:auto" />
{#if $settings.folders.length === 0}

No folders yet. Create one above.

{:else}
{#each $settings.folders as folder}
{#if editingId === folder.id} { if (e.key === "Enter") commitEdit(); if (e.key === "Escape") editingId = null; }} on:blur={commitEdit} style="flex:1;width:auto" use:focusInput /> {:else} {folder.name} {folder.mangaIds.length} manga {/if}
{/each}
{/if}
{:else if tab === "about"}

Moku

A manga reader frontend for Suwayomi / Tachidesk.

Built with Tauri + Svelte. Connects to tachidesk-server.

{:else if tab === "devtools"}

Splash Screen

Preview idle screenShow the idle splash — dismiss with any click or key

Build Info

Mode: {import.meta.env.MODE}

{/if}