mirror of
https://github.com/zadam/trilium.git
synced 2025-11-11 17:08:58 +01:00
chore(react/type_widgets): bring back add include to note
This commit is contained in:
parent
0ac428b57a
commit
3673162a48
@ -34,6 +34,7 @@ import { ChooseNoteTypeCallback } from "../widgets/dialogs/note_type_chooser.jsx
|
||||
import type RootContainer from "../widgets/containers/root_container.js";
|
||||
import { SqlExecuteResults } from "@triliumnext/commons";
|
||||
import { AddLinkOpts } from "../widgets/dialogs/add_link.jsx";
|
||||
import { IncludeNoteOpts } from "../widgets/dialogs/include_note.jsx";
|
||||
|
||||
interface Layout {
|
||||
getRootWidget: (appContext: AppContext) => RootContainer;
|
||||
@ -223,7 +224,7 @@ export type CommandMappings = {
|
||||
showPasswordNotSet: CommandData;
|
||||
showProtectedSessionPasswordDialog: CommandData;
|
||||
showUploadAttachmentsDialog: CommandData & { noteId: string };
|
||||
showIncludeNoteDialog: CommandData & { textTypeWidget: EditableTextTypeWidget };
|
||||
showIncludeNoteDialog: CommandData & IncludeNoteOpts;
|
||||
showAddLinkDialog: CommandData & AddLinkOpts;
|
||||
closeProtectedSessionPasswordDialog: CommandData;
|
||||
copyImageReferenceToClipboard: CommandData;
|
||||
|
||||
@ -10,15 +10,20 @@ import tree from "../../services/tree";
|
||||
import froca from "../../services/froca";
|
||||
import EditableTextTypeWidget, { type BoxSize } from "../type_widgets_old/editable_text";
|
||||
import { useTriliumEvent } from "../react/hooks";
|
||||
import { CKEditorApi } from "../type_widgets/text/CKEditorWithWatchdog";
|
||||
|
||||
export interface IncludeNoteOpts {
|
||||
editorApi: CKEditorApi;
|
||||
}
|
||||
|
||||
export default function IncludeNoteDialog() {
|
||||
const [textTypeWidget, setTextTypeWidget] = useState<EditableTextTypeWidget>();
|
||||
const editorApiRef = useRef<CKEditorApi>(null);
|
||||
const [suggestion, setSuggestion] = useState<Suggestion | null>(null);
|
||||
const [boxSize, setBoxSize] = useState("medium");
|
||||
const [shown, setShown] = useState(false);
|
||||
|
||||
useTriliumEvent("showIncludeNoteDialog", ({ textTypeWidget }) => {
|
||||
setTextTypeWidget(textTypeWidget);
|
||||
useTriliumEvent("showIncludeNoteDialog", ({ editorApi }) => {
|
||||
editorApiRef.current = editorApi;
|
||||
setShown(true);
|
||||
});
|
||||
|
||||
@ -32,12 +37,9 @@ export default function IncludeNoteDialog() {
|
||||
onShown={() => triggerRecentNotes(autoCompleteRef.current)}
|
||||
onHidden={() => setShown(false)}
|
||||
onSubmit={() => {
|
||||
if (!suggestion?.notePath || !textTypeWidget) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!suggestion?.notePath || !editorApiRef.current) return;
|
||||
setShown(false);
|
||||
includeNote(suggestion.notePath, textTypeWidget, boxSize as BoxSize);
|
||||
includeNote(suggestion.notePath, editorApiRef.current, boxSize as BoxSize);
|
||||
}}
|
||||
footer={<Button text={t("include_note.button_include")} keyboardShortcut="Enter" />}
|
||||
show={shown}
|
||||
@ -69,7 +71,7 @@ export default function IncludeNoteDialog() {
|
||||
)
|
||||
}
|
||||
|
||||
async function includeNote(notePath: string, textTypeWidget: EditableTextTypeWidget, boxSize: BoxSize) {
|
||||
async function includeNote(notePath: string, editorApi: CKEditorApi, boxSize: BoxSize) {
|
||||
const noteId = tree.getNoteIdFromUrl(notePath);
|
||||
if (!noteId) {
|
||||
return;
|
||||
@ -79,8 +81,8 @@ async function includeNote(notePath: string, textTypeWidget: EditableTextTypeWid
|
||||
if (["image", "canvas", "mermaid"].includes(note?.type ?? "")) {
|
||||
// there's no benefit to use insert note functionlity for images,
|
||||
// so we'll just add an IMG tag
|
||||
textTypeWidget.addImage(noteId);
|
||||
editorApi.addImage(noteId);
|
||||
} else {
|
||||
textTypeWidget.addIncludeNote(noteId, boxSize);
|
||||
editorApi.addIncludeNote(noteId, boxSize);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,6 +3,9 @@ import { PopupEditor, ClassicEditor, EditorWatchdog, type WatchdogConfig, CKText
|
||||
import { buildConfig, BuildEditorOptions } from "./config";
|
||||
import { useLegacyImperativeHandlers } from "../../react/hooks";
|
||||
import link from "../../../services/link";
|
||||
import froca from "../../../services/froca";
|
||||
|
||||
export type BoxSize = "small" | "medium" | "full";
|
||||
|
||||
export interface CKEditorApi {
|
||||
/** returns true if user selected some text, false if there's no selection */
|
||||
@ -10,6 +13,8 @@ export interface CKEditorApi {
|
||||
getSelectedText(): string;
|
||||
addLink(notePath: string, linkTitle: string | null, externalLink?: boolean): void;
|
||||
addLinkToEditor(linkHref: string, linkTitle: string): void;
|
||||
addIncludeNote(noteId: string, boxSize?: BoxSize): void;
|
||||
addImage(noteId: string): Promise<void>;
|
||||
}
|
||||
|
||||
interface CKEditorWithWatchdogProps extends Pick<HTMLProps<HTMLDivElement>, "className" | "tabIndex"> {
|
||||
@ -78,6 +83,35 @@ export default function CKEditorWithWatchdog({ content, contentLanguage, classNa
|
||||
}
|
||||
});
|
||||
},
|
||||
addIncludeNote(noteId, boxSize) {
|
||||
const editor = watchdogRef.current?.editor;
|
||||
if (!editor) return;
|
||||
|
||||
editor?.model.change((writer) => {
|
||||
// Insert <includeNote>*</includeNote> at the current selection position
|
||||
// in a way that will result in creating a valid model structure
|
||||
editor?.model.insertContent(
|
||||
writer.createElement("includeNote", {
|
||||
noteId: noteId,
|
||||
boxSize: boxSize
|
||||
})
|
||||
);
|
||||
});
|
||||
},
|
||||
async addImage(noteId) {
|
||||
const editor = watchdogRef.current?.editor;
|
||||
if (!editor) return;
|
||||
|
||||
const note = await froca.getNote(noteId);
|
||||
if (!note) return;
|
||||
|
||||
editor.model.change(() => {
|
||||
const encodedTitle = encodeURIComponent(note.title);
|
||||
const src = `api/images/${note.noteId}/${encodedTitle}`;
|
||||
|
||||
editor?.execute("insertImage", { source: src });
|
||||
});
|
||||
},
|
||||
}));
|
||||
|
||||
useLegacyImperativeHandlers({
|
||||
|
||||
@ -2,13 +2,14 @@ import { useRef, useState } from "preact/hooks";
|
||||
import dialog from "../../../services/dialog";
|
||||
import toast from "../../../services/toast";
|
||||
import utils, { deferred, isMobile } from "../../../services/utils";
|
||||
import { useEditorSpacedUpdate, useKeyboardShortcuts, useNoteLabel, useTriliumEvent, useTriliumOption, useTriliumOptionBool } from "../../react/hooks";
|
||||
import { useEditorSpacedUpdate, useKeyboardShortcuts, useLegacyImperativeHandlers, useNoteLabel, useTriliumEvent, useTriliumOption, useTriliumOptionBool } from "../../react/hooks";
|
||||
import { TypeWidgetProps } from "../type_widget";
|
||||
import CKEditorWithWatchdog, { CKEditorApi } from "./CKEditorWithWatchdog";
|
||||
import "./EditableText.css";
|
||||
import { CKTextEditor, ClassicEditor, EditorWatchdog } from "@triliumnext/ckeditor5";
|
||||
import Component from "../../../components/component";
|
||||
import options from "../../../services/options";
|
||||
import { loadIncludedNote, refreshIncludedNote } from "./utils";
|
||||
|
||||
/**
|
||||
* The editor can operate into two distinct modes:
|
||||
@ -67,16 +68,30 @@ export default function EditableText({ note, parentComponent, ntxId, noteContext
|
||||
editor?.editing.view.focus();
|
||||
});
|
||||
|
||||
useTriliumEvent("addLinkToText", ({ ntxId: eventNtxId }) => {
|
||||
if (eventNtxId !== ntxId || !editorApiRef.current) return;
|
||||
parentComponent?.triggerCommand("showAddLinkDialog", {
|
||||
text: editorApiRef.current.getSelectedText(),
|
||||
hasSelection: editorApiRef.current.hasSelection(),
|
||||
async addLink(notePath, linkTitle, externalLink) {
|
||||
await waitForEditor();
|
||||
return editorApiRef.current?.addLink(notePath, linkTitle, externalLink);
|
||||
}
|
||||
});
|
||||
useLegacyImperativeHandlers({
|
||||
addLinkToTextCommand() {
|
||||
if (!editorApiRef.current) return;
|
||||
parentComponent?.triggerCommand("showAddLinkDialog", {
|
||||
text: editorApiRef.current.getSelectedText(),
|
||||
hasSelection: editorApiRef.current.hasSelection(),
|
||||
async addLink(notePath, linkTitle, externalLink) {
|
||||
await waitForEditor();
|
||||
return editorApiRef.current?.addLink(notePath, linkTitle, externalLink);
|
||||
}
|
||||
});
|
||||
},
|
||||
addIncludeNoteToTextCommand() {
|
||||
if (!editorApiRef.current) return;
|
||||
parentComponent?.triggerCommand("showIncludeNoteDialog", {
|
||||
editorApi: editorApiRef.current,
|
||||
});
|
||||
},
|
||||
loadIncludedNote
|
||||
});
|
||||
|
||||
useTriliumEvent("refreshIncludedNote", ({ noteId }) => {
|
||||
if (!containerRef.current) return;
|
||||
refreshIncludedNote(containerRef.current, noteId);
|
||||
});
|
||||
|
||||
async function waitForEditor() {
|
||||
|
||||
@ -39,6 +39,7 @@ export default function ReadOnlyText({ note, noteContext, ntxId }: TypeWidgetPro
|
||||
|
||||
// React to included note changes.
|
||||
useTriliumEvent("refreshIncludedNote", ({ noteId }) => {
|
||||
console.log("Refresh ", noteId);
|
||||
if (!contentRef.current) return;
|
||||
refreshIncludedNote(contentRef.current, noteId);
|
||||
});
|
||||
|
||||
@ -14,7 +14,6 @@ import type FNote from "../../entities/fnote.js";
|
||||
import { PopupEditor, ClassicEditor, EditorWatchdog, type CKTextEditor, type MentionFeed, type WatchdogConfig, EditorConfig } from "@triliumnext/ckeditor5";
|
||||
import { updateTemplateCache } from "./ckeditor/snippets.js";
|
||||
|
||||
export type BoxSize = "small" | "medium" | "full";
|
||||
|
||||
export default class EditableTextTypeWidget extends AbstractTextTypeWidget {
|
||||
|
||||
@ -105,37 +104,6 @@ export default class EditableTextTypeWidget extends AbstractTextTypeWidget {
|
||||
}
|
||||
}
|
||||
|
||||
addIncludeNoteToTextCommand() {
|
||||
this.triggerCommand("showIncludeNoteDialog", { textTypeWidget: this });
|
||||
}
|
||||
|
||||
addIncludeNote(noteId: string, boxSize?: BoxSize) {
|
||||
this.watchdog.editor?.model.change((writer) => {
|
||||
// Insert <includeNote>*</includeNote> at the current selection position
|
||||
// in a way that will result in creating a valid model structure
|
||||
this.watchdog.editor?.model.insertContent(
|
||||
writer.createElement("includeNote", {
|
||||
noteId: noteId,
|
||||
boxSize: boxSize
|
||||
})
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
async addImage(noteId: string) {
|
||||
const note = await froca.getNote(noteId);
|
||||
if (!note || !this.watchdog.editor) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.watchdog.editor.model.change((writer) => {
|
||||
const encodedTitle = encodeURIComponent(note.title);
|
||||
const src = `api/images/${note.noteId}/${encodedTitle}`;
|
||||
|
||||
this.watchdog.editor?.execute("insertImage", { source: src });
|
||||
});
|
||||
}
|
||||
|
||||
async createNoteForReferenceLink(title: string) {
|
||||
if (!this.notePath) {
|
||||
return;
|
||||
@ -153,10 +121,6 @@ export default class EditableTextTypeWidget extends AbstractTextTypeWidget {
|
||||
return resp.note.getBestNotePathString();
|
||||
}
|
||||
|
||||
async refreshIncludedNoteEvent({ noteId }: EventData<"refreshIncludedNote">) {
|
||||
this.refreshIncludedNote(this.$editor, noteId);
|
||||
}
|
||||
|
||||
async reinitialize() {
|
||||
const data = this.watchdog.editor?.getData();
|
||||
await this.reinitializeWithData(data ?? "");
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user