summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorWolfgang Müller2025-02-18 15:51:14 +0100
committerWolfgang Müller2025-02-18 15:51:14 +0100
commit3f6bd71aaac4277d046485fe8ea2a791ea089cd8 (patch)
treeb07f2bd3096695cf94c7c0b341e4dae150673a6b
parentc70a78623a7fe2db2af1efb6a9896097f59855fc (diff)
downloadhircine-3f6bd71aaac4277d046485fe8ea2a791ea089cd8.tar.gz
frontend: Migrate PageView to Svelte 5
-rw-r--r--frontend/src/lib/Reader.svelte.ts59
-rw-r--r--frontend/src/lib/reader/PageView.svelte19
-rw-r--r--frontend/src/lib/reader/Reader.svelte73
-rw-r--r--frontend/src/lib/reader/components/CloseReaderButton.svelte2
-rw-r--r--frontend/src/lib/reader/components/PageIndicator.svelte2
-rw-r--r--frontend/src/lib/reader/components/ReaderMenuButton.svelte2
-rw-r--r--frontend/src/routes/archives/[id]/+page.svelte3
-rw-r--r--frontend/src/routes/comics/[id]/+page.svelte3
-rw-r--r--frontend/tests/Reader.test.ts2
9 files changed, 78 insertions, 87 deletions
diff --git a/frontend/src/lib/Reader.svelte.ts b/frontend/src/lib/Reader.svelte.ts
new file mode 100644
index 0000000..f5a5322
--- /dev/null
+++ b/frontend/src/lib/Reader.svelte.ts
@@ -0,0 +1,59 @@
+import { Layout, type PageFragment } from '$gql/graphql';
+import { getContext, setContext } from 'svelte';
+
+export interface Chunk {
+ main: PageFragment;
+ secondary?: PageFragment;
+ index: number;
+}
+
+class ReaderContext {
+ visible = $state(false);
+ sidebar = $state(false);
+ pages: PageFragment[] = $state([]);
+ page = $state(0);
+
+ open = (page: number) => {
+ this.page = page;
+ this.visible = true;
+ };
+}
+
+export function initReaderContext() {
+ return setContext<ReaderContext>('reader', new ReaderContext());
+}
+
+export function getReaderContext() {
+ return getContext<ReaderContext>('reader');
+}
+
+export function partition(pages: PageFragment[], layout: Layout): [Chunk[], number[]] {
+ const single = layout === Layout.Single;
+ const offset = layout === Layout.DoubleOffset;
+
+ const chunks: Chunk[] = [];
+ const lookup: number[] = Array<number>(pages.length);
+
+ for (let chunkIndex = 0, pageIndex = 0; pageIndex < pages.length; chunkIndex++) {
+ const wide = () => pages[pageIndex].image.aspectRatio > 1;
+
+ const nextPage = () => {
+ lookup[pageIndex] = chunkIndex;
+ return pages[pageIndex++];
+ };
+
+ const offsetFirst = pageIndex === 0 && offset;
+ const full = single || wide() || offsetFirst;
+
+ const chunk: Chunk = { index: pageIndex, main: nextPage() };
+
+ if (!full && pageIndex < pages.length) {
+ if (!wide()) {
+ chunk.secondary = nextPage();
+ }
+ }
+
+ chunks.push(chunk);
+ }
+ return [chunks, lookup];
+}
diff --git a/frontend/src/lib/reader/PageView.svelte b/frontend/src/lib/reader/PageView.svelte
index fc45cfa..2f8def7 100644
--- a/frontend/src/lib/reader/PageView.svelte
+++ b/frontend/src/lib/reader/PageView.svelte
@@ -1,20 +1,14 @@
<script lang="ts">
import { Direction, Layout, type PageFragment } from '$gql/graphql';
+ import { getReaderContext, partition } from '$lib/Reader.svelte';
import { binds } from '$lib/Shortcuts';
import { src } from '$lib/Utils';
- import { getReaderContext, partition, type Chunk } from './Reader.svelte';
+ import PageIndicator from './components/PageIndicator.svelte';
import ReaderPage from './ReaderPage.svelte';
const reader = getReaderContext();
- export let direction: Direction;
- export let layout: Layout;
-
- let chunks: Chunk[] = [];
- let lookup: number[] = [];
-
- let main: PageFragment;
- let secondary: PageFragment | undefined;
+ let { direction, layout }: { direction: Direction; layout: Layout } = $props();
function gotoChunk(to: number) {
if (to < 0 || to >= chunks.length) return;
@@ -61,8 +55,8 @@
}
}
- $: [chunks, lookup] = partition(reader.pages, layout);
- $: layout, ({ main, secondary } = chunks[lookup[reader.page]]);
+ let [chunks, lookup] = $derived(partition(reader.pages, layout));
+ let { main, secondary } = $derived(chunks[lookup[reader.page]]);
</script>
<svelte:document
@@ -89,6 +83,9 @@
<ReaderPage page={secondary} onclick={next} --justify="flex-end" />
<ReaderPage page={main} onclick={prev} --justify="flex-start" />
{/if}
+<div class="absolute right-0 bottom-0 z-10 flex p-1 text-lg">
+ <PageIndicator />
+</div>
<div class="invisible absolute">
{#each pagesAround(reader.page) as page}
<img src={src(page.image, 'full')} alt="" />
diff --git a/frontend/src/lib/reader/Reader.svelte b/frontend/src/lib/reader/Reader.svelte
index b5cc725..2e7e851 100644
--- a/frontend/src/lib/reader/Reader.svelte
+++ b/frontend/src/lib/reader/Reader.svelte
@@ -1,72 +1,10 @@
-<script lang="ts" module>
- import { Layout, type PageFragment } from '$gql/graphql';
- import { getContext, setContext } from 'svelte';
-
- export interface Chunk {
- main: PageFragment;
- secondary?: PageFragment;
- index: number;
- }
-
- class ReaderContext {
- visible = $state(false);
- sidebar = $state(false);
- pages: PageFragment[] = $state([]);
- page = $state(0);
-
- open = (page: number) => {
- this.page = page;
- this.visible = true;
- };
- }
-
- export function initReaderContext() {
- return setContext<ReaderContext>('reader', new ReaderContext());
- }
-
- export function getReaderContext() {
- return getContext<ReaderContext>('reader');
- }
-
- export function partition(pages: PageFragment[], layout: Layout): [Chunk[], number[]] {
- const single = layout === Layout.Single;
- const offset = layout === Layout.DoubleOffset;
-
- const chunks: Chunk[] = [];
- const lookup: number[] = Array<number>(pages.length);
-
- for (let chunkIndex = 0, pageIndex = 0; pageIndex < pages.length; chunkIndex++) {
- const wide = () => pages[pageIndex].image.aspectRatio > 1;
-
- const nextPage = () => {
- lookup[pageIndex] = chunkIndex;
- return pages[pageIndex++];
- };
-
- const offsetFirst = pageIndex === 0 && offset;
- const full = single || wide() || offsetFirst;
-
- const chunk: Chunk = { index: pageIndex, main: nextPage() };
-
- if (!full && pageIndex < pages.length) {
- if (!wide()) {
- chunk.secondary = nextPage();
- }
- }
-
- chunks.push(chunk);
- }
- return [chunks, lookup];
- }
-</script>
-
<script lang="ts">
import { trapFocus } from '$lib/Actions';
+ import { getReaderContext } from '$lib/Reader.svelte';
import { fadeDefault, slideXDefault } from '$lib/Transitions';
import type { Snippet } from 'svelte';
import { fade, slide } from 'svelte/transition';
import CloseReaderButton from './components/CloseReaderButton.svelte';
- import PageIndicator from './components/PageIndicator.svelte';
import ReaderMenuButton from './components/ReaderMenuButton.svelte';
let { sidebar, children }: { sidebar?: Snippet; children?: Snippet } = $props();
@@ -77,7 +15,7 @@
{#if reader.visible}
<div
role="dialog"
- class="fixed bottom-0 left-0 right-0 top-0 z-10 flex h-full w-full bg-black"
+ class="fixed top-0 right-0 bottom-0 left-0 z-10 flex h-full w-full bg-black"
transition:fade={fadeDefault}
use:trapFocus
>
@@ -95,13 +33,8 @@
{/if}
<CloseReaderButton />
</div>
- <div class="absolute bottom-0 right-0 z-10 flex p-1 text-lg">
- <PageIndicator />
- </div>
- <div class="flex grow">
- {@render children?.()}
- </div>
+ {@render children?.()}
</main>
</div>
{/if}
diff --git a/frontend/src/lib/reader/components/CloseReaderButton.svelte b/frontend/src/lib/reader/components/CloseReaderButton.svelte
index f3eb4ba..8dc5f4f 100644
--- a/frontend/src/lib/reader/components/CloseReaderButton.svelte
+++ b/frontend/src/lib/reader/components/CloseReaderButton.svelte
@@ -1,6 +1,6 @@
<script lang="ts">
+ import { getReaderContext } from '$lib/Reader.svelte';
import { accelerator } from '$lib/Shortcuts';
- import { getReaderContext } from '../Reader.svelte';
const reader = getReaderContext();
diff --git a/frontend/src/lib/reader/components/PageIndicator.svelte b/frontend/src/lib/reader/components/PageIndicator.svelte
index 3b11389..d0a3d0c 100644
--- a/frontend/src/lib/reader/components/PageIndicator.svelte
+++ b/frontend/src/lib/reader/components/PageIndicator.svelte
@@ -1,5 +1,5 @@
<script lang="ts">
- import { getReaderContext } from '../Reader.svelte';
+ import { getReaderContext } from '$lib/Reader.svelte';
const reader = getReaderContext();
</script>
diff --git a/frontend/src/lib/reader/components/ReaderMenuButton.svelte b/frontend/src/lib/reader/components/ReaderMenuButton.svelte
index 58648e8..ea2705d 100644
--- a/frontend/src/lib/reader/components/ReaderMenuButton.svelte
+++ b/frontend/src/lib/reader/components/ReaderMenuButton.svelte
@@ -1,6 +1,6 @@
<script lang="ts">
+ import { getReaderContext } from '$lib/Reader.svelte';
import { accelerator } from '$lib/Shortcuts';
- import { getReaderContext } from '../Reader.svelte';
const reader = getReaderContext();
diff --git a/frontend/src/routes/archives/[id]/+page.svelte b/frontend/src/routes/archives/[id]/+page.svelte
index 56c3273..9eedcb2 100644
--- a/frontend/src/routes/archives/[id]/+page.svelte
+++ b/frontend/src/routes/archives/[id]/+page.svelte
@@ -2,6 +2,7 @@
import { updateArchives } from '$gql/Mutations';
import { archiveQuery } from '$gql/Queries';
import { Direction, Layout, type FullArchiveFragment, type PageFragment } from '$gql/graphql';
+ import { initReaderContext } from '$lib/Reader.svelte';
import { toastFinally } from '$lib/Toasts';
import Guard from '$lib/components/Guard.svelte';
import Head from '$lib/components/Head.svelte';
@@ -9,7 +10,7 @@
import Grid from '$lib/containers/Grid.svelte';
import Gallery from '$lib/gallery/Gallery.svelte';
import PageView from '$lib/reader/PageView.svelte';
- import Reader, { initReaderContext } from '$lib/reader/Reader.svelte';
+ import Reader from '$lib/reader/Reader.svelte';
import { initSelectionContext } from '$lib/selection/Selection.svelte';
import ArchiveDelete from '$lib/tabs/ArchiveDelete.svelte';
import ArchiveDetails from '$lib/tabs/ArchiveDetails.svelte';
diff --git a/frontend/src/routes/comics/[id]/+page.svelte b/frontend/src/routes/comics/[id]/+page.svelte
index abe3798..28a8dde 100644
--- a/frontend/src/routes/comics/[id]/+page.svelte
+++ b/frontend/src/routes/comics/[id]/+page.svelte
@@ -10,6 +10,7 @@
type UpdateComicInput
} from '$gql/graphql';
import { comicPending } from '$lib/Form';
+ import { initReaderContext } from '$lib/Reader.svelte';
import { toastFinally } from '$lib/Toasts';
import { preventOnPending } from '$lib/Utils';
import BookmarkButton from '$lib/components/BookmarkButton.svelte';
@@ -23,7 +24,7 @@
import ComicForm from '$lib/forms/ComicForm.svelte';
import Gallery from '$lib/gallery/Gallery.svelte';
import PageView from '$lib/reader/PageView.svelte';
- import Reader, { initReaderContext } from '$lib/reader/Reader.svelte';
+ import Reader from '$lib/reader/Reader.svelte';
import ComicScrapeForm from '$lib/scraper/ComicScrapeForm.svelte';
import { initScraperContext } from '$lib/scraper/Scraper.svelte';
import { initSelectionContext } from '$lib/selection/Selection.svelte';
diff --git a/frontend/tests/Reader.test.ts b/frontend/tests/Reader.test.ts
index a4928af..5113e65 100644
--- a/frontend/tests/Reader.test.ts
+++ b/frontend/tests/Reader.test.ts
@@ -1,5 +1,5 @@
import { Layout, type PageFragment } from '$gql/graphql';
-import { partition, type Chunk } from '$lib/reader/Reader.svelte';
+import { partition, type Chunk } from '$lib/Reader.svelte';
import { expect, test } from 'vitest';