summaryrefslogtreecommitdiffstatshomepage
path: root/frontend/src/lib/reader
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/src/lib/reader')
-rw-r--r--frontend/src/lib/reader/PageView.svelte15
-rw-r--r--frontend/src/lib/reader/Reader.svelte24
-rw-r--r--frontend/src/lib/reader/components/ReaderMenuButton.svelte2
-rw-r--r--frontend/src/lib/reader/components/ToggleFullscreenButton.svelte34
4 files changed, 64 insertions, 11 deletions
diff --git a/frontend/src/lib/reader/PageView.svelte b/frontend/src/lib/reader/PageView.svelte
index 50c0873..2b61a78 100644
--- a/frontend/src/lib/reader/PageView.svelte
+++ b/frontend/src/lib/reader/PageView.svelte
@@ -102,13 +102,14 @@
{@render pagesIn(currentChunk)}
</SliderMargin>
<div class:reverse class="flex w-full bg-gray-400/60 backdrop-blur-2xl">
+ <!-- eslint-disable-next-line svelte/require-each-key -->
{#each chunks as chunk, index}
<button
type="button"
class:read={index <= lookup[reader.page]}
- class="group/page relative grow [&.read]:bg-blue-600/60"
+ class="group/page relative grow"
onclick={() => reader.open(chunk.index)}
- aria-label={`Open page ${chunk.index}`}
+ aria-label={`Open page ${chunk.index + 1}`}
>
<SliderTooltip>
{@render pagesIn(chunk)}
@@ -123,13 +124,19 @@
</div>
<div class="invisible absolute">
- {#each pagesAround(reader.page) as page}
+ {#each pagesAround(reader.page) as page (page.id)}
<img src={src(page.image, 'full')} alt="" />
{/each}
</div>
-<style>
+<style lang="postcss">
+ @reference "tailwindcss/theme";
+
.reverse {
flex-direction: row-reverse;
}
+
+ button.read {
+ @apply bg-blue-600/60;
+ }
</style>
diff --git a/frontend/src/lib/reader/Reader.svelte b/frontend/src/lib/reader/Reader.svelte
index 2e7e851..a720a77 100644
--- a/frontend/src/lib/reader/Reader.svelte
+++ b/frontend/src/lib/reader/Reader.svelte
@@ -6,10 +6,13 @@
import { fade, slide } from 'svelte/transition';
import CloseReaderButton from './components/CloseReaderButton.svelte';
import ReaderMenuButton from './components/ReaderMenuButton.svelte';
+ import ToggleFullscreenButton from './components/ToggleFullscreenButton.svelte';
let { sidebar, children }: { sidebar?: Snippet; children?: Snippet } = $props();
const reader = getReaderContext();
+
+ let dialog: HTMLDivElement | undefined = $state();
</script>
{#if reader.visible}
@@ -18,20 +21,29 @@
class="fixed top-0 right-0 bottom-0 left-0 z-10 flex h-full w-full bg-black"
transition:fade={fadeDefault}
use:trapFocus
+ bind:this={dialog}
>
{#if sidebar && reader.sidebar}
- <aside class="w-[36rem] shrink-0 bg-slate-800" transition:slide={slideXDefault}>
+ <aside
+ class="z-10 w-[36rem] shrink-0 bg-slate-800 shadow-md shadow-slate-800"
+ transition:slide={slideXDefault}
+ >
<div class="flex h-full min-w-[36rem] flex-col gap-4 overflow-auto p-4">
{@render sidebar?.()}
</div>
</aside>
{/if}
<main class="relative flex grow">
- <div class="absolute flex w-full p-1 text-lg [&>*:last-child]:ml-auto">
- {#if sidebar}
- <ReaderMenuButton />
- {/if}
- <CloseReaderButton />
+ <div class="absolute flex w-full p-1 text-lg">
+ <div class="flex flex-col gap-1">
+ {#if sidebar}
+ <ReaderMenuButton />
+ {/if}
+ </div>
+ <div class="ml-auto flex flex-col gap-1">
+ <CloseReaderButton />
+ <ToggleFullscreenButton {dialog} />
+ </div>
</div>
{@render children?.()}
diff --git a/frontend/src/lib/reader/components/ReaderMenuButton.svelte b/frontend/src/lib/reader/components/ReaderMenuButton.svelte
index da494e3..924342f 100644
--- a/frontend/src/lib/reader/components/ReaderMenuButton.svelte
+++ b/frontend/src/lib/reader/components/ReaderMenuButton.svelte
@@ -9,7 +9,7 @@
<button
type="button"
- class="btn-transparent invisible xl:visible"
+ class="btn-transparent hidden xl:flex"
{title}
aria-label={title}
onclick={() => (reader.sidebar = !reader.sidebar)}
diff --git a/frontend/src/lib/reader/components/ToggleFullscreenButton.svelte b/frontend/src/lib/reader/components/ToggleFullscreenButton.svelte
new file mode 100644
index 0000000..9ad4ce6
--- /dev/null
+++ b/frontend/src/lib/reader/components/ToggleFullscreenButton.svelte
@@ -0,0 +1,34 @@
+<script lang="ts">
+ import { accelerator } from '$lib/Shortcuts';
+ import { toastFinally } from '$lib/Toasts';
+
+ let { dialog }: { dialog?: HTMLElement } = $props();
+
+ function onclick() {
+ if (isFullscreen) {
+ document.exitFullscreen().catch(toastFinally);
+ } else if (dialog?.requestFullscreen) {
+ dialog.requestFullscreen().catch(toastFinally);
+ }
+ }
+
+ let fullscreenElement: HTMLElement | null = $state(null);
+ let isFullscreen = $derived(fullscreenElement !== null);
+</script>
+
+<svelte:document bind:fullscreenElement />
+
+<button
+ type="button"
+ class="btn-transparent"
+ title="Toggle fullscreen"
+ aria-label="Toggle fullscreen"
+ {onclick}
+ use:accelerator={'f'}
+>
+ {#if isFullscreen}
+ <span class="icon-lg icon-[material-symbols--fullscreen-exit]"></span>
+ {:else}
+ <span class="icon-lg icon-[material-symbols--fullscreen]"></span>
+ {/if}
+</button>