mirror of
https://github.com/zadam/trilium.git
synced 2025-11-01 10:55:55 +01:00
chore(react/type_widgets): save if needed
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { useNoteContext, useTriliumEvent } from "./react/hooks"
|
||||
import { useNoteContext, useTriliumEvent, useTriliumEvents } from "./react/hooks"
|
||||
import FNote from "../entities/fnote";
|
||||
import protected_session_holder from "../services/protected_session_holder";
|
||||
import { useEffect, useRef, useState } from "preact/hooks";
|
||||
@@ -9,6 +9,7 @@ import "./NoteDetail.css";
|
||||
import attributes from "../services/attributes";
|
||||
import { ExtendedNoteType, TYPE_MAPPINGS } from "./note_types";
|
||||
import { dynamicRequire, isMobile } from "../services/utils";
|
||||
import { ReactWrappedWidget } from "./basic_widget";
|
||||
|
||||
/**
|
||||
* The note detail is in charge of rendering the content of a note, by determining its type (e.g. text, code) and using the appropriate view widget.
|
||||
|
||||
@@ -13,18 +13,6 @@ export default class NoteDetailWidget extends NoteContextAwareWidget {
|
||||
appContext.addBeforeUnloadListener(this);
|
||||
}
|
||||
|
||||
async beforeNoteSwitchEvent({ noteContext }: EventData<"beforeNoteSwitch">) {
|
||||
if (this.isNoteContext(noteContext.ntxId)) {
|
||||
await this.spacedUpdate.updateNowIfNecessary();
|
||||
}
|
||||
}
|
||||
|
||||
async beforeNoteContextRemoveEvent({ ntxIds }: EventData<"beforeNoteContextRemove">) {
|
||||
if (this.isNoteContext(ntxIds)) {
|
||||
await this.spacedUpdate.updateNowIfNecessary();
|
||||
}
|
||||
}
|
||||
|
||||
async runActiveNoteCommand(params: CommandListenerData<"runActiveNote">) {
|
||||
if (this.isNoteContext(params.ntxId)) {
|
||||
// make sure that script is saved before running it #4028
|
||||
|
||||
@@ -23,6 +23,7 @@ import protected_session_holder from "../../services/protected_session_holder";
|
||||
import server from "../../services/server";
|
||||
import { removeIndividualBinding } from "../../services/shortcuts";
|
||||
import { ViewScope } from "../../services/link";
|
||||
import { VirtualConsolePrinter } from "happy-dom";
|
||||
|
||||
export function useTriliumEvent<T extends EventNames>(eventName: T, handler: (data: EventData<T>) => void) {
|
||||
const parentComponent = useContext(ParentComponent);
|
||||
@@ -77,8 +78,9 @@ export function useSpacedUpdate(callback: () => void | Promise<void>, interval =
|
||||
return spacedUpdateRef.current;
|
||||
}
|
||||
|
||||
export function useEditorSpacedUpdate({ note, getData, onContentChange, dataSaved, updateInterval }: {
|
||||
export function useEditorSpacedUpdate({ note, noteContext, getData, onContentChange, dataSaved, updateInterval }: {
|
||||
note: FNote,
|
||||
noteContext: NoteContext | null | undefined,
|
||||
getData: () => Promise<object | undefined> | object | undefined,
|
||||
onContentChange: (newContent: string) => void,
|
||||
dataSaved?: () => void,
|
||||
@@ -114,6 +116,18 @@ export function useEditorSpacedUpdate({ note, getData, onContentChange, dataSave
|
||||
spacedUpdate.setUpdateInterval(updateInterval);
|
||||
}, [ updateInterval ]);
|
||||
|
||||
// Save if needed upon switching tabs.
|
||||
useTriliumEvent("beforeNoteSwitch", async ({ noteContext: eventNoteContext }) => {
|
||||
if (eventNoteContext.ntxId !== noteContext?.ntxId) return;
|
||||
await spacedUpdate.updateNowIfNecessary();
|
||||
});
|
||||
|
||||
// Save if needed upon tab closing.
|
||||
useTriliumEvent("beforeNoteContextRemove", async ({ ntxIds }) => {
|
||||
if (!noteContext?.ntxId || !ntxIds.includes(noteContext.ntxId)) return;
|
||||
await spacedUpdate.updateNowIfNecessary();
|
||||
})
|
||||
|
||||
return spacedUpdate;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ export default function AiChat({ note, noteContext }: TypeWidgetProps) {
|
||||
const dataRef = useRef<object>();
|
||||
const spacedUpdate = useEditorSpacedUpdate({
|
||||
note,
|
||||
noteContext,
|
||||
getData: async () => ({
|
||||
content: JSON.stringify(dataRef.current)
|
||||
}),
|
||||
|
||||
@@ -11,6 +11,7 @@ import { RefObject } from "preact";
|
||||
import server from "../../services/server";
|
||||
import { ExcalidrawElement, NonDeletedExcalidrawElement } from "@excalidraw/excalidraw/element/types";
|
||||
import { goToLinkExt } from "../../services/link";
|
||||
import NoteContext from "../../components/note_context";
|
||||
|
||||
// currently required by excalidraw, in order to allows self-hosting fonts locally.
|
||||
// this avoids making excalidraw load the fonts from an external CDN.
|
||||
@@ -27,14 +28,14 @@ interface CanvasContent {
|
||||
appState: Partial<AppState>;
|
||||
}
|
||||
|
||||
export default function Canvas({ note }: TypeWidgetProps) {
|
||||
export default function Canvas({ note, noteContext }: TypeWidgetProps) {
|
||||
const apiRef = useRef<ExcalidrawImperativeAPI>(null);
|
||||
const [ isReadOnly ] = useNoteLabelBoolean(note, "readOnly");
|
||||
const themeStyle = useMemo(() => {
|
||||
const documentStyle = window.getComputedStyle(document.documentElement);
|
||||
return documentStyle.getPropertyValue("--theme-style")?.trim() as AppState["theme"];
|
||||
}, []);
|
||||
const persistence = usePersistence(note, apiRef, themeStyle, isReadOnly);
|
||||
const persistence = usePersistence(note, noteContext, apiRef, themeStyle, isReadOnly);
|
||||
|
||||
/** Use excalidraw's native zoom instead of the global zoom. */
|
||||
const onWheel = useCallback((e: MouseEvent) => {
|
||||
@@ -85,7 +86,7 @@ export default function Canvas({ note }: TypeWidgetProps) {
|
||||
)
|
||||
}
|
||||
|
||||
function usePersistence(note: FNote, apiRef: RefObject<ExcalidrawImperativeAPI>, theme: AppState["theme"], isReadOnly: boolean): Partial<ExcalidrawProps> {
|
||||
function usePersistence(note: FNote, noteContext: NoteContext, apiRef: RefObject<ExcalidrawImperativeAPI>, theme: AppState["theme"], isReadOnly: boolean): Partial<ExcalidrawProps> {
|
||||
const libraryChanged = useRef(false);
|
||||
|
||||
/**
|
||||
@@ -104,6 +105,7 @@ function usePersistence(note: FNote, apiRef: RefObject<ExcalidrawImperativeAPI>,
|
||||
|
||||
const spacedUpdate = useEditorSpacedUpdate({
|
||||
note,
|
||||
noteContext,
|
||||
onContentChange(newContent) {
|
||||
const api = apiRef.current;
|
||||
if (!api) return;
|
||||
|
||||
@@ -22,13 +22,14 @@ interface MindElixirProps {
|
||||
onChange?: () => void;
|
||||
}
|
||||
|
||||
export default function MindMap({ note, ntxId }: TypeWidgetProps) {
|
||||
export default function MindMap({ note, ntxId, noteContext }: TypeWidgetProps) {
|
||||
const content = VanillaMindElixir.new(NEW_TOPIC_NAME);
|
||||
const apiRef = useRef<MindElixirInstance>(null);
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const [ isReadOnly ] = useNoteLabelBoolean(note, "readOnly");
|
||||
const spacedUpdate = useEditorSpacedUpdate({
|
||||
note,
|
||||
noteContext,
|
||||
getData: async () => {
|
||||
if (!apiRef.current) return;
|
||||
return {
|
||||
|
||||
@@ -70,12 +70,13 @@ function formatViewSource(note: FNote, content: string) {
|
||||
return content;
|
||||
}
|
||||
|
||||
export function EditableCode({ note, ntxId, debounceUpdate, parentComponent, updateInterval, onContentChanged, dataSaved, ...editorProps }: EditableCodeProps) {
|
||||
export function EditableCode({ note, ntxId, noteContext, debounceUpdate, parentComponent, updateInterval, onContentChanged, dataSaved, ...editorProps }: EditableCodeProps) {
|
||||
const editorRef = useRef<VanillaCodeMirror>(null);
|
||||
const containerRef = useRef<HTMLPreElement>(null);
|
||||
const [ vimKeymapEnabled ] = useTriliumOptionBool("vimKeymapEnabled");
|
||||
const spacedUpdate = useEditorSpacedUpdate({
|
||||
note,
|
||||
noteContext,
|
||||
getData: () => ({ content: editorRef.current?.getText() }),
|
||||
onContentChange: (content) => {
|
||||
const codeEditor = editorRef.current;
|
||||
|
||||
@@ -43,7 +43,7 @@ declare module "jsplumb" {
|
||||
}
|
||||
}
|
||||
|
||||
export default function RelationMap({ note, ntxId }: TypeWidgetProps) {
|
||||
export default function RelationMap({ note, noteContext, ntxId }: TypeWidgetProps) {
|
||||
const [ data, setData ] = useState<MapData>();
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const mapApiRef = useRef<RelationMapApi>(null);
|
||||
@@ -51,6 +51,7 @@ export default function RelationMap({ note, ntxId }: TypeWidgetProps) {
|
||||
|
||||
const spacedUpdate = useEditorSpacedUpdate({
|
||||
note,
|
||||
noteContext,
|
||||
getData() {
|
||||
return {
|
||||
content: JSON.stringify(data),
|
||||
|
||||
@@ -37,6 +37,7 @@ export default function EditableText({ note, parentComponent, ntxId, noteContext
|
||||
const initialized = useRef(deferred<void>());
|
||||
const spacedUpdate = useEditorSpacedUpdate({
|
||||
note,
|
||||
noteContext,
|
||||
getData() {
|
||||
const editor = watchdogRef.current?.editor;
|
||||
if (!editor) {
|
||||
|
||||
Reference in New Issue
Block a user