mirror of
https://github.com/zadam/trilium.git
synced 2025-12-29 18:54:29 +01:00
chore(react/type_widget): scroll to end & focus
This commit is contained in:
parent
efaa1815ec
commit
46db047fa0
@ -869,6 +869,29 @@ export function getErrorMessage(e: unknown) {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Deduplicate with server
|
||||
export interface DeferredPromise<T> extends Promise<T> {
|
||||
resolve: (value: T | PromiseLike<T>) => void;
|
||||
reject: (reason?: any) => void;
|
||||
}
|
||||
|
||||
// TODO: Deduplicate with server
|
||||
export function deferred<T>(): DeferredPromise<T> {
|
||||
return (() => {
|
||||
let resolve!: (value: T | PromiseLike<T>) => void;
|
||||
let reject!: (reason?: any) => void;
|
||||
|
||||
let promise = new Promise<T>((res, rej) => {
|
||||
resolve = res;
|
||||
reject = rej;
|
||||
}) as DeferredPromise<T>;
|
||||
|
||||
promise.resolve = resolve;
|
||||
promise.reject = reject;
|
||||
return promise as DeferredPromise<T>;
|
||||
})();
|
||||
}
|
||||
|
||||
export default {
|
||||
reloadFrontendApp,
|
||||
restartDesktopApp,
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import { useRef, useState } from "preact/hooks";
|
||||
import dialog from "../../../services/dialog";
|
||||
import toast from "../../../services/toast";
|
||||
import utils, { isMobile } from "../../../services/utils";
|
||||
import { useEditorSpacedUpdate, useNoteLabel, useTriliumOption } from "../../react/hooks";
|
||||
import utils, { deferred, isMobile } from "../../../services/utils";
|
||||
import { useEditorSpacedUpdate, useNoteLabel, useTriliumEvent, useTriliumOption } from "../../react/hooks";
|
||||
import { TypeWidgetProps } from "../type_widget";
|
||||
import CKEditorWithWatchdog from "./CKEditorWithWatchdog";
|
||||
import "./EditableText.css";
|
||||
@ -15,12 +15,13 @@ import Component from "../../../components/component";
|
||||
* - Ballon block mode, in which there is a floating toolbar for the selected text, but another floating button for the entire block (i.e. paragraph).
|
||||
* - Decoupled mode, in which the editing toolbar is actually added on the client side (in {@link ClassicEditorToolbar}), see https://ckeditor.com/docs/ckeditor5/latest/examples/framework/bottom-toolbar-editor.html for an example on how the decoupled editor works.
|
||||
*/
|
||||
export default function EditableText({ note, parentComponent }: TypeWidgetProps) {
|
||||
export default function EditableText({ note, parentComponent, ntxId }: TypeWidgetProps) {
|
||||
const [ content, setContent ] = useState<string>();
|
||||
const watchdogRef = useRef<EditorWatchdog>(null);
|
||||
const [ language ] = useNoteLabel(note, "language");
|
||||
const [ textNoteEditorType ] = useTriliumOption("textNoteEditorType");
|
||||
const isClassicEditor = isMobile() || textNoteEditorType === "ckeditor-classic";
|
||||
const initialized = useRef(deferred<void>());
|
||||
const spacedUpdate = useEditorSpacedUpdate({
|
||||
note,
|
||||
getData() {
|
||||
@ -43,6 +44,27 @@ export default function EditableText({ note, parentComponent }: TypeWidgetProps)
|
||||
}
|
||||
})
|
||||
|
||||
useTriliumEvent("scrollToEnd", () => {
|
||||
const editor = watchdogRef.current?.editor;
|
||||
if (!editor) return;
|
||||
|
||||
editor.model.change((writer) => {
|
||||
const rootItem = editor.model.document.getRoot();
|
||||
if (rootItem) {
|
||||
writer.setSelection(writer.createPositionAt(rootItem, "end"));
|
||||
}
|
||||
});
|
||||
editor.editing.view.focus();
|
||||
});
|
||||
|
||||
useTriliumEvent("focusOnDetail", async ({ ntxId: eventNtxId }) => {
|
||||
if (eventNtxId !== ntxId) return;
|
||||
await initialized.current;
|
||||
const editor = watchdogRef.current?.editor;
|
||||
if (!editor) return;
|
||||
editor.editing.view.focus();
|
||||
});
|
||||
|
||||
return (
|
||||
<div class="note-detail-editable-text note-detail-printable">
|
||||
{note && <CKEditorWithWatchdog
|
||||
@ -68,6 +90,8 @@ export default function EditableText({ note, parentComponent }: TypeWidgetProps)
|
||||
if (isClassicEditor) {
|
||||
setupClassicEditor(editor, parentComponent);
|
||||
}
|
||||
|
||||
initialized.current.resolve();
|
||||
}}
|
||||
/>}
|
||||
</div>
|
||||
@ -106,7 +130,6 @@ function onNotificationWarning(data, evt) {
|
||||
function setupClassicEditor(editor: CKTextEditor, parentComponent: Component | undefined) {
|
||||
if (!parentComponent) return;
|
||||
const $classicToolbarWidget = findClassicToolbar(parentComponent);
|
||||
console.log("Found ", $classicToolbarWidget);
|
||||
|
||||
$classicToolbarWidget.empty();
|
||||
if ($classicToolbarWidget.length) {
|
||||
@ -140,7 +163,6 @@ function findClassicToolbar(parentComponent: Component): JQuery<HTMLElement> {
|
||||
|
||||
if (!utils.isMobile()) {
|
||||
const $parentSplit = $widget.parents(".note-split.type-text");
|
||||
console.log("Got split ", $parentSplit)
|
||||
|
||||
if ($parentSplit.length) {
|
||||
// The editor is in a normal tab.
|
||||
|
||||
@ -51,26 +51,6 @@ export default class EditableTextTypeWidget extends AbstractTextTypeWidget {
|
||||
await this.createEditor();
|
||||
}
|
||||
|
||||
focus() {
|
||||
const editor = this.watchdog.editor;
|
||||
if (editor) {
|
||||
editor.editing.view.focus();
|
||||
} else {
|
||||
this.$editor.trigger("focus");
|
||||
}
|
||||
}
|
||||
|
||||
scrollToEnd() {
|
||||
this.watchdog?.editor?.model.change((writer) => {
|
||||
const rootItem = this.watchdog?.editor?.model.document.getRoot();
|
||||
if (rootItem) {
|
||||
writer.setSelection(writer.createPositionAt(rootItem, "end"));
|
||||
}
|
||||
});
|
||||
|
||||
this.watchdog?.editor?.editing.view.focus();
|
||||
}
|
||||
|
||||
show() { }
|
||||
|
||||
getEditor() {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user