feat: refactor how frontend was structured
Some checks failed
Deploy to GitHub Pages / build_site (push) Failing after 1m16s

This commit is contained in:
2024-04-25 01:53:20 +02:00
parent f51f61df17
commit c28ef550a9
18 changed files with 264 additions and 225 deletions

View File

@@ -0,0 +1,39 @@
<script lang="ts">
import { getContext } from "svelte";
import type { Readable } from "svelte/store";
export let id: string;
export let icon: string = "";
export let title = "";
const registerPanel =
getContext<(id: string, icon: string) => Readable<boolean>>(
"registerPanel",
);
let visible = registerPanel(id, icon);
</script>
{#if $visible}
<div class="wrapper">
{#if title}
<header>
<h3>{title}</h3>
</header>
{/if}
<slot />
</div>
{/if}
<style>
header {
border-bottom: solid thin var(--outline);
height: 69px;
display: flex;
align-items: center;
padding-left: 1em;
}
h3 {
margin: 0px;
}
</style>

View File

@@ -1,33 +1,34 @@
<script lang="ts">
import type { NodeInput } from "@nodes/types";
import type { Writable } from "svelte/store";
import localStore from "$lib/helpers/localStore";
import type { SvelteComponent } from "svelte";
import NestedSettings from "./NestedSettings.svelte";
import { setContext } from "svelte";
import { derived } from "svelte/store";
export let panels: Record<
let panels: Record<
string,
{
icon: string;
id: string;
hidden?: boolean;
props?: Record<string, unknown>;
component?: typeof SvelteComponent<{}, {}, {}>;
definition: Record<string, NodeInput>;
settings: Writable<Record<string, unknown>>;
}
>;
> = {};
const activePanel = localStore<keyof typeof panels | false>(
"nodes.settings.activePanel",
false,
);
$: keys = panels
? (Object.keys(panels) as unknown as (keyof typeof panels)[]).filter(
(key) => !!panels[key]?.id && panels[key]?.hidden !== true,
(key) => !!panels[key]?.id,
)
: [];
setContext("registerPanel", (id: string, icon: string) => {
panels[id] = { id, icon };
return derived(activePanel, ($activePanel) => {
return $activePanel === id;
});
});
function setActivePanel(panel: keyof typeof panels | false) {
if (panel === $activePanel) {
$activePanel = false;
@@ -37,28 +38,6 @@
$activePanel = false;
}
}
interface Nested {
[key: string]: NodeInput | Nested;
}
function constructNested(panel: (typeof panels)[keyof typeof panels]) {
const nested: Nested = {};
for (const key in panel.definition) {
const parts = key.split(".");
let current = nested;
for (let i = 0; i < parts.length; i++) {
if (i === parts.length - 1) {
current[parts[i]] = panel.definition[key];
} else {
current[parts[i]] = current[parts[i]] || {};
current = current[parts[i]] as Nested;
}
}
}
return nested;
}
</script>
<div class="wrapper" class:visible={$activePanel}>
@@ -81,25 +60,7 @@
{/each}
</div>
<div class="content">
{#if $activePanel && panels[$activePanel] && panels[$activePanel].hidden !== true}
<h1 class="m-0 p-4">{panels[$activePanel].id}</h1>
{#key $activePanel}
{#if panels[$activePanel]?.component}
<svelte:component
this={panels[$activePanel].component}
{...panels[$activePanel]?.props}
/>
{:else}
<div class="flex flex-col">
<NestedSettings
id={$activePanel}
settings={constructNested(panels[$activePanel])}
store={panels[$activePanel].settings}
/>
</div>
{/if}
{/key}
{/if}
<slot />
</div>
</div>

View File

@@ -10,6 +10,7 @@ export const AppSettings = localStore("node-settings", {
showVertices: false,
centerCamera: true,
showStemLines: false,
amount: 5
});
const themes = ["dark", "light", "catppuccin", "solarized", "high-contrast", "nord", "dracula"];

View File

@@ -1,6 +1,6 @@
<script lang="ts">
import type { Node, NodeInput } from "@nodes/types";
import NestedSettings from "../NestedSettings.svelte";
import NestedSettings from "./NestedSettings.svelte";
import { writable } from "svelte/store";
import type { GraphManager } from "$lib/graph-interface/graph-manager";
@@ -28,7 +28,7 @@
export let manager: GraphManager;
export let node: Node;
export let node: Node | undefined;
let nodeDefinition: Record<string, NodeInput> | undefined;
$: nodeDefinition = node?.tmp?.type
? filterInputs(node.tmp.type.inputs)

View File

@@ -0,0 +1,40 @@
<script lang="ts">
import type { NodeInput } from "@nodes/types";
import NestedSettings from "./NestedSettings.svelte";
import type { Writable } from "svelte/store";
interface Nested {
[key: string]: NodeInput | Nested;
}
export let type: Record<string, NodeInput>;
export let store: Writable<Record<string, any>>;
function constructNested(type: Record<string, NodeInput>) {
const nested: Nested = {};
for (const key in type) {
const parts = key.split(".");
let current = nested;
for (let i = 0; i < parts.length; i++) {
if (i === parts.length - 1) {
current[parts[i]] = type[key];
} else {
current[parts[i]] = current[parts[i]] || {};
current = current[parts[i]] as Nested;
}
}
}
return nested;
}
$: settings = constructNested({
randomSeed: { type: "boolean", value: false },
...type,
});
</script>
{#key settings}
<NestedSettings id="graph-settings" {settings} {store} />
{/key}

View File

@@ -3,7 +3,7 @@
import { ShortCut } from "@nodes/ui";
export let keymap: ReturnType<typeof createKeyMap>;
const keys = keymap.keys;
const keys = keymap?.keys;
</script>
<div class="wrapper">
@@ -13,7 +13,12 @@
{#each $keys as key}
{#if key.description}
<div class="command-wrapper">
<ShortCut {...key} />
<ShortCut
alt={key.alt}
ctrl={key.ctrl}
shift={key.shift}
key={key.key}
/>
</div>
<p>{key.description}</p>
{/if}

View File

@@ -4,8 +4,12 @@
import Input from "@nodes/ui";
import type { Writable } from "svelte/store";
type Button = { type: "button"; label?: string; callback: () => void };
type Input = NodeInput | Button;
interface Nested {
[key: string]: Nested | NodeInput;
[key: string]: (Nested & { __title?: string }) | Input;
}
export let id: string;
@@ -20,22 +24,23 @@
export let depth = 0;
const keys = Object.keys(settings).filter((key) => key !== "__title");
function isNodeInput(v: NodeInput | Nested): v is NodeInput {
function isNodeInput(v: Input | Nested): v is Input {
return v && "type" in v;
}
console.log({ settings, store });
</script>
{#if store}
{#if $store}
{#each keys as key}
{@const value = settings[key]}
<div class="wrapper" class:first-level={depth === 0}>
{#if isNodeInput(value)}
{#if value !== undefined && isNodeInput(value)}
<div class="input input-{settings[key].type}">
{#if settings[key].type === "button"}
<button on:click={() => settings[key]?.callback?.()}
>{settings[key].label || key}</button
{#if value.type === "button"}
<button on:click={() => value?.callback?.()}
>{value.label || key}</button
>
{:else if "setting" in value}
{: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}