Skip to content

Commit

Permalink
Render note highlighting on document
Browse files Browse the repository at this point in the history
  • Loading branch information
eyeseast committed May 21, 2024
1 parent 0cc30ee commit feb31cf
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 3 deletions.
4 changes: 4 additions & 0 deletions src/lib/api/notes.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ describe("note helper methods", () => {
);
});

test("noteHashUrl", () => {
expect(notes.noteHashUrl(n)).toStrictEqual("#document/p3/a557");
});

test("width", () => {
expect(notes.width(n)).toStrictEqual(n.x2 - n.x1);
});
Expand Down
4 changes: 4 additions & 0 deletions src/lib/api/notes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ export function noteUrl(document: Document, note: Note): URL {
);
}

export function noteHashUrl(note: Note): string {
return `#document/p${note.page_number + 1}/a${note.id}`;
}

/** Width of a note, relative to the document */
export function width(note: Note): number {
return note.x2 - note.x1;
Expand Down
51 changes: 51 additions & 0 deletions src/lib/components/documents/Note.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<!--
@component
A single note, either overlaid on a document or on its own.
It has two states, focused and normal.
-->

<script lang="ts">
import type { Note } from "$lib/api/types";
import { noteHashUrl, width, height } from "$lib/api/notes";
export let note: Note;
export let focused = false;
</script>

{#if focused}
<div class="note"></div>
{:else}
<a
href={noteHashUrl(note)}
class="note {note.access}"
title={note.title}
style:top="{note.y1 * 100}%"
style:left="{note.x1 * 100}%"
style:width="{width(note) * 100}%"
style:height="{height(note) * 100}%"
>
{note.title}
</a>
{/if}

<style>
a.note {
color: transparent;
position: absolute;
border: 2px solid var(--note-public);
background-color: var(--note-public);
opacity: 0.33;
pointer-events: all;
}
.note.private {
border-color: var(--note-private);
}
.note.org {
border-color: var(--note-org);
}
</style>
12 changes: 11 additions & 1 deletion src/lib/components/documents/PDF.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,15 @@
$: sizes = pageSizes(document.page_spec);
// index notes by page
$: notes = document.notes.reduce((m, note) => {
if (!m[note.page_number]) {
m[note.page_number] = [];
}
m[note.page_number].push(note);
return m;
}, {});
let progress = {
loaded: 0,
total: 0,
Expand All @@ -56,7 +65,8 @@

<div class="pages">
{#each sizes as [width, height], n}
<PdfPage page_number={n + 1} {pdf} {scale} {width} {height} />
{@const page_number = n + 1}
<PdfPage {page_number} {pdf} {scale} {width} {height} notes={notes[n]} />
{/each}
</div>

Expand Down
37 changes: 35 additions & 2 deletions src/lib/components/documents/PDFPage.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,23 @@ Selectable text can be rendered in one of two ways:
- Passed in as a server-fetched JSON object
-->
<script lang="ts">
import type { TextPosition } from "$lib/api/types";
import type { TextPosition, Note as NoteType } from "$lib/api/types";
import * as pdfjs from "pdfjs-dist/build/pdf.mjs";
import Note from "./Note.svelte";
import NoteTab from "./NoteTab.svelte";
import Page from "./Page.svelte";
import { noteHashUrl } from "$lib/api/notes";
export let page_number: number; // 1-indexed
export let pdf; // Promise<PDFDocumentProxy>
export let scale: number | "width" | "height";
export let text: TextPosition[] = [];
export let width: number;
export let height: number;
export let notes: NoteType[] = [];
let canvas: HTMLCanvasElement;
let container: HTMLElement;
Expand Down Expand Up @@ -189,6 +194,20 @@ Selectable text can be rendered in one of two ways:
<!-- pdfjs.renderTextLayer will fill this in -->
</div>
{/if}
<div class="notes">
{#each notes as note}
<a
class="note"
href={noteHashUrl(note)}
title={note.title}
style:top="{note.y1 * 100}%"
>
<NoteTab access={note.access} />
</a>

<Note {note} />
{/each}
</div>
</div>
</Page>

Expand Down Expand Up @@ -216,7 +235,6 @@ Selectable text can be rendered in one of two ways:
top: 0;
bottom: 0;
width: 100%;
opacity: 0.5;
}
.word {
Expand Down Expand Up @@ -258,6 +276,21 @@ Selectable text can be rendered in one of two ways:
width: 100%;
}
.notes {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
pointer-events: none;
}
.note {
position: absolute;
pointer-events: all;
left: -3rem;
transform: translateY(calc(-1.75rem / 3));
}
/* pdfjs creates this */
:global(.hiddenCanvasElement) {
display: none;
Expand Down

0 comments on commit feb31cf

Please sign in to comment.