From 802f06a3246423639eab80f49008eae36a7fe2a6 Mon Sep 17 00:00:00 2001 From: sawka Date: Mon, 15 Sep 2025 13:16:58 -0700 Subject: [PATCH 01/10] fix toc toggle --- frontend/app/element/markdown-util.ts | 2 +- frontend/app/element/markdown.tsx | 35 ++++++++++++++++++--------- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/frontend/app/element/markdown-util.ts b/frontend/app/element/markdown-util.ts index 01cb0241fe..ae860648d1 100644 --- a/frontend/app/element/markdown-util.ts +++ b/frontend/app/element/markdown-util.ts @@ -162,7 +162,7 @@ export const resolveRemoteFile = async (filepath: string, resolveOpts: MarkdownR const baseDirUri = formatRemoteUri(resolveOpts.baseDir, resolveOpts.connName); const fileInfo = await RpcApi.FileJoinCommand(TabRpcClient, [baseDirUri, filepath]); const remoteUri = formatRemoteUri(fileInfo.path, resolveOpts.connName); - console.log("markdown resolve", resolveOpts, filepath, "=>", baseDirUri, remoteUri); + // console.log("markdown resolve", resolveOpts, filepath, "=>", baseDirUri, remoteUri); const usp = new URLSearchParams(); usp.set("path", remoteUri); return getWebServerEndpoint() + "/wave/stream-file?" + usp.toString(); diff --git a/frontend/app/element/markdown.tsx b/frontend/app/element/markdown.tsx index da826dad8d..4c76958b48 100644 --- a/frontend/app/element/markdown.tsx +++ b/frontend/app/element/markdown.tsx @@ -383,19 +383,30 @@ const Markdown = ({ }; const toc = useMemo(() => { - if (showToc && tocRef.current.length > 0) { - return tocRef.current.map((item) => { + if (showToc) { + if (tocRef.current.length > 0) { + return tocRef.current.map((item) => { + return ( + setFocusedHeading(item.href)} + > + {item.value} + + ); + }); + } else { return ( - setFocusedHeading(item.href)} +
- {item.value} - + No sub-headings found +
); - }); + } } }, [showToc, tocRef]); @@ -483,9 +494,9 @@ const Markdown = ({
{scrollable ? : } {toc && ( - +
-

Table of Contents

+

Table of Contents

{toc}
From 8ce4ed0ad6232d562ddb77c41843369398a7d809 Mon Sep 17 00:00:00 2001 From: sawka Date: Mon, 15 Sep 2025 13:28:38 -0700 Subject: [PATCH 02/10] possible fix for double editor bug --- frontend/app/view/codeeditor/codeeditor.tsx | 31 +++------------------ frontend/app/view/preview/preview-edit.tsx | 2 -- 2 files changed, 4 insertions(+), 29 deletions(-) diff --git a/frontend/app/view/codeeditor/codeeditor.tsx b/frontend/app/view/codeeditor/codeeditor.tsx index d351aa9bcf..1c6ddf03b3 100644 --- a/frontend/app/view/codeeditor/codeeditor.tsx +++ b/frontend/app/view/codeeditor/codeeditor.tsx @@ -8,9 +8,7 @@ import type * as MonacoTypes from "monaco-editor/esm/vs/editor/editor.api"; import { configureMonacoYaml } from "monaco-yaml"; import React, { useMemo, useRef } from "react"; -import { RpcApi } from "@/app/store/wshclientapi"; -import { TabRpcClient } from "@/app/store/wshrpcutil"; -import { boundNumber, makeConnRoute } from "@/util/util"; +import { boundNumber } from "@/util/util"; import editorWorker from "monaco-editor/esm/vs/editor/editor.worker?worker"; import cssWorker from "monaco-editor/esm/vs/language/css/css.worker?worker"; import htmlWorker from "monaco-editor/esm/vs/language/html/html.worker?worker"; @@ -19,7 +17,6 @@ import tsWorker from "monaco-editor/esm/vs/language/typescript/ts.worker?worker" import { SchemaEndpoints, getSchemaEndpointInfo } from "./schemaendpoints"; import ymlWorker from "./yamlworker?worker"; - // there is a global monaco variable (TODO get the correct TS type) declare var monaco: Monaco; @@ -109,15 +106,13 @@ function defaultEditorOptions(): MonacoTypes.editor.IEditorOptions { interface CodeEditorProps { blockId: string; text: string; - filename: string; fileinfo: FileInfo; language?: string; - meta?: MetaType; onChange?: (text: string) => void; onMount?: (monacoPtr: MonacoTypes.editor.IStandaloneCodeEditor, monaco: Monaco) => () => void; } -export function CodeEditor({ blockId, text, language, filename, fileinfo, meta, onChange, onMount }: CodeEditorProps) { +export function CodeEditor({ blockId, text, language, fileinfo, onChange, onMount }: CodeEditorProps) { const divRef = useRef(null); const unmountRef = useRef<() => void>(null); const minimapEnabled = useOverrideConfigAtom(blockId, "editor:minimapenabled") ?? false; @@ -125,7 +120,7 @@ export function CodeEditor({ blockId, text, language, filename, fileinfo, meta, const wordWrap = useOverrideConfigAtom(blockId, "editor:wordwrap") ?? false; const fontSize = boundNumber(useOverrideConfigAtom(blockId, "editor:fontsize"), 6, 64); const theme = "wave-theme-dark"; - const [absPath, setAbsPath] = React.useState(""); + const editorPath = useRef(crypto.randomUUID()).current; React.useEffect(() => { return () => { @@ -136,24 +131,6 @@ export function CodeEditor({ blockId, text, language, filename, fileinfo, meta, }; }, []); - React.useEffect(() => { - const inner = async () => { - try { - const fileInfo = await RpcApi.RemoteFileJoinCommand(TabRpcClient, [filename], { - route: makeConnRoute(meta.connection ?? ""), - }); - setAbsPath(fileInfo.path); - } catch (e) { - setAbsPath(filename); - } - }; - inner(); - }, [filename]); - - React.useEffect(() => { - console.log("abspath is", absPath); - }, [absPath]); - function handleEditorChange(text: string, ev: MonacoTypes.editor.IModelContentChangedEvent) { if (onChange) { onChange(text); @@ -185,7 +162,7 @@ export function CodeEditor({ blockId, text, language, filename, fileinfo, meta, options={editorOpts} onChange={handleEditorChange} onMount={handleEditorOnMount} - path={absPath} + path={editorPath} language={language} />
diff --git a/frontend/app/view/preview/preview-edit.tsx b/frontend/app/view/preview/preview-edit.tsx index 3915424828..dfc907aa33 100644 --- a/frontend/app/view/preview/preview-edit.tsx +++ b/frontend/app/view/preview/preview-edit.tsx @@ -67,9 +67,7 @@ function CodeEditPreview({ model }: SpecializedViewProps) { setNewFileContent(text)} onMount={onMount} /> From fc948c193bd6d21ca692019335a819d9f9416898 Mon Sep 17 00:00:00 2001 From: sawka Date: Mon, 15 Sep 2025 13:33:53 -0700 Subject: [PATCH 03/10] simplify more --- frontend/app/view/codeeditor/codeeditor.tsx | 8 ++++---- frontend/app/view/preview/preview-edit.tsx | 4 +--- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/frontend/app/view/codeeditor/codeeditor.tsx b/frontend/app/view/codeeditor/codeeditor.tsx index 1c6ddf03b3..3f278a6825 100644 --- a/frontend/app/view/codeeditor/codeeditor.tsx +++ b/frontend/app/view/codeeditor/codeeditor.tsx @@ -106,13 +106,13 @@ function defaultEditorOptions(): MonacoTypes.editor.IEditorOptions { interface CodeEditorProps { blockId: string; text: string; - fileinfo: FileInfo; + readonly: boolean; language?: string; onChange?: (text: string) => void; onMount?: (monacoPtr: MonacoTypes.editor.IStandaloneCodeEditor, monaco: Monaco) => () => void; } -export function CodeEditor({ blockId, text, language, fileinfo, onChange, onMount }: CodeEditorProps) { +export function CodeEditor({ blockId, text, language, readonly, onChange, onMount }: CodeEditorProps) { const divRef = useRef(null); const unmountRef = useRef<() => void>(null); const minimapEnabled = useOverrideConfigAtom(blockId, "editor:minimapenabled") ?? false; @@ -145,13 +145,13 @@ export function CodeEditor({ blockId, text, language, fileinfo, onChange, onMoun const editorOpts = useMemo(() => { const opts = defaultEditorOptions(); - opts.readOnly = fileinfo.readonly; + opts.readOnly = readonly; opts.minimap.enabled = minimapEnabled; opts.stickyScroll.enabled = stickyScrollEnabled; opts.wordWrap = wordWrap ? "on" : "off"; opts.fontSize = fontSize; return opts; - }, [minimapEnabled, stickyScrollEnabled, wordWrap, fontSize, fileinfo.readonly]); + }, [minimapEnabled, stickyScrollEnabled, wordWrap, fontSize, readonly]); return (
diff --git a/frontend/app/view/preview/preview-edit.tsx b/frontend/app/view/preview/preview-edit.tsx index dfc907aa33..f249f7ee7f 100644 --- a/frontend/app/view/preview/preview-edit.tsx +++ b/frontend/app/view/preview/preview-edit.tsx @@ -16,8 +16,6 @@ function CodeEditPreview({ model }: SpecializedViewProps) { const fileContent = useAtomValue(model.fileContent); const setNewFileContent = useSetAtom(model.newFileContent); const fileInfo = useAtomValue(model.statFile); - const fileName = fileInfo?.name; - const blockMeta = useAtomValue(model.blockAtom)?.meta; function codeEditKeyDownHandler(e: WaveKeyboardEvent): boolean { if (checkKeyPressed(e, "Cmd:e")) { @@ -67,7 +65,7 @@ function CodeEditPreview({ model }: SpecializedViewProps) { setNewFileContent(text)} onMount={onMount} /> From 3396acfa433b268f9103a9e440cbe1e479df7a69 Mon Sep 17 00:00:00 2001 From: sawka Date: Mon, 15 Sep 2025 14:08:08 -0700 Subject: [PATCH 04/10] remove scss classes, replace with tw --- frontend/app/element/markdown.tsx | 8 +- .../app/view/preview/preview-markdown.tsx | 3 +- .../app/view/preview/preview-streaming.tsx | 24 ++-- frontend/app/view/preview/preview.scss | 106 ------------------ frontend/app/view/preview/preview.tsx | 5 +- 5 files changed, 21 insertions(+), 125 deletions(-) delete mode 100644 frontend/app/view/preview/preview.scss diff --git a/frontend/app/element/markdown.tsx b/frontend/app/element/markdown.tsx index 4c76958b48..7539aa3130 100644 --- a/frontend/app/element/markdown.tsx +++ b/frontend/app/element/markdown.tsx @@ -10,7 +10,7 @@ import { transformBlocks, } from "@/app/element/markdown-util"; import remarkMermaidToTag from "@/app/element/remark-mermaid-to-tag"; -import { boundNumber, useAtomValueSafe } from "@/util/util"; +import { boundNumber, useAtomValueSafe, cn } from "@/util/util"; import clsx from "clsx"; import { Atom } from "jotai"; import { OverlayScrollbarsComponent, OverlayScrollbarsComponentRef } from "overlayscrollbars-react"; @@ -297,6 +297,7 @@ type MarkdownProps = { showTocAtom?: Atom; style?: React.CSSProperties; className?: string; + contentClassName?: string; onClickExecute?: (cmd: string) => void; resolveOpts?: MarkdownResolveOpts; scrollable?: boolean; @@ -311,6 +312,7 @@ const Markdown = ({ showTocAtom, style, className, + contentClassName, resolveOpts, fontSizeOverride, fixedFontSizeOverride, @@ -455,7 +457,7 @@ const Markdown = ({ return ( { return ( -
+
+
); diff --git a/frontend/app/view/preview/preview-streaming.tsx b/frontend/app/view/preview/preview-streaming.tsx index d76bef4289..f16babe7f8 100644 --- a/frontend/app/view/preview/preview-streaming.tsx +++ b/frontend/app/view/preview/preview-streaming.tsx @@ -13,14 +13,14 @@ function ImageZoomControls() { const { zoomIn, zoomOut, resetTransform } = useControls(); return ( -
- - -
@@ -29,13 +29,13 @@ function ImageZoomControls() { function StreamingImagePreview({ url }: { url: string }) { return ( -
+
{({ zoomIn, zoomOut, resetTransform, ...rest }) => ( <> - - + + )} @@ -57,15 +57,15 @@ function StreamingPreview({ model }: SpecializedViewProps) { const streamingUrl = `${getWebServerEndpoint()}/wave/stream-file?${usp.toString()}`; if (fileInfo.mimetype === "application/pdf") { return ( -
+