Browse Source

外部自动同步数据

feature/627
tianYun 2 weeks ago
parent
commit
c8d08c4025
  1. 1
      src/components/composer/GenerationComposer.tsx
  2. 73
      src/store/workflowStore.ts

1
src/components/composer/GenerationComposer.tsx

@ -949,6 +949,7 @@ function ComposerEditor({
useEffect(() => { useEffect(() => {
if (isHidden) { if (isHidden) {
persistCurrentComposerConfig();
stopReferenceAudioPreview(); stopReferenceAudioPreview();
onHiddenPersisted?.(); onHiddenPersisted?.();
return; return;

73
src/store/workflowStore.ts

@ -641,14 +641,22 @@ function buildReferenceSubjectNodePatch(
node: WorkflowNode, node: WorkflowNode,
beforeMaterials: ComposerReferenceMaterial[], beforeMaterials: ComposerReferenceMaterial[],
afterMaterials: ComposerReferenceMaterial[], afterMaterials: ComposerReferenceMaterial[],
options: { syncPrompt?: boolean } = {} options: {
syncPrompt?: boolean;
promptBeforeMaterials?: ComposerReferenceMaterial[];
promptAfterMaterials?: ComposerReferenceMaterial[];
} = {}
): Partial<WorkflowNodeData> | null { ): Partial<WorkflowNodeData> | null {
const data = node.data as { parameters?: Record<string, unknown>; inputPrompt?: unknown; prompt?: unknown }; const data = node.data as { parameters?: Record<string, unknown>; inputPrompt?: unknown; prompt?: unknown };
const previousSubjects = readNodeReferenceSubjects(node); const previousSubjects = readNodeReferenceSubjects(node);
const nextSubjects = buildReferenceSubjectListParameter(afterMaterials); const nextSubjects = buildReferenceSubjectListParameter(afterMaterials);
const previousPrompt = readNodeInputPrompt(node); const previousPrompt = readNodeInputPrompt(node);
const nextPrompt = options.syncPrompt const nextPrompt = options.syncPrompt
? syncPromptReferenceMaterials(previousPrompt, beforeMaterials, afterMaterials) ? syncPromptReferenceMaterials(
previousPrompt,
options.promptBeforeMaterials ?? beforeMaterials,
options.promptAfterMaterials ?? afterMaterials
)
: previousPrompt; : previousPrompt;
const nextSubType = isVideoGenerationNode(node) const nextSubType = isVideoGenerationNode(node)
? normalizeVideoGenerationSubType( ? normalizeVideoGenerationSubType(
@ -803,11 +811,48 @@ function applyReferenceSubjectListPatch(
const orderedAfterMaterials = options.preserveMaterialOrder const orderedAfterMaterials = options.preserveMaterialOrder
? afterMaterials ? afterMaterials
: orderReferenceMaterials(afterMaterials, previousOrder); : orderReferenceMaterials(afterMaterials, previousOrder);
const patch = buildReferenceSubjectNodePatch(node, orderedBeforeMaterials, orderedAfterMaterials, options); const patch = buildReferenceSubjectNodePatch(node, orderedBeforeMaterials, orderedAfterMaterials, {
...options,
promptBeforeMaterials: beforeMaterials,
promptAfterMaterials: afterMaterials,
});
if (!patch) return; if (!patch) return;
get().updateNodeData(nodeId, patch); get().updateNodeData(nodeId, patch);
} }
function collectReferenceMaterialsBeforeRemovingSourceNodes(
removedNodeIds: Set<string>,
get: () => WorkflowStore
): { beforeMaterialsByTarget: Map<string, ComposerReferenceMaterial[]>; removedEdges: WorkflowEdge[] } {
const removedEdges = get().edges.filter(
(edge) => removedNodeIds.has(edge.source) || removedNodeIds.has(edge.target)
);
const beforeMaterialsByTarget = new Map<string, ComposerReferenceMaterial[]>();
removedEdges.forEach((edge) => {
if (!removedNodeIds.has(edge.source) || removedNodeIds.has(edge.target)) return;
if (beforeMaterialsByTarget.has(edge.target)) return;
beforeMaterialsByTarget.set(edge.target, buildNodeReferenceMaterials(edge.target, get));
});
return { beforeMaterialsByTarget, removedEdges };
}
function applyReferenceMaterialChangesAfterRemovingSourceNodes(
beforeMaterialsByTarget: Map<string, ComposerReferenceMaterial[]>,
get: () => WorkflowStore
): void {
beforeMaterialsByTarget.forEach((beforeMaterials, targetNodeId) => {
if (!get().nodes.some((node) => node.id === targetNodeId)) return;
get().applyNodeReferenceMaterialsChange(
targetNodeId,
beforeMaterials,
buildNodeReferenceMaterials(targetNodeId, get),
{ syncPrompt: true }
);
});
}
/** Capture current undoable state as a deep-cloned snapshot */ /** Capture current undoable state as a deep-cloned snapshot */
function captureUndoSnapshot(state: WorkflowStore): UndoSnapshot { function captureUndoSnapshot(state: WorkflowStore): UndoSnapshot {
const cloned = clonePreservingStrings({ const cloned = clonePreservingStrings({
@ -1490,6 +1535,10 @@ const workflowStoreImpl: StateCreator<WorkflowStore> = (set, get) => ({
removeNode: (nodeId: string) => { removeNode: (nodeId: string) => {
pushUndoCheckpoint(get, set); pushUndoCheckpoint(get, set);
const { beforeMaterialsByTarget, removedEdges } = collectReferenceMaterialsBeforeRemovingSourceNodes(
new Set([nodeId]),
get
);
set((state) => ({ set((state) => ({
nodes: state.nodes.filter((node) => node.id !== nodeId), nodes: state.nodes.filter((node) => node.id !== nodeId),
edges: state.edges.filter( edges: state.edges.filter(
@ -1497,6 +1546,15 @@ const workflowStoreImpl: StateCreator<WorkflowStore> = (set, get) => ({
), ),
hasUnsavedChanges: true, hasUnsavedChanges: true,
})); }));
if (removedEdges.length > 0) {
deleteCheckpointActive = true;
try {
clearStaleInputImages(removedEdges, get);
applyReferenceMaterialChangesAfterRemovingSourceNodes(beforeMaterialsByTarget, get);
} finally {
deleteCheckpointActive = false;
}
}
get().incrementManualChangeCount(); get().incrementManualChangeCount();
}, },
@ -1562,6 +1620,13 @@ const workflowStoreImpl: StateCreator<WorkflowStore> = (set, get) => ({
setTimeout(() => { deleteCheckpointActive = false; }, 0); setTimeout(() => { deleteCheckpointActive = false; }, 0);
} }
const removedNodeIds = new Set(
effectiveChanges.filter((change) => change.type === "remove").map((change) => change.id)
);
const { beforeMaterialsByTarget, removedEdges } = hasRemoveChange
? collectReferenceMaterialsBeforeRemovingSourceNodes(removedNodeIds, get)
: { beforeMaterialsByTarget: new Map<string, ComposerReferenceMaterial[]>(), removedEdges: [] };
set((state) => { set((state) => {
const removedGroupIds = new Set<string>(); const removedGroupIds = new Set<string>();
for (const change of effectiveChanges) { for (const change of effectiveChanges) {
@ -1647,6 +1712,8 @@ const workflowStoreImpl: StateCreator<WorkflowStore> = (set, get) => ({
}); });
if (hasRemoveChange) { if (hasRemoveChange) {
clearStaleInputImages(removedEdges, get);
applyReferenceMaterialChangesAfterRemovingSourceNodes(beforeMaterialsByTarget, get);
get().incrementManualChangeCount(); get().incrementManualChangeCount();
} }
}, },

Loading…
Cancel
Save