diff --git a/tools/FileBrowser.css b/dev/FileBrowser.css similarity index 100% rename from tools/FileBrowser.css rename to dev/FileBrowser.css diff --git a/tools/FileBrowser.tsx b/dev/FileBrowser.tsx similarity index 95% rename from tools/FileBrowser.tsx rename to dev/FileBrowser.tsx index 210bc8a..e05293a 100644 --- a/tools/FileBrowser.tsx +++ b/dev/FileBrowser.tsx @@ -1,6 +1,6 @@ import "./FileBrowser.css"; 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; diff --git a/tools/controls/InputField.css b/dev/controls/InputField.css similarity index 100% rename from tools/controls/InputField.css rename to dev/controls/InputField.css diff --git a/tools/controls/InputField.tsx b/dev/controls/InputField.tsx similarity index 100% rename from tools/controls/InputField.tsx rename to dev/controls/InputField.tsx diff --git a/tools/controls/RangeSlider.css b/dev/controls/RangeSlider.css similarity index 100% rename from tools/controls/RangeSlider.css rename to dev/controls/RangeSlider.css diff --git a/tools/controls/RangeSlider.tsx b/dev/controls/RangeSlider.tsx similarity index 100% rename from tools/controls/RangeSlider.tsx rename to dev/controls/RangeSlider.tsx diff --git a/tools/icons/ArrowAutofitHeight.tsx b/dev/icons/ArrowAutofitHeight.tsx similarity index 100% rename from tools/icons/ArrowAutofitHeight.tsx rename to dev/icons/ArrowAutofitHeight.tsx diff --git a/tools/icons/ArrowAutofitWidth.tsx b/dev/icons/ArrowAutofitWidth.tsx similarity index 100% rename from tools/icons/ArrowAutofitWidth.tsx rename to dev/icons/ArrowAutofitWidth.tsx diff --git a/tools/icons/File.tsx b/dev/icons/File.tsx similarity index 100% rename from tools/icons/File.tsx rename to dev/icons/File.tsx diff --git a/tools/icons/FileDelta.tsx b/dev/icons/FileDelta.tsx similarity index 100% rename from tools/icons/FileDelta.tsx rename to dev/icons/FileDelta.tsx diff --git a/tools/icons/FileMusic.tsx b/dev/icons/FileMusic.tsx similarity index 100% rename from tools/icons/FileMusic.tsx rename to dev/icons/FileMusic.tsx diff --git a/tools/icons/FilePencil.tsx b/dev/icons/FilePencil.tsx similarity index 100% rename from tools/icons/FilePencil.tsx rename to dev/icons/FilePencil.tsx diff --git a/tools/icons/FileUnknown.tsx b/dev/icons/FileUnknown.tsx similarity index 100% rename from tools/icons/FileUnknown.tsx rename to dev/icons/FileUnknown.tsx diff --git a/tools/icons/FloppyDisc.tsx b/dev/icons/FloppyDisc.tsx similarity index 100% rename from tools/icons/FloppyDisc.tsx rename to dev/icons/FloppyDisc.tsx diff --git a/tools/icons/Folder.tsx b/dev/icons/Folder.tsx similarity index 100% rename from tools/icons/Folder.tsx rename to dev/icons/Folder.tsx diff --git a/tools/icons/FolderOpen.tsx b/dev/icons/FolderOpen.tsx similarity index 100% rename from tools/icons/FolderOpen.tsx rename to dev/icons/FolderOpen.tsx diff --git a/tools/icons/Lasso.tsx b/dev/icons/Lasso.tsx similarity index 100% rename from tools/icons/Lasso.tsx rename to dev/icons/Lasso.tsx diff --git a/tools/icons/LassoPolygon.tsx b/dev/icons/LassoPolygon.tsx similarity index 100% rename from tools/icons/LassoPolygon.tsx rename to dev/icons/LassoPolygon.tsx diff --git a/tools/icons/LayoutGrid.tsx b/dev/icons/LayoutGrid.tsx similarity index 100% rename from tools/icons/LayoutGrid.tsx rename to dev/icons/LayoutGrid.tsx diff --git a/tools/icons/Pencil.tsx b/dev/icons/Pencil.tsx similarity index 100% rename from tools/icons/Pencil.tsx rename to dev/icons/Pencil.tsx diff --git a/tools/icons/Polygon.tsx b/dev/icons/Polygon.tsx similarity index 100% rename from tools/icons/Polygon.tsx rename to dev/icons/Polygon.tsx diff --git a/tools/icons/Refresh.tsx b/dev/icons/Refresh.tsx similarity index 100% rename from tools/icons/Refresh.tsx rename to dev/icons/Refresh.tsx diff --git a/tools/icons/RefreshAlert.tsx b/dev/icons/RefreshAlert.tsx similarity index 100% rename from tools/icons/RefreshAlert.tsx rename to dev/icons/RefreshAlert.tsx diff --git a/tools/icons/RefreshDot.tsx b/dev/icons/RefreshDot.tsx similarity index 100% rename from tools/icons/RefreshDot.tsx rename to dev/icons/RefreshDot.tsx diff --git a/tools/icons/Script.tsx b/dev/icons/Script.tsx similarity index 100% rename from tools/icons/Script.tsx rename to dev/icons/Script.tsx diff --git a/tools/icons/StackBackward.tsx b/dev/icons/StackBackward.tsx similarity index 100% rename from tools/icons/StackBackward.tsx rename to dev/icons/StackBackward.tsx diff --git a/tools/icons/StackForward.tsx b/dev/icons/StackForward.tsx similarity index 100% rename from tools/icons/StackForward.tsx rename to dev/icons/StackForward.tsx diff --git a/tools/icons/TransformPoint.tsx b/dev/icons/TransformPoint.tsx similarity index 100% rename from tools/icons/TransformPoint.tsx rename to dev/icons/TransformPoint.tsx diff --git a/tools/icons/ZoomScan.tsx b/dev/icons/ZoomScan.tsx similarity index 100% rename from tools/icons/ZoomScan.tsx rename to dev/icons/ZoomScan.tsx diff --git a/tools/icons/index.ts b/dev/icons/index.ts similarity index 100% rename from tools/icons/index.ts rename to dev/icons/index.ts diff --git a/tools/main.css b/dev/main.css similarity index 100% rename from tools/main.css rename to dev/main.css diff --git a/tools/main.tsx b/dev/main.tsx similarity index 73% rename from tools/main.tsx rename to dev/main.tsx index 91b9f0f..e5233a1 100644 --- a/tools/main.tsx +++ b/dev/main.tsx @@ -1,10 +1,10 @@ import "./main.css"; import { type Component, createSignal, onMount } from "solid-js"; 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 { 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 { ArrowAutofitHeightIcon, @@ -13,31 +13,40 @@ import { ZoomScanIcon, } from "./icons/index.ts"; -const root = new Map([ - [ - "Brrr", - new Map([ - [ - "folder", - new Map([ - ["fuzz", "/fuzz.file"], - ["buzz", "/buzz.file"], - ]), - ], - ["dnd:", "/dnd.file"], - ["bla", "/bla.file"], - ]), - ], - [ - "folder", - new Map([ - ["fuzz", "/fuzz.file"], - ["buzz", "/buzz.file"], - ]), - ], - ["foo", "/foo.file"], - ["bar", "/bar.file"], -]); +function sceneTreeBuilder( + current: BrowserFolder, + entries: string[], + index: number, + ref: string[], +): void { + console.log(entries); + + const next = current.has(entries[0]) + ? (current.get(entries[0]) as BrowserFolder) + : (new Map() as BrowserFolder); + + if (entries.length > 1) { + current.set(entries.shift() as string, next); + sceneTreeBuilder(next, entries, index, ref); + } else { + // if (entries[0] !== "index.ts") { + // return; + // } + current.set(entries[0], entries[0]); + } +} +async function fetchSceneIndex(): Promise { + 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 { gameContainer.style = `position: relative; top: 0; left: ${width}px; width: ${document.body.offsetWidth - width}px;`; diff --git a/dev/server/middleware.ts b/dev/server/middleware.ts new file mode 100644 index 0000000..4d69189 --- /dev/null +++ b/dev/server/middleware.ts @@ -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; + } + } +} diff --git a/main.ts b/main.ts index 90cc0d9..5d13647 100644 --- a/main.ts +++ b/main.ts @@ -19,7 +19,7 @@ function animate(timestamp: number): void { (async () => { 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(); diff --git a/vite.config.ts b/vite.config.ts index fefd00f..270c83b 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,15 +1,24 @@ import { fileURLToPath, URL } from "node:url"; -import { defineConfig } from "vite"; +import { defineConfig, type Plugin } from "vite"; 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({ - server: { - host: "localhost", - port: 3080, - hmr: false, - }, + server: { host, port, hmr: false }, build: { target: "esnext" }, - plugins: [solidPlugin()], + plugins: [solidPlugin(), devTools()], resolve: { alias: { "#/": fileURLToPath(new URL("./", import.meta.url)),