chore(collection/presentation): rewrite horizontal slide links

This commit is contained in:
Elian Doran 2025-10-18 18:37:29 +03:00
parent 0c3d225379
commit c04c38e61d
No known key found for this signature in database
4 changed files with 39 additions and 2 deletions

View File

@ -4,6 +4,7 @@ import froca from "../services/froca.js";
import FAttribute from "../entities/fattribute.js"; import FAttribute from "../entities/fattribute.js";
import noteAttributeCache from "../services/note_attribute_cache.js"; import noteAttributeCache from "../services/note_attribute_cache.js";
import FBranch from "../entities/fbranch.js"; import FBranch from "../entities/fbranch.js";
import FBlob from "../entities/fblob.js";
type AttributeDefinitions = { [key in `#${string}`]: string; }; type AttributeDefinitions = { [key in `#${string}`]: string; };
type RelationDefinitions = { [key in `~${string}`]: string; }; type RelationDefinitions = { [key in `~${string}`]: string; };
@ -12,6 +13,7 @@ interface NoteDefinition extends AttributeDefinitions, RelationDefinitions {
id?: string | undefined; id?: string | undefined;
title: string; title: string;
children?: NoteDefinition[]; children?: NoteDefinition[];
content?: string;
} }
/** /**
@ -51,6 +53,20 @@ export function buildNote(noteDef: NoteDefinition) {
froca.notes[note.noteId] = note; froca.notes[note.noteId] = note;
let childNotePosition = 0; let childNotePosition = 0;
// Manage content.
const content = noteDef.content ?? "";
note.getContent = async () => content;
const blob = new FBlob({
blobId: utils.randomString(10),
content,
contentLength: content.length,
dateModified: new Date().toISOString(),
utcDateModified: new Date().toISOString()
});
note.getBlob = async () => blob;
// Manage children.
if (noteDef.children) { if (noteDef.children) {
for (const childDef of noteDef.children) { for (const childDef of noteDef.children) {
const childNote = buildNote(childDef); const childNote = buildNote(childDef);

View File

@ -177,6 +177,7 @@ function Presentation({ presentation, setApi } : { presentation: PresentationMod
function Slide({ slide }: { slide: PresentationSlideBaseModel }) { function Slide({ slide }: { slide: PresentationSlideBaseModel }) {
return ( return (
<section <section
id={slide.noteId}
data-note-id={slide.noteId} data-note-id={slide.noteId}
data-background-color={slide.backgroundColor} data-background-color={slide.backgroundColor}
data-background-gradient={slide.backgroundGradient} data-background-gradient={slide.backgroundGradient}

View File

@ -2,7 +2,6 @@ import { beforeAll, describe, expect, it } from "vitest";
import { buildNote } from "../../../test/easy-froca"; import { buildNote } from "../../../test/easy-froca";
import FNote from "../../../entities/fnote"; import FNote from "../../../entities/fnote";
import { buildPresentationModel, PresentationModel } from "./model"; import { buildPresentationModel, PresentationModel } from "./model";
import froca from "../../../services/froca";
let presentationNote!: FNote; let presentationNote!: FNote;
let data!: PresentationModel; let data!: PresentationModel;
@ -11,6 +10,7 @@ describe("Presentation model", () => {
beforeAll(async () => { beforeAll(async () => {
presentationNote = buildNote({ presentationNote = buildNote({
title: "Presentation", title: "Presentation",
id: "presentation",
"#viewType": "presentation", "#viewType": "presentation",
"children": [ "children": [
{ {
@ -26,6 +26,7 @@ describe("Presentation model", () => {
{ {
title: "Second slide", title: "Second slide",
id: "slide3", id: "slide3",
content: `<p>Go to&nbsp;<a class="reference-link" href="#root/presentation/slide1">First slide</a>.</p>`,
children: [ children: [
{ {
id: "slide4", id: "slide4",
@ -64,4 +65,12 @@ describe("Presentation model", () => {
it("empty slides don't render children", () => { it("empty slides don't render children", () => {
expect(data.slides[0].content.__html).toStrictEqual(""); expect(data.slides[0].content.__html).toStrictEqual("");
}); });
it("rewrites links to other slides", () => {
expect(data.slides[1].content.__html).toStrictEqual(`<div class="ck-content"><p>Go to&nbsp;<a class="reference-link" href="#/slide1"><span class="bx bx-folder"></span>First slide</a>.</p></div>`);
});
it("doesn't rewrite links if they are not part of the slideshow", () => {
});
}); });

View File

@ -1,3 +1,4 @@
import { NoteType } from "@triliumnext/commons";
import FNote from "../../../entities/fnote"; import FNote from "../../../entities/fnote";
import contentRenderer from "../../../services/content_renderer"; import contentRenderer from "../../../services/content_renderer";
@ -11,6 +12,7 @@ interface PresentationSlideModel extends PresentationSlideBaseModel {
/** Either a top-level slide or a vertical slide. */ /** Either a top-level slide or a vertical slide. */
export interface PresentationSlideBaseModel { export interface PresentationSlideBaseModel {
noteId: string; noteId: string;
type: NoteType;
content: DangerouslySetInnerHTML; content: DangerouslySetInnerHTML;
backgroundColor?: string; backgroundColor?: string;
backgroundGradient?: string; backgroundGradient?: string;
@ -25,8 +27,9 @@ export async function buildPresentationModel(note: FNote): Promise<PresentationM
const slides: PresentationSlideModel[] = await Promise.all(slideNotes.map(async slideNote => ({ const slides: PresentationSlideModel[] = await Promise.all(slideNotes.map(async slideNote => ({
...(await buildSlideModel(slideNote)), ...(await buildSlideModel(slideNote)),
verticalSlides: await buildVerticalSlides(slideNote) verticalSlides: await buildVerticalSlides(slideNote)
}))) })));
postProcessSlides(slides);
return { slides }; return { slides };
} }
@ -45,6 +48,7 @@ async function buildSlideModel(note: FNote): Promise<PresentationSlideBaseModel>
return { return {
noteId: note.noteId, noteId: note.noteId,
type: note.type,
content: await processContent(note), content: await processContent(note),
backgroundColor: !isGradient ? slideBackground : undefined, backgroundColor: !isGradient ? slideBackground : undefined,
backgroundGradient: isGradient ? slideBackground : undefined backgroundGradient: isGradient ? slideBackground : undefined
@ -57,3 +61,10 @@ async function processContent(note: FNote): Promise<DangerouslySetInnerHTML> {
}); });
return { __html: $renderedContent.html() }; return { __html: $renderedContent.html() };
} }
async function postProcessSlides(slides: PresentationSlideModel[]) {
for (const slide of slides) {
if (slide.type !== "text") continue;
slide.content.__html = slide.content.__html.replaceAll(/href="[^"]*#root[a-zA-Z0-9_\/]*\/([a-zA-Z0-9_]+)[^"]*"/g, `href="#/$1"`);
}
}