forked from 77media/video-flow
101 lines
3.4 KiB
TypeScript
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>
|
|
);
|
|
}
|