Skip to content

Commit

Permalink
Switch between text and document views without losing page position
Browse files Browse the repository at this point in the history
  • Loading branch information
eyeseast committed May 15, 2024
1 parent 647628b commit f43273c
Show file tree
Hide file tree
Showing 7 changed files with 124 additions and 47 deletions.
59 changes: 59 additions & 0 deletions src/lib/components/documents/Text.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<!--
@component
Text wraps a list of TextPage components for loading and management
-->
<script lang="ts">
import type { Writable } from "svelte/store";
import type { DocumentText } from "$lib/api/types";
import { getContext, onMount } from "svelte";
import Page from "./Page.svelte";
import TextPage from "./TextPage.svelte";
import { scrollToPage } from "$lib/utils/scroll";
export let text: Promise<DocumentText> | DocumentText;
export let total: number = 0;
export let zoom: number = 1;
const currentPage: Writable<number> = getContext("currentPage");
onMount(async () => {
await text; // wait until it loads
if ($currentPage > 1) {
scrollToPage($currentPage);
}
});
</script>

<div class="textPages" style:--zoom={zoom}>
{#await text}
<!-- loading state-->
{#each Array(total).fill(null) as p, n}
<Page page_number={n + 1} mode="text">
<div class="placeholder"></div>
</Page>
{/each}
{:then { pages }}
{#each pages as { page, contents }}
<TextPage {page} {contents} />
{/each}
{/await}
</div>

<style>
.textPages {
max-width: 48rem;
padding: 0 1rem;
margin: 0 auto;
width: 100%;
}
.placeholder {
aspect-ratio: calc(11 / 8.5);
box-shadow: var(--shadow);
width: 66ch;
}
</style>
23 changes: 23 additions & 0 deletions src/lib/components/documents/stories/Text.stories.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<script context="module" lang="ts">
import type { DocumentText } from "$lib/api/types";
import { Story } from "@storybook/addon-svelte-csf";
import Text from "../Text.svelte";
export const meta = {
title: "Components / Documents / Text",
component: Text,
parameters: { layout: "centered" },
};
import txt from "$lib/api/fixtures/documents/document.txt.json";
const loading: Promise<DocumentText> = new Promise(() => {});
</script>

<Story name="default">
<Text text={txt} />
</Story>

<Story name="waiting to load">
<Text text={loading} total={txt.pages.length} />
</Story>
3 changes: 1 addition & 2 deletions src/lib/components/documents/stories/TextPage.stories.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@
import TextPage from "../TextPage.svelte";
export const meta = {
title: "Components / Documents / Text",
title: "Components / Documents / Text page",
component: TextPage,
tags: ["autodocs"],
parameters: { layout: "centered" },
};
Expand Down
14 changes: 14 additions & 0 deletions src/lib/utils/scroll.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { pageHashUrl } from "../api/documents";

/**
* Scroll to a page using a standard ID
*
* @param n page number
*/
export function scrollToPage(n: number): void {
const pageId = pageHashUrl(n).replace("#", "");
const heading = window.document.getElementById(pageId);

if (!heading) return console.error(`Missing page ${n}`);
heading.scrollIntoView();
}
15 changes: 1 addition & 14 deletions src/routes/documents/[id]-[slug]/+layout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,9 @@ import type { Document } from "@/lib/api/types";

import { redirect, error } from "@sveltejs/kit";

import { DC_BASE } from "@/config/config.js";
import * as documents from "$lib/api/documents";
import { getPinnedAddons } from "$lib/api/addons";
import { breadcrumbTrail, getPrivateAsset } from "$lib/utils/index";
import { breadcrumbTrail } from "$lib/utils/index";

function documentPath(document: Document) {
return `/documents/${document.id}-${document.slug}/`;
Expand All @@ -34,23 +33,11 @@ export async function load({ fetch, params, parent }) {
{ href: documentPath(document), title: document.title },
]);

let asset_url = documents.pdfUrl(document);

// assets still processing are in private storage until finished
if (document.access !== "public" || String(asset_url).startsWith(DC_BASE)) {
asset_url = await getPrivateAsset(asset_url, fetch).catch((e) => {
console.error(e);
console.error(asset_url.href);
return asset_url;
});
}

// stream this
const pinnedAddons = getPinnedAddons(fetch);

return {
document,
asset_url,
pinnedAddons,
breadcrumbs,
};
Expand Down
39 changes: 9 additions & 30 deletions src/routes/documents/[id]-[slug]/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<script lang="ts">
import type { Sizes, ViewerMode } from "@/lib/api/types.js";
import { browser } from "$app/environment";
import { afterNavigate, goto, replaceState } from "$app/navigation";
import { page } from "$app/stores";
Expand All @@ -21,12 +20,13 @@
import Paginator from "@/common/Paginator.svelte";
import PDF from "$lib/components/documents/PDF.svelte";
import Search from "$lib/components/forms/Search.svelte";
import TextPage from "$lib/components/documents/TextPage.svelte";
import Text from "$lib/components/documents/Text.svelte";
import ThumbnailGrid from "$lib/components/documents/ThumbnailGrid.svelte";
// config and utils
import { IMAGE_WIDTHS_MAP } from "@/config/config.js";
import { pageHashUrl, pageFromHash } from "$lib/api/documents";
import { scrollToPage } from "$lib/utils/scroll";
export let data;
Expand Down Expand Up @@ -72,18 +72,24 @@
u.searchParams.set("mode", mode);
if ($currentPage > 1) {
u.hash = pageHashUrl($currentPage);
}
goto(u);
}
// pagination
function next() {
$currentPage = Math.min($currentPage + 1, document.page_count);
scrollToPage($currentPage);
replaceState(pageHashUrl($currentPage), {});
}
function previous() {
$currentPage = Math.max($currentPage - 1, 1);
scrollToPage($currentPage);
replaceState(pageHashUrl($currentPage), {});
}
function onHashChange(e: HashChangeEvent) {
Expand All @@ -92,20 +98,6 @@
scrollToPage($currentPage);
}
// scroll to a page
function scrollToPage(n: number) {
if (!browser) return;
const pageId = pageHashUrl(n).replace("#", "");
const heading = window.document.getElementById(pageId);
if (!heading) return console.error(`Missing page ${n}`);
heading.scrollIntoView();
// push or replace?
replaceState(pageHashUrl(n), {});
}
/**
* Generate a default zoom, based on mode
* @param mode
Expand Down Expand Up @@ -195,13 +187,7 @@
{/if}

{#if mode === "text"}
{#await text then { pages }}
<div class="textPages">
{#each pages as { page, contents }}
<TextPage {page} {contents} --zoom={zoom} />
{/each}
</div>
{/await}
<Text {text} zoom={+zoom || 1} total={document.page_count} />
{/if}

{#if mode === "thumbnails"}
Expand Down Expand Up @@ -250,13 +236,6 @@
</ContentLayout>

<style>
.textPages {
max-width: 48rem;
padding: 0 1rem;
margin: 0 auto;
width: 100%;
}
label.mode,
label.zoom {
display: flex;
Expand Down
18 changes: 17 additions & 1 deletion src/routes/documents/[id]-[slug]/+page.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import type { DocumentText, ViewerMode } from "$lib/api/types.js";

import { DC_BASE } from "@/config/config.js";
import * as documents from "$lib/api/documents";
import { getPrivateAsset } from "$lib/utils/api";

export async function load({ fetch, parent, url }) {
let mode: ViewerMode =
Expand All @@ -9,18 +12,31 @@ export async function load({ fetch, parent, url }) {
mode = documents.MODES[0];
}

const { document } = await parent();

// only load text in text mode
let text: Promise<DocumentText> = Promise.resolve({
updated: 0,
pages: [],
});

if (mode === "text") {
const { document } = await parent();
text = documents.text(document, fetch);
}

let asset_url = documents.pdfUrl(document);

// assets still processing are in private storage until finished
if (document.access !== "public" || String(asset_url).startsWith(DC_BASE)) {
asset_url = await getPrivateAsset(asset_url, fetch).catch((e) => {
console.error(e);
console.error(asset_url.href);
return asset_url;
});
}

return {
asset_url,
mode,
text,
};
Expand Down

0 comments on commit f43273c

Please sign in to comment.