mirror of
https://github.com/zadam/trilium.git
synced 2025-11-10 23:35:50 +01:00
chore(react/type_widget): port doc widget
This commit is contained in:
@@ -6,6 +6,8 @@ import { useEffect, useState } from "preact/hooks";
|
||||
import NoteContext from "../components/note_context";
|
||||
import Empty from "./type_widgets/Empty";
|
||||
import { VNode } from "preact";
|
||||
import Doc from "./type_widgets/Doc";
|
||||
import { TypeWidgetProps } from "./type_widgets/type_widget";
|
||||
|
||||
/**
|
||||
* A `NoteType` altered by the note detail widget, taking into consideration whether the note is editable or not and adding special note types such as an empty one,
|
||||
@@ -18,9 +20,15 @@ type ExtendedNoteType = Exclude<NoteType, "launcher" | "text" | "code"> | "empty
|
||||
*/
|
||||
export default function NoteDetail() {
|
||||
const { note, type } = useNoteInfo();
|
||||
const { viewScope, ntxId } = useNoteContext();
|
||||
const [ correspondingWidget, setCorrespondingWidget ] = useState<VNode>();
|
||||
|
||||
useEffect(() => setCorrespondingWidget(getCorrespondingWidget(type)), [ type ]);
|
||||
const props: TypeWidgetProps = {
|
||||
note: note!,
|
||||
viewScope,
|
||||
ntxId
|
||||
};
|
||||
useEffect(() => setCorrespondingWidget(getCorrespondingWidget(type, props)), [ note, viewScope, type ]);
|
||||
|
||||
return (
|
||||
<div>
|
||||
@@ -45,10 +53,12 @@ function useNoteInfo() {
|
||||
return { note, type };
|
||||
}
|
||||
|
||||
function getCorrespondingWidget(noteType: ExtendedNoteType | undefined) {
|
||||
function getCorrespondingWidget(noteType: ExtendedNoteType | undefined, props: TypeWidgetProps) {
|
||||
switch (noteType) {
|
||||
case "empty":
|
||||
return <Empty />
|
||||
case "doc":
|
||||
return <Doc {...props} />
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
50
apps/client/src/widgets/type_widgets/Doc.css
Normal file
50
apps/client/src/widgets/type_widgets/Doc.css
Normal file
@@ -0,0 +1,50 @@
|
||||
.note-detail-doc-content {
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.note-detail-doc-content pre {
|
||||
border: 0;
|
||||
box-shadow: var(--code-block-box-shadow);
|
||||
padding: 15px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.note-detail-doc-content code {
|
||||
font-variant: none;
|
||||
}
|
||||
|
||||
.note-detail-doc-content pre:not(.hljs) {
|
||||
background-color: var(--accented-background-color);
|
||||
border: 1px solid var(--main-border-color);
|
||||
}
|
||||
|
||||
.note-detail-doc.contextual-help {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.note-detail-doc.contextual-help h2,
|
||||
.note-detail-doc.contextual-help h3,
|
||||
.note-detail-doc.contextual-help h4,
|
||||
.note-detail-doc.contextual-help h5,
|
||||
.note-detail-doc.contextual-help h6 {
|
||||
font-size: 1.25rem;
|
||||
background-color: var(--main-background-color);
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 50;
|
||||
margin: 0;
|
||||
padding-bottom: 0.25em;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
td img {
|
||||
max-width: 40vw;
|
||||
}
|
||||
|
||||
figure.table {
|
||||
overflow: auto !important;
|
||||
}
|
||||
38
apps/client/src/widgets/type_widgets/Doc.tsx
Normal file
38
apps/client/src/widgets/type_widgets/Doc.tsx
Normal file
@@ -0,0 +1,38 @@
|
||||
import { useEffect, useRef, useState } from "preact/hooks";
|
||||
import { RawHtmlBlock } from "../react/RawHtml";
|
||||
import renderDoc from "../../services/doc_renderer";
|
||||
import "./Doc.css";
|
||||
import { TypeWidgetProps } from "./type_widget";
|
||||
import { useTriliumEvent } from "../react/hooks";
|
||||
import { refToJQuerySelector } from "../react/react_utils";
|
||||
|
||||
export default function Doc({ note, viewScope, ntxId }: TypeWidgetProps) {
|
||||
const [ html, setHtml ] = useState<string>();
|
||||
const initialized = useRef<Promise<void> | null>(null);
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (!note) return;
|
||||
|
||||
initialized.current = renderDoc(note).then($content => {
|
||||
setHtml($content.html());
|
||||
});
|
||||
}, [ note ]);
|
||||
|
||||
useTriliumEvent("executeWithContentElement", async ({ resolve, ntxId: eventNtxId}) => {
|
||||
console.log("Got request for content ", ntxId, eventNtxId);
|
||||
if (eventNtxId !== ntxId) return;
|
||||
await initialized.current;
|
||||
resolve(refToJQuerySelector(containerRef));
|
||||
});
|
||||
|
||||
return (
|
||||
<div className={`note-detail-doc note-detail-printable ${viewScope?.viewMode === "contextual-help" ? "contextual-help" : ""}`}>
|
||||
<RawHtmlBlock
|
||||
containerRef={containerRef}
|
||||
className="note-detail-doc-content ck-content"
|
||||
html={html}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
8
apps/client/src/widgets/type_widgets/type_widget.ts
Normal file
8
apps/client/src/widgets/type_widgets/type_widget.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import FNote from "../../entities/fnote";
|
||||
import { ViewScope } from "../../services/link";
|
||||
|
||||
export interface TypeWidgetProps {
|
||||
note: FNote;
|
||||
viewScope: ViewScope | undefined;
|
||||
ntxId: string | null | undefined;
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
import type { EventData } from "../../components/app_context.js";
|
||||
import type FNote from "../../entities/fnote.js";
|
||||
import renderDoc from "../../services/doc_renderer.js";
|
||||
import TypeWidget from "./type_widget.js";
|
||||
|
||||
const TPL = /*html*/`<div class="note-detail-doc note-detail-printable">
|
||||
<style>
|
||||
.note-detail-doc-content {
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.note-detail-doc-content pre {
|
||||
border: 0;
|
||||
box-shadow: var(--code-block-box-shadow);
|
||||
padding: 15px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.note-detail-doc-content code {
|
||||
font-variant: none;
|
||||
}
|
||||
|
||||
.note-detail-doc-content pre:not(.hljs) {
|
||||
background-color: var(--accented-background-color);
|
||||
border: 1px solid var(--main-border-color);
|
||||
}
|
||||
|
||||
.note-detail-doc.contextual-help {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.note-detail-doc.contextual-help h2,
|
||||
.note-detail-doc.contextual-help h3,
|
||||
.note-detail-doc.contextual-help h4,
|
||||
.note-detail-doc.contextual-help h5,
|
||||
.note-detail-doc.contextual-help h6 {
|
||||
font-size: 1.25rem;
|
||||
background-color: var(--main-background-color);
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 50;
|
||||
margin: 0;
|
||||
padding-bottom: 0.25em;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
td img {
|
||||
max-width: 40vw;
|
||||
}
|
||||
|
||||
figure.table {
|
||||
overflow: auto !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="note-detail-doc-content ck-content"></div>
|
||||
</div>`;
|
||||
|
||||
export default class DocTypeWidget extends TypeWidget {
|
||||
|
||||
private $content!: JQuery<HTMLElement>;
|
||||
|
||||
static getType() {
|
||||
return "doc";
|
||||
}
|
||||
|
||||
doRender() {
|
||||
this.$widget = $(TPL);
|
||||
this.$content = this.$widget.find(".note-detail-doc-content");
|
||||
|
||||
super.doRender();
|
||||
}
|
||||
|
||||
async doRefresh(note: FNote) {
|
||||
this.initialized = renderDoc(note).then(($content) => {
|
||||
this.$content.html($content.html());
|
||||
});
|
||||
this.$widget.toggleClass("contextual-help", this.noteContext?.viewScope?.viewMode === "contextual-help");
|
||||
}
|
||||
|
||||
async executeWithContentElementEvent({ resolve, ntxId }: EventData<"executeWithContentElement">) {
|
||||
if (!this.isNoteContext(ntxId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
await this.initialized;
|
||||
|
||||
resolve(this.$content);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user