diff --git a/frontend/app/element/markdown.tsx b/frontend/app/element/markdown.tsx index 44b0e280e..59925fdeb 100644 --- a/frontend/app/element/markdown.tsx +++ b/frontend/app/element/markdown.tsx @@ -178,7 +178,7 @@ type MarkdownProps = { }; const Markdown = ({ text, textAtom, showTocAtom, style, className, resolveOpts, onClickExecute }: MarkdownProps) => { - const textAtomValue = useAtomValueSafe(textAtom); + const textAtomValue = useAtomValueSafe(textAtom); const tocRef = useRef([]); const showToc = useAtomValueSafe(showTocAtom) ?? false; const contentsOsRef = useRef(null); diff --git a/frontend/app/view/codeeditor/codeeditor.tsx b/frontend/app/view/codeeditor/codeeditor.tsx index ae9d56b98..dc544678d 100644 --- a/frontend/app/view/codeeditor/codeeditor.tsx +++ b/frontend/app/view/codeeditor/codeeditor.tsx @@ -2,12 +2,11 @@ // SPDX-License-Identifier: Apache-2.0 import { atoms } from "@/app/store/global"; -import { useAtomValueSafe } from "@/util/util"; import loader from "@monaco-editor/loader"; import { Editor, Monaco } from "@monaco-editor/react"; -import { Atom, atom, useAtomValue } from "jotai"; +import { atom, useAtomValue } from "jotai"; import type * as MonacoTypes from "monaco-editor/esm/vs/editor/editor.api"; -import React, { useMemo, useRef, useState } from "react"; +import React, { useMemo, useRef } from "react"; import "./codeeditor.less"; // there is a global monaco variable (TODO get the correct TS type) @@ -71,8 +70,7 @@ function defaultEditorOptions(): MonacoTypes.editor.IEditorOptions { } interface CodeEditorProps { - text?: string; - textAtom?: Atom | Atom>; + text: string; filename: string; language?: string; onChange?: (text: string) => void; @@ -89,13 +87,11 @@ const stickyScrollEnabledAtom = atom((get) => { return settings["editor:stickyscrollenabled"] ?? false; }); -export function CodeEditor({ text, textAtom, language, filename, onChange, onMount }: CodeEditorProps) { +export function CodeEditor({ text, language, filename, onChange, onMount }: CodeEditorProps) { const divRef = useRef(null); const unmountRef = useRef<() => void>(null); const minimapEnabled = useAtomValue(minimapEnabledAtom); const stickyScrollEnabled = useAtomValue(stickyScrollEnabledAtom); - const textAtomValue = useAtomValueSafe(textAtom); - const [textValue] = useState(() => textAtomValue ?? text); const theme = "wave-theme-dark"; React.useEffect(() => { @@ -131,7 +127,7 @@ export function CodeEditor({ text, textAtom, language, filename, onChange, onMou
>; fileMimeTypeLoadable: jotai.Atom>; fileContent: jotai.Atom>; - fileContentLastSaved: jotai.PrimitiveAtom; - fileContentModified: jotai.PrimitiveAtom; - previewFileContent: jotai.WritableAtom, [value: string], void>; + newFileContent: jotai.PrimitiveAtom; openFileModal: jotai.PrimitiveAtom; openFileError: jotai.PrimitiveAtom; @@ -210,7 +208,6 @@ export class PreviewModel implements ViewModel { const blockData = get(this.blockAtom); return blockData?.meta?.edit ?? false; }); - this.viewName = jotai.atom("Preview"); this.viewText = jotai.atom((get) => { let headerPath = get(this.metaFilePath); @@ -244,7 +241,7 @@ export class PreviewModel implements ViewModel { }, ]; let saveClassName = "secondary"; - if (get(this.fileContentModified) !== null) { + if (get(this.newFileContent) !== null) { saveClassName = "primary"; } if (isCeView) { @@ -371,6 +368,7 @@ export class PreviewModel implements ViewModel { return fileInfo?.mimetype; }); this.fileMimeTypeLoadable = loadable(this.fileMimeType); + this.newFileContent = jotai.atom(null) as jotai.PrimitiveAtom; this.goParentDirectory = this.goParentDirectory.bind(this); const fullFileAtom = jotai.atom>(async (get) => { @@ -391,23 +389,6 @@ export class PreviewModel implements ViewModel { this.fullFile = fullFileAtom; this.fileContent = fileContentAtom; - this.fileContentModified = jotai.atom(); - this.fileContentLastSaved = jotai.atom(); - this.previewFileContent = jotai.atom( - async (get) => { - const fileContentModified = get(this.fileContentModified); - const fileContentLastSaved = get(this.fileContentLastSaved); - if (!fileContentModified) { - return fileContentLastSaved ?? (await get(this.fileContent)); - } else { - return fileContentModified; - } - }, - (_get, set, value) => { - set(this.fileContentModified, value); - } - ); - this.specializedView = jotai.atom>(async (get) => { return this.getSpecializedView(get); }); @@ -552,7 +533,7 @@ export class PreviewModel implements ViewModel { if (filePath == null) { return; } - const newFileContent = globalStore.get(this.fileContentModified); + const newFileContent = globalStore.get(this.newFileContent); if (newFileContent == null) { console.log("not saving file, newFileContent is null"); return; @@ -560,8 +541,7 @@ export class PreviewModel implements ViewModel { const conn = globalStore.get(this.connection) ?? ""; try { services.FileService.SaveFile(conn, filePath, util.stringToBase64(newFileContent)); - globalStore.set(this.fileContentModified, null); - globalStore.set(this.fileContentLastSaved, newFileContent); + globalStore.set(this.newFileContent, null); console.log("saved file", filePath); } catch (error) { console.error("Error saving file:", error); @@ -569,7 +549,9 @@ export class PreviewModel implements ViewModel { } async handleFileRevert() { - globalStore.set(this.fileContentModified, null); + const fileContent = await globalStore.get(this.fileContent); + this.monacoRef.current?.setValue(fileContent); + globalStore.set(this.newFileContent, null); } async handleOpenFile(filePath: string) { @@ -639,7 +621,7 @@ export class PreviewModel implements ViewModel { const loadableSV = globalStore.get(this.loadableSpecializedView); if (loadableSV.state == "hasData") { if (loadableSV.data.specializedView == "codeedit") { - if (globalStore.get(this.fileContentModified) != null) { + if (globalStore.get(this.newFileContent) != null) { menuItems.push({ type: "separator" }); menuItems.push({ label: "Save File", @@ -729,11 +711,7 @@ function MarkdownPreview({ model }: SpecializedViewProps) { }, [connName, fileInfo.dir]); return (
- +
); } @@ -784,7 +762,8 @@ function StreamingPreview({ model }: SpecializedViewProps) { } function CodeEditPreview({ model }: SpecializedViewProps) { - const setNewFileContent = jotai.useSetAtom(model.previewFileContent); + const fileContent = jotai.useAtomValue(model.fileContent); + const setNewFileContent = jotai.useSetAtom(model.newFileContent); const fileName = jotai.useAtomValue(model.statFilePath); function codeEditKeyDownHandler(e: WaveKeyboardEvent): boolean { @@ -833,16 +812,16 @@ function CodeEditPreview({ model }: SpecializedViewProps) { return ( setNewFileContent(text)} onMount={onMount} /> ); } function CSVViewPreview({ model, parentRef }: SpecializedViewProps) { - const fileContent = jotai.useAtomValue(model.previewFileContent); + const fileContent = jotai.useAtomValue(model.fileContent); const fileName = jotai.useAtomValue(model.statFilePath); return ; }