From e2521424eb92e30e7d87aaf504510bdc772d7cec Mon Sep 17 00:00:00 2001
From: zh15728828264 <133273926+zh15728828264@users.noreply.github.com>
Date: Wed, 26 Aug 2026 14:05:00 +0800
Subject: [PATCH] =?UTF-8?q?feat(create):=20=E5=88=9B=E4=BD=9C=E5=B7=A5?=
=?UTF-8?q?=E4=BD=9C=E5=8F=B0=20-=20=E6=94=AF=E6=8C=81=E5=8F=82=E8=80=83?=
=?UTF-8?q?=E5=86=85=E5=AE=B9=E5=B1=82=E5=8F=A0=E5=B1=95=E5=BC=80=E4=B8=8E?=
=?UTF-8?q?=E6=8B=96=E6=8B=BD=E6=8E=92=E5=BA=8F?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
合并 PR #307。\n\n原作者:陈泽 <749959948@qq.com>
---
web/src/pages/create/index.tsx | 127 ++++++++++++++++++++++---
web/src/styles/globals.css | 121 +++++++++++++++++++++++
web/test/create-library-button.test.ts | 31 +++++-
3 files changed, 261 insertions(+), 18 deletions(-)
diff --git a/web/src/pages/create/index.tsx b/web/src/pages/create/index.tsx
index c3ffd085a..fbdbb326a 100644
--- a/web/src/pages/create/index.tsx
+++ b/web/src/pages/create/index.tsx
@@ -1,6 +1,7 @@
-import { useCallback, useEffect, useMemo, useRef, useState, type ChangeEvent, type CSSProperties, type ReactNode, type RefObject } from "react";
+import { useCallback, useEffect, useMemo, useRef, useState, type ChangeEvent, type CSSProperties, type FocusEvent, type MouseEvent, type PointerEvent, type ReactNode, type RefObject } from "react";
import { App, Button, Drawer, Modal, Popover, Spin, Tooltip } from "antd";
-import { ArrowDown, ArrowUp, Check, ChevronDown, Clapperboard, Clock3, Copy, Download, FileText, Film, FolderOpen, History, Image as ImageIcon, LoaderCircle, Maximize2, MessageSquareText, Music2, Paperclip, Plus, RefreshCw, Search, SlidersHorizontal, Sparkles, Trash2, WandSparkles, X } from "lucide-react";
+import { Reorder } from "motion/react";
+import { ArrowDown, ArrowUp, Check, ChevronDown, ChevronLeft, ChevronRight, Clapperboard, Clock3, Copy, Download, FileText, Film, FolderOpen, History, Image as ImageIcon, LoaderCircle, Maximize2, MessageSquareText, Music2, Paperclip, Plus, RefreshCw, Search, SlidersHorizontal, Sparkles, Trash2, WandSparkles, X } from "lucide-react";
import { Link } from "react-router";
import { AIMessageMarkdown } from "@/components/ai/ai-message-markdown";
@@ -469,6 +470,10 @@ export default function CreatePage() {
if (reference) setPrompt((current) => removeCreationReferenceTokens(current, [reference]));
};
+ const reorderAttachments = useCallback((next: CreationAttachment[]) => {
+ setAttachments(next);
+ }, []);
+
const submit = async (retryContext?: CreationRetryContext, retryLockKey?: string) => {
const releaseRetryLock = () => {
if (retryLockKey) retryPreparingRef.current.delete(retryLockKey);
@@ -829,6 +834,7 @@ export default function CreatePage() {
maxReferences,
references: mentionReferences,
onRemoveAttachment: removeAttachment,
+ onReorderAttachments: reorderAttachments,
onOpenLibrary: () => setLibraryOpen(true),
fileInputRef,
onFileChange: handleFileChange,
@@ -1064,24 +1070,20 @@ function CreationMediaPreviewModal({ url, type, onClose }: { url: string; type:
return {url ? type === "video" ? :
: null};
}
-function CreationAttachmentThumbnail({ item, primary = false, canAddMore = false, onPreview, onRemove, onAdd }: {
+function CreationAttachmentThumbnail({ item, onPreview, onRemove }: {
item: CreationAttachment;
- primary?: boolean;
- canAddMore?: boolean;
onPreview: (type: "image" | "video", url: string) => void;
onRemove: (id: string) => void;
- onAdd?: () => void;
}) {
const kind = creationAttachmentKind(item);
const previewable = kind === "image" || kind === "video";
const url = (kind === "video" ? item.url : item.previewUrl) || "";
- return
-