From e7616b43ad1eacdade2884f7b0816c05fc4dd67f Mon Sep 17 00:00:00 2001 From: bkellam Date: Mon, 26 Aug 2024 21:40:08 -0700 Subject: [PATCH] Add topbar to code editor to indicate open file + hold the close button --- src/app/page.tsx | 82 +++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 67 insertions(+), 15 deletions(-) diff --git a/src/app/page.tsx b/src/app/page.tsx index 531c98a8..ce6339da 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -5,8 +5,8 @@ import { Separator } from "@/components/ui/separator"; import { useNonEmptyQueryParam } from "@/hooks/useNonEmptyQueryParam"; import { defaultKeymap } from "@codemirror/commands"; import { javascript } from "@codemirror/lang-javascript"; -import { keymap } from "@codemirror/view"; -import { SymbolIcon } from "@radix-ui/react-icons"; +import { EditorView, keymap, ViewPlugin, ViewUpdate } from "@codemirror/view"; +import { SymbolIcon, FileIcon, Cross1Icon } from "@radix-ui/react-icons"; import { ScrollArea, Scrollbar } from "@radix-ui/react-scroll-area"; import CodeMirror from '@uiw/react-codemirror'; import Image from "next/image"; @@ -24,6 +24,7 @@ import { GetSourceResponse, pathQueryParamName, repoQueryParamName } from "@/lib import { createPathWithQueryParams } from "@/lib/utils"; import { ThemeSelectorButton } from "./themeSelectorButton"; import { useTheme } from "next-themes"; +import { Button } from "@/components/ui/button"; interface ZoekMatch { URL: string, @@ -67,6 +68,7 @@ export default function Home() { const [isCodePanelOpen, setIsCodePanelOpen] = useState(false); const [code, setCode] = useState(""); + const [filepath, setFilepath] = useState(""); const [fileMatches, setFileMatches] = useState([]); const [isLoading, setIsLoading] = useState(false); @@ -138,6 +140,7 @@ export default function Home() { .then((body: GetSourceResponse) => { setIsCodePanelOpen(true); setCode(body.content); + setFilepath(match.FileName); }); }} /> @@ -153,6 +156,8 @@ export default function Home() { > setIsCodePanelOpen(false)} /> )} @@ -163,10 +168,14 @@ export default function Home() { interface CodeEditorProps { code: string; + filepath: string; + onClose: () => void; } const CodeEditor = ({ code, + filepath, + onClose, }: CodeEditorProps) => { const { theme: _theme, systemTheme } = useTheme(); const theme = useMemo(() => { @@ -177,19 +186,62 @@ const CodeEditor = ({ return _theme ?? "light"; }, [_theme]); + const [gutterWidth, setGutterWidth] = useState(0); + const gutterWidthPlugin = useMemo(() => { + return ViewPlugin.fromClass(class { + width: number = 0; + constructor(view: EditorView) { + this.measureWidth(view) + } + update(update: ViewUpdate) { + if (update.geometryChanged) this.measureWidth(update.view) + } + measureWidth(view: EditorView) { + let gutter = view.scrollDOM.querySelector('.cm-gutters') as HTMLElement + if (gutter) this.width = gutter.offsetWidth + } + }); + }, []); + return ( - - - - +
+
+
+
+ +
+ {filepath} +
+ +
+ + { + const width = update.view.plugin(gutterWidthPlugin)?.width; + if (width) { + setGutterWidth(width); + } + }) + ]} + /> + + +
) } @@ -272,7 +324,7 @@ const FileMatch = ({
{ + onClick={() => { onOpenFile(); }} >