mirror of
https://github.com/zadam/trilium.git
synced 2025-11-01 03:59:05 +01:00
refactor(react): use beta approach for handling events everywhere
This commit is contained in:
parent
a507991808
commit
f2db7baeba
@ -1,6 +1,8 @@
|
|||||||
import utils from "../services/utils.js";
|
import utils from "../services/utils.js";
|
||||||
import type { CommandMappings, CommandNames, EventData, EventNames } from "./app_context.js";
|
import type { CommandMappings, CommandNames, EventData, EventNames } from "./app_context.js";
|
||||||
|
|
||||||
|
type EventHandler = ((data: any) => void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract class for all components in the Trilium's frontend.
|
* Abstract class for all components in the Trilium's frontend.
|
||||||
*
|
*
|
||||||
@ -19,6 +21,7 @@ export class TypedComponent<ChildT extends TypedComponent<ChildT>> {
|
|||||||
initialized: Promise<void> | null;
|
initialized: Promise<void> | null;
|
||||||
parent?: TypedComponent<any>;
|
parent?: TypedComponent<any>;
|
||||||
_position!: number;
|
_position!: number;
|
||||||
|
private listeners: Record<string, EventHandler[]> | null = {};
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.componentId = `${this.sanitizedClassName}-${utils.randomString(8)}`;
|
this.componentId = `${this.sanitizedClassName}-${utils.randomString(8)}`;
|
||||||
@ -76,6 +79,14 @@ export class TypedComponent<ChildT extends TypedComponent<ChildT>> {
|
|||||||
handleEventInChildren<T extends EventNames>(name: T, data: EventData<T>): Promise<unknown[] | unknown> | null {
|
handleEventInChildren<T extends EventNames>(name: T, data: EventData<T>): Promise<unknown[] | unknown> | null {
|
||||||
const promises: Promise<unknown>[] = [];
|
const promises: Promise<unknown>[] = [];
|
||||||
|
|
||||||
|
// Handle React children.
|
||||||
|
if (this.listeners?.[name]) {
|
||||||
|
for (const listener of this.listeners[name]) {
|
||||||
|
listener(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle legacy children.
|
||||||
for (const child of this.children) {
|
for (const child of this.children) {
|
||||||
const ret = child.handleEvent(name, data) as Promise<void>;
|
const ret = child.handleEvent(name, data) as Promise<void>;
|
||||||
|
|
||||||
@ -120,6 +131,35 @@ export class TypedComponent<ChildT extends TypedComponent<ChildT>> {
|
|||||||
|
|
||||||
return promise;
|
return promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
registerHandler<T extends EventNames>(name: T, handler: EventHandler) {
|
||||||
|
if (!this.listeners) {
|
||||||
|
this.listeners = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.listeners[name]) {
|
||||||
|
this.listeners[name] = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.listeners[name].includes(handler)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.listeners[name].push(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
removeHandler<T extends EventNames>(name: T, handler: EventHandler) {
|
||||||
|
if (!this.listeners?.[name]?.includes(handler)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.listeners[name] = this.listeners[name]
|
||||||
|
.filter(listener => listener !== handler);
|
||||||
|
|
||||||
|
if (!this.listeners[name].length) {
|
||||||
|
delete this.listeners[name];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class Component extends TypedComponent<Component> {}
|
export default class Component extends TypedComponent<Component> {}
|
||||||
|
|||||||
@ -278,12 +278,9 @@ export function wrapReactWidgets<T extends TypedComponent<any>>(components: (T |
|
|||||||
return wrappedResult;
|
return wrappedResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
type EventHandler = ((data: any) => void);
|
|
||||||
|
|
||||||
export class ReactWrappedWidget extends BasicWidget {
|
export class ReactWrappedWidget extends BasicWidget {
|
||||||
|
|
||||||
private el: VNode;
|
private el: VNode;
|
||||||
private listeners: Record<string, EventHandler[]> = {};
|
|
||||||
|
|
||||||
constructor(el: VNode) {
|
constructor(el: VNode) {
|
||||||
super();
|
super();
|
||||||
@ -294,41 +291,4 @@ export class ReactWrappedWidget extends BasicWidget {
|
|||||||
this.$widget = renderReactWidget(this, this.el);
|
this.$widget = renderReactWidget(this, this.el);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleEvent<T extends EventNames>(name: T, data: EventData<T>): Promise<unknown[] | unknown> | null | undefined {
|
|
||||||
if (!this.listeners[name]) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const listener of this.listeners[name]) {
|
|
||||||
listener(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
super.handleEvent(name, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
registerHandler<T extends EventNames>(name: T, handler: EventHandler) {
|
|
||||||
if (!this.listeners[name]) {
|
|
||||||
this.listeners[name] = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.listeners[name].includes(handler)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.listeners[name].push(handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
removeHandler<T extends EventNames>(name: T, handler: EventHandler) {
|
|
||||||
if (!this.listeners[name]?.includes(handler)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.listeners[name] = this.listeners[name]
|
|
||||||
.filter(listener => listener !== handler);
|
|
||||||
|
|
||||||
if (!this.listeners[name].length) {
|
|
||||||
delete this.listeners[name];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,14 +7,14 @@ import openService from "../../services/open.js";
|
|||||||
import { useState } from "preact/hooks";
|
import { useState } from "preact/hooks";
|
||||||
import type { CSSProperties } from "preact/compat";
|
import type { CSSProperties } from "preact/compat";
|
||||||
import type { AppInfo } from "@triliumnext/commons";
|
import type { AppInfo } from "@triliumnext/commons";
|
||||||
import { useTriliumEventBeta } from "../react/hooks.jsx";
|
import { useTriliumEvent } from "../react/hooks.jsx";
|
||||||
|
|
||||||
export default function AboutDialog() {
|
export default function AboutDialog() {
|
||||||
let [appInfo, setAppInfo] = useState<AppInfo | null>(null);
|
let [appInfo, setAppInfo] = useState<AppInfo | null>(null);
|
||||||
let [shown, setShown] = useState(false);
|
let [shown, setShown] = useState(false);
|
||||||
const forceWordBreak: CSSProperties = { wordBreak: "break-all" };
|
const forceWordBreak: CSSProperties = { wordBreak: "break-all" };
|
||||||
|
|
||||||
useTriliumEventBeta("openAboutDialog", () => setShown(true));
|
useTriliumEvent("openAboutDialog", () => setShown(true));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal className="about-dialog"
|
<Modal className="about-dialog"
|
||||||
|
|||||||
@ -11,7 +11,7 @@ import { default as TextTypeWidget } from "../type_widgets/editable_text.js";
|
|||||||
import { logError } from "../../services/ws";
|
import { logError } from "../../services/ws";
|
||||||
import FormGroup from "../react/FormGroup.js";
|
import FormGroup from "../react/FormGroup.js";
|
||||||
import { refToJQuerySelector } from "../react/react_utils";
|
import { refToJQuerySelector } from "../react/react_utils";
|
||||||
import { useTriliumEventBeta } from "../react/hooks";
|
import { useTriliumEvent } from "../react/hooks";
|
||||||
|
|
||||||
type LinkType = "reference-link" | "external-link" | "hyper-link";
|
type LinkType = "reference-link" | "external-link" | "hyper-link";
|
||||||
|
|
||||||
@ -24,7 +24,7 @@ export default function AddLinkDialog() {
|
|||||||
const [ suggestion, setSuggestion ] = useState<Suggestion | null>(null);
|
const [ suggestion, setSuggestion ] = useState<Suggestion | null>(null);
|
||||||
const [ shown, setShown ] = useState(false);
|
const [ shown, setShown ] = useState(false);
|
||||||
|
|
||||||
useTriliumEventBeta("showAddLinkDialog", ( { textTypeWidget, text }) => {
|
useTriliumEvent("showAddLinkDialog", ( { textTypeWidget, text }) => {
|
||||||
setTextTypeWidget(textTypeWidget);
|
setTextTypeWidget(textTypeWidget);
|
||||||
initialText.current = text;
|
initialText.current = text;
|
||||||
setShown(true);
|
setShown(true);
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import froca from "../../services/froca.js";
|
|||||||
import tree from "../../services/tree.js";
|
import tree from "../../services/tree.js";
|
||||||
import Button from "../react/Button.jsx";
|
import Button from "../react/Button.jsx";
|
||||||
import FormGroup from "../react/FormGroup.js";
|
import FormGroup from "../react/FormGroup.js";
|
||||||
import { useTriliumEventBeta } from "../react/hooks.jsx";
|
import { useTriliumEvent } from "../react/hooks.jsx";
|
||||||
import FBranch from "../../entities/fbranch.js";
|
import FBranch from "../../entities/fbranch.js";
|
||||||
|
|
||||||
export default function BranchPrefixDialog() {
|
export default function BranchPrefixDialog() {
|
||||||
@ -17,7 +17,7 @@ export default function BranchPrefixDialog() {
|
|||||||
const [ prefix, setPrefix ] = useState(branch?.prefix ?? "");
|
const [ prefix, setPrefix ] = useState(branch?.prefix ?? "");
|
||||||
const branchInput = useRef<HTMLInputElement>(null);
|
const branchInput = useRef<HTMLInputElement>(null);
|
||||||
|
|
||||||
useTriliumEventBeta("editBranchPrefix", async () => {
|
useTriliumEvent("editBranchPrefix", async () => {
|
||||||
const notePath = appContext.tabManager.getActiveContextNotePath();
|
const notePath = appContext.tabManager.getActiveContextNotePath();
|
||||||
if (!notePath) {
|
if (!notePath) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -12,7 +12,7 @@ import toast from "../../services/toast";
|
|||||||
import RenameNoteBulkAction from "../bulk_actions/note/rename_note";
|
import RenameNoteBulkAction from "../bulk_actions/note/rename_note";
|
||||||
import FNote from "../../entities/fnote";
|
import FNote from "../../entities/fnote";
|
||||||
import froca from "../../services/froca";
|
import froca from "../../services/froca";
|
||||||
import { useTriliumEventBeta } from "../react/hooks";
|
import { useTriliumEvent } from "../react/hooks";
|
||||||
|
|
||||||
export default function BulkActionsDialog() {
|
export default function BulkActionsDialog() {
|
||||||
const [ selectedOrActiveNoteIds, setSelectedOrActiveNoteIds ] = useState<string[]>();
|
const [ selectedOrActiveNoteIds, setSelectedOrActiveNoteIds ] = useState<string[]>();
|
||||||
@ -22,7 +22,7 @@ export default function BulkActionsDialog() {
|
|||||||
const [ existingActions, setExistingActions ] = useState<RenameNoteBulkAction[]>([]);
|
const [ existingActions, setExistingActions ] = useState<RenameNoteBulkAction[]>([]);
|
||||||
const [ shown, setShown ] = useState(false);
|
const [ shown, setShown ] = useState(false);
|
||||||
|
|
||||||
useTriliumEventBeta("openBulkActionsDialog", async ({ selectedOrActiveNoteIds }) => {
|
useTriliumEvent("openBulkActionsDialog", async ({ selectedOrActiveNoteIds }) => {
|
||||||
setSelectedOrActiveNoteIds(selectedOrActiveNoteIds);
|
setSelectedOrActiveNoteIds(selectedOrActiveNoteIds);
|
||||||
setBulkActionNote(await froca.getNote("_bulkAction"));
|
setBulkActionNote(await froca.getNote("_bulkAction"));
|
||||||
setShown(true);
|
setShown(true);
|
||||||
@ -46,7 +46,7 @@ export default function BulkActionsDialog() {
|
|||||||
refreshExistingActions();
|
refreshExistingActions();
|
||||||
}, [refreshExistingActions]);
|
}, [refreshExistingActions]);
|
||||||
|
|
||||||
useTriliumEventBeta("entitiesReloaded", ({ loadResults }) => {
|
useTriliumEvent("entitiesReloaded", ({ loadResults }) => {
|
||||||
if (loadResults.getAttributeRows().find((row) =>
|
if (loadResults.getAttributeRows().find((row) =>
|
||||||
row.type === "label" && row.name === "action" && row.noteId === "_bulkAction")) {
|
row.type === "label" && row.name === "action" && row.noteId === "_bulkAction")) {
|
||||||
refreshExistingActions();
|
refreshExistingActions();
|
||||||
|
|||||||
@ -13,7 +13,7 @@ import tree from "../../services/tree";
|
|||||||
import branches from "../../services/branches";
|
import branches from "../../services/branches";
|
||||||
import toast from "../../services/toast";
|
import toast from "../../services/toast";
|
||||||
import NoteList from "../react/NoteList";
|
import NoteList from "../react/NoteList";
|
||||||
import { useTriliumEventBeta } from "../react/hooks";
|
import { useTriliumEvent } from "../react/hooks";
|
||||||
|
|
||||||
export default function CloneToDialog() {
|
export default function CloneToDialog() {
|
||||||
const [ clonedNoteIds, setClonedNoteIds ] = useState<string[]>();
|
const [ clonedNoteIds, setClonedNoteIds ] = useState<string[]>();
|
||||||
@ -22,7 +22,7 @@ export default function CloneToDialog() {
|
|||||||
const [ shown, setShown ] = useState(false);
|
const [ shown, setShown ] = useState(false);
|
||||||
const autoCompleteRef = useRef<HTMLInputElement>(null);
|
const autoCompleteRef = useRef<HTMLInputElement>(null);
|
||||||
|
|
||||||
useTriliumEventBeta("cloneNoteIdsTo", ({ noteIds }) => {
|
useTriliumEvent("cloneNoteIdsTo", ({ noteIds }) => {
|
||||||
if (!noteIds || noteIds.length === 0) {
|
if (!noteIds || noteIds.length === 0) {
|
||||||
noteIds = [appContext.tabManager.getActiveContextNoteId() ?? ""];
|
noteIds = [appContext.tabManager.getActiveContextNoteId() ?? ""];
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import Button from "../react/Button";
|
|||||||
import { t } from "../../services/i18n";
|
import { t } from "../../services/i18n";
|
||||||
import { useState } from "preact/hooks";
|
import { useState } from "preact/hooks";
|
||||||
import FormCheckbox from "../react/FormCheckbox";
|
import FormCheckbox from "../react/FormCheckbox";
|
||||||
import { useTriliumEventBeta } from "../react/hooks";
|
import { useTriliumEvent } from "../react/hooks";
|
||||||
|
|
||||||
interface ConfirmDialogProps {
|
interface ConfirmDialogProps {
|
||||||
title?: string;
|
title?: string;
|
||||||
@ -27,8 +27,8 @@ export default function ConfirmDialog() {
|
|||||||
setShown(true);
|
setShown(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
useTriliumEventBeta("showConfirmDialog", ({ message, callback }) => showDialog(null, message, callback, false));
|
useTriliumEvent("showConfirmDialog", ({ message, callback }) => showDialog(null, message, callback, false));
|
||||||
useTriliumEventBeta("showConfirmDeleteNoteBoxWithNoteDialog", ({ title, callback }) => showDialog(title, t("confirm.are_you_sure_remove_note", { title: title }), callback, true));
|
useTriliumEvent("showConfirmDeleteNoteBoxWithNoteDialog", ({ title, callback }) => showDialog(title, t("confirm.are_you_sure_remove_note", { title: title }), callback, true));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
|
|||||||
@ -2,7 +2,6 @@ import { useRef, useState, useEffect } from "preact/hooks";
|
|||||||
import { t } from "../../services/i18n.js";
|
import { t } from "../../services/i18n.js";
|
||||||
import FormCheckbox from "../react/FormCheckbox.js";
|
import FormCheckbox from "../react/FormCheckbox.js";
|
||||||
import Modal from "../react/Modal.js";
|
import Modal from "../react/Modal.js";
|
||||||
import ReactBasicWidget from "../react/ReactBasicWidget.js";
|
|
||||||
import type { DeleteNotesPreview } from "@triliumnext/commons";
|
import type { DeleteNotesPreview } from "@triliumnext/commons";
|
||||||
import server from "../../services/server.js";
|
import server from "../../services/server.js";
|
||||||
import froca from "../../services/froca.js";
|
import froca from "../../services/froca.js";
|
||||||
@ -10,7 +9,7 @@ import FNote from "../../entities/fnote.js";
|
|||||||
import link from "../../services/link.js";
|
import link from "../../services/link.js";
|
||||||
import Button from "../react/Button.jsx";
|
import Button from "../react/Button.jsx";
|
||||||
import Alert from "../react/Alert.jsx";
|
import Alert from "../react/Alert.jsx";
|
||||||
import useTriliumEvent, { useTriliumEventBeta } from "../react/hooks.jsx";
|
import { useTriliumEvent } from "../react/hooks.jsx";
|
||||||
|
|
||||||
export interface ResolveOptions {
|
export interface ResolveOptions {
|
||||||
proceed: boolean;
|
proceed: boolean;
|
||||||
@ -39,7 +38,7 @@ export default function DeleteNotesDialog() {
|
|||||||
const [ shown, setShown ] = useState(false);
|
const [ shown, setShown ] = useState(false);
|
||||||
const okButtonRef = useRef<HTMLButtonElement>(null);
|
const okButtonRef = useRef<HTMLButtonElement>(null);
|
||||||
|
|
||||||
useTriliumEventBeta("showDeleteNotesDialog", (opts) => {
|
useTriliumEvent("showDeleteNotesDialog", (opts) => {
|
||||||
setOpts(opts);
|
setOpts(opts);
|
||||||
setShown(true);
|
setShown(true);
|
||||||
})
|
})
|
||||||
|
|||||||
@ -11,7 +11,7 @@ import toastService, { ToastOptions } from "../../services/toast";
|
|||||||
import utils from "../../services/utils";
|
import utils from "../../services/utils";
|
||||||
import open from "../../services/open";
|
import open from "../../services/open";
|
||||||
import froca from "../../services/froca";
|
import froca from "../../services/froca";
|
||||||
import { useTriliumEventBeta } from "../react/hooks";
|
import { useTriliumEvent } from "../react/hooks";
|
||||||
|
|
||||||
interface ExportDialogProps {
|
interface ExportDialogProps {
|
||||||
branchId?: string | null;
|
branchId?: string | null;
|
||||||
@ -27,7 +27,7 @@ export default function ExportDialog() {
|
|||||||
const [ opmlVersion, setOpmlVersion ] = useState("2.0");
|
const [ opmlVersion, setOpmlVersion ] = useState("2.0");
|
||||||
const [ shown, setShown ] = useState(false);
|
const [ shown, setShown ] = useState(false);
|
||||||
|
|
||||||
useTriliumEventBeta("showExportDialog", async ({ notePath, defaultType }) => {
|
useTriliumEvent("showExportDialog", async ({ notePath, defaultType }) => {
|
||||||
const { noteId, parentNoteId } = tree.getNoteIdAndParentIdFromUrl(notePath);
|
const { noteId, parentNoteId } = tree.getNoteIdAndParentIdFromUrl(notePath);
|
||||||
if (!parentNoteId) {
|
if (!parentNoteId) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -5,11 +5,11 @@ import { CommandNames } from "../../components/app_context.js";
|
|||||||
import RawHtml from "../react/RawHtml.jsx";
|
import RawHtml from "../react/RawHtml.jsx";
|
||||||
import { useEffect, useState } from "preact/hooks";
|
import { useEffect, useState } from "preact/hooks";
|
||||||
import keyboard_actions from "../../services/keyboard_actions.js";
|
import keyboard_actions from "../../services/keyboard_actions.js";
|
||||||
import { useTriliumEventBeta } from "../react/hooks.jsx";
|
import { useTriliumEvent } from "../react/hooks.jsx";
|
||||||
|
|
||||||
export default function HelpDialog() {
|
export default function HelpDialog() {
|
||||||
const [ shown, setShown ] = useState(false);
|
const [ shown, setShown ] = useState(false);
|
||||||
useTriliumEventBeta("showCheatsheet", () => setShown(true));
|
useTriliumEvent("showCheatsheet", () => setShown(true));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import Modal from "../react/Modal";
|
|||||||
import RawHtml from "../react/RawHtml";
|
import RawHtml from "../react/RawHtml";
|
||||||
import ReactBasicWidget from "../react/ReactBasicWidget";
|
import ReactBasicWidget from "../react/ReactBasicWidget";
|
||||||
import importService, { UploadFilesOptions } from "../../services/import";
|
import importService, { UploadFilesOptions } from "../../services/import";
|
||||||
import { useTriliumEventBeta } from "../react/hooks";
|
import { useTriliumEvent } from "../react/hooks";
|
||||||
|
|
||||||
export default function ImportDialog() {
|
export default function ImportDialog() {
|
||||||
const [ parentNoteId, setParentNoteId ] = useState<string>();
|
const [ parentNoteId, setParentNoteId ] = useState<string>();
|
||||||
@ -23,7 +23,7 @@ export default function ImportDialog() {
|
|||||||
const [ replaceUnderscoresWithSpaces, setReplaceUnderscoresWithSpaces ] = useState(true);
|
const [ replaceUnderscoresWithSpaces, setReplaceUnderscoresWithSpaces ] = useState(true);
|
||||||
const [ shown, setShown ] = useState(false);
|
const [ shown, setShown ] = useState(false);
|
||||||
|
|
||||||
useTriliumEventBeta("showImportDialog", ({ noteId }) => {
|
useTriliumEvent("showImportDialog", ({ noteId }) => {
|
||||||
setParentNoteId(noteId);
|
setParentNoteId(noteId);
|
||||||
tree.getNoteTitle(noteId).then(setNoteTitle);
|
tree.getNoteTitle(noteId).then(setNoteTitle);
|
||||||
setShown(true);
|
setShown(true);
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import { Suggestion, triggerRecentNotes } from "../../services/note_autocomplete
|
|||||||
import tree from "../../services/tree";
|
import tree from "../../services/tree";
|
||||||
import froca from "../../services/froca";
|
import froca from "../../services/froca";
|
||||||
import EditableTextTypeWidget from "../type_widgets/editable_text";
|
import EditableTextTypeWidget from "../type_widgets/editable_text";
|
||||||
import useTriliumEvent from "../react/hooks";
|
import { useTriliumEvent } from "../react/hooks";
|
||||||
|
|
||||||
export default function IncludeNoteDialog() {
|
export default function IncludeNoteDialog() {
|
||||||
const [textTypeWidget, setTextTypeWidget] = useState<EditableTextTypeWidget>();
|
const [textTypeWidget, setTextTypeWidget] = useState<EditableTextTypeWidget>();
|
||||||
|
|||||||
@ -4,12 +4,12 @@ import utils from "../../services/utils.js";
|
|||||||
import Button from "../react/Button.js";
|
import Button from "../react/Button.js";
|
||||||
import Modal from "../react/Modal.js";
|
import Modal from "../react/Modal.js";
|
||||||
import { useState } from "preact/hooks";
|
import { useState } from "preact/hooks";
|
||||||
import { useTriliumEventBeta } from "../react/hooks.jsx";
|
import { useTriliumEvent } from "../react/hooks.jsx";
|
||||||
|
|
||||||
export default function IncorrectCpuArchDialogComponent() {
|
export default function IncorrectCpuArchDialogComponent() {
|
||||||
const [ shown, setShown ] = useState(false);
|
const [ shown, setShown ] = useState(false);
|
||||||
const downloadButtonRef = useRef<HTMLButtonElement>(null);
|
const downloadButtonRef = useRef<HTMLButtonElement>(null);
|
||||||
useTriliumEventBeta("showCpuArchWarning", () => setShown(true));
|
useTriliumEvent("showCpuArchWarning", () => setShown(true));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
|
|||||||
@ -4,14 +4,14 @@ import { t } from "../../services/i18n";
|
|||||||
import Button from "../react/Button";
|
import Button from "../react/Button";
|
||||||
import { useRef, useState } from "preact/hooks";
|
import { useRef, useState } from "preact/hooks";
|
||||||
import { RawHtmlBlock } from "../react/RawHtml";
|
import { RawHtmlBlock } from "../react/RawHtml";
|
||||||
import { useTriliumEventBeta } from "../react/hooks";
|
import { useTriliumEvent } from "../react/hooks";
|
||||||
|
|
||||||
export default function InfoDialog() {
|
export default function InfoDialog() {
|
||||||
const [ opts, setOpts ] = useState<EventData<"showInfoDialog">>();
|
const [ opts, setOpts ] = useState<EventData<"showInfoDialog">>();
|
||||||
const [ shown, setShown ] = useState(false);
|
const [ shown, setShown ] = useState(false);
|
||||||
const okButtonRef = useRef<HTMLButtonElement>(null);
|
const okButtonRef = useRef<HTMLButtonElement>(null);
|
||||||
|
|
||||||
useTriliumEventBeta("showInfoDialog", (opts) => {
|
useTriliumEvent("showInfoDialog", (opts) => {
|
||||||
setOpts(opts);
|
setOpts(opts);
|
||||||
setShown(true);
|
setShown(true);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import note_autocomplete, { Suggestion } from "../../services/note_autocomplete"
|
|||||||
import appContext from "../../components/app_context";
|
import appContext from "../../components/app_context";
|
||||||
import commandRegistry from "../../services/command_registry";
|
import commandRegistry from "../../services/command_registry";
|
||||||
import { refToJQuerySelector } from "../react/react_utils";
|
import { refToJQuerySelector } from "../react/react_utils";
|
||||||
import { useTriliumEventBeta } from "../react/hooks";
|
import { useTriliumEvent } from "../react/hooks";
|
||||||
|
|
||||||
const KEEP_LAST_SEARCH_FOR_X_SECONDS = 120;
|
const KEEP_LAST_SEARCH_FOR_X_SECONDS = 120;
|
||||||
|
|
||||||
@ -50,8 +50,8 @@ export default function JumpToNoteDialogComponent() {
|
|||||||
setLastOpenedTs(Date.now());
|
setLastOpenedTs(Date.now());
|
||||||
}
|
}
|
||||||
|
|
||||||
useTriliumEventBeta("jumpToNote", () => openDialog(false));
|
useTriliumEvent("jumpToNote", () => openDialog(false));
|
||||||
useTriliumEventBeta("commandPalette", () => openDialog(true));
|
useTriliumEvent("commandPalette", () => openDialog(true));
|
||||||
|
|
||||||
async function onItemSelected(suggestion?: Suggestion | null) {
|
async function onItemSelected(suggestion?: Suggestion | null) {
|
||||||
if (!suggestion) {
|
if (!suggestion) {
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import toast from "../../services/toast";
|
|||||||
import utils from "../../services/utils";
|
import utils from "../../services/utils";
|
||||||
import Modal from "../react/Modal";
|
import Modal from "../react/Modal";
|
||||||
import Button from "../react/Button";
|
import Button from "../react/Button";
|
||||||
import { useTriliumEventBeta } from "../react/hooks";
|
import { useTriliumEvent } from "../react/hooks";
|
||||||
|
|
||||||
interface RenderMarkdownResponse {
|
interface RenderMarkdownResponse {
|
||||||
htmlContent: string;
|
htmlContent: string;
|
||||||
@ -32,8 +32,8 @@ export default function MarkdownImportDialog() {
|
|||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useTriliumEventBeta("importMarkdownInline", triggerImport);
|
useTriliumEvent("importMarkdownInline", triggerImport);
|
||||||
useTriliumEventBeta("pasteMarkdownIntoText", triggerImport);
|
useTriliumEvent("pasteMarkdownIntoText", triggerImport);
|
||||||
|
|
||||||
async function sendForm() {
|
async function sendForm() {
|
||||||
await convertMarkdownToHtml(text);
|
await convertMarkdownToHtml(text);
|
||||||
|
|||||||
@ -11,7 +11,7 @@ import tree from "../../services/tree";
|
|||||||
import froca from "../../services/froca";
|
import froca from "../../services/froca";
|
||||||
import branches from "../../services/branches";
|
import branches from "../../services/branches";
|
||||||
import toast from "../../services/toast";
|
import toast from "../../services/toast";
|
||||||
import { useTriliumEventBeta } from "../react/hooks";
|
import { useTriliumEvent } from "../react/hooks";
|
||||||
|
|
||||||
export default function MoveToDialog() {
|
export default function MoveToDialog() {
|
||||||
const [ movedBranchIds, setMovedBranchIds ] = useState<string[]>();
|
const [ movedBranchIds, setMovedBranchIds ] = useState<string[]>();
|
||||||
@ -19,7 +19,7 @@ export default function MoveToDialog() {
|
|||||||
const [ shown, setShown ] = useState(false);
|
const [ shown, setShown ] = useState(false);
|
||||||
const autoCompleteRef = useRef<HTMLInputElement>(null);
|
const autoCompleteRef = useRef<HTMLInputElement>(null);
|
||||||
|
|
||||||
useTriliumEventBeta("moveBranchIdsTo", ({ branchIds }) => {
|
useTriliumEvent("moveBranchIdsTo", ({ branchIds }) => {
|
||||||
setMovedBranchIds(branchIds);
|
setMovedBranchIds(branchIds);
|
||||||
setShown(true);
|
setShown(true);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import { MenuCommandItem, MenuItem } from "../../menus/context_menu";
|
|||||||
import { TreeCommandNames } from "../../menus/tree_context_menu";
|
import { TreeCommandNames } from "../../menus/tree_context_menu";
|
||||||
import { Suggestion } from "../../services/note_autocomplete";
|
import { Suggestion } from "../../services/note_autocomplete";
|
||||||
import Badge from "../react/Badge";
|
import Badge from "../react/Badge";
|
||||||
import { useTriliumEventBeta } from "../react/hooks";
|
import { useTriliumEvent } from "../react/hooks";
|
||||||
|
|
||||||
export interface ChooseNoteTypeResponse {
|
export interface ChooseNoteTypeResponse {
|
||||||
success: boolean;
|
success: boolean;
|
||||||
@ -31,7 +31,7 @@ export default function NoteTypeChooserDialogComponent() {
|
|||||||
const [ parentNote, setParentNote ] = useState<Suggestion | null>();
|
const [ parentNote, setParentNote ] = useState<Suggestion | null>();
|
||||||
const [ noteTypes, setNoteTypes ] = useState<MenuItem<TreeCommandNames>[]>([]);
|
const [ noteTypes, setNoteTypes ] = useState<MenuItem<TreeCommandNames>[]>([]);
|
||||||
|
|
||||||
useTriliumEventBeta("chooseNoteType", ({ callback }) => {
|
useTriliumEvent("chooseNoteType", ({ callback }) => {
|
||||||
setCallback(() => callback);
|
setCallback(() => callback);
|
||||||
setShown(true);
|
setShown(true);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -3,11 +3,11 @@ import { t } from "../../services/i18n";
|
|||||||
import Button from "../react/Button";
|
import Button from "../react/Button";
|
||||||
import appContext from "../../components/app_context";
|
import appContext from "../../components/app_context";
|
||||||
import { useState } from "preact/hooks";
|
import { useState } from "preact/hooks";
|
||||||
import { useTriliumEventBeta } from "../react/hooks";
|
import { useTriliumEvent } from "../react/hooks";
|
||||||
|
|
||||||
export default function PasswordNotSetDialog() {
|
export default function PasswordNotSetDialog() {
|
||||||
const [ shown, setShown ] = useState(false);
|
const [ shown, setShown ] = useState(false);
|
||||||
useTriliumEventBeta("showPasswordNotSet", () => setShown(true));
|
useTriliumEvent("showPasswordNotSet", () => setShown(true));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import Modal from "../react/Modal";
|
|||||||
import FormTextBox from "../react/FormTextBox";
|
import FormTextBox from "../react/FormTextBox";
|
||||||
import FormGroup from "../react/FormGroup";
|
import FormGroup from "../react/FormGroup";
|
||||||
import { refToJQuerySelector } from "../react/react_utils";
|
import { refToJQuerySelector } from "../react/react_utils";
|
||||||
import { useTriliumEventBeta } from "../react/hooks";
|
import { useTriliumEvent } from "../react/hooks";
|
||||||
|
|
||||||
// JQuery here is maintained for compatibility with existing code.
|
// JQuery here is maintained for compatibility with existing code.
|
||||||
interface ShownCallbackData {
|
interface ShownCallbackData {
|
||||||
@ -36,7 +36,7 @@ export default function PromptDialog() {
|
|||||||
const [ shown, setShown ] = useState(false);
|
const [ shown, setShown ] = useState(false);
|
||||||
const submitValue = useRef<string>(null);
|
const submitValue = useRef<string>(null);
|
||||||
|
|
||||||
useTriliumEventBeta("showPromptDialog", (newOpts) => {
|
useTriliumEvent("showPromptDialog", (newOpts) => {
|
||||||
opts.current = newOpts;
|
opts.current = newOpts;
|
||||||
setValue(newOpts.defaultValue ?? "");
|
setValue(newOpts.defaultValue ?? "");
|
||||||
setShown(true);
|
setShown(true);
|
||||||
|
|||||||
@ -4,15 +4,15 @@ import Button from "../react/Button";
|
|||||||
import FormTextBox from "../react/FormTextBox";
|
import FormTextBox from "../react/FormTextBox";
|
||||||
import Modal from "../react/Modal";
|
import Modal from "../react/Modal";
|
||||||
import protected_session from "../../services/protected_session";
|
import protected_session from "../../services/protected_session";
|
||||||
import { useTriliumEventBeta } from "../react/hooks";
|
import { useTriliumEvent } from "../react/hooks";
|
||||||
|
|
||||||
export default function ProtectedSessionPasswordDialog() {
|
export default function ProtectedSessionPasswordDialog() {
|
||||||
const [ shown, setShown ] = useState(false);
|
const [ shown, setShown ] = useState(false);
|
||||||
const [ password, setPassword ] = useState("");
|
const [ password, setPassword ] = useState("");
|
||||||
const inputRef = useRef<HTMLInputElement>(null);
|
const inputRef = useRef<HTMLInputElement>(null);
|
||||||
|
|
||||||
useTriliumEventBeta("showProtectedSessionPasswordDialog", () => setShown(true));
|
useTriliumEvent("showProtectedSessionPasswordDialog", () => setShown(true));
|
||||||
useTriliumEventBeta("closeProtectedSessionPasswordDialog", () => setShown(false));
|
useTriliumEvent("closeProtectedSessionPasswordDialog", () => setShown(false));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
|
|||||||
@ -13,7 +13,7 @@ import { formatDateTime } from "../../utils/formatters";
|
|||||||
import link from "../../services/link";
|
import link from "../../services/link";
|
||||||
import RawHtml from "../react/RawHtml";
|
import RawHtml from "../react/RawHtml";
|
||||||
import ws from "../../services/ws";
|
import ws from "../../services/ws";
|
||||||
import { useTriliumEventBeta } from "../react/hooks";
|
import { useTriliumEvent } from "../react/hooks";
|
||||||
|
|
||||||
export default function RecentChangesDialog() {
|
export default function RecentChangesDialog() {
|
||||||
const [ ancestorNoteId, setAncestorNoteId ] = useState<string>();
|
const [ ancestorNoteId, setAncestorNoteId ] = useState<string>();
|
||||||
@ -21,7 +21,7 @@ export default function RecentChangesDialog() {
|
|||||||
const [ needsRefresh, setNeedsRefresh ] = useState(false);
|
const [ needsRefresh, setNeedsRefresh ] = useState(false);
|
||||||
const [ shown, setShown ] = useState(false);
|
const [ shown, setShown ] = useState(false);
|
||||||
|
|
||||||
useTriliumEventBeta("showRecentChanges", ({ ancestorNoteId }) => {
|
useTriliumEvent("showRecentChanges", ({ ancestorNoteId }) => {
|
||||||
setNeedsRefresh(true);
|
setNeedsRefresh(true);
|
||||||
setAncestorNoteId(ancestorNoteId ?? hoisted_note.getHoistedNoteId());
|
setAncestorNoteId(ancestorNoteId ?? hoisted_note.getHoistedNoteId());
|
||||||
setShown(true);
|
setShown(true);
|
||||||
|
|||||||
@ -8,7 +8,6 @@ import server from "../../services/server";
|
|||||||
import toast from "../../services/toast";
|
import toast from "../../services/toast";
|
||||||
import Button from "../react/Button";
|
import Button from "../react/Button";
|
||||||
import Modal from "../react/Modal";
|
import Modal from "../react/Modal";
|
||||||
import ReactBasicWidget from "../react/ReactBasicWidget";
|
|
||||||
import FormList, { FormListItem } from "../react/FormList";
|
import FormList, { FormListItem } from "../react/FormList";
|
||||||
import utils from "../../services/utils";
|
import utils from "../../services/utils";
|
||||||
import { Dispatch, StateUpdater, useEffect, useRef, useState } from "preact/hooks";
|
import { Dispatch, StateUpdater, useEffect, useRef, useState } from "preact/hooks";
|
||||||
@ -18,7 +17,7 @@ import type { CSSProperties } from "preact/compat";
|
|||||||
import open from "../../services/open";
|
import open from "../../services/open";
|
||||||
import ActionButton from "../react/ActionButton";
|
import ActionButton from "../react/ActionButton";
|
||||||
import options from "../../services/options";
|
import options from "../../services/options";
|
||||||
import useTriliumEvent from "../react/hooks";
|
import { useTriliumEvent } from "../react/hooks";
|
||||||
|
|
||||||
export default function RevisionsDialog() {
|
export default function RevisionsDialog() {
|
||||||
const [ note, setNote ] = useState<FNote>();
|
const [ note, setNote ] = useState<FNote>();
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import FormTextBox from "../react/FormTextBox";
|
|||||||
import Modal from "../react/Modal";
|
import Modal from "../react/Modal";
|
||||||
import server from "../../services/server";
|
import server from "../../services/server";
|
||||||
import FormGroup from "../react/FormGroup";
|
import FormGroup from "../react/FormGroup";
|
||||||
import { useTriliumEventBeta } from "../react/hooks";
|
import { useTriliumEvent } from "../react/hooks";
|
||||||
|
|
||||||
export default function SortChildNotesDialog() {
|
export default function SortChildNotesDialog() {
|
||||||
const [ parentNoteId, setParentNoteId ] = useState<string>();
|
const [ parentNoteId, setParentNoteId ] = useState<string>();
|
||||||
@ -18,7 +18,7 @@ export default function SortChildNotesDialog() {
|
|||||||
const [ sortLocale, setSortLocale ] = useState("");
|
const [ sortLocale, setSortLocale ] = useState("");
|
||||||
const [ shown, setShown ] = useState(false);
|
const [ shown, setShown ] = useState(false);
|
||||||
|
|
||||||
useTriliumEventBeta("sortChildNotes", ({ node }) => {
|
useTriliumEvent("sortChildNotes", ({ node }) => {
|
||||||
setParentNoteId(node.data.noteId);
|
setParentNoteId(node.data.noteId);
|
||||||
setShown(true);
|
setShown(true);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import ReactBasicWidget from "../react/ReactBasicWidget";
|
|||||||
import options from "../../services/options";
|
import options from "../../services/options";
|
||||||
import importService from "../../services/import.js";
|
import importService from "../../services/import.js";
|
||||||
import tree from "../../services/tree";
|
import tree from "../../services/tree";
|
||||||
import { useTriliumEventBeta } from "../react/hooks";
|
import { useTriliumEvent } from "../react/hooks";
|
||||||
|
|
||||||
export default function UploadAttachmentsDialog() {
|
export default function UploadAttachmentsDialog() {
|
||||||
const [ parentNoteId, setParentNoteId ] = useState<string>();
|
const [ parentNoteId, setParentNoteId ] = useState<string>();
|
||||||
@ -19,7 +19,7 @@ export default function UploadAttachmentsDialog() {
|
|||||||
const [ description, setDescription ] = useState<string | undefined>(undefined);
|
const [ description, setDescription ] = useState<string | undefined>(undefined);
|
||||||
const [ shown, setShown ] = useState(false);
|
const [ shown, setShown ] = useState(false);
|
||||||
|
|
||||||
useTriliumEventBeta("showUploadAttachmentsDialog", ({ noteId }) => {
|
useTriliumEvent("showUploadAttachmentsDialog", ({ noteId }) => {
|
||||||
setParentNoteId(noteId);
|
setParentNoteId(noteId);
|
||||||
setShown(true);
|
setShown(true);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { useEffect, useRef, useState } from "preact/hooks";
|
import { useEffect, useRef, useState } from "preact/hooks";
|
||||||
import { t } from "../services/i18n";
|
import { t } from "../services/i18n";
|
||||||
import FormTextBox from "./react/FormTextBox";
|
import FormTextBox from "./react/FormTextBox";
|
||||||
import { useNoteContext, useNoteProperty, useSpacedUpdate, useTriliumEventBeta } from "./react/hooks";
|
import { useNoteContext, useNoteProperty, useSpacedUpdate, useTriliumEvent } from "./react/hooks";
|
||||||
import protected_session_holder from "../services/protected_session_holder";
|
import protected_session_holder from "../services/protected_session_holder";
|
||||||
import server from "../services/server";
|
import server from "../services/server";
|
||||||
import "./note_title.css";
|
import "./note_title.css";
|
||||||
@ -48,12 +48,12 @@ export default function NoteTitleWidget() {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
appContext.addBeforeUnloadListener(() => spacedUpdate.isAllSavedAndTriggerUpdate());
|
appContext.addBeforeUnloadListener(() => spacedUpdate.isAllSavedAndTriggerUpdate());
|
||||||
}, []);
|
}, []);
|
||||||
useTriliumEventBeta([ "beforeNoteSwitch", "beforeNoteContextRemove" ], () => spacedUpdate.updateNowIfNecessary());
|
useTriliumEvent([ "beforeNoteSwitch", "beforeNoteContextRemove" ], () => spacedUpdate.updateNowIfNecessary());
|
||||||
|
|
||||||
// Manage focus.
|
// Manage focus.
|
||||||
const textBoxRef = useRef<HTMLInputElement>(null);
|
const textBoxRef = useRef<HTMLInputElement>(null);
|
||||||
const isNewNote = useRef<boolean>();
|
const isNewNote = useRef<boolean>();
|
||||||
useTriliumEventBeta([ "focusOnTitle", "focusAndSelectTitle" ], (e) => {
|
useTriliumEvent([ "focusOnTitle", "focusAndSelectTitle" ], (e) => {
|
||||||
if (noteContext?.isActive() && textBoxRef.current) {
|
if (noteContext?.isActive() && textBoxRef.current) {
|
||||||
textBoxRef.current.focus();
|
textBoxRef.current.focus();
|
||||||
isNewNote.current = ("isNewNote" in e ? e.isNewNote : false);
|
isNewNote.current = ("isNewNote" in e ? e.isNewNote : false);
|
||||||
|
|||||||
@ -5,94 +5,25 @@ import SpacedUpdate from "../../services/spaced_update";
|
|||||||
import { OptionNames } from "@triliumnext/commons";
|
import { OptionNames } from "@triliumnext/commons";
|
||||||
import options, { type OptionValue } from "../../services/options";
|
import options, { type OptionValue } from "../../services/options";
|
||||||
import utils, { reloadFrontendApp } from "../../services/utils";
|
import utils, { reloadFrontendApp } from "../../services/utils";
|
||||||
import Component from "../../components/component";
|
|
||||||
import NoteContext from "../../components/note_context";
|
import NoteContext from "../../components/note_context";
|
||||||
import BasicWidget, { ReactWrappedWidget } from "../basic_widget";
|
import BasicWidget, { ReactWrappedWidget } from "../basic_widget";
|
||||||
import FNote from "../../entities/fnote";
|
import FNote from "../../entities/fnote";
|
||||||
import attributes from "../../services/attributes";
|
import attributes from "../../services/attributes";
|
||||||
import FBlob from "../../entities/fblob";
|
import FBlob from "../../entities/fblob";
|
||||||
import NoteContextAwareWidget from "../note_context_aware_widget";
|
import NoteContextAwareWidget from "../note_context_aware_widget";
|
||||||
import { Ref, RefObject, VNode } from "preact";
|
import { RefObject, VNode } from "preact";
|
||||||
import { Tooltip } from "bootstrap";
|
import { Tooltip } from "bootstrap";
|
||||||
import { CSSProperties } from "preact/compat";
|
import { CSSProperties } from "preact/compat";
|
||||||
|
|
||||||
type TriliumEventHandler<T extends EventNames> = (data: EventData<T>) => void;
|
type TriliumEventHandler<T extends EventNames> = (data: EventData<T>) => void;
|
||||||
const registeredHandlers: Map<Component, Map<EventNames, TriliumEventHandler<any>[]>> = new Map();
|
|
||||||
|
|
||||||
/**
|
export function useTriliumEvent<T extends EventNames>(eventName: T | T[], handler: TriliumEventHandler<T>) {
|
||||||
* Allows a React component to react to Trilium events (e.g. `entitiesReloaded`). When the desired event is triggered, the handler is invoked with the event parameters.
|
const parentComponent = useContext(ParentComponent);
|
||||||
*
|
|
||||||
* Under the hood, it works by altering the parent (Trilium) component of the React element to introduce the corresponding event.
|
if (!parentComponent) {
|
||||||
*
|
console.error("React widget has no legacy parent component. Event handling will not work.", new Error().stack);
|
||||||
* @param eventName the name of the Trilium event to listen for.
|
|
||||||
* @param handler the handler to be invoked when the event is triggered.
|
|
||||||
* @param enabled determines whether the event should be listened to or not. Useful to conditionally limit the listener based on a state (e.g. a modal being displayed).
|
|
||||||
*/
|
|
||||||
export default function useTriliumEvent<T extends EventNames>(eventName: T, handler: TriliumEventHandler<T>, enabled = true) {
|
|
||||||
const parentWidget = useContext(ParentComponent);
|
|
||||||
if (!parentWidget) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const handlerName = `${eventName}Event`;
|
|
||||||
const customHandler = useMemo(() => {
|
|
||||||
return async (data: EventData<T>) => {
|
|
||||||
// Inform the attached event listeners.
|
|
||||||
const eventHandlers = registeredHandlers.get(parentWidget)?.get(eventName) ?? [];
|
|
||||||
for (const eventHandler of eventHandlers) {
|
|
||||||
eventHandler(data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, [ eventName, parentWidget ]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
// Attach to the list of handlers.
|
|
||||||
let handlersByWidget = registeredHandlers.get(parentWidget);
|
|
||||||
if (!handlersByWidget) {
|
|
||||||
handlersByWidget = new Map();
|
|
||||||
registeredHandlers.set(parentWidget, handlersByWidget);
|
|
||||||
}
|
|
||||||
|
|
||||||
let handlersByWidgetAndEventName = handlersByWidget.get(eventName);
|
|
||||||
if (!handlersByWidgetAndEventName) {
|
|
||||||
handlersByWidgetAndEventName = [];
|
|
||||||
handlersByWidget.set(eventName, handlersByWidgetAndEventName);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!handlersByWidgetAndEventName.includes(handler)) {
|
|
||||||
handlersByWidgetAndEventName.push(handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply the custom event handler.
|
|
||||||
if (parentWidget[handlerName] && parentWidget[handlerName] !== customHandler) {
|
|
||||||
console.warn(`Widget ${parentWidget.componentId} already had an event listener and it was replaced by the React one.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
parentWidget[handlerName] = customHandler;
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
const eventHandlers = registeredHandlers.get(parentWidget)?.get(eventName);
|
|
||||||
if (!eventHandlers || !eventHandlers.includes(handler)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove the event handler from the array.
|
|
||||||
const newEventHandlers = eventHandlers.filter(e => e !== handler);
|
|
||||||
if (newEventHandlers.length) {
|
|
||||||
registeredHandlers.get(parentWidget)?.set(eventName, newEventHandlers);
|
|
||||||
} else {
|
|
||||||
registeredHandlers.get(parentWidget)?.delete(eventName);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!registeredHandlers.get(parentWidget)?.size) {
|
|
||||||
registeredHandlers.delete(parentWidget);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}, [ eventName, parentWidget, handler ]);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function useTriliumEventBeta<T extends EventNames>(eventName: T | T[], handler: TriliumEventHandler<T>) {
|
|
||||||
const parentComponent = useContext(ParentComponent) as ReactWrappedWidget;
|
|
||||||
|
|
||||||
if (Array.isArray(eventName)) {
|
if (Array.isArray(eventName)) {
|
||||||
for (const eventSingleName of eventName) {
|
for (const eventSingleName of eventName) {
|
||||||
@ -185,7 +116,7 @@ export function useTriliumOptionBeta(name: OptionNames, needsRefresh?: boolean):
|
|||||||
}
|
}
|
||||||
}, [ name, needsRefresh ]);
|
}, [ name, needsRefresh ]);
|
||||||
|
|
||||||
useTriliumEventBeta("entitiesReloaded", useCallback(({ loadResults }) => {
|
useTriliumEvent("entitiesReloaded", useCallback(({ loadResults }) => {
|
||||||
if (loadResults.getOptionNames().includes(name)) {
|
if (loadResults.getOptionNames().includes(name)) {
|
||||||
const newValue = options.get(name);
|
const newValue = options.get(name);
|
||||||
setValue(newValue);
|
setValue(newValue);
|
||||||
@ -283,20 +214,20 @@ export function useNoteContext() {
|
|||||||
setNote(noteContext?.note);
|
setNote(noteContext?.note);
|
||||||
}, [ notePath ]);
|
}, [ notePath ]);
|
||||||
|
|
||||||
useTriliumEventBeta("activeContextChanged", ({ noteContext }) => {
|
useTriliumEvent("activeContextChanged", ({ noteContext }) => {
|
||||||
setNoteContext(noteContext);
|
setNoteContext(noteContext);
|
||||||
setNotePath(noteContext.notePath);
|
setNotePath(noteContext.notePath);
|
||||||
});
|
});
|
||||||
useTriliumEventBeta("setNoteContext", ({ noteContext }) => {
|
useTriliumEvent("setNoteContext", ({ noteContext }) => {
|
||||||
setNoteContext(noteContext);
|
setNoteContext(noteContext);
|
||||||
});
|
});
|
||||||
useTriliumEventBeta("noteSwitchedAndActivated", ({ noteContext }) => {
|
useTriliumEvent("noteSwitchedAndActivated", ({ noteContext }) => {
|
||||||
setNoteContext(noteContext);
|
setNoteContext(noteContext);
|
||||||
});
|
});
|
||||||
useTriliumEventBeta("noteSwitched", ({ noteContext, notePath }) => {
|
useTriliumEvent("noteSwitched", ({ noteContext, notePath }) => {
|
||||||
setNotePath(notePath);
|
setNotePath(notePath);
|
||||||
});
|
});
|
||||||
useTriliumEventBeta("frocaReloaded", () => {
|
useTriliumEvent("frocaReloaded", () => {
|
||||||
setNote(noteContext?.note);
|
setNote(noteContext?.note);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -336,7 +267,7 @@ export function useNoteProperty<T extends keyof FNote>(note: FNote | null | unde
|
|||||||
useEffect(() => refreshValue(), [ note, note[property] ]);
|
useEffect(() => refreshValue(), [ note, note[property] ]);
|
||||||
|
|
||||||
// Watch for external changes.
|
// Watch for external changes.
|
||||||
useTriliumEventBeta("entitiesReloaded", ({ loadResults }) => {
|
useTriliumEvent("entitiesReloaded", ({ loadResults }) => {
|
||||||
if (loadResults.isNoteReloaded(note.noteId, componentId)) {
|
if (loadResults.isNoteReloaded(note.noteId, componentId)) {
|
||||||
refreshValue();
|
refreshValue();
|
||||||
}
|
}
|
||||||
@ -349,7 +280,7 @@ export function useNoteRelation(note: FNote | undefined | null, relationName: st
|
|||||||
const [ relationValue, setRelationValue ] = useState<string | null | undefined>(note?.getRelationValue(relationName));
|
const [ relationValue, setRelationValue ] = useState<string | null | undefined>(note?.getRelationValue(relationName));
|
||||||
|
|
||||||
useEffect(() => setRelationValue(note?.getRelationValue(relationName) ?? null), [ note ]);
|
useEffect(() => setRelationValue(note?.getRelationValue(relationName) ?? null), [ note ]);
|
||||||
useTriliumEventBeta("entitiesReloaded", ({ loadResults }) => {
|
useTriliumEvent("entitiesReloaded", ({ loadResults }) => {
|
||||||
for (const attr of loadResults.getAttributeRows()) {
|
for (const attr of loadResults.getAttributeRows()) {
|
||||||
if (attr.type === "relation" && attr.name === relationName && attributes.isAffecting(attr, note)) {
|
if (attr.type === "relation" && attr.name === relationName && attributes.isAffecting(attr, note)) {
|
||||||
setRelationValue(attr.value ?? null);
|
setRelationValue(attr.value ?? null);
|
||||||
@ -380,7 +311,7 @@ export function useNoteLabel(note: FNote | undefined | null, labelName: string):
|
|||||||
const [ labelValue, setLabelValue ] = useState<string | null | undefined>(note?.getLabelValue(labelName));
|
const [ labelValue, setLabelValue ] = useState<string | null | undefined>(note?.getLabelValue(labelName));
|
||||||
|
|
||||||
useEffect(() => setLabelValue(note?.getLabelValue(labelName) ?? null), [ note ]);
|
useEffect(() => setLabelValue(note?.getLabelValue(labelName) ?? null), [ note ]);
|
||||||
useTriliumEventBeta("entitiesReloaded", ({ loadResults }) => {
|
useTriliumEvent("entitiesReloaded", ({ loadResults }) => {
|
||||||
for (const attr of loadResults.getAttributeRows()) {
|
for (const attr of loadResults.getAttributeRows()) {
|
||||||
if (attr.type === "label" && attr.name === labelName && attributes.isAffecting(attr, note)) {
|
if (attr.type === "label" && attr.name === labelName && attributes.isAffecting(attr, note)) {
|
||||||
setLabelValue(attr.value ?? null);
|
setLabelValue(attr.value ?? null);
|
||||||
@ -409,7 +340,7 @@ export function useNoteLabelBoolean(note: FNote | undefined | null, labelName: s
|
|||||||
|
|
||||||
useEffect(() => setLabelValue(!!note?.hasLabel(labelName)), [ note ]);
|
useEffect(() => setLabelValue(!!note?.hasLabel(labelName)), [ note ]);
|
||||||
|
|
||||||
useTriliumEventBeta("entitiesReloaded", ({ loadResults }) => {
|
useTriliumEvent("entitiesReloaded", ({ loadResults }) => {
|
||||||
for (const attr of loadResults.getAttributeRows()) {
|
for (const attr of loadResults.getAttributeRows()) {
|
||||||
if (attr.type === "label" && attr.name === labelName && attributes.isAffecting(attr, note)) {
|
if (attr.type === "label" && attr.name === labelName && attributes.isAffecting(attr, note)) {
|
||||||
setLabelValue(!attr.isDeleted);
|
setLabelValue(!attr.isDeleted);
|
||||||
@ -442,7 +373,7 @@ export function useNoteBlob(note: FNote | null | undefined): [ FBlob | null | un
|
|||||||
}
|
}
|
||||||
|
|
||||||
useEffect(refresh, [ note?.noteId ]);
|
useEffect(refresh, [ note?.noteId ]);
|
||||||
useTriliumEventBeta("entitiesReloaded", ({ loadResults }) => {
|
useTriliumEvent("entitiesReloaded", ({ loadResults }) => {
|
||||||
if (note && loadResults.hasRevisionForNote(note.noteId)) {
|
if (note && loadResults.hasRevisionForNote(note.noteId)) {
|
||||||
refresh();
|
refresh();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import Dropdown from "../react/Dropdown";
|
|||||||
import { NOTE_TYPES } from "../../services/note_types";
|
import { NOTE_TYPES } from "../../services/note_types";
|
||||||
import { FormDropdownDivider, FormListBadge, FormListItem } from "../react/FormList";
|
import { FormDropdownDivider, FormListBadge, FormListItem } from "../react/FormList";
|
||||||
import { getAvailableLocales, t } from "../../services/i18n";
|
import { getAvailableLocales, t } from "../../services/i18n";
|
||||||
import { useNoteLabel, useNoteLabelBoolean, useNoteProperty, useTriliumEventBeta, useTriliumOption, useTriliumOptionBeta, useTriliumOptionJson } from "../react/hooks";
|
import { useNoteLabel, useNoteLabelBoolean, useNoteProperty, useTriliumEvent, useTriliumOption, useTriliumOptionBeta, useTriliumOptionJson } from "../react/hooks";
|
||||||
import mime_types from "../../services/mime_types";
|
import mime_types from "../../services/mime_types";
|
||||||
import { Locale, NoteType, ToggleInParentResponse } from "@triliumnext/commons";
|
import { Locale, NoteType, ToggleInParentResponse } from "@triliumnext/commons";
|
||||||
import server from "../../services/server";
|
import server from "../../services/server";
|
||||||
@ -179,7 +179,7 @@ function BookmarkSwitch({ note }: { note?: FNote | null }) {
|
|||||||
}, [ note ]);
|
}, [ note ]);
|
||||||
|
|
||||||
useEffect(() => refreshState(), [ note ]);
|
useEffect(() => refreshState(), [ note ]);
|
||||||
useTriliumEventBeta("entitiesReloaded", ({ loadResults }) => {
|
useTriliumEvent("entitiesReloaded", ({ loadResults }) => {
|
||||||
if (note && loadResults.getBranchRows().find((b) => b.noteId === note.noteId)) {
|
if (note && loadResults.getBranchRows().find((b) => b.noteId === note.noteId)) {
|
||||||
refreshState();
|
refreshState();
|
||||||
}
|
}
|
||||||
@ -228,7 +228,7 @@ function SharedSwitch({ note }: { note?: FNote | null }) {
|
|||||||
}, [ note ]);
|
}, [ note ]);
|
||||||
|
|
||||||
useEffect(() => refreshState(), [ note ]);
|
useEffect(() => refreshState(), [ note ]);
|
||||||
useTriliumEventBeta("entitiesReloaded", ({ loadResults }) => {
|
useTriliumEvent("entitiesReloaded", ({ loadResults }) => {
|
||||||
if (note && loadResults.getBranchRows().find((b) => b.noteId === note.noteId)) {
|
if (note && loadResults.getBranchRows().find((b) => b.noteId === note.noteId)) {
|
||||||
refreshState();
|
refreshState();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { useEffect, useState } from "preact/hooks";
|
import { useEffect, useState } from "preact/hooks";
|
||||||
import { TabContext } from "./ribbon-interface";
|
import { TabContext } from "./ribbon-interface";
|
||||||
import FAttribute from "../../entities/fattribute";
|
import FAttribute from "../../entities/fattribute";
|
||||||
import { useLegacyWidget, useTriliumEventBeta } from "../react/hooks";
|
import { useLegacyWidget, useTriliumEvent } from "../react/hooks";
|
||||||
import attributes from "../../services/attributes";
|
import attributes from "../../services/attributes";
|
||||||
import { t } from "../../services/i18n";
|
import { t } from "../../services/i18n";
|
||||||
import attribute_renderer from "../../services/attribute_renderer";
|
import attribute_renderer from "../../services/attribute_renderer";
|
||||||
@ -29,7 +29,7 @@ export default function InheritedAttributesTab({ note, componentId }: TabContext
|
|||||||
}
|
}
|
||||||
|
|
||||||
useEffect(refresh, [ note ]);
|
useEffect(refresh, [ note ]);
|
||||||
useTriliumEventBeta("entitiesReloaded", ({ loadResults }) => {
|
useTriliumEvent("entitiesReloaded", ({ loadResults }) => {
|
||||||
if (loadResults.getAttributeRows(componentId).find((attr) => attributes.isAffecting(attr, note))) {
|
if (loadResults.getAttributeRows(componentId).find((attr) => attributes.isAffecting(attr, note))) {
|
||||||
refresh();
|
refresh();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import Button from "../react/Button";
|
|||||||
import { formatDateTime } from "../../utils/formatters";
|
import { formatDateTime } from "../../utils/formatters";
|
||||||
import { formatSize } from "../../services/utils";
|
import { formatSize } from "../../services/utils";
|
||||||
import LoadingSpinner from "../react/LoadingSpinner";
|
import LoadingSpinner from "../react/LoadingSpinner";
|
||||||
import { useTriliumEventBeta } from "../react/hooks";
|
import { useTriliumEvent } from "../react/hooks";
|
||||||
|
|
||||||
export default function NoteInfoTab({ note }: TabContext) {
|
export default function NoteInfoTab({ note }: TabContext) {
|
||||||
const [ metadata, setMetadata ] = useState<MetadataResponse>();
|
const [ metadata, setMetadata ] = useState<MetadataResponse>();
|
||||||
@ -26,7 +26,7 @@ export default function NoteInfoTab({ note }: TabContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
useEffect(refresh, [ note?.noteId ]);
|
useEffect(refresh, [ note?.noteId ]);
|
||||||
useTriliumEventBeta("entitiesReloaded", ({ loadResults }) => {
|
useTriliumEvent("entitiesReloaded", ({ loadResults }) => {
|
||||||
const noteId = note?.noteId;
|
const noteId = note?.noteId;
|
||||||
if (noteId && (loadResults.isNoteReloaded(noteId) || loadResults.isNoteContentReloaded(noteId))) {
|
if (noteId && (loadResults.isNoteReloaded(noteId) || loadResults.isNoteContentReloaded(noteId))) {
|
||||||
refresh();
|
refresh();
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { TabContext } from "./ribbon-interface";
|
import { TabContext } from "./ribbon-interface";
|
||||||
import { t } from "../../services/i18n";
|
import { t } from "../../services/i18n";
|
||||||
import Button from "../react/Button";
|
import Button from "../react/Button";
|
||||||
import { useTriliumEventBeta } from "../react/hooks";
|
import { useTriliumEvent } from "../react/hooks";
|
||||||
import { useEffect, useMemo, useState } from "preact/hooks";
|
import { useEffect, useMemo, useState } from "preact/hooks";
|
||||||
import { NotePathRecord } from "../../entities/fnote";
|
import { NotePathRecord } from "../../entities/fnote";
|
||||||
import NoteLink from "../react/NoteLink";
|
import NoteLink from "../react/NoteLink";
|
||||||
@ -18,7 +18,7 @@ export default function NotePathsTab({ note, hoistedNoteId, notePath }: TabConte
|
|||||||
}
|
}
|
||||||
|
|
||||||
useEffect(refresh, [ note?.noteId ]);
|
useEffect(refresh, [ note?.noteId ]);
|
||||||
useTriliumEventBeta("entitiesReloaded", ({ loadResults }) => {
|
useTriliumEvent("entitiesReloaded", ({ loadResults }) => {
|
||||||
const noteId = note?.noteId;
|
const noteId = note?.noteId;
|
||||||
if (!noteId) return;
|
if (!noteId) return;
|
||||||
if (loadResults.getBranchRows().find((branch) => branch.noteId === noteId)
|
if (loadResults.getBranchRows().find((branch) => branch.noteId === noteId)
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import toast from "../../services/toast";
|
|||||||
import froca from "../../services/froca";
|
import froca from "../../services/froca";
|
||||||
import { useContext, useEffect, useState } from "preact/hooks";
|
import { useContext, useEffect, useState } from "preact/hooks";
|
||||||
import { ParentComponent } from "../react/react_utils";
|
import { ParentComponent } from "../react/react_utils";
|
||||||
import { useTriliumEventBeta } from "../react/hooks";
|
import { useTriliumEvent } from "../react/hooks";
|
||||||
import appContext from "../../components/app_context";
|
import appContext from "../../components/app_context";
|
||||||
import server from "../../services/server";
|
import server from "../../services/server";
|
||||||
import ws from "../../services/ws";
|
import ws from "../../services/ws";
|
||||||
@ -65,7 +65,7 @@ export default function SearchDefinitionTab({ note, ntxId }: TabContext) {
|
|||||||
|
|
||||||
// Refresh the list of available and active options.
|
// Refresh the list of available and active options.
|
||||||
useEffect(refreshOptions, [ note ]);
|
useEffect(refreshOptions, [ note ]);
|
||||||
useTriliumEventBeta("entitiesReloaded", ({ loadResults }) => {
|
useTriliumEvent("entitiesReloaded", ({ loadResults }) => {
|
||||||
if (loadResults.getAttributeRows().find((attrRow) => attributes.isAffecting(attrRow, note))) {
|
if (loadResults.getAttributeRows().find((attrRow) => attributes.isAffecting(attrRow, note))) {
|
||||||
refreshOptions();
|
refreshOptions();
|
||||||
}
|
}
|
||||||
@ -166,7 +166,7 @@ function BulkActionsList({ note }: { note: FNote }) {
|
|||||||
|
|
||||||
// React to changes.
|
// React to changes.
|
||||||
useEffect(refreshBulkActions, [ note ]);
|
useEffect(refreshBulkActions, [ note ]);
|
||||||
useTriliumEventBeta("entitiesReloaded", ({loadResults}) => {
|
useTriliumEvent("entitiesReloaded", ({loadResults}) => {
|
||||||
if (loadResults.getAttributeRows().find(attr => attr.type === "label" && attr.name === "action" && attributes.isAffecting(attr, note))) {
|
if (loadResults.getAttributeRows().find(attr => attr.type === "label" && attr.name === "action" && attributes.isAffecting(attr, note))) {
|
||||||
refreshBulkActions();
|
refreshBulkActions();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import { t } from "../../../services/i18n";
|
|||||||
import server from "../../../services/server";
|
import server from "../../../services/server";
|
||||||
import note_autocomplete, { Suggestion } from "../../../services/note_autocomplete";
|
import note_autocomplete, { Suggestion } from "../../../services/note_autocomplete";
|
||||||
import CKEditor, { CKEditorApi } from "../../react/CKEditor";
|
import CKEditor, { CKEditorApi } from "../../react/CKEditor";
|
||||||
import { useLegacyImperativeHandlers, useLegacyWidget, useTooltip, useTriliumEventBeta } from "../../react/hooks";
|
import { useLegacyImperativeHandlers, useLegacyWidget, useTooltip, useTriliumEvent } from "../../react/hooks";
|
||||||
import FAttribute from "../../../entities/fattribute";
|
import FAttribute from "../../../entities/fattribute";
|
||||||
import attribute_renderer from "../../../services/attribute_renderer";
|
import attribute_renderer from "../../../services/attribute_renderer";
|
||||||
import FNote from "../../../entities/fnote";
|
import FNote from "../../../entities/fnote";
|
||||||
@ -215,7 +215,7 @@ export default function AttributeEditor({ note, componentId, notePath, ntxId }:
|
|||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => refresh(), [ note ]);
|
useEffect(() => refresh(), [ note ]);
|
||||||
useTriliumEventBeta("entitiesReloaded", ({ loadResults }) => {
|
useTriliumEvent("entitiesReloaded", ({ loadResults }) => {
|
||||||
if (loadResults.getAttributeRows(componentId).find((attr) => attributes.isAffecting(attr, note))) {
|
if (loadResults.getAttributeRows(componentId).find((attr) => attributes.isAffecting(attr, note))) {
|
||||||
console.log("Trigger due to entities reloaded");
|
console.log("Trigger due to entities reloaded");
|
||||||
refresh();
|
refresh();
|
||||||
@ -257,11 +257,11 @@ export default function AttributeEditor({ note, componentId, notePath, ntxId }:
|
|||||||
}), []));
|
}), []));
|
||||||
|
|
||||||
// Keyboard shortcuts
|
// Keyboard shortcuts
|
||||||
useTriliumEventBeta("addNewLabel", ({ ntxId: eventNtxId }) => {
|
useTriliumEvent("addNewLabel", ({ ntxId: eventNtxId }) => {
|
||||||
if (eventNtxId !== ntxId) return;
|
if (eventNtxId !== ntxId) return;
|
||||||
handleAddNewAttributeCommand("addNewLabel");
|
handleAddNewAttributeCommand("addNewLabel");
|
||||||
});
|
});
|
||||||
useTriliumEventBeta("addNewRelation", ({ ntxId: eventNtxId }) => {
|
useTriliumEvent("addNewRelation", ({ ntxId: eventNtxId }) => {
|
||||||
if (eventNtxId !== ntxId) return;
|
if (eventNtxId !== ntxId) return;
|
||||||
handleAddNewAttributeCommand("addNewRelation");
|
handleAddNewAttributeCommand("addNewRelation");
|
||||||
});
|
});
|
||||||
|
|||||||
@ -76,7 +76,6 @@ const CONTENT_WIDGETS: Record<OptionPages | "_backendLog", ((typeof NoteContextA
|
|||||||
*/
|
*/
|
||||||
export default class ContentWidgetTypeWidget extends TypeWidget {
|
export default class ContentWidgetTypeWidget extends TypeWidget {
|
||||||
private $content!: JQuery<HTMLElement>;
|
private $content!: JQuery<HTMLElement>;
|
||||||
private widget?: BasicWidget;
|
|
||||||
|
|
||||||
static getType() {
|
static getType() {
|
||||||
return "contentWidget";
|
return "contentWidget";
|
||||||
@ -113,7 +112,6 @@ export default class ContentWidgetTypeWidget extends TypeWidget {
|
|||||||
this.child(widget);
|
this.child(widget);
|
||||||
|
|
||||||
this.$content.append(widget.render());
|
this.$content.append(widget.render());
|
||||||
this.widget = widget;
|
|
||||||
await widget.refresh();
|
await widget.refresh();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -10,7 +10,7 @@ import toast from "../../../services/toast";
|
|||||||
import dialog from "../../../services/dialog";
|
import dialog from "../../../services/dialog";
|
||||||
import { formatDateTime } from "../../../utils/formatters";
|
import { formatDateTime } from "../../../utils/formatters";
|
||||||
import ActionButton from "../../react/ActionButton";
|
import ActionButton from "../../react/ActionButton";
|
||||||
import useTriliumEvent from "../../react/hooks";
|
import { useTriliumEvent } from "../../react/hooks";
|
||||||
|
|
||||||
type RenameTokenCallback = (tokenId: string, oldName: string) => Promise<void>;
|
type RenameTokenCallback = (tokenId: string, oldName: string) => Promise<void>;
|
||||||
type DeleteTokenCallback = (tokenId: string, name: string ) => Promise<void>;
|
type DeleteTokenCallback = (tokenId: string, name: string ) => Promise<void>;
|
||||||
|
|||||||
@ -11,7 +11,7 @@ import { useCallback, useEffect, useState } from "preact/hooks";
|
|||||||
import server from "../../../services/server";
|
import server from "../../../services/server";
|
||||||
import options from "../../../services/options";
|
import options from "../../../services/options";
|
||||||
import dialog from "../../../services/dialog";
|
import dialog from "../../../services/dialog";
|
||||||
import useTriliumEvent from "../../react/hooks";
|
import { useTriliumEvent } from "../../react/hooks";
|
||||||
|
|
||||||
export default function ShortcutSettings() {
|
export default function ShortcutSettings() {
|
||||||
const [ keyboardShortcuts, setKeyboardShortcuts ] = useState<KeyboardShortcut[]>([]);
|
const [ keyboardShortcuts, setKeyboardShortcuts ] = useState<KeyboardShortcut[]>([]);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user