From e7786318286bdaac873e04720022d24ce2a874da Mon Sep 17 00:00:00 2001 From: Pihkaal Date: Sun, 28 Jan 2024 21:35:06 +0100 Subject: [PATCH] feat(nvim): display selected file in tree in the editor --- package.json | 1 + pnpm-lock.yaml | 31 +++++++++++++++ src/App.tsx | 49 ++++++++++++------------ src/components/Nvim/Nvim.tsx | 60 ++++++++++++++++++++++++++++-- src/components/Nvim/NvimEditor.tsx | 16 ++++++++ src/components/Nvim/NvimTree.tsx | 5 +++ src/utils/filesystem.ts | 4 ++ 7 files changed, 139 insertions(+), 27 deletions(-) create mode 100644 src/components/Nvim/NvimEditor.tsx diff --git a/package.json b/package.json index 8c321dc..2ecb7d1 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "axios": "^1.6.7", "react": "18.2.0", "react-dom": "18.2.0", + "react-router-dom": "^6.21.3", "vite-tsconfig-paths": "^4.3.1", "zod": "^3.22.4" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f9099e0..80028e5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,6 +14,9 @@ dependencies: react-dom: specifier: 18.2.0 version: 18.2.0(react@18.2.0) + react-router-dom: + specifier: ^6.21.3 + version: 6.21.3(react-dom@18.2.0)(react@18.2.0) vite-tsconfig-paths: specifier: ^4.3.1 version: 4.3.1(typescript@5.3.3)(vite@5.0.12) @@ -419,6 +422,11 @@ packages: dev: true optional: true + /@remix-run/router@1.14.2: + resolution: {integrity: sha512-ACXpdMM9hmKZww21yEqWwiLws/UPLhNKvimN8RrYSqPSvB3ov7sLvAcfvaxePeLvccTQKGdkDIhLYApZVDFuKg==} + engines: {node: '>=14.0.0'} + dev: false + /@rollup/rollup-android-arm-eabi@4.9.6: resolution: {integrity: sha512-MVNXSSYN6QXOulbHpLMKYi60ppyO13W9my1qogeiAqtjb2yR4LSmfU2+POvDkLzhjYLXz9Rf9+9a3zFHW1Lecg==} cpu: [arm] @@ -2726,6 +2734,29 @@ packages: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} dev: true + /react-router-dom@6.21.3(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-kNzubk7n4YHSrErzjLK72j0B5i969GsuCGazRl3G6j1zqZBLjuSlYBdVdkDOgzGdPIffUOc9nmgiadTEVoq91g==} + engines: {node: '>=14.0.0'} + peerDependencies: + react: '>=16.8' + react-dom: '>=16.8' + dependencies: + '@remix-run/router': 1.14.2 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-router: 6.21.3(react@18.2.0) + dev: false + + /react-router@6.21.3(react@18.2.0): + resolution: {integrity: sha512-a0H638ZXULv1OdkmiK6s6itNhoy33ywxmUFT/xtSoVyf9VnC7n7+VT4LjVzdIHSaF5TIh9ylUgxMXksHTgGrKg==} + engines: {node: '>=14.0.0'} + peerDependencies: + react: '>=16.8' + dependencies: + '@remix-run/router': 1.14.2 + react: 18.2.0 + dev: false + /react@18.2.0: resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} engines: {node: '>=0.10.0'} diff --git a/src/App.tsx b/src/App.tsx index c5c60fe..da230d8 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,3 +1,4 @@ +import { BrowserRouter } from "react-router-dom"; import { MusicPlayer } from "./components/MusicPlayer"; import { MusicVisualizer } from "./components/MusicVisualizer"; import { Nvim } from "./components/Nvim/Nvim"; @@ -7,32 +8,34 @@ import { AppContextProvider } from "./context/AppContext"; function App() { return ( -
- - - - - - -
- - - + +
+ - + -
-
+ +
+ + + + + + + +
+ +
); } diff --git a/src/components/Nvim/Nvim.tsx b/src/components/Nvim/Nvim.tsx index 9891d16..b69c23a 100644 --- a/src/components/Nvim/Nvim.tsx +++ b/src/components/Nvim/Nvim.tsx @@ -2,19 +2,71 @@ import { useApp } from "~/context/AppContext"; import { NvimStatusBar } from "./NvimStatusBar"; import { NvimTree } from "./NvimTree"; import { buildFileTree } from "~/utils/filesystem"; +import { useEffect, useState } from "react"; +import axios from "axios"; +import { useLocation, useNavigate } from "react-router-dom"; +import { NvimEditor } from "./NvimEditor"; + +const fetchData = async ( + branch: string, + repo: string, + file: string, +): Promise => { + try { + const response = await axios.get( + `https://raw.githubusercontent.com/pihkaal/${repo}/${branch}/${file}`, + ); + return response.data; + } catch { + return null; + } +}; export const Nvim = () => { const manifest = useApp(); + const [data, setData] = useState(null); + + const location = useLocation(); + const navigate = useNavigate(); + + useEffect(() => { + const params = new URLSearchParams(location.search); + const view = params.get("view"); + if (!view) { + navigate("?view=README.md"); + return; + } + + const path = view.split("/"); + if (path.length === 1) { + path.splice(0, 0, "pihkaal"); + } + const repo = path[0]!; + const file = path[1]!; + + void (async () => { + const data = + (await fetchData("main", repo, file)) ?? + (await fetchData("dev", repo, file)); + if (!data) { + navigate("?view=README.md"); + return; + } + + setData(data); + })(); + }, [location, navigate]); return ( -
-
+
+
-
+
+ +
-
diff --git a/src/components/Nvim/NvimEditor.tsx b/src/components/Nvim/NvimEditor.tsx new file mode 100644 index 0000000..1acec90 --- /dev/null +++ b/src/components/Nvim/NvimEditor.tsx @@ -0,0 +1,16 @@ +import { useTerminal } from "~/context/TerminalContext"; +import { TerminalRenderer } from "~/utils/terminal/renderer"; + +export const NvimEditor = (props: { content: string | null }) => { + const { cols: width, rows: height } = useTerminal(); + + const canvas = new TerminalRenderer(width * 0.8, height - 2); + + if (props.content) { + props.content.split("\n").forEach((line, y) => { + canvas.write(0, y, line); + }); + } + + return canvas.render(); +}; diff --git a/src/components/Nvim/NvimTree.tsx b/src/components/Nvim/NvimTree.tsx index 7e1b91e..ce7b0f6 100644 --- a/src/components/Nvim/NvimTree.tsx +++ b/src/components/Nvim/NvimTree.tsx @@ -1,4 +1,5 @@ import { useState, useEffect } from "react"; +import { useNavigate } from "react-router-dom"; import { useTerminal } from "~/context/TerminalContext"; import { DEFAULT_FILE_STYLE, @@ -23,6 +24,7 @@ const PATH_UNFOLDED: Cell = { export const NvimTree = (props: { files: Array }) => { const [selected, setSelected] = useState(0); const [files, setFiles] = useState(props.files); + const navigate = useNavigate(); const { cols: width, rows: height } = useTerminal(); const canvas = new TerminalRenderer(width * 0.2, height - 2, { @@ -108,6 +110,9 @@ export const NvimTree = (props: { files: Array }) => { if (current.type === "directory") { current.folded = !current.folded; setFiles([...files]); + } else { + //document.location.href = `?view=${current.path}` + navigate(`?view=${current.path}`); } break; } diff --git a/src/utils/filesystem.ts b/src/utils/filesystem.ts index 818b724..368d657 100644 --- a/src/utils/filesystem.ts +++ b/src/utils/filesystem.ts @@ -25,6 +25,7 @@ export const FILE_STYLES: Record = { export type File = { name: string; + path: string; } & ( | { type: "file"; @@ -54,17 +55,20 @@ export const buildFileTree = (manifest: Manifest): Array => { project.files.forEach(file => { files.push({ name: file, + path: file, type: "file", }); }); } else { files.push({ name: project.name, + path: project.name, type: "directory", folded: true, children: sortFiles( project.files.map(file => ({ name: file, + path: `${project.name}/${file}`, type: "file", })), ),