darabos commited on
Commit
b45955a
·
1 Parent(s): 3e1ec11

Allow working with files in directories.

Browse files
README.md CHANGED
@@ -41,7 +41,7 @@ uv pip install -e lynxkite-core/[dev] -e lynxkite-app/[dev] -e lynxkite-graph-an
41
  This also builds the frontend, hopefully very quickly. To run it:
42
 
43
  ```bash
44
- cd examples && LYNXKITE_RELOAD=1 lynxkite
45
  ```
46
 
47
  If you also want to make changes to the frontend with hot reloading:
 
41
  This also builds the frontend, hopefully very quickly. To run it:
42
 
43
  ```bash
44
+ cd examples && lynxkite
45
  ```
46
 
47
  If you also want to make changes to the frontend with hot reloading:
lynxkite-app/src/lynxkite_app/crdt.py CHANGED
@@ -300,14 +300,14 @@ def sanitize_path(path):
300
  return os.path.relpath(os.path.normpath(os.path.join("/", path)), "/")
301
 
302
 
303
- @router.websocket("/ws/crdt/{room_name}")
304
  async def crdt_websocket(websocket: fastapi.WebSocket, room_name: str):
305
  room_name = sanitize_path(room_name)
306
  server = pycrdt_websocket.ASGIServer(ws_websocket_server)
307
  await server({"path": room_name}, websocket._receive, websocket._send)
308
 
309
 
310
- @router.websocket("/ws/code/crdt/{room_name}")
311
  async def code_crdt_websocket(websocket: fastapi.WebSocket, room_name: str):
312
  room_name = sanitize_path(room_name)
313
  server = pycrdt_websocket.ASGIServer(code_websocket_server)
 
300
  return os.path.relpath(os.path.normpath(os.path.join("/", path)), "/")
301
 
302
 
303
+ @router.websocket("/ws/crdt/{room_name:path}")
304
  async def crdt_websocket(websocket: fastapi.WebSocket, room_name: str):
305
  room_name = sanitize_path(room_name)
306
  server = pycrdt_websocket.ASGIServer(ws_websocket_server)
307
  await server({"path": room_name}, websocket._receive, websocket._send)
308
 
309
 
310
+ @router.websocket("/ws/code/crdt/{room_name:path}")
311
  async def code_crdt_websocket(websocket: fastapi.WebSocket, room_name: str):
312
  room_name = sanitize_path(room_name)
313
  server = pycrdt_websocket.ASGIServer(code_websocket_server)
lynxkite-app/web/src/Code.tsx CHANGED
@@ -3,7 +3,7 @@
3
  import Editor, { type Monaco } from "@monaco-editor/react";
4
  import type { editor } from "monaco-editor";
5
  import { useEffect, useRef } from "react";
6
- import { Link, useParams } from "react-router";
7
  import { WebsocketProvider } from "y-websocket";
8
  import * as Y from "yjs";
9
  // @ts-ignore
@@ -16,7 +16,7 @@ import favicon from "./assets/favicon.ico";
16
  import theme from "./code-theme.ts";
17
 
