diff options
author | Wolfgang Müller | 2025-02-18 15:51:14 +0100 |
---|---|---|
committer | Wolfgang Müller | 2025-02-18 15:51:14 +0100 |
commit | 3f6bd71aaac4277d046485fe8ea2a791ea089cd8 (patch) | |
tree | b07f2bd3096695cf94c7c0b341e4dae150673a6b | |
parent | c70a78623a7fe2db2af1efb6a9896097f59855fc (diff) | |
download | hircine-3f6bd71aaac4277d046485fe8ea2a791ea089cd8.tar.gz |
frontend: Migrate PageView to Svelte 5
-rw-r--r-- | frontend/src/lib/Reader.svelte.ts | 59 | ||||
-rw-r--r-- | frontend/src/lib/reader/PageView.svelte | 19 | ||||
-rw-r--r-- | frontend/src/lib/reader/Reader.svelte | 73 | ||||
-rw-r--r-- | frontend/src/lib/reader/components/CloseReaderButton.svelte | 2 | ||||
-rw-r--r-- | frontend/src/lib/reader/components/PageIndicator.svelte | 2 | ||||
-rw-r--r-- | frontend/src/lib/reader/components/ReaderMenuButton.svelte | 2 | ||||
-rw-r--r-- | frontend/src/routes/archives/[id]/+page.svelte | 3 | ||||
-rw-r--r-- | frontend/src/routes/comics/[id]/+page.svelte | 3 | ||||
-rw-r--r-- | frontend/tests/Reader.test.ts | 2 |
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'; |