feat: some shit

This commit is contained in:
2024-12-17 19:22:57 +01:00
parent 5421349c79
commit 5c1c8c480b
33 changed files with 620 additions and 633 deletions

View File

@ -0,0 +1,92 @@
<script lang="ts">
import type { Node, NodeInput } from "@nodes/types";
import NestedSettings from "./NestedSettings.svelte";
import type { GraphManager } from "$lib/graph-interface/graph-manager";
type Props = {
manager: GraphManager;
node: Node;
};
const { manager, node }: Props = $props();
const nodeDefinition = filterInputs(node.tmp?.type?.inputs);
function filterInputs(inputs?: Record<string, NodeInput>) {
const _inputs = $state.snapshot(inputs);
return Object.fromEntries(
Object.entries(structuredClone(_inputs ?? {}))
.filter(([_key, value]) => {
return value.hidden === true;
})
.map(([key, value]) => {
//@ts-ignore
value.__node_type = node?.tmp?.type.id;
//@ts-ignore
value.__node_input = key;
return [key, value];
}),
);
}
type Store = Record<string, number | number[]>;
let store = $state<Store>(createStore(node?.props, nodeDefinition));
function createStore(
props: Node["props"],
inputs: Record<string, NodeInput>,
): Store {
const store: Store = {};
Object.keys(inputs).forEach((key) => {
if (props) {
//@ts-ignore
store[key] = props[key] || inputs[key].value;
}
});
return store;
}
let lastPropsHash = "";
function updateNode() {
if (!node || !store) return;
let needsUpdate = false;
Object.keys(store).forEach((_key: string) => {
node.props = node.props || {};
const key = _key as keyof typeof store;
if (node && store) {
needsUpdate = true;
node.props[key] = store[key];
}
});
let propsHash = JSON.stringify(node.props);
if (propsHash === lastPropsHash) {
return;
}
lastPropsHash = propsHash;
if (needsUpdate) {
manager.execute();
}
}
$effect(() => {
if (store && store) {
updateNode();
}
});
</script>
{#if node}
{#key node.id}
{#if nodeDefinition && store && Object.keys(nodeDefinition).length > 0}
<NestedSettings
id="activeNodeSettings"
bind:value={store}
type={nodeDefinition}
/>
{:else}
<p class="mx-4">Active Node has no Settings</p>
{/if}
{/key}
{:else}
<p class="mx-4">No active node</p>
{/if}

View File

@ -1,85 +1,20 @@
<script lang="ts">
import type { Node, NodeInput } from "@nodes/types";
import NestedSettings from "./NestedSettings.svelte";
import { writable } from "svelte/store";
import type { Node } from "@nodes/types";
import type { GraphManager } from "$lib/graph-interface/graph-manager";
import ActiveNodeSelected from "./ActiveNodeSelected.svelte";
export let manager: GraphManager;
export let node: Node | undefined;
type Props = {
manager: GraphManager;
node: Node | undefined;
};
function filterInputs(inputs: Record<string, NodeInput>) {
return Object.fromEntries(
Object.entries(inputs)
.filter(([_key, value]) => {
return value.hidden === true;
})
.map(([key, value]) => {
//@ts-ignore
value.__node_type = node?.tmp?.type.id;
//@ts-ignore
value.__node_input = key;
return [key, value];
}),
);
}
function createStore(
props: Node["props"],
inputs: Record<string, NodeInput>,
) {
const store: Record<string, unknown> = {};
Object.keys(inputs).forEach((key) => {
if (props) {
//@ts-ignore
store[key] = props[key] || inputs[key].value;
}
});
return writable(store);
}
let nodeDefinition: Record<string, NodeInput> | undefined;
$: nodeDefinition = node?.tmp?.type
? filterInputs(node.tmp.type.inputs)
: undefined;
$: store = node ? createStore(node.props, nodeDefinition) : undefined;
let lastPropsHash = "";
function updateNode() {
if (!node || !$store) return;
let needsUpdate = false;
Object.keys($store).forEach((_key: string) => {
node.props = node.props || {};
const key = _key as keyof typeof $store;
if (node && $store) {
needsUpdate = true;
node.props[key] = $store[key];
}
});
let propsHash = JSON.stringify(node.props);
if (propsHash === lastPropsHash) {
return;
}
lastPropsHash = propsHash;
// console.log(needsUpdate, node.props, $store);
if (needsUpdate) {
manager.execute();
}
}
$: if (store && $store) {
updateNode();
}
const { manager, node }: Props = $props();
</script>
{#if node}
{#key node.id}
{#if nodeDefinition && store && Object.keys(nodeDefinition).length > 0}
<NestedSettings
id="activeNodeSettings"
settings={nodeDefinition}
{store}
/>
{#if node}
<ActiveNodeSelected {manager} {node} />
{:else}
<p class="mx-4">Active Node has no Settings</p>
{/if}

View File

@ -1,44 +1,49 @@
<script lang="ts">
import type { createKeyMap } from "$lib/helpers/createKeyMap";
import { ShortCut } from "@nodes/ui";
import { get } from "svelte/store";
export let keymap: ReturnType<typeof createKeyMap>;
const keys = keymap?.keys;
export let title = "Keymap";
type Props = {
keymaps: {
keymap: ReturnType<typeof createKeyMap>;
title: string;
}[];
};
let { keymaps }: Props = $props();
console.log({ keymaps });
</script>
<div class="wrapper">
<h3>{title}</h3>
<section>
{#each $keys as key}
{#if key.description}
<div class="command-wrapper">
<ShortCut
alt={key.alt}
ctrl={key.ctrl}
shift={key.shift}
key={key.key}
/>
</div>
<p>{key.description}</p>
{/if}
<table class="wrapper">
<tbody>
{#each keymaps as keymap}
<tr>
<td colspan="2">
<h3>{keymap.title}</h3>
</td>
</tr>
{#each get(keymap.keymap?.keys) as key}
<tr>
{#if key.description}
<td class="command-wrapper">
<ShortCut
alt={key.alt}
ctrl={key.ctrl}
shift={key.shift}
key={key.key}
/>
</td>
<td>{key.description}</td>
{/if}
</tr>
{/each}
{/each}
</section>
</div>
</tbody>
</table>
<style>
.wrapper {
padding: 1em;
display: flex;
flex-direction: column;
gap: 1em;
}
section {
display: grid;
grid-template-columns: min-content 1fr;
gap: 1em;
}
h3 {
@ -51,10 +56,11 @@
align-items: center;
}
p {
td {
font-size: 0.9em;
margin: 0;
display: flex;
padding: 7px;
padding-left: 0;
align-items: center;
}
</style>

View File

@ -1,3 +1,7 @@
<script module lang="ts">
let openSections = localState<Record<string,boolean>>("open-details", {});
</script>
<script lang="ts">
import NestedSettings from "./NestedSettings.svelte";
import {localState} from "$lib/helpers/localState.svelte";
@ -11,15 +15,18 @@
interface Nested {
[key: string]: (Nested & { title?: string }) | InputType;
}
type SettingsType = Record<string, Nested>;
type SettingsValue = Record<string, Record<string, unknown> | string | number | boolean>;
type Props = {
id: string;
key?: string;
value: Record<string, unknown> | string | number | boolean;
type: Nested;
value: SettingsValue;
type: SettingsType;
depth?: number;
};
let { id, key = "", value = $bindable(), type, depth = 0 }: Props = $props();
function isNodeInput(v: InputType | Nested): v is InputType {
@ -28,14 +35,14 @@
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;
});
}
if(open !== undefined){
openSections[id] = open;
};
});
}
$effect(() => {
@ -49,7 +56,7 @@
</script>
{#if key && isNodeInput(type?.[key]) }
<div class="input input-{type[key].type}">
<div class="input input-{type[key].type}" class:first-level={depth === 1}>
{#if type[key].type === "button"}
<button onclick={() => console.log(type[key])}>
{type[key].label || key}
@ -65,27 +72,25 @@
<NestedSettings
id={`${id}.${childKey}`}
key={childKey}
value={value as Record<string, unknown>}
type={type as Nested}
value={value}
type={type}
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>
<summary><p>{type[key]?.title||key}</p></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}
value={value[key] as SettingsValue}
type={type[key] as SettingsType}
depth={depth + 1}
/>
{/each}
@ -103,9 +108,18 @@
user-select: none;
margin-bottom: 1em;
}
summary::marker { }
summary > p {
display: inline;
padding-left: 6px;
}
details {
padding: 1em;
padding-bottom: 0;
padding-left: 21px;
}
.input {
@ -114,7 +128,7 @@
display: flex;
flex-direction: column;
gap: 10px;
padding-left: 14px;
padding-left: 20px;
}
.input-boolean {
@ -126,16 +140,12 @@
order: 2;
}
.first-level > .input {
padding-right: 1rem;
.first-level.input {
padding-left: 1em;
padding-right: 1em;
padding-bottom: 1px;
}
.first-level {
border-bottom: solid thin var(--outline);
}
.first-level > details {
border: none;
}
hr {
position: absolute;
margin: 0;