From 5e2fd1fff9f8186536996bb1339fd103857bf8c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8C=97=E6=9E=B3?= <7854742+wang_rumeng@user.noreply.gitee.com> Date: Mon, 18 Aug 2025 21:42:20 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=A7=92=E8=89=B2=E5=88=97?= =?UTF-8?q?=E8=A1=A8=E5=BC=B9=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/ui/shot-editor/CharacterToken.tsx | 15 +++- components/ui/shot-editor/ShotsEditor.tsx | 10 +-- components/ui/shot-tab-content.tsx | 87 +++++++++++--------- 3 files changed, 60 insertions(+), 52 deletions(-) diff --git a/components/ui/shot-editor/CharacterToken.tsx b/components/ui/shot-editor/CharacterToken.tsx index 5cbcd90..a793080 100644 --- a/components/ui/shot-editor/CharacterToken.tsx +++ b/components/ui/shot-editor/CharacterToken.tsx @@ -11,7 +11,7 @@ interface CharacterTokenOptions { export function CharacterToken(props: ReactNodeViewProps) { const [showRoleList, setShowRoleList] = useState(false); - const [listPosition, setListPosition] = useState({ top: 0, left: 0 }); + const [listPosition, setListPosition] = useState({ top: 0, left: 0, bottom: 0 }); const { name } = props.node.attrs as ScriptRoleEntity; const extension = props.extension as Node; const roles = extension.options.roles || []; @@ -31,6 +31,7 @@ export function CharacterToken(props: ReactNodeViewProps) { // 计算理想的顶部位置(在token下方) let top = tokenRect.bottom + 8; // 8px 间距 let left = tokenRect.left; + let bottom = tokenRect.top; // 检查是否超出底部 if (top + listRect.height > viewportHeight) { @@ -44,10 +45,18 @@ export function CharacterToken(props: ReactNodeViewProps) { left = viewportWidth - listRect.width - 8; } + // 检查是否超出顶部 + if (bottom - listRect.height < 0) { + // 如果超出顶部,将列表显示在token下方 + bottom = tokenRect.bottom + 8; + } + // 确保不会超出左侧 left = Math.max(8, left); + // 确保不会超顶部 + top = Math.max(0, top); - setListPosition({ top, left }); + setListPosition({ top, left, bottom }); }; // 监听窗口大小变化 @@ -107,7 +116,7 @@ export function CharacterToken(props: ReactNodeViewProps) { exit={{ opacity: 0, y: 4 }} transition={{ duration: 0.2 }} ref={listRef} - className="fixed w-64 rounded-lg backdrop-blur-md bg-white/10 border border-white/20 p-2 z-[51]" + className="fixed w-64 rounded-lg backdrop-blur-md bg-white/10 border border-white/20 p-2 z-[51] overflow-y-auto" style={{ top: listPosition.top, left: listPosition.left diff --git a/components/ui/shot-editor/ShotsEditor.tsx b/components/ui/shot-editor/ShotsEditor.tsx index 9a562d9..4d80bf2 100644 --- a/components/ui/shot-editor/ShotsEditor.tsx +++ b/components/ui/shot-editor/ShotsEditor.tsx @@ -26,17 +26,11 @@ const createEmptyShot = (): Shot => ({ name: `shot${Date.now()}`, shotDescContent: [{ type: 'paragraph', - content: [{ - type: 'text', - text: 'Add shot description here...' - }] + content: [] }], shotDialogsContent: [{ type: 'paragraph', - content: [{ - type: 'text', - text: 'Add shot dialogue here...' - }] + content: [] }] }); diff --git a/components/ui/shot-tab-content.tsx b/components/ui/shot-tab-content.tsx index 8dcdfa6..9e748bf 100644 --- a/components/ui/shot-tab-content.tsx +++ b/components/ui/shot-tab-content.tsx @@ -342,55 +342,60 @@ export const ShotTabContent = (props: ShotTabContentProps) => {
{/* 选中的视频预览 */} <> - {shotData[selectedIndex]?.status === 0 && ( + {(shotData[selectedIndex]?.status === 0) && (
Loading...
)} - {shotData[selectedIndex]?.status === 1 && ( - - - - {/* 人物替换按钮 */} - handleScan()} - className={`p-2 backdrop-blur-sm transition-colors z-10 rounded-full - ${scanState === 'detected' - ? 'bg-cyan-500/50 hover:bg-cyan-500/70 text-white' - : 'bg-black/50 hover:bg-black/70 text-white' - }`} - whileHover={{ scale: 1.05 }} - whileTap={{ scale: 0.95 }} - > - {scanState === 'scanning' ? ( - - ) : scanState === 'detected' ? ( - - ) : ( - - )} - + + {shotData[selectedIndex]?.status === 1 && shotData[selectedIndex]?.videoUrl.length && ( + + + + {/* 人物替换按钮 */} + handleScan()} + className={`p-2 backdrop-blur-sm transition-colors z-10 rounded-full + ${scanState === 'detected' + ? 'bg-cyan-500/50 hover:bg-cyan-500/70 text-white' + : 'bg-black/50 hover:bg-black/70 text-white' + }`} + whileHover={{ scale: 1.05 }} + whileTap={{ scale: 0.95 }} + > + {scanState === 'scanning' ? ( + + ) : scanState === 'detected' ? ( + + ) : ( + + )} + + - - )} - {shotData[selectedIndex]?.status === 2 && ( + )} + + {(shotData[selectedIndex]?.status === 2 || !shotData[selectedIndex]?.videoUrl.length) && (
- 任务失败,点击重新生成 + Failed, click to regenerate
)}