18
  export default function Code() {
19
- const { path } = useParams();
20
  const parentDir = path!.split("/").slice(0, -1).join("/");
21
  const yDocRef = useRef<any>();
22
  const wsProviderRef = useRef<any>();
 
3
  import Editor, { type Monaco } from "@monaco-editor/react";
4
  import type { editor } from "monaco-editor";
5
  import { useEffect, useRef } from "react";
6
+ import { Link, useLocation } from "react-router";
7
  import { WebsocketProvider } from "y-websocket";
8
  import * as Y from "yjs";
9
  // @ts-ignore
 
16
  import theme from "./code-theme.ts";
17
 
18
  export default function Code() {
19
+ const path = decodeURIComponent(useLocation().pathname).replace(/^\/code\//, "");
20
  const parentDir = path!.split("/").slice(0, -1).join("/");
21
  const yDocRef = useRef<any>();
22
  const wsProviderRef = useRef<any>();
lynxkite-app/web/src/Directory.tsx CHANGED
@@ -1,6 +1,6 @@
1
  import { useState } from "react";
2
  // The directory browser.
3
- import { Link, useNavigate, useParams } from "react-router";
4
  import useSWR from "swr";
5
  import type { DirectoryEntry } from "./apiTypes.ts";
6
 
@@ -58,7 +58,7 @@ function EntryCreator(props: {
58
  const fetcher = (url: string) => fetch(url).then((res) => res.json());
59
 
60
  export default function () {
61
- const { path } = useParams();
62
  const encodedPath = encodeURIComponent(path || "");
63
  const list = useSWR(`/api/dir/list?path=${encodedPath}`, fetcher, {
64
  dedupingInterval: 0,
 
1
  import { useState } from "react";
2
  // The directory browser.
3
+ import { Link, useLocation, useNavigate } from "react-router";
4
  import useSWR from "swr";
5
  import type { DirectoryEntry } from "./apiTypes.ts";
6
 
 
58
  const fetcher = (url: string) => fetch(url).then((res) => res.json());
59
 
60
  export default function () {
61
+ const path = decodeURIComponent(useLocation().pathname).replace(/^[/]$|^[/]dir$|^[/]dir[/]/, "");
62
  const encodedPath = encodeURIComponent(path || "");
63
  const list = useSWR(`/api/dir/list?path=${encodedPath}`, fetcher, {
64
  dedupingInterval: 0,
lynxkite-app/web/src/main.tsx CHANGED
@@ -13,9 +13,9 @@ createRoot(document.getElementById("root")!).render(
13
  <Routes>
14
  <Route path="/" element={<Directory />} />
15
  <Route path="/dir" element={<Directory />} />
16
- <Route path="/dir/:path" element={<Directory />} />
17
- <Route path="/edit/:path" element={<Workspace />} />
18
- <Route path="/code/:path" element={<Code />} />
19
  </Routes>
20
  </BrowserRouter>
21
  </StrictMode>,
 
13
  <Routes>
14
  <Route path="/" element={<Directory />} />
15
  <Route path="/dir" element={<Directory />} />
16
+ <Route path="/dir/*" element={<Directory />} />
17
+ <Route path="/edit/*" element={<Workspace />} />
18
+ <Route path="/code/*" element={<Code />} />
19
  </Routes>
20
  </BrowserRouter>
21
  </StrictMode>,
lynxkite-app/web/src/workspace/Workspace.tsx CHANGED
@@ -18,7 +18,7 @@ import {
18
  } from "@xyflow/react";
19
  import axios from "axios";
20
  import { type MouseEvent, useCallback, useEffect, useMemo, useState } from "react";
21
- import { useParams } from "react-router";
22
  import useSWR, { type Fetcher } from "swr";
23
  import { WebsocketProvider } from "y-websocket";
24
  // @ts-ignore
@@ -55,7 +55,7 @@ function LynxKiteFlow() {
55
  const reactFlow = useReactFlow();
56
  const [nodes, setNodes] = useState([] as Node[]);
57
  const [edges, setEdges] = useState([] as Edge[]);
58
- const { path } = useParams();
59
  const shortPath = path!
60
  .split("/")
61
  .pop()!
 
18
  } from "@xyflow/react";
19
  import axios from "axios";
20
  import { type MouseEvent, useCallback, useEffect, useMemo, useState } from "react";
21
+ import { useLocation } from "react-router";
22
  import useSWR, { type Fetcher } from "swr";
23
  import { WebsocketProvider } from "y-websocket";
24
  // @ts-ignore
 
55
  const reactFlow = useReactFlow();
56
  const [nodes, setNodes] = useState([] as Node[]);
57
  const [edges, setEdges] = useState([] as Edge[]);
58
+ const path = decodeURIComponent(useLocation().pathname).replace(/^\/edit\//, "");
59
  const shortPath = path!
60
  .split("/")
61
  .pop()!