You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

120 lines
3.5 KiB

"use client";
import { useEffect, useRef } from "react";
import { App } from "antd";
import { useShallow } from "zustand/shallow";
import { useI18n } from "@/i18n";
import { updateCanvasWorkflow } from "@/lib/canvasWorkflowApi";
import { useCanvasWorkflowStore } from "@/store/canvasWorkflowStore";
import { useWorkflowStore } from "@/store/workflowStore";
import { buildSerializedWorkflow } from "@/store/utils/workflowSerialization";
import { pickCanvasWorkflowCoverImage } from "@/utils/canvasWorkflowCoverImage";
const CANVAS_WORKFLOW_AUTO_UPDATE_DELAY_MS = 5_000;
export function useCanvasWorkflowAutoUpdate() {
const { t } = useI18n();
const { message } = App.useApp();
const saveVersionRef = useRef(0);
const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
const {
currentCanvasWorkflowId,
currentCanvasWorkflowTitle,
currentCanvasWorkflowDescription,
isLoadingCanvasWorkflow,
} = useCanvasWorkflowStore(useShallow((state) => ({
currentCanvasWorkflowId: state.currentCanvasWorkflowId,
currentCanvasWorkflowTitle: state.currentCanvasWorkflowTitle,
currentCanvasWorkflowDescription: state.currentCanvasWorkflowDescription,
isLoadingCanvasWorkflow: state.isLoadingCanvasWorkflow,
})));
const {
workflowId,
workflowName,
nodes,
edges,
edgeStyle,
groups,
hasUnsavedChanges,
markAsSaved,
} = useWorkflowStore(useShallow((state) => ({
workflowId: state.workflowId,
workflowName: state.workflowName,
nodes: state.nodes,
edges: state.edges,
edgeStyle: state.edgeStyle,
groups: state.groups,
hasUnsavedChanges: state.hasUnsavedChanges,
markAsSaved: state.markAsSaved,
})));
useEffect(() => {
if (timerRef.current) {
clearTimeout(timerRef.current);
timerRef.current = null;
}
if (!currentCanvasWorkflowId || !hasUnsavedChanges || isLoadingCanvasWorkflow) {
return;
}
saveVersionRef.current += 1;
const scheduledVersion = saveVersionRef.current;
timerRef.current = setTimeout(() => {
const workflow = buildSerializedWorkflow({
workflowId,
workflowName,
nameOverride: workflowName || currentCanvasWorkflowTitle || undefined,
nodes,
edges,
edgeStyle,
groups,
});
const title = workflowName?.trim() || currentCanvasWorkflowTitle || workflow.name;
const description = currentCanvasWorkflowDescription.trim();
const coverUrl = pickCanvasWorkflowCoverImage(nodes);
void updateCanvasWorkflow({
id: currentCanvasWorkflowId,
title,
...(description ? { desp: description } : {}),
properties: JSON.stringify(workflow),
...(coverUrl ? { coverUrl } : {}),
})
.then(() => {
if (saveVersionRef.current === scheduledVersion) {
markAsSaved();
}
})
.catch((error) => {
const errorMessage = error instanceof Error ? error.message : t("workflowSave.failed");
void message.error(errorMessage);
});
}, CANVAS_WORKFLOW_AUTO_UPDATE_DELAY_MS);
return () => {
if (timerRef.current) {
clearTimeout(timerRef.current);
timerRef.current = null;
}
};
}, [
currentCanvasWorkflowId,
currentCanvasWorkflowTitle,
currentCanvasWorkflowDescription,
isLoadingCanvasWorkflow,
workflowId,
workflowName,
nodes,
edges,
edgeStyle,
groups,
hasUnsavedChanges,
markAsSaved,
message,
t,
]);
}