From d04f61752da89a96a352e5a4addfec52a0be6c93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20H=C3=B6lting?= <87192362+moritz-hoelting@users.noreply.github.com> Date: Fri, 21 Jun 2024 08:07:38 +0200 Subject: [PATCH] add function for extracting files from editor --- package.json | 3 +- pnpm-lock.yaml | 17 +++++ src/components/Playground.tsx | 95 ++++++++++++++++++++++++---- src/components/playground/Header.tsx | 10 +-- 4 files changed, 105 insertions(+), 20 deletions(-) diff --git a/package.json b/package.json index 5e769bf..5c7fc82 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,8 @@ "shiki": "^1.7.0", "starlight-links-validator": "^0.7.1", "tm-themes": "^1.4.3", - "typescript": "^5.4.5" + "typescript": "^5.4.5", + "use-immer": "^0.10.0" }, "devDependencies": { "sass": "^1.77.6" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5af981c..8770354 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -65,6 +65,9 @@ dependencies: typescript: specifier: ^5.4.5 version: 5.4.5 + use-immer: + specifier: ^0.10.0 + version: 0.10.0(immer@10.1.1)(react@18.3.1) devDependencies: sass: @@ -3278,6 +3281,10 @@ packages: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} dev: false + /immer@10.1.1: + resolution: {integrity: sha512-s2MPrmjovJcoMaHtx6K11Ra7oD05NT97w1IC5zpMkT6Atjr7H8LjaDd81iIxUYpMKSRRNMJE703M1Fhr/TctHw==} + dev: false + /immutable@4.3.6: resolution: {integrity: sha512-Ju0+lEMyzMVZarkTn/gqRpdqd5dOPaz1mCZ0SH3JV6iFw81PldE/PEB1hWVEA288HPt4WXW8O7AWxB10M+03QQ==} @@ -5490,6 +5497,16 @@ packages: picocolors: 1.0.1 dev: false + /use-immer@0.10.0(immer@10.1.1)(react@18.3.1): + resolution: {integrity: sha512-/eVwNR4TG9Tm/dd+aHYLLaI0FLfYKlkTqKMkn78Ah/EYVzWd/zJIgpkdoFEKbhQJOGo8XN7/mWrTx0exp1c+Ug==} + peerDependencies: + immer: '>=8.0.0' + react: ^16.8.0 || ^17.0.1 || ^18.0.0 + dependencies: + immer: 10.1.1 + react: 18.3.1 + dev: false + /util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} dev: false diff --git a/src/components/Playground.tsx b/src/components/Playground.tsx index cc2a32c..8a903ba 100644 --- a/src/components/Playground.tsx +++ b/src/components/Playground.tsx @@ -1,13 +1,13 @@ import React, { useEffect, useState } from "react"; import { useMonaco, type Monaco } from "@monaco-editor/react"; -import FileView from "./playground/FileView"; -import Editor from "./playground/Editor"; +import { useImmer, type ImmerHook, type Updater } from "use-immer"; import "@styles/playground.scss"; import mainFileContent from "@assets/playground/main.shu?raw"; import packTomlContent from "@assets/playground/pack.toml?raw"; - +import FileView from "./playground/FileView"; +import Editor from "./playground/Editor"; import Header from "./playground/Header"; export type File = { @@ -21,7 +21,7 @@ export type Directory = { export type SetState = React.Dispatch>; export default function Playground() { - const rootDir: Directory = { + const [rootDir, updateRootDir] = useImmer({ dirs: { src: { files: { @@ -46,15 +46,29 @@ export default function Playground() { language: "toml", }, }, - }; + } as Directory); const [fileName, setFileName] = useState("src/main.shu"); const file = getFile(rootDir, fileName)!; + const onBuild: () => void = () => { + if (monaco) { + console.log(getFiles(monaco)); + } else { + console.error("monaco has not loaded"); + } + }; + const onZip: () => void = () => { + if (monaco) { + loadFile(monaco, updateRootDir, {content: "zip"}, "dist/pack.zip"); + } else { + console.error("onZip not set");} + }; + const monaco = useMonaco(); useEffect(() => { if (monaco) { - loadFiles(monaco, rootDir); + loadFiles(monaco, updateRootDir, rootDir); } }, [monaco]); @@ -68,7 +82,7 @@ export default function Playground() { marginTop: "0.5cm", }} > -
+
, dir: Directory, prefix = "") { for (const [name, d] of Object.entries(dir.dirs ?? {})) { - loadFiles(monaco, d, prefix + name + "/"); + loadFiles(monaco, updater, d, prefix + name + "/"); + updater(dir => { + let current = dir; + for(const part of [...prefix.split("/").filter(s => s !== ""), name]) { + if (!current.dirs) { + current.dirs = {}; + } + current = current.dirs[part]; + } + }); } for (const [name, file] of Object.entries(dir.files ?? {})) { - loadFile(monaco, file, prefix + name); + loadFile(monaco, updater, file, prefix + name); } } -function loadFile(monaco: Monaco, file: File, name: string) { +function loadFile(monaco: Monaco, updater: Updater, file: File, name: string) { const uri = monaco.Uri.parse(name); if (!monaco.editor.getModel(uri)) { monaco.editor.createModel(file.content, file.language, uri); } + updater(dir => { + let current = dir; + const parts = name.split("/").filter(s => s !== ""); + const last = parts.pop()!; + for(const part of parts) { + console.log(part); + if (!current.dirs) { + current.dirs = {}; + } + current = current.dirs[part]; + } + if (!current.files) { + current.files = {}; + } + current.files[last] = file; + }); } + + diff --git a/src/components/playground/Header.tsx b/src/components/playground/Header.tsx index 6e07a90..1530cd2 100644 --- a/src/components/playground/Header.tsx +++ b/src/components/playground/Header.tsx @@ -1,12 +1,6 @@ import SplitButton from "./SplitButton"; -export default function Header() { - const clickBuild = () => { - console.log("build"); - } - const clickZip = () => { - console.log("zip"); - } +export default function Header({onBuild, onZip}: {onBuild: () => void; onZip: () => void;}){ return (

Playground

- Build + Build
); }