From 684f29056eeb854acb48937d16315601d1b8db09 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: Sat, 30 Aug 2025 20:30:20 +0800 Subject: [PATCH] =?UTF-8?q?-=20[x]=20Chatbox-=E5=BF=AB=E6=8D=B7=E6=93=8D?= =?UTF-8?q?=E4=BD=9C=E6=8C=89=E9=92=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/SmartChatBox/InputBar.tsx | 14 ++ components/SmartChatBox/QuickActionTags.tsx | 123 ++++++++++++++++++ components/SmartChatBox/SmartChatBox.tsx | 2 +- .../pages/work-flow/use-workflow-data.tsx | 3 +- 4 files changed, 140 insertions(+), 2 deletions(-) create mode 100644 components/SmartChatBox/QuickActionTags.tsx diff --git a/components/SmartChatBox/InputBar.tsx b/components/SmartChatBox/InputBar.tsx index 0f70fe0..5ff55b4 100644 --- a/components/SmartChatBox/InputBar.tsx +++ b/components/SmartChatBox/InputBar.tsx @@ -3,6 +3,7 @@ import { Image as ImageIcon, Send, Trash2, ArrowUp } from "lucide-react"; import { MessageBlock } from "./types"; import { useUploadFile } from "@/app/service/domain/service"; import { motion, AnimatePresence } from "framer-motion"; +import { QuickActionTags, QuickAction } from "./QuickActionTags"; // 防抖函数 function debounce void>(func: T, wait: number) { @@ -233,6 +234,19 @@ export function InputBar({ onSend, setVideoPreview, initialVideoUrl, initialVide )} + {/* 快捷操作标签组 */} + { + // 将标签文本添加到输入框 + setText(action.label); + // 聚焦输入框并触发高度调整 + if (textareaRef.current) { + textareaRef.current.focus(); + adjustHeight(); + } + }} + /> + void; +} + +/** + * 快捷操作标签组组件 + * @param props 组件属性 + * @returns JSX.Element + */ +export function QuickActionTags({ actions = DEFAULT_QUICK_ACTIONS, onTagClick }: QuickActionTagsProps) { + const scrollContainerRef = useRef(null); + + const scroll = useCallback((direction: 'left' | 'right') => { + const container = scrollContainerRef.current; + if (!container) return; + + const scrollAmount = 200; // 每次滚动的距离 + const targetScroll = container.scrollLeft + (direction === 'left' ? -scrollAmount : scrollAmount); + + container.scrollTo({ + left: targetScroll, + behavior: 'smooth' + }); + }, []); + + return ( +
+ {/* 左侧渐变遮罩 */} +
+ + {/* 左滚动按钮 */} + scroll('left')} + className="absolute left-1 z-20 p-1 rounded-full bg-black/30 text-white/80 + backdrop-blur-sm opacity-0 group-hover:opacity-100 transition-opacity + hover:bg-black/40" + whileHover={{ scale: 1.1 }} + whileTap={{ scale: 0.9 }} + data-alt="scroll-left" + > + + + + {/* 标签滚动容器 */} +
+ {actions.map((action) => ( + onTagClick(action)} + whileHover={{ scale: 1.05 }} + whileTap={{ scale: 0.95 }} + className="flex-none px-[8px] py-[3px] rounded-full text-[10px] text-white/80 + backdrop-blur-md bg-white/10 border border-white/20 + hover:bg-white/20 hover:text-white + transition-colors duration-200 + shadow-[0_4px_6px_-1px_rgba(0,0,0,0.1),0_2px_4px_-1px_rgba(0,0,0,0.06)]" + data-alt={`quick-action-${action.id}`} + > + {action.label} + + ))} +
+ + {/* 右侧渐变遮罩 */} +
+ + {/* 右滚动按钮 */} + scroll('right')} + className="absolute right-1 z-20 p-1 rounded-full bg-black/30 text-white/80 + backdrop-blur-sm opacity-0 group-hover:opacity-100 transition-opacity + hover:bg-black/40" + whileHover={{ scale: 1.1 }} + whileTap={{ scale: 0.9 }} + data-alt="scroll-right" + > + + +
+ ); +} + +// 添加全局样式来隐藏滚动条 +const style = document.createElement('style'); +style.textContent = ` + /* Hide scrollbar for Chrome, Safari and Opera */ + .no-scrollbar::-webkit-scrollbar { + display: none; + } +`; +document.head.appendChild(style); diff --git a/components/SmartChatBox/SmartChatBox.tsx b/components/SmartChatBox/SmartChatBox.tsx index 6f5d16d..5d0ac65 100644 --- a/components/SmartChatBox/SmartChatBox.tsx +++ b/components/SmartChatBox/SmartChatBox.tsx @@ -168,7 +168,7 @@ export default function SmartChatBox({
{/* Loading indicator */} - {isLoading && !hasMore && ( + {isLoading && (
diff --git a/components/pages/work-flow/use-workflow-data.tsx b/components/pages/work-flow/use-workflow-data.tsx index 5d0dcdf..e8feca0 100644 --- a/components/pages/work-flow/use-workflow-data.tsx +++ b/components/pages/work-flow/use-workflow-data.tsx @@ -17,6 +17,7 @@ export function useWorkflowData() { const episodeId = searchParams.get('episodeId') || ''; const from = searchParams.get('from') || ''; const token = localStorage.getItem('token') || ''; + const useid = JSON.parse(localStorage.getItem("currentUser") || '{}').id || NaN; let tempTaskObject = useRef({ title: '', @@ -114,7 +115,7 @@ export function useWorkflowData() { const generateEditPlan = useCallback(async () => { await getGenerateEditPlan({ project_id: episodeId }); - window.open(`https://smartcut.huiying.video/ai-editor/${episodeId}?token=${token}`, '_self'); + window.open(`https://smartcut.huiying.video/ai-editor/${episodeId}?token=${token}&userid=${useid}`, '_self'); }, [episodeId]); // useEffect(() => {