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(() => {