diff options
author | Wolfgang Müller | 2025-02-19 15:39:48 +0100 |
---|---|---|
committer | Wolfgang Müller | 2025-02-19 15:39:48 +0100 |
commit | 6bc3ca7032c78c77a6e2b316789938221d686d8b (patch) | |
tree | b70bdd334a825b1fe6d14603e214b993ed2ce08b /frontend/src/lib/reader/PageView.svelte | |
parent | 2177d004c88d1daccc9ae4808dc75b66eb0f2d3a (diff) | |
download | hircine-6bc3ca7032c78c77a6e2b316789938221d686d8b.tar.gz |
frontend: Implement a better page indicator
This replaces the very simplistic x/y page indicator with a visual bar
at the bottom of the reader that allows the user quick access to any
arbitrary page. At the margins it shows the current page number(s) and
the total amount of pages.
Diffstat (limited to 'frontend/src/lib/reader/PageView.svelte')
-rw-r--r-- | frontend/src/lib/reader/PageView.svelte | 60 |
1 files changed, 51 insertions, 9 deletions
diff --git a/frontend/src/lib/reader/PageView.svelte b/frontend/src/lib/reader/PageView.svelte index 2f8def7..50c0873 100644 --- a/frontend/src/lib/reader/PageView.svelte +++ b/frontend/src/lib/reader/PageView.svelte @@ -1,10 +1,11 @@ <script lang="ts"> import { Direction, Layout, type PageFragment } from '$gql/graphql'; - import { getReaderContext, partition } from '$lib/Reader.svelte'; + import { type Chunk, getReaderContext, partition } from '$lib/Reader.svelte'; import { binds } from '$lib/Shortcuts'; import { src } from '$lib/Utils'; - import PageIndicator from './components/PageIndicator.svelte'; import ReaderPage from './ReaderPage.svelte'; + import SliderMargin from './components/SliderMargin.svelte'; + import SliderTooltip from './components/SliderTooltip.svelte'; const reader = getReaderContext(); @@ -56,7 +57,10 @@ } let [chunks, lookup] = $derived(partition(reader.pages, layout)); - let { main, secondary } = $derived(chunks[lookup[reader.page]]); + let currentChunk = $derived(chunks[lookup[reader.page]]); + let { main, secondary } = $derived(currentChunk); + + let reverse = $derived(direction === Direction.RightToLeft); </script> <svelte:document @@ -76,18 +80,56 @@ {#if !secondary} <ReaderPage page={main} onclick={clickMain} --justify="center" /> -{:else if direction === Direction.LeftToRight} - <ReaderPage page={main} onclick={prev} --justify="flex-end" /> - <ReaderPage page={secondary} onclick={next} --justify="flex-start" /> -{:else} +{:else if reverse} <ReaderPage page={secondary} onclick={next} --justify="flex-end" /> <ReaderPage page={main} onclick={prev} --justify="flex-start" /> +{:else} + <ReaderPage page={main} onclick={prev} --justify="flex-end" /> + <ReaderPage page={secondary} onclick={next} --justify="flex-start" /> {/if} -<div class="absolute right-0 bottom-0 z-10 flex p-1 text-lg"> - <PageIndicator /> + +{#snippet pagesIn(chunk: Chunk)} + {#if chunk.secondary} + {chunk.index + 1} - {chunk.index + 2} + {:else} + {chunk.index + 1} + {/if} +{/snippet} + +<div class="group/slider absolute bottom-0 z-1 flex w-full pt-20"> + <div class:reverse class="flex h-1 w-full transition-[height] group-hover/slider:h-8"> + <SliderMargin> + {@render pagesIn(currentChunk)} + </SliderMargin> + <div class:reverse class="flex w-full bg-gray-400/60 backdrop-blur-2xl"> + {#each chunks as chunk, index} + <button + type="button" + class:read={index <= lookup[reader.page]} + class="group/page relative grow [&.read]:bg-blue-600/60" + onclick={() => reader.open(chunk.index)} + aria-label={`Open page ${chunk.index}`} + > + <SliderTooltip> + {@render pagesIn(chunk)} + </SliderTooltip> + </button> + {/each} + </div> + <SliderMargin> + {reader.pages.length} + </SliderMargin> + </div> </div> + <div class="invisible absolute"> {#each pagesAround(reader.page) as page} <img src={src(page.image, 'full')} alt="" /> {/each} </div> + +<style> + .reverse { + flex-direction: row-reverse; + } +</style> |