diff --git a/src/components/__tests__/GenerationComposer.test.tsx b/src/components/__tests__/GenerationComposer.test.tsx
index 3247b80d..6b3d14d3 100644
--- a/src/components/__tests__/GenerationComposer.test.tsx
+++ b/src/components/__tests__/GenerationComposer.test.tsx
@@ -1674,6 +1674,59 @@ describe("GenerationComposer", () => {
]);
});
+ it("reorders connected image materials by dragging thumbnails", async () => {
+ useWorkflowStore.setState({
+ nodes: [
+ imageNode("img-a", false, { outputImage: "https://static.popi.art/a.jpg" }),
+ imageNode("img-b", false, { outputImage: "https://static.popi.art/b.jpg" }),
+ videoNode("vid-1", true, {
+ inputPrompt: "use @图1 and @图2",
+ }),
+ ],
+ edges: [
+ imageEdge("img-a", "vid-1", 0),
+ imageEdge("img-b", "vid-1", 1),
+ ],
+ });
+ render();
+
+ const dataTransferStore = new Map();
+ const dataTransfer = {
+ effectAllowed: "all",
+ setData: (type: string, value: string) => dataTransferStore.set(type, value),
+ getData: (type: string) => dataTransferStore.get(type) ?? "",
+ };
+ const firstImage = screen.getByLabelText("参考图片 1");
+ const secondImage = screen.getByLabelText("参考图片 2");
+ expect(firstImage.querySelector("img")).toHaveAttribute("draggable", "false");
+ const prompt = screen.getByDisplayValue("use @图1 and @图2") as HTMLTextAreaElement;
+
+ fireEvent.dragStart(secondImage, { dataTransfer });
+ fireEvent.drop(firstImage, { dataTransfer });
+
+ expect(prompt).toHaveValue("use @图2 and @图1");
+ fireEvent.click(screen.getByLabelText(/Generate|生成/));
+
+ await waitFor(() => {
+ expect(useWorkflowStore.getState().regenerateNode).toHaveBeenCalledWith("vid-1");
+ });
+ const data = useWorkflowStore.getState().nodes[2].data as GenerateVideoNodeData;
+ expect(data.parameters?.referenceSubjectList).toEqual([
+ {
+ id: 1,
+ type: "image",
+ url: "https://static.popi.art/b.jpg",
+ name: "图1",
+ },
+ {
+ id: 2,
+ type: "image",
+ url: "https://static.popi.art/a.jpg",
+ name: "图2",
+ },
+ ]);
+ });
+
it("does not allow first/last frame mode unless exactly two images are connected", async () => {
useWorkflowStore.setState({
nodes: [
diff --git a/src/components/composer/GenerationComposer.tsx b/src/components/composer/GenerationComposer.tsx
index c6211e16..860af2bb 100644
--- a/src/components/composer/GenerationComposer.tsx
+++ b/src/components/composer/GenerationComposer.tsx
@@ -787,11 +787,13 @@ function ReferenceMaterialCard({
) : material.type === "video" ? (