(null);
+ const blob = useNoteBlob(note);
+ const spacedUpdate = useEditorSpacedUpdate({
+ note,
+ getData: () => ({ content: editorRef.current?.getText() })
+ });
+
+ useEffect(() => {
+ spacedUpdate.allowUpdateWithoutChange(() => {
+ const codeEditor = editorRef.current;
+ if (!codeEditor) return;
+ codeEditor.setText(blob?.content ?? "");
+ codeEditor.setMimeType(note.mime);
+ codeEditor.clearHistory();
+ });
+ }, [ blob ]);
+
+ return (
+
+ {
+ spacedUpdate.scheduleUpdate();
+ }}
+ />
+
+ )
+}
diff --git a/apps/client/src/widgets/type_widgets/code/CodeMirror.tsx b/apps/client/src/widgets/type_widgets/code/CodeMirror.tsx
index 7a22d58f7..b1d48c32e 100644
--- a/apps/client/src/widgets/type_widgets/code/CodeMirror.tsx
+++ b/apps/client/src/widgets/type_widgets/code/CodeMirror.tsx
@@ -1,18 +1,20 @@
import { useEffect, useRef } from "preact/hooks";
import { EditorConfig, default as VanillaCodeMirror } from "@triliumnext/codemirror";
-import { useTriliumEvent, useTriliumOptionBool } from "../../react/hooks";
+import { useSyncedRef, useTriliumEvent, useTriliumOptionBool } from "../../react/hooks";
import { refToJQuerySelector } from "../../react/react_utils";
+import { RefObject } from "preact";
interface CodeMirrorProps extends Omit {
content: string;
mime: string;
className?: string;
ntxId: string | null | undefined;
+ editorRef?: RefObject;
}
-export default function CodeMirror({ className, content, mime, ntxId, ...extraOpts }: CodeMirrorProps) {
+export default function CodeMirror({ className, content, mime, ntxId, editorRef: externalEditorRef, ...extraOpts }: CodeMirrorProps) {
const parentRef = useRef(null);
- const codeEditorRef = useRef(null);
+ const codeEditorRef = useRef();
const [ codeLineWrapEnabled ] = useTriliumOptionBool("codeLineWrapEnabled");
const initialized = $.Deferred();
@@ -39,6 +41,9 @@ export default function CodeMirror({ className, content, mime, ntxId, ...extraOp
...extraOpts
});
codeEditorRef.current = codeEditor;
+ if (externalEditorRef) {
+ externalEditorRef.current = codeEditor;
+ }
initialized.resolve();
return () => codeEditor.destroy();
diff --git a/apps/client/src/widgets/type_widgets/code/ReadOnlyCode.tsx b/apps/client/src/widgets/type_widgets/code/ReadOnlyCode.tsx
deleted file mode 100644
index bdbb71ad5..000000000
--- a/apps/client/src/widgets/type_widgets/code/ReadOnlyCode.tsx
+++ /dev/null
@@ -1,29 +0,0 @@
-import { useEffect, useState } from "preact/hooks";
-import { TypeWidgetProps } from "../type_widget";
-import "./code.css";
-import CodeMirror from "./CodeMirror";
-import utils from "../../../services/utils";
-import { useNoteBlob } from "../../react/hooks";
-
-export default function ReadOnlyCode({ note, viewScope, ntxId }: TypeWidgetProps) {
- const [ content, setContent ] = useState("");
- const blob = useNoteBlob(note);
-
- useEffect(() => {
- if (!blob) return;
- const isFormattable = note.type === "text" && viewScope?.viewMode === "source";
- setContent(isFormattable ? utils.formatHtml(blob.content) : blob.content);
- }, [ blob ]);
-
- return (
-
-
-
- )
-}
diff --git a/apps/client/src/widgets/type_widgets/code/code.css b/apps/client/src/widgets/type_widgets/code/code.css
index 1af75176a..5ee6953fd 100644
--- a/apps/client/src/widgets/type_widgets/code/code.css
+++ b/apps/client/src/widgets/type_widgets/code/code.css
@@ -1,4 +1,18 @@
+/* #region Read-only code */
.note-detail-readonly-code {
min-height: 50px;
position: relative;
-}
\ No newline at end of file
+}
+/* #endregion */
+
+/* #region Editable code */
+.note-detail-code {
+ position: relative;
+ height: 100%;
+}
+
+.note-detail-code-editor {
+ min-height: 50px;
+ height: 100%;
+}
+/* #endregion */
diff --git a/apps/client/src/widgets/type_widgets/type_widget.ts b/apps/client/src/widgets/type_widgets/type_widget.ts
index 68c307002..146d6efb0 100644
--- a/apps/client/src/widgets/type_widgets/type_widget.ts
+++ b/apps/client/src/widgets/type_widgets/type_widget.ts
@@ -1,5 +1,6 @@
import FNote from "../../entities/fnote";
import { ViewScope } from "../../services/link";
+import SpacedUpdate from "../../services/spaced_update";
export interface TypeWidgetProps {
note: FNote;
diff --git a/apps/client/src/widgets/type_widgets_old/editable_code.ts b/apps/client/src/widgets/type_widgets_old/editable_code.ts
index cdf4b912e..9290c8492 100644
--- a/apps/client/src/widgets/type_widgets_old/editable_code.ts
+++ b/apps/client/src/widgets/type_widgets_old/editable_code.ts
@@ -10,21 +10,7 @@ import { hasTouchBar } from "../../services/utils.js";
import type { EditorConfig } from "@triliumnext/codemirror";
const TPL = /*html*/`
-`;
+`;
export default class EditableCodeTypeWidget extends AbstractCodeTypeWidget {
@@ -60,8 +46,6 @@ export default class EditableCodeTypeWidget extends AbstractCodeTypeWidget {
if (this.debounceUpdate) {
this.spacedUpdate.resetUpdateTimer();
}
-
- this.spacedUpdate.scheduleUpdate();
},
tabIndex: 300
}
@@ -71,7 +55,7 @@ export default class EditableCodeTypeWidget extends AbstractCodeTypeWidget {
const blob = await this.note?.getBlob();
await this.spacedUpdate.allowUpdateWithoutChange(() => {
- this._update(note, blob?.content ?? "");
+ this._update(note, blob?.content ?? "");
});
this.show();
@@ -81,12 +65,6 @@ export default class EditableCodeTypeWidget extends AbstractCodeTypeWidget {
}
}
- getData() {
- return {
- content: this.codeEditor.getText()
- };
- }
-
buildTouchBarCommand({ TouchBar, buildIcon }: CommandListenerData<"buildTouchBar">) {
const items: TouchBarItem[] = [];
const note = this.note;