Skip to content

Commit

Permalink
Render new note component into note embeds
Browse files Browse the repository at this point in the history
Fixes #923
  • Loading branch information
allanlasser committed Dec 13, 2024
1 parent c489fe6 commit 1c8ae00
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 218 deletions.
72 changes: 40 additions & 32 deletions src/lib/components/viewer/Note.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import type { Document, Note, Sizes } from "$lib/api/types";
import DOMPurify from "isomorphic-dompurify";
import { createEventDispatcher, onMount } from "svelte";
import { createEventDispatcher } from "svelte";
import { _ } from "svelte-i18n";
import {
Globe16,
Expand All @@ -25,7 +25,7 @@
} from "svelte-octicons";
import { ALLOWED_ATTR, ALLOWED_TAGS } from "@/config/config.js";
import { width, height, isPageLevel, noteHashUrl } from "$lib/api/notes";
import { width, height, isPageLevel } from "$lib/api/notes";
import { pageImageUrl } from "$lib/api/documents";
import Portal from "../layouts/Portal.svelte";
import Modal from "../layouts/Modal.svelte";
Expand All @@ -40,13 +40,13 @@
import { getViewerHref } from "$lib/utils/viewer";
import Button from "../common/Button.svelte";
const documentStore = getDocument();
const pdf = getPDF();
const embed = isEmbedded();
const mode = getCurrentMode();
const dispatch = createEventDispatcher();
export let document = getDocument();
export let note: Note;
export let scale = 2;
Expand Down Expand Up @@ -77,12 +77,12 @@
let shareNoteOpen = false;
$: document = $documentStore;
$: doc = $document;
$: page_level = isPageLevel(note);
$: page_number = note.page_number + 1; // note pages are 0-indexed
$: user = typeof note.user === "object" ? (note.user as User) : null;
$: rendering = render(canvas, document, $pdf); // avoid re-using the same canvas
$: edit_link = getViewerHref({ document, note, mode: "annotating" });
$: rendering = render(canvas, doc, $pdf); // avoid re-using the same canvas
$: edit_link = getViewerHref({ document: doc, note, mode: "annotating" });
$: canEdit = note.edit_access && !embed;
async function render(
Expand Down Expand Up @@ -207,7 +207,7 @@
style:--note-height={height(note)}
>
<header>
{#if !page_level && $mode === "document"}
{#if !embed && !page_level && $mode === "document"}
<Button minW={false} ghost on:click={closeNote}>
<XCircle16 />
</Button>
Expand All @@ -231,36 +231,44 @@
<p>{@html clean(note.content)}</p>
</div>
{/if}
<footer>
<span class="access {note.access}">
<svelte:component this={access[note.access].icon} />
{$_(`access.${access[note.access].value}.title`)}
</span>
<div class="actions">
{#if canEdit}
<Button ghost minW={false} mode="primary" size="small" href={edit_link}>
<Pencil16 />
{$_("dialog.edit")}
{#if !embed}
<footer>
<span class="access {note.access}">
<svelte:component this={access[note.access].icon} />
{$_(`access.${access[note.access].value}.title`)}
</span>
<div class="actions">
{#if canEdit}
<Button
ghost
minW={false}
mode="primary"
size="small"
href={edit_link}
>
<Pencil16 />
{$_("dialog.edit")}
</Button>
{/if}
<Button
ghost
minW={false}
mode="primary"
size="small"
on:click={() => (shareNoteOpen = true)}
>
<Share16 />
{$_("dialog.share")}
</Button>
{/if}
<Button
ghost
minW={false}
mode="primary"
size="small"
on:click={() => (shareNoteOpen = true)}
>
<Share16 />
{$_("dialog.share")}
</Button>
</div>
</footer>
</div>
</footer>
{/if}
</div>
{#if shareNoteOpen}
{#if !embed && shareNoteOpen}
<Portal>
<Modal on:close={() => (shareNoteOpen = false)}>
<h1 slot="title">{$_("dialog.share")}</h1>
<Share {document} note={note.id} currentTab="note" />
<Share document={doc} note={note.id} currentTab="note" />
</Modal>
</Portal>
{/if}
Expand Down
205 changes: 19 additions & 186 deletions src/routes/embed/documents/[id]/annotations/[note_id]/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,42 +1,36 @@
<script lang="ts">
import DOMPurify from "isomorphic-dompurify";
import { onMount } from "svelte";
import { onMount, setContext } from "svelte";
import { writable } from "svelte/store";
import { _ } from "svelte-i18n";
import { informSize } from "$lib/utils/embed";
import { pageImageUrl } from "$lib/api/documents";
import * as notes from "$lib/api/notes";
import { embedUrl } from "$lib/api/embed";
import { canonicalNoteUrl, noteUrl } from "$lib/api/notes";
import { pageSizesFromSpec } from "$lib/utils/pageSize";
import { IMAGE_WIDTHS_MAP } from "@/config/config.js";
import Note from "$lib/components/viewer/Note.svelte";
import EmbedLayout from "@/lib/components/layouts/EmbedLayout.svelte";
export let data;
const docWidth = IMAGE_WIDTHS_MAP.get("normal") ?? 700;
let elem: HTMLElement;
$: doc = data.document;
$: note = data.note;
$: alt = `Page ${note.page_number + 1} of ${doc.title}`;
$: src = pageImageUrl(doc, note.page_number + 1, "normal").toString();
$: sizes = doc.page_spec ? pageSizesFromSpec(doc.page_spec) : [];
$: aspect = sizes[note.page_number] ?? 11 / 8.5;
$: url = canonicalNoteUrl(doc, note).toString();
$: viewerUrl = noteUrl(doc, note).href;
$: title = `${note.title} (${$_("documents.pageAbbrev")} ${
note.page_number + 1
})`;
$: maxWidth = docWidth * notes.width(note);
$: height = docWidth * aspect;
onMount(() => {
informSize(elem);
});
function clean(s: string): string {
return DOMPurify.sanitize(s);
}
setContext("document", writable(doc));
setContext("embed", true);
setContext("currentMode", writable("note"));
setContext("pdf", undefined);
</script>

<svelte:head>
Expand All @@ -61,180 +55,19 @@
<meta property="og:image" content={src} />
</svelte:head>

<div class="DC-note" bind:this={elem} style={`background-image: url(${src})`}>
<div class="DC-note-header">
<a
href={noteUrl(doc, note).toString()}
class="DC-note-embed-resource"
target="_blank"
title={$_("embedNote.viewTheNote", { values: { title: note.title } })}
>
<span class="DC-note-title">{note.title}</span>
<span class="DC-note-page-number"
>({$_("documents.pageAbbrev")} {note.page_number + 1})</span
>
</a>
</div>

<div
class="DC-note-image-max-bounds"
class:public={note.access === "public"}
class:organization={note.access === "organization"}
class:private={note.access === "private"}
style:max-width="{maxWidth}px"
>
<div
class="DC-note-image-aspect-ratio"
style:padding-bottom="{(notes.height(note) / notes.width(note)) *
aspect *
100}%"
>
<a
href={noteUrl(doc, note).toString()}
target="_blank"
class="DC-note-image-link"
style:left="{(note.x1 * -100) / notes.width(note)}%"
style:top="{(note.y1 * -100) / notes.height(note)}%"
style:width="{100 / notes.width(note)}%"
style:height="{100 / notes.height(note)}%"
>
<img {src} {alt} width="{docWidth}px" height="{height}px" />
</a>
<div bind:this={elem}>
<EmbedLayout canonicalUrl={viewerUrl}>
<div class="card">
<Note document={writable(doc)} {note} />
</div>
</div>

<div class="DC-note-body">
{@html clean(note.content ?? "")}
</div>

<div class="DC-note-credit">
<a
href={noteUrl(doc, note).toString()}
target="_blank"
title={$_("embedNote.viewTheNote", { values: { title: note.title } })}
>
{@html $_("embedNote.viewDoc")}
</a>
</div>

<div class="DC-note-background-fader" />
</EmbedLayout>
</div>

<style>
.DC-note {
position: relative;
padding: 0 0.5em;
border: 1px solid #ebebeb;
box-shadow: inset 0 0 40px #505050;
font:
400 10pt/14pt -apple-system,
system-ui,
BlinkMacSystemFont,
"Segoe UI",
Roboto,
"Helvetica Neue",
Arial,
sans-serif;
color: black;
background-color: white;
background-size: 100% auto;
background-repeat: no-repeat;
background-position: center center;
}
.DC-note a {
color: #5a76a0;
text-decoration: underline;
}
.DC-note > * {
position: relative;
z-index: 1;
}
.DC-note-header,
.DC-note-body,
:global(.DC-note-credit) {
margin: 10px auto;
padding: 0 5px;
max-width: 600px;
}
.DC-note-title {
font-weight: bold;
}
.DC-note-image-max-bounds {
border-radius: var(--radius);
box-shadow: 0 0 7px rgba(0, 0, 0, 0.25);
box-sizing: content-box;
position: relative;
font-size: 0;
overflow: hidden;
margin: 10px auto;
}
.DC-note-image-max-bounds.public {
border: var(--annotationBorderWidth) solid var(--annotationBorder);
}
.DC-note-image-max-bounds.organization {
border: var(--annotationBorderWidth) solid var(--organizationAnnotation);
}
.DC-note-image-max-bounds.private {
border: var(--annotationBorderWidth) solid var(--privateAnnotation);
}
.DC-note-image-aspect-ratio {
position: relative;
overflow: hidden;
height: 0;
max-width: 100%;
}
.DC-note-image-link {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
right: 0;
bottom: 0;
overflow: hidden;
display: block;
}
.DC-note-image-link img {
margin: 0 !important;
border: 0 !important;
outline: 0 !important;
max-width: none !important;
max-height: none !important;
display: block !important;
position: absolute;
height: auto;
transform-origin: top left;
}
.DC-note-credit {
font-size: 0.9em;
}
:global(.DC-note-logotype-link) {
font-weight: 700;
font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI",
Roboto, "Helvetica Neue", Arial, sans-serif;
}
.DC-note-background-fader {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 0;
background-color: rgba(255, 255, 255, 0.93);
.card {
margin: 1rem;
width: calc(100% - 2rem);
border: 1px solid var(--gray-2);
box-shadow: var(--shadow-2);
}
</style>

0 comments on commit 1c8ae00

Please sign in to comment.