Templates view and store

This commit is contained in:
space-nuko
2023-05-24 17:38:37 -05:00
parent da917a2a50
commit 4dfa665303
16 changed files with 444 additions and 71 deletions

View File

@@ -9,6 +9,7 @@ import type { ComfyWidgetNode } from '$lib/nodes/widgets';
import type ComfyGraph from '$lib/ComfyGraph';
import type { ComfyBoxWorkflow, WorkflowAttributes, WorkflowInstID } from './workflowState';
import workflowState from './workflowState';
import type { SerializedComfyBoxTemplate } from '$lib/ComfyBoxTemplate';
export function isComfyWidgetNode(node: LGraphNode): node is ComfyWidgetNode {
return "svelteComponentType" in node
@@ -635,7 +636,7 @@ for (const cat of Object.values(ALL_ATTRIBUTES)) {
export { ALL_ATTRIBUTES };
// TODO Should be nested by category for name uniqueness?
const defaultWidgetAttributes: Attributes = {} as any
export const defaultWidgetAttributes: Attributes = {} as any
export const defaultWorkflowAttributes: WorkflowAttributes = {} as any
for (const cat of Object.values(ALL_ATTRIBUTES)) {
for (const spec of Object.values(cat.specs)) {
@@ -657,7 +658,7 @@ export interface IDragItem {
/*
* Type of the item.
*/
type: "container" | "widget",
type: "container" | "widget" | "template",
/*
* Unique ID of the item.
@@ -707,6 +708,21 @@ export interface WidgetLayout extends IDragItem {
node: ComfyWidgetNode
}
/*
* A template being dragged into the workflow UI.
*
* These will never be saved, instead they will be expanded inside
* updateChildren() and then removed.
*/
export interface TemplateLayout extends IDragItem {
type: "template",
/*
* Template to expand
*/
template: SerializedComfyBoxTemplate
}
export type DefaultLayout = {
root: ContainerLayout,
left: ContainerLayout,
@@ -874,7 +890,7 @@ function createRaw(workflow: ComfyBoxWorkflow | null = null): WritableLayoutStat
if (newChildren)
state.allItems[parent.id].children = newChildren;
for (const child of state.allItems[parent.id].children) {
if (child.id === SHADOW_PLACEHOLDER_ITEM_ID)
if (child.id === SHADOW_PLACEHOLDER_ITEM_ID || child.type === "template")
continue;
state.allItems[child.id].parent = parent;
}

View File

@@ -0,0 +1,101 @@
import type { SerializedComfyBoxTemplate } from '$lib/ComfyBoxTemplate';
import type { UUID } from '@litegraph-ts/core';
import { get, writable } from 'svelte/store';
import type { Readable, Writable } from 'svelte/store';
export type TemplateState = {
templates: SerializedComfyBoxTemplate[]
templatesByID: Record<UUID, SerializedComfyBoxTemplate>
}
type TemplateStateOps = {
save: () => void,
load: () => void,
add: (template: SerializedComfyBoxTemplate) => boolean,
remove: (templateID: UUID) => boolean,
}
export type WritableTemplateStateStore = Writable<TemplateState> & TemplateStateOps;
const store: Writable<TemplateState> = writable(
{
templates: [],
templatesByID: {}
})
function add(template: SerializedComfyBoxTemplate): boolean {
const state = get(store);
if (state.templatesByID[template.id]) {
return false;
}
store.update(s => {
s.templates.push(template);
s.templatesByID[template.id] = template;
return s;
})
save();
return true;
}
function remove(templateID: UUID): boolean {
const state = get(store);
if (!state.templatesByID[templateID]) {
return false;
}
store.update(s => {
const index = s.templates.findIndex(t => t.id === templateID)
s.templates.splice(index, 1);
delete s.templatesByID[templateID];
return s;
})
save();
return true;
}
function save() {
const json = JSON.stringify(get(store).templates)
localStorage.setItem("templates", json)
store.set(get(store))
}
function load() {
const json = localStorage.getItem("templates")
if (!json) {
console.info("No templates in local storage, creating store")
save();
return;
}
const data = JSON.parse(json) as SerializedComfyBoxTemplate[];
if (Array.isArray(data)) {
const templatesByID: Record<UUID, SerializedComfyBoxTemplate> =
data.map(d => [d.id, d])
.reduce((dict, el: [UUID, SerializedComfyBoxTemplate]) => (dict[el[0]] = el[1], dict), {})
store.set({
templates: data,
templatesByID
})
}
else {
store.set({
templates: [],
templatesByID: {}
})
}
}
const templateStateStore: WritableTemplateStateStore =
{
...store,
add,
remove,
save,
load,
}
export default templateStateStore;