diff --git a/ui/src/App.tsx b/ui/src/App.tsx index 2dfc963..8f00a1d 100644 --- a/ui/src/App.tsx +++ b/ui/src/App.tsx @@ -32,7 +32,6 @@ import { openWorkflowInNewTab, } from "./utils"; import { Topbar } from "./topbar/Topbar"; -// import { authTokenListener, pullAuthTokenCloseIfExist } from "./auth/authUtils"; import { PanelPosition, Workflow } from "./types/dbTypes"; import { useDialog } from "./components/AlertDialogProvider"; import React from "react"; @@ -43,6 +42,7 @@ const GalleryModal = React.lazy(() => import("./gallery/GalleryModal")); import { scanLocalNewFiles } from "./Api"; import { IconExternalLink } from "@tabler/icons-react"; import { DRAWER_Z_INDEX } from "./const"; +import ServerEventListener from "./model-manager/hooks/ServerEventListener"; const ModelManagerTopbar = React.lazy( () => import("./model-manager/topbar/ModelManagerTopbar"), @@ -452,10 +452,8 @@ export default function App() { setIsDirty(res); }); }, 1000); - // pullAuthTokenCloseIfExist(); window.addEventListener("keydown", shortcutListener); - // window.addEventListener("message", authTokenListener); const fileInput = document.getElementById( "comfy-file-input", @@ -588,6 +586,7 @@ export default function App() { setRoute("root")} /> )} + diff --git a/ui/src/db-tables/TableBase.ts b/ui/src/db-tables/TableBase.ts index ee9b2e5..8506718 100644 --- a/ui/src/db-tables/TableBase.ts +++ b/ui/src/db-tables/TableBase.ts @@ -92,4 +92,11 @@ export class TableBase { await indexdb[this.tableName].delete(id); await this.saveDiskDB(); } + public async listByIndex(index: keyof T, value: string): Promise { + const list = await indexdb[this.tableName] + .where(index as string) + .equals(value) + .toArray(); + return list as any[]; + } } diff --git a/ui/src/db-tables/indexdb.ts b/ui/src/db-tables/indexdb.ts index cb6569b..ce7430d 100644 --- a/ui/src/db-tables/indexdb.ts +++ b/ui/src/db-tables/indexdb.ts @@ -1,4 +1,3 @@ -// db.ts import Dexie, { Table } from "dexie"; import { Workflow, @@ -37,12 +36,10 @@ class ManagerDB extends Dexie { models: "&id, fileName, fileHash", cache: "&id", }) - .upgrade((trans) => { - // Here you can write logic to initialize or migrate data to the new 'media' table, if necessary - }); + .upgrade((trans) => {}); this.version(2) .stores({ - workflows: "&id, name, parentFolderID", // Primary key and indexed props + workflows: "&id, name, parentFolderID", changelogs: "&id, workflowID", media: "&id, workflowID", folders: "&id, name, parentFolderID", @@ -52,9 +49,20 @@ class ManagerDB extends Dexie { cache: "&id", workflowVersions: "&id, name, workflowID", }) - .upgrade((trans) => { - // Here you can write logic to initialize or migrate data to the new 'media' table, if necessary - }); + .upgrade((trans) => {}); + this.version(3) + .stores({ + workflows: "&id, name, parentFolderID, cloudID", // Primary key and indexed props + changelogs: "&id, workflowID", + media: "&id, workflowID", + folders: "&id, name, parentFolderID", + tags: "&name", + userSettings: "&id", + models: "&id, fileName, fileHash", + cache: "&id", + workflowVersions: "&id, name, workflowID, cloudID", + }) + .upgrade((trans) => {}); } } diff --git a/ui/src/model-manager/hooks/ServerEventListener.ts b/ui/src/model-manager/hooks/ServerEventListener.ts new file mode 100644 index 0000000..4baf062 --- /dev/null +++ b/ui/src/model-manager/hooks/ServerEventListener.ts @@ -0,0 +1,104 @@ +import { useContext, useEffect } from "react"; +import { useDialog } from "../../components/AlertDialogProvider"; +import { + workflowVersionsTable, + workflowsTable, +} from "../../db-tables/WorkspaceDB"; +import { WorkspaceContext } from "../../WorkspaceContext"; + +export default function ServerEventListener() { + const { showDialog } = useDialog(); + const { loadWorkflowID } = useContext(WorkspaceContext); + const openWorkflow = async (evt: OpenWorkflowEvent) => { + const { workflow, version } = evt.detail; + if (!workflow.id || !version.id) return; + const existingWorkflow = ( + await workflowsTable?.listByIndex("cloudID", workflow.id) + )?.at(0); + if (existingWorkflow) { + const existingVersion = ( + await workflowVersionsTable?.listByIndex("cloudID", version.id) + )?.at(0); + if (existingVersion) { + // existing workflow and version + await loadWorkflowID(existingWorkflow.id); + } else { + // existing workflow but new version + await workflowVersionsTable?.add({ + cloudID: version.id, + workflowID: existingWorkflow.id, + name: version.name, + json: version.json, + }); + } + } else { + // new workflow new version + const newWorkflow = await workflowsTable?.add({ + cloudID: workflow.id, + name: workflow.name, + json: version.json, + updateTime: Date.now(), + }); + if (!newWorkflow) { + alert("Failed to add workflow to local db"); + return; + } + await workflowVersionsTable?.add({ + cloudID: version.id, + workflowID: newWorkflow.id, + name: version.name, + json: version.json, + }); + await loadWorkflowID(newWorkflow.id); + } + }; + const cloudEventListener = async (event: MessageEvent) => { + const evt: CloudMessageEvent = event.data; + if (isOpenWorkflowEvent(evt)) { + const origin = event.origin; + showDialog( + `Open workflow "${evt.detail.workflow.name}", version "${evt.detail.version.name}" from ${origin}`, + [ + { + label: "Open", + colorScheme: "teal", + onClick: () => { + openWorkflow(evt); + }, + }, + ], + ); + } + }; + useEffect(() => { + if (window.opener) { + window.opener.postMessage("comfyui_workspace_manager_connected", "*"); + } + window.addEventListener("message", cloudEventListener); + }, []); + return null; +} + +interface CloudMessageEvent { + type: "workspace_check_connection" | "workspace_open_workflow"; + detail: any; +} + +interface OpenWorkflowEvent extends CloudMessageEvent { + type: "workspace_open_workflow"; + detail: { + workflow: { + id: string; + name: string; + }; + version: { + id: string; + name: string; + json: string; + }; + }; +} + +function isOpenWorkflowEvent(n: CloudMessageEvent): n is OpenWorkflowEvent { + return n.type === "workspace_open_workflow"; +} diff --git a/ui/src/share/SharedTopbarButton.tsx b/ui/src/share/SharedTopbarButton.tsx index f69db8d..c96e9e3 100644 --- a/ui/src/share/SharedTopbarButton.tsx +++ b/ui/src/share/SharedTopbarButton.tsx @@ -33,6 +33,8 @@ export function SharedTopbarButton({}) { { window.open(workflowsTable?.curWorkflow?.cloudURL); }} @@ -40,7 +42,7 @@ export function SharedTopbarButton({}) { size={"xs"} iconSpacing={"2px"} leftIcon={} - height={"26px"} + height={"27px"} px={1} > {privacy ? : "Shared"}