81 lines
2.6 KiB
TypeScript
81 lines
2.6 KiB
TypeScript
import { RefreshCw, Trash2 } from "lucide-react";
|
|
|
|
interface GeneratedVideo {
|
|
id: string;
|
|
name: string;
|
|
path: string;
|
|
size_mb: number;
|
|
created_at: number;
|
|
}
|
|
|
|
interface HistoryListProps {
|
|
generatedVideos: GeneratedVideo[];
|
|
selectedVideoId: string | null;
|
|
onSelectVideo: (video: GeneratedVideo) => void;
|
|
onDeleteVideo: (id: string) => void;
|
|
onRefresh: () => void;
|
|
registerVideoRef: (id: string, element: HTMLDivElement | null) => void;
|
|
formatDate: (timestamp: number) => string;
|
|
}
|
|
|
|
export function HistoryList({
|
|
generatedVideos,
|
|
selectedVideoId,
|
|
onSelectVideo,
|
|
onDeleteVideo,
|
|
onRefresh,
|
|
registerVideoRef,
|
|
formatDate,
|
|
}: HistoryListProps) {
|
|
return (
|
|
<div className="bg-white/5 rounded-2xl p-6 border border-white/10 backdrop-blur-sm">
|
|
<div className="flex justify-between items-center mb-4">
|
|
<h2 className="text-lg font-semibold text-white flex items-center gap-2">📂 历史作品</h2>
|
|
<button
|
|
onClick={onRefresh}
|
|
className="px-3 py-1 text-xs bg-white/10 hover:bg-white/20 rounded text-gray-300 flex items-center gap-1"
|
|
>
|
|
<RefreshCw className="h-3.5 w-3.5" />
|
|
刷新
|
|
</button>
|
|
</div>
|
|
{generatedVideos.length === 0 ? (
|
|
<div className="text-center py-4 text-gray-500">
|
|
<p>暂无生成的作品</p>
|
|
</div>
|
|
) : (
|
|
<div
|
|
className="space-y-2 max-h-64 overflow-y-auto hide-scrollbar"
|
|
style={{ contentVisibility: 'auto' }}
|
|
>
|
|
{generatedVideos.map((v) => (
|
|
<div
|
|
key={v.id}
|
|
ref={(el) => registerVideoRef(v.id, el)}
|
|
className={`p-3 rounded-lg border transition-all flex items-center justify-between group ${selectedVideoId === v.id
|
|
? "border-purple-500 bg-purple-500/20"
|
|
: "border-white/10 bg-white/5 hover:border-white/30"
|
|
}`}
|
|
>
|
|
<button onClick={() => onSelectVideo(v)} className="flex-1 text-left">
|
|
<div className="text-white text-sm truncate">{formatDate(v.created_at)}</div>
|
|
<div className="text-gray-400 text-xs">{v.size_mb.toFixed(1)} MB</div>
|
|
</button>
|
|
<button
|
|
onClick={(e) => {
|
|
e.stopPropagation();
|
|
onDeleteVideo(v.id);
|
|
}}
|
|
className="p-1 text-gray-500 hover:text-red-400 opacity-0 group-hover:opacity-100 transition-opacity"
|
|
title="删除视频"
|
|
>
|
|
<Trash2 className="h-4 w-4" />
|
|
</button>
|
|
</div>
|
|
))}
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|