video-flow-b/components/common/PhotoStoryMode.tsx
2025-08-16 21:38:05 +08:00

101 lines
3.4 KiB
TypeScript

"use client";
import { Loader2, Trash2, ChevronDown } from "lucide-react";
import { Dropdown, Image } from "antd";
import { EyeOutlined } from "@ant-design/icons";
import { useImageStoryServiceHook } from "@/app/service/Interaction/ImageStoryService";
/**
* 图片故事模式组件
* 显示图片预览、分析状态和故事类型选择器
* 使用ImageStoryService hook管理状态和业务逻辑
*/
export function PhotoStoryMode() {
// 使用图片故事服务hook
const {
activeImageUrl,
selectedCategory,
isAnalyzing,
isUploading,
storyTypeOptions,
updateStoryType,
resetImageStory,
} = useImageStoryServiceHook();
return (
<div className="absolute top-[-110px] left-14 right-0 flex items-center justify-between">
{/* 左侧:图片预览区域和分析状态指示器 */}
<div className="flex items-center gap-3">
{/* 图片预览区域 - 使用Ant Design Image组件 */}
<div className="relative w-24 h-24 rounded-lg overflow-hidden bg-white/[0.05] border border-white/[0.1] shadow-[0_4px_16px_rgba(0,0,0,0.2)]">
{activeImageUrl && (
<Image
src={activeImageUrl}
alt="Story inspiration"
className="w-full h-full object-cover"
preview={{
mask: (
<EyeOutlined className="w-6 h-6 text-white/80" />
),
maskClassName:
"flex items-center justify-center bg-black/50 hover:bg-black/70 transition-colors",
}}
/>
)}
</div>
{/* 删除图片按钮 - 简洁样式 */}
{activeImageUrl && (
<button
onClick={resetImageStory}
className="absolute -top-2 left-24 w-6 h-6 bg-black/60 hover:bg-black/80 rounded-full flex items-center justify-center text-white/80 hover:text-white transition-all duration-200 z-10"
title="删除图片并退出图片故事模式"
>
<Trash2 className="w-2.5 h-2.5" />
</button>
)}
{/* 分析状态指示器 */}
{isAnalyzing && (
<div className="flex items-center gap-2 px-3 py-2 bg-white/[0.1] rounded-lg">
<Loader2 className="w-4 h-4 animate-spin text-white/80" />
<span className="text-sm text-white/80">
{isUploading
? "Uploading image..."
: "Analyzing image..."}
</span>
</div>
)}
</div>
{/* 右侧:故事类型选择器 */}
{activeImageUrl && (
<Dropdown
menu={{
items: storyTypeOptions.map((type) => ({
key: type.key,
label: (
<div className="px-3 py-2 text-sm text-white/90">
{type.label}
</div>
),
})),
onClick: ({ key }) => updateStoryType(key),
}}
trigger={["click"]}
placement="bottomRight"
>
<button className="px-3 py-2 bg-white/[0.1] hover:bg-white/[0.15] border border-white/[0.2] rounded-lg text-white/80 text-sm transition-colors flex items-center gap-2">
<span>
{storyTypeOptions.find(
(t) => t.key === selectedCategory
)?.label || "Auto"}
</span>
<ChevronDown className="w-3 h-3" />
</button>
</Dropdown>
)}
</div>
);
}