更新 chatbox h5样式

This commit is contained in:
moux1024 2025-09-23 13:23:30 +08:00
parent 26ce68bd54
commit cd004dcc4f
4 changed files with 38 additions and 15 deletions

View File

@ -4,6 +4,8 @@ import { MessageBlock } from "./types";
import { useUploadFile } from "@/app/service/domain/service"; import { useUploadFile } from "@/app/service/domain/service";
import { motion, AnimatePresence } from "framer-motion"; import { motion, AnimatePresence } from "framer-motion";
import { QuickActionTags, QuickAction } from "./QuickActionTags"; import { QuickActionTags, QuickAction } from "./QuickActionTags";
import { useDeviceType } from '@/hooks/useDeviceType';
// 防抖函数 // 防抖函数
function debounce<T extends (...args: any[]) => void>(func: T, wait: number) { function debounce<T extends (...args: any[]) => void>(func: T, wait: number) {
@ -35,6 +37,7 @@ export function InputBar({ onSend, setVideoPreview, initialVideoUrl, initialVide
const [videoUrl, setVideoUrl] = useState<string | null>(initialVideoUrl || null); const [videoUrl, setVideoUrl] = useState<string | null>(initialVideoUrl || null);
const [videoId, setVideoId] = useState<string | null>(initialVideoId || null); const [videoId, setVideoId] = useState<string | null>(initialVideoId || null);
const [isMultiline, setIsMultiline] = useState(false); const [isMultiline, setIsMultiline] = useState(false);
const { isMobile, isTablet, isDesktop } = useDeviceType();
const textareaRef = useRef<HTMLTextAreaElement>(null); const textareaRef = useRef<HTMLTextAreaElement>(null);
const { uploadFile } = useUploadFile(); const { uploadFile } = useUploadFile();
@ -174,7 +177,7 @@ export function InputBar({ onSend, setVideoPreview, initialVideoUrl, initialVide
}; };
return ( return (
<div data-alt="input-bar"> <div data-alt="input-bar" className={`${isMobile ? 'absolute bottom-0 left-0 right-0 bg-[#141414]' : ''}`}>
{/* 媒体预览 */} {/* 媒体预览 */}
<div className="px-3 pt-3 flex gap-2" data-alt="media-preview"> <div className="px-3 pt-3 flex gap-2" data-alt="media-preview">
{/* 图片预览 */} {/* 图片预览 */}

View File

@ -5,6 +5,7 @@ import { bubbleVariants, hhmm } from "./utils";
import { ProgressBar } from "./ProgressBar"; import { ProgressBar } from "./ProgressBar";
import { Loader2, AlertCircle, CheckCircle2 } from "lucide-react"; import { Loader2, AlertCircle, CheckCircle2 } from "lucide-react";
import { Image } from 'antd'; import { Image } from 'antd';
import { useDeviceType } from '@/hooks/useDeviceType';
interface MessageRendererProps { interface MessageRendererProps {
msg: ChatMessage; msg: ChatMessage;
@ -15,6 +16,7 @@ export function MessageRenderer({ msg, sendMessage }: MessageRendererProps) {
// Decide bubble style // Decide bubble style
const isUser = msg.role === "user"; const isUser = msg.role === "user";
const isSystem = msg.role === "system"; const isSystem = msg.role === "system";
const { isMobile, isTablet, isDesktop } = useDeviceType();
const bubbleClass = useMemo(() => { const bubbleClass = useMemo(() => {
if (isSystem) return "bg-[#281c1459] text-white"; if (isSystem) return "bg-[#281c1459] text-white";
@ -78,7 +80,7 @@ export function MessageRenderer({ msg, sendMessage }: MessageRendererProps) {
data-alt="message-bubble" data-alt="message-bubble"
key={msg.id} key={msg.id}
> >
<div className={`max-w-[75%] rounded-2xl shadow-md p-3 ${bubbleClass}`}> <div className={`${isMobile ? 'max-w-full' : 'max-w-[75%]'} rounded-2xl shadow-md p-3 ${bubbleClass}`}>
{/* Header */} {/* Header */}
{/* <div className="flex items-center gap-2 text-[11px] opacity-80 mb-1"> {/* <div className="flex items-center gap-2 text-[11px] opacity-80 mb-1">
{badge} {badge}

View File

@ -7,6 +7,7 @@ import { useMessages } from "./useMessages";
import { DateDivider } from "./DateDivider"; import { DateDivider } from "./DateDivider";
import { LoadMoreButton } from "./LoadMoreButton"; import { LoadMoreButton } from "./LoadMoreButton";
import { ChatMessage } from "./types"; import { ChatMessage } from "./types";
import { useDeviceType } from '@/hooks/useDeviceType';
interface SmartChatBoxProps { interface SmartChatBoxProps {
isSmartChatBoxOpen: boolean; isSmartChatBoxOpen: boolean;
@ -51,7 +52,7 @@ export default function SmartChatBox({
// 消息列表引用 // 消息列表引用
const listRef = useRef<HTMLDivElement>(null); const listRef = useRef<HTMLDivElement>(null);
const [isAtBottom, setIsAtBottom] = useState(true); const [isAtBottom, setIsAtBottom] = useState(true);
const { isMobile, isTablet, isDesktop } = useDeviceType();
// 检查是否滚动到底部 // 检查是否滚动到底部
const checkIfAtBottom = useCallback(() => { const checkIfAtBottom = useCallback(() => {
if (listRef.current) { if (listRef.current) {
@ -148,18 +149,18 @@ export default function SmartChatBox({
}, [messages]); }, [messages]);
return ( return (
<div className="h-full w-full text-gray-100 flex flex-col" data-alt="smart-chat-box"> <div className={`${isMobile ? 'z-[49]' : 'h-full'} w-full text-gray-100 flex flex-col`} data-alt="smart-chat-box">
{/* Header */} {/* Header */}
<div className="px-4 py-3 border-b border-white/10 flex items-center justify-between" data-alt="chat-header"> <div className={`px-4 py-3 border-b border-white/10 flex items-center justify-between ${isMobile ? 'sticky top-0 bg-[#141414] z-[1]' : ''}`} data-alt="chat-header">
<div className="font-semibold flex items-center gap-2"> <div className="font-semibold flex items-center gap-2">
<span>Chat</span> <span>Chat</span>
{/* System push toggle */} {/* System push toggle */}
<Switch <Switch
checkedChildren="On" checkedChildren="On"
unCheckedChildren="Off" unCheckedChildren="Off"
checked={systemPush} checked={systemPush}
onChange={toggleSystemPush} onChange={toggleSystemPush}
className="ml-2 " className="ml-2"
/> />
</div> </div>
<div className="text-xs opacity-70"> <div className="text-xs opacity-70">

View File

@ -235,6 +235,11 @@ const WorkFlow = React.memo(function WorkFlow() {
toggleVideoPlay, toggleVideoPlay,
} = usePlaybackControls(taskObject.videos.data, taskObject.currentStage); } = usePlaybackControls(taskObject.videos.data, taskObject.currentStage);
useEffect(() => {
if (isMobile) {
setIsSmartChatBoxOpen(false);
}
}, [isMobile]);
useEffect(() => { useEffect(() => {
console.log('changedIndex_work-flow', currentSketchIndex, taskObject); console.log('changedIndex_work-flow', currentSketchIndex, taskObject);
}, [currentSketchIndex, taskObject]); }, [currentSketchIndex, taskObject]);
@ -613,6 +618,14 @@ Please process this video editing request.`;
<div <div
className="fixed right-[1rem] bottom-[10rem] z-[49]" className="fixed right-[1rem] bottom-[10rem] z-[49]"
> >
{isMobile ? (
<GlassIconButton
icon={Bot}
size='md'
onClick={() => setIsSmartChatBoxOpen(true)}
className="backdrop-blur-lg"
/>
) : (
<Tooltip title="Open chat" placement="left"> <Tooltip title="Open chat" placement="left">
<GlassIconButton <GlassIconButton
icon={Bot} icon={Bot}
@ -621,12 +634,13 @@ Please process this video editing request.`;
className="backdrop-blur-lg" className="backdrop-blur-lg"
/> />
</Tooltip> </Tooltip>
)}
</div> </div>
{/* 智能对话弹窗 */} {/* 智能对话弹窗 */}
<Drawer <Drawer
width="25%" width={isMobile ? '100vw' : '25%'}
placement="right" placement={isMobile ? 'bottom' : 'right'}
closable={false} closable={false}
maskClosable={false} maskClosable={false}
open={isSmartChatBoxOpen} open={isSmartChatBoxOpen}
@ -638,15 +652,18 @@ Please process this video editing request.`;
className="backdrop-blur-lg bg-black/30 border border-white/20 shadow-xl" className="backdrop-blur-lg bg-black/30 border border-white/20 shadow-xl"
style={{ style={{
backgroundColor: 'transparent', backgroundColor: 'transparent',
borderBottomLeftRadius: 10, ...(isMobile
borderTopLeftRadius: 10, ? { borderTopLeftRadius: 10, borderTopRightRadius: 10 }
: { borderBottomLeftRadius: 10, borderTopLeftRadius: 10 }),
overflow: 'hidden', overflow: 'hidden',
}} }}
styles={{ styles={{
body: { body: {
backgroundColor: 'transparent', backgroundColor: 'transparent',
padding: 0, padding: 0,
}, maxHeight: '100vh',
overflow: 'auto',
}
}} }}
onClose={() => setIsSmartChatBoxOpen(false)} onClose={() => setIsSmartChatBoxOpen(false)}
> >