diff options
Diffstat (limited to 'frontend/src/lib/reader/PageView.svelte')
-rw-r--r-- | frontend/src/lib/reader/PageView.svelte | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/frontend/src/lib/reader/PageView.svelte b/frontend/src/lib/reader/PageView.svelte new file mode 100644 index 0000000..cc4d10e --- /dev/null +++ b/frontend/src/lib/reader/PageView.svelte @@ -0,0 +1,67 @@ +<script lang="ts"> + import { Direction, Layout, type PageFragment } from '$gql/graphql'; + import { getReaderContext, partition, type Chunk } from '$lib/Reader'; + import { binds } from '$lib/Shortcuts'; + 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; + + function gotoChunk(to: number) { + if (to < 0 || to >= chunks.length) return; + + $reader.page = chunks[to].index; + } + + const next = () => gotoChunk(lookup[$reader.page] + 1); + const prev = () => gotoChunk(lookup[$reader.page] - 1); + + const clickLeft = () => (direction === Direction.LeftToRight ? prev() : next()); + const clickRight = () => (direction === Direction.RightToLeft ? prev() : next()); + + function clickMain(event: MouseEvent & { currentTarget: EventTarget | null }) { + if (event.currentTarget instanceof Element) { + const rect = event.currentTarget.getBoundingClientRect(); + + if (event.clientX - rect.left < rect.width / 2) { + clickLeft(); + } else { + clickRight(); + } + } + } + + $: [chunks, lookup] = partition($reader.pages, layout); + $: layout, ({ main, secondary } = chunks[lookup[$reader.page]]); +</script> + +<svelte:document + use:binds={[ + ['ArrowLeft', clickLeft], + ['ArrowRight', clickRight], + ['ArrowUp', prev], + ['ArrowDown', next], + ['PageUp', prev], + ['PageDown', next], + [' ', next], + ['Backspace', prev] + ]} +/> + +{#if !secondary} + <ReaderPage page={main} on:click={clickMain} --justify="center" /> +{:else if direction === Direction.LeftToRight} + <ReaderPage page={main} on:click={prev} --justify="flex-end" /> + <ReaderPage page={secondary} on:click={next} --justify="flex-start" /> +{:else} + <ReaderPage page={secondary} on:click={next} --justify="flex-end" /> + <ReaderPage page={main} on:click={prev} --justify="flex-start" /> +{/if} |