feat: migrate some more stuff to svelte-5, mainly app settings
Some checks failed
Deploy to GitHub Pages / build_site (push) Failing after 4s

This commit is contained in:
2024-11-08 02:38:19 +01:00
parent 4f03f2af5a
commit 5421349c79
34 changed files with 375 additions and 165 deletions

View File

@ -11,7 +11,7 @@
function filterInputs(inputs: Record<string, NodeInput>) {
return Object.fromEntries(
Object.entries(inputs)
.filter(([key, value]) => {
.filter(([_key, value]) => {
return value.hidden === true;
})
.map(([key, value]) => {

View File

@ -3,6 +3,7 @@
import type { OBJExporter } from "three/addons/exporters/OBJExporter.js";
import type { GLTFExporter } from "three/addons/exporters/GLTFExporter.js";
import FileSaver from "file-saver";
import { appSettings } from "../app-settings.svelte";
// Download
const download = (
@ -51,6 +52,8 @@
// download .obj file
download(result, "plant", "text/plain", "obj");
}
</script>
<div class="p-2">

View File

@ -1,70 +1,100 @@
<script lang="ts">
import localStore from "$lib/helpers/localStore";
import NestedSettings from "./NestedSettings.svelte";
import {localState} from "$lib/helpers/localState.svelte";
import type { NodeInput } from "@nodes/types";
import Input from "@nodes/ui";
import type { Writable } from "svelte/store";
type Button = { type: "button"; label?: string; callback: () => void };
type Button = { type: "button"; label?: string };
type InputType = NodeInput | Button;
interface Nested {
[key: string]: (Nested & { __title?: string }) | InputType;
[key: string]: (Nested & { title?: string }) | InputType;
}
export let id: string;
type Props = {
id: string;
key?: string;
value: Record<string, unknown> | string | number | boolean;
type: Nested;
depth?: number;
};
$: expandedDetails = localStore<Record<string, boolean>>(
`nodes.settings.expanded.${id}`,
{},
);
let { id, key = "", value = $bindable(), type, depth = 0 }: Props = $props();
export let settings: Nested;
export let store: Writable<Record<string, any>>;
export let depth = 0;
const keys = Object.keys(settings).filter((key) => key !== "__title");
function isNodeInput(v: InputType | Nested): v is InputType {
return v && "type" in v;
}
let internalValue = $state(Array.isArray(type?.[key]?.options) ? type[key]?.options?.indexOf(value?.[key]) : value?.[key]);
let openSections = localState("open-details", {});
let open = $state(openSections[id]);
if(depth > 0 && !isNodeInput(type[key])){
$effect(() => {
if(open !== undefined){}
openSections[id] = open;
});
}
$effect(() => {
if(key === "" || internalValue === undefined) return;
if(isNodeInput(type[key]) && Array.isArray(type[key]?.options) && typeof internalValue === "number"){
value[key] = type[key].options?.[internalValue];
}else{
value[key] = internalValue;
}
})
</script>
{#if $store}
{#each keys as key}
{@const value = settings[key]}
<div class="wrapper" class:first-level={depth === 0}>
{#if value !== undefined && isNodeInput(value)}
<div
class="input input-{settings[key].type}"
data-node-type={value?.__node_type || null}
data-node-input={value?.__node_input || null}
>
{#if value.type === "button"}
<button on:click={() => value?.callback?.()}
>{value.label || key}</button
>
{:else if "setting" in value && value.setting !== undefined}
<label for={key}>{settings[key].label || key}</label>
<Input id={key} input={value} bind:value={$store[value?.setting]} />
{:else}
<label for={key}>{settings[key].label || key}</label>
<Input id={key} input={value} bind:value={$store[key]} />
{/if}
</div>
{:else}
{#if depth > 0}
<hr />
{/if}
{#if key && isNodeInput(type?.[key]) }
<div class="input input-{type[key].type}">
{#if type[key].type === "button"}
<button onclick={() => console.log(type[key])}>
{type[key].label || key}
</button>
{:else}
<label for={id}>{type[key].label || key}</label>
<Input id={id} input={type[key]} bind:value={internalValue} />
{/if}
</div>
{:else}
{#if depth === 0}
{#each Object.keys(type).filter((key) => key !== "title") as childKey}
<NestedSettings
id={`${id}.${childKey}`}
key={childKey}
value={value as Record<string, unknown>}
type={type as Nested}
depth={depth + 1}
/>
{/each}
{#if depth > 0}
<hr />
{/if}
{:else if key && type?.[key]}
{#if depth > 0}
<hr />
{/if}
<details bind:open>
<summary>{type[key]?.title||key}</summary>
<div class="content">
{#each Object.keys(type[key]).filter((key) => key !== "title") as childKey}
<NestedSettings
id={`${id}.${childKey}`}
key={childKey}
value={value[key] as Record<string, unknown>}
type={type[key] as Nested}
depth={depth + 1}
/>
{/each}
</div>
</details>
{/if}
<details bind:open={$expandedDetails[key]}>
<summary>{settings[key]?.__title || key}</summary>
<div class="content">
<svelte:self settings={settings[key]} {store} depth={depth + 1} />
</div>
</details>
{/if}
</div>
{/each}
{/if}
<style>