This commit is contained in:
kolaflash
2025-12-16 20:36:09 +01:00
parent 897c414b44
commit 1dc9c803b3
35 changed files with 114 additions and 36 deletions
@@ -1,6 +1,6 @@
import "./FileBrowser.css"; import "./FileBrowser.css";
import { type Component, createSignal, Index, Show } from "solid-js"; import { type Component, createSignal, Index, Show } from "solid-js";
import { FileIcon, FolderIcon, FolderOpenIcon } from "./icons/index.ts"; import { FileIcon, FolderIcon, FolderOpenIcon } from "#/dev/icons/index.ts";
export type BrowserFolder = Map<string, string | BrowserFolder>; export type BrowserFolder = Map<string, string | BrowserFolder>;
View File
+36 -27
View File
@@ -1,10 +1,10 @@
import "./main.css"; import "./main.css";
import { type Component, createSignal, onMount } from "solid-js"; import { type Component, createSignal, onMount } from "solid-js";
import { render } from "solid-js/web"; import { render } from "solid-js/web";
import { InputField } from "#/dev/controls/InputField.tsx";
import { RangeSlider } from "#/dev/controls/RangeSlider.tsx";
import { currentScene } from "#/engine/Scene.ts"; import { currentScene } from "#/engine/Scene.ts";
import { setScale, viewport } from "#/engine/Viewport.ts"; import { setScale, viewport } from "#/engine/Viewport.ts";
import { InputField } from "#/tools/controls/InputField.tsx";
import { RangeSlider } from "#/tools/controls/RangeSlider.tsx";
import { type BrowserFolder, FileBrowser } from "./FileBrowser.tsx"; import { type BrowserFolder, FileBrowser } from "./FileBrowser.tsx";
import { import {
ArrowAutofitHeightIcon, ArrowAutofitHeightIcon,
@@ -13,31 +13,40 @@ import {
ZoomScanIcon, ZoomScanIcon,
} from "./icons/index.ts"; } from "./icons/index.ts";
const root = new Map<string, string | BrowserFolder>([ function sceneTreeBuilder(
[ current: BrowserFolder,
"Brrr", entries: string[],
new Map<string, string | BrowserFolder>([ index: number,
[ ref: string[],
"folder", ): void {
new Map<string, string | BrowserFolder>([ console.log(entries);
["fuzz", "/fuzz.file"],
["buzz", "/buzz.file"], const next = current.has(entries[0])
]), ? (current.get(entries[0]) as BrowserFolder)
], : (new Map() as BrowserFolder);
["dnd:", "/dnd.file"],
["bla", "/bla.file"], if (entries.length > 1) {
]), current.set(entries.shift() as string, next);
], sceneTreeBuilder(next, entries, index, ref);
[ } else {
"folder", // if (entries[0] !== "index.ts") {
new Map<string, string | BrowserFolder>([ // return;
["fuzz", "/fuzz.file"], // }
["buzz", "/buzz.file"], current.set(entries[0], entries[0]);
]), }
], }
["foo", "/foo.file"], async function fetchSceneIndex(): Promise<BrowserFolder> {
["bar", "/bar.file"], const indexRef: string[] = await (await fetch("/api/scenes")).json();
]);
return indexRef.reduce((root, entry, index) => {
const entries = `scenes${entry}`.split("/");
sceneTreeBuilder(root, entries, index, indexRef);
return root;
}, new Map() as BrowserFolder);
}
const root = await fetchSceneIndex();
function adjustGameContainer(gameContainer: HTMLElement, width: number): void { function adjustGameContainer(gameContainer: HTMLElement, width: number): void {
gameContainer.style = `position: relative; top: 0; left: ${width}px; width: ${document.body.offsetWidth - width}px;`; gameContainer.style = `position: relative; top: 0; left: ${width}px; width: ${document.body.offsetWidth - width}px;`;
+60
View File
@@ -0,0 +1,60 @@
import { readdirSync, writeFileSync } from "node:fs";
import type { IncomingMessage, ServerResponse } from "node:http";
function buildBrowserIndex(name: string, dir: string): string[] {
const dirents = readdirSync(dir, {
withFileTypes: true,
recursive: true,
});
return dirents
.filter((dirent) => dirent.isFile() && dirent.name !== name)
.map((dirent) => {
const path = dirent.parentPath.substring(dir.length);
return `${path}/${dirent.name}`;
});
}
function get(req: IncomingMessage, res: ServerResponse): void {
console.log(req.url);
const match = req.url?.match(/\/(\w+)$/);
if (!match) {
res.statusCode = 400;
res.end();
}
const sceneData = buildBrowserIndex("scenes", "scenes"); // FIXME
res.writeHead(200, { "Content-Type": "application/json" });
res.end(JSON.stringify(sceneData));
}
function post(req: IncomingMessage, res: ServerResponse): void {
// let body = "";
// req.on("data", (chunk) => {
// body += chunk.toString();
// });
// req.on("end", () => {
// const data: SceneData = JSON.parse(body);
// writeFileSync(
// `${dev.scenesDir}/${data.name}.json`,
// JSON.stringify(data, null, 2),
// "utf8",
// );
// res.statusCode = 204;
// res.end();
// });
}
export default function (req: IncomingMessage, res: ServerResponse): void {
switch (req.method) {
case "GET": {
get(req, res);
break;
}
case "POST": {
post(req, res);
break;
}
}
}
+1 -1
View File
@@ -19,7 +19,7 @@ function animate(timestamp: number): void {
(async () => { (async () => {
if (import.meta.env.DEV) { if (import.meta.env.DEV) {
import("#/tools/main.tsx").then((m) => m.use(viewport.gameContainer)); import("#/dev/main.tsx").then((m) => m.use(viewport.gameContainer));
} }
initViewport(); initViewport();
+16 -7
View File
@@ -1,15 +1,24 @@
import { fileURLToPath, URL } from "node:url"; import { fileURLToPath, URL } from "node:url";
import { defineConfig } from "vite"; import { defineConfig, type Plugin } from "vite";
import solidPlugin from "vite-plugin-solid"; import solidPlugin from "vite-plugin-solid";
import middleware from "#/dev/server/middleware.ts";
export const host = "localhost";
export const port = 3080;
function devTools(): Plugin {
return {
name: "dev-tools",
configureServer(server) {
server.middlewares.use("/api", middleware);
},
};
}
export default defineConfig({ export default defineConfig({
server: { server: { host, port, hmr: false },
host: "localhost",
port: 3080,
hmr: false,
},
build: { target: "esnext" }, build: { target: "esnext" },
plugins: [solidPlugin()], plugins: [solidPlugin(), devTools()],
resolve: { resolve: {
alias: { alias: {
"#/": fileURLToPath(new URL("./", import.meta.url)), "#/": fileURLToPath(new URL("./", import.meta.url)),