新增 历史记录中的生成详情显示参考图

This commit is contained in:
2025-09-15 22:30:39 +08:00
parent 7a5e5d77b0
commit a922a4e507
3 changed files with 169 additions and 60 deletions

View File

@@ -5,6 +5,7 @@ import { History, Download, Image as ImageIcon } from 'lucide-react';
import { cn } from '../utils/cn';
import { ImagePreviewModal } from './ImagePreviewModal';
import * as indexedDBService from '../services/indexedDBService';
import { useIndexedDBListener } from '../hooks/useIndexedDBListener';
export const HistoryPanel: React.FC = () => {
const {
@@ -37,9 +38,8 @@ export const HistoryPanel: React.FC = () => {
// 存储从Blob URL解码的图像数据
const [decodedImages, setDecodedImages] = useState<Record<string, string>>({});
// 存储从IndexedDB获取的完整记录
const [dbGenerations, setDbGenerations] = useState<any[]>([]);
const [dbEdits, setDbEdits] = useState<any[]>([]);
// 使用自定义hook获取IndexedDB记录
const { generations: dbGenerations, edits: dbEdits, loading, error, refresh } = useIndexedDBListener();
// 筛选和搜索状态
const [startDate, setStartDate] = useState<string>('');
@@ -80,50 +80,39 @@ export const HistoryPanel: React.FC = () => {
}
}, [canvasImage]);
// 当组件挂载时从IndexedDB获取记录
useEffect(() => {
const loadDBRecords = async () => {
try {
// 初始化数据库
await indexedDBService.initDB();
// 获取所有生成记录和编辑记录
const allGenerations = await indexedDBService.getAllGenerations();
const allEdits = await indexedDBService.getAllEdits();
setDbGenerations(allGenerations);
setDbEdits(allEdits);
} catch (err) {
console.error('从IndexedDB加载记录失败:', err);
}
};
loadDBRecords();
}, []);
// 当有新记录添加时,重新加载记录
useEffect(() => {
// 监听store中的记录变化如果有新记录则重新加载
const handleStorageChange = (e: StorageEvent) => {
if (e.key === 'nano-banana-store') {
// 重新加载记录
const loadDBRecords = async () => {
try {
const allGenerations = await indexedDBService.getAllGenerations();
const allEdits = await indexedDBService.getAllEdits();
setDbGenerations(allGenerations);
setDbEdits(allEdits);
} catch (err) {
console.error('从IndexedDB重新加载记录失败:', err);
}
};
loadDBRecords();
}
};
window.addEventListener('storage', handleStorageChange);
return () => window.removeEventListener('storage', handleStorageChange);
}, []);
// 错误处理显示
if (error) {
return (
<div className="w-80 bg-white border-l border-gray-200 p-6 flex flex-col h-full">
<div className="flex items-center justify-between mb-6">
<div className="flex items-center space-x-2">
<History className="h-5 w-5 text-gray-400" />
<h3 className="text-sm font-medium text-gray-300"></h3>
</div>
<Button
variant="ghost"
size="icon"
onClick={() => setShowHistory(!showHistory)}
className="h-6 w-6"
title="隐藏历史面板"
>
×
</Button>
</div>
<div className="text-center py-8 text-red-500">
<p className="text-sm">: {error}</p>
<Button
variant="outline"
size="sm"
className="mt-2"
onClick={refresh}
>
</Button>
</div>
</div>
);
}
// 筛选记录的函数
const filterRecords = (records: any[], isGeneration: boolean) => {
@@ -233,16 +222,7 @@ export const HistoryPanel: React.FC = () => {
<Button
variant="ghost"
size="icon"
onClick={async () => {
try {
const allGenerations = await indexedDBService.getAllGenerations();
const allEdits = await indexedDBService.getAllEdits();
setDbGenerations(allGenerations);
setDbEdits(allEdits);
} catch (err) {
console.error('刷新历史记录失败:', err);
}
}}
onClick={refresh}
className="h-6 w-6"
title="刷新历史记录"
>
@@ -601,9 +581,37 @@ export const HistoryPanel: React.FC = () => {
{gen.sourceAssets && gen.sourceAssets.length > 0 && (
<div>
<h5 className="text-xs font-medium text-gray-500 mb-2"></h5>
<div className="text-xs text-gray-600">
<div className="text-xs text-gray-600 mb-2">
{gen.sourceAssets.length}
</div>
<div className="flex flex-wrap gap-2">
{gen.sourceAssets.slice(0, 4).map((asset: any, index: number) => (
<div
key={asset.id}
className="relative w-16 h-16 rounded border overflow-hidden cursor-pointer"
onClick={(e) => {
e.stopPropagation();
setPreviewModal({
open: true,
imageUrl: asset.url,
title: `参考图像 ${index + 1}`,
description: `${asset.width} × ${asset.height}`
});
}}
>
<img
src={asset.url}
alt={`参考图像 ${index + 1}`}
className="w-full h-full object-cover"
/>
</div>
))}
{gen.sourceAssets.length > 4 && (
<div className="w-16 h-16 rounded border flex items-center justify-center bg-gray-100 text-xs text-gray-500">
+{gen.sourceAssets.length - 4}
</div>
)}
</div>
</div>
)}
</div>
@@ -669,6 +677,42 @@ export const HistoryPanel: React.FC = () => {
<div className="text-xs text-gray-600">
基于: G{dbGenerations.findIndex(g => g.id === parentGen.id) + 1}
</div>
{/* 显示原始生成的参考图像 */}
{parentGen.sourceAssets && parentGen.sourceAssets.length > 0 && (
<div className="mt-2">
<div className="text-xs text-gray-600 mb-2">
:
</div>
<div className="flex flex-wrap gap-2">
{parentGen.sourceAssets.slice(0, 4).map((asset: any, index: number) => (
<div
key={asset.id}
className="relative w-16 h-16 rounded border overflow-hidden cursor-pointer"
onClick={(e) => {
e.stopPropagation();
setPreviewModal({
open: true,
imageUrl: asset.url,
title: `原始参考图像 ${index + 1}`,
description: `${asset.width} × ${asset.height}`
});
}}
>
<img
src={asset.url}
alt={`原始参考图像 ${index + 1}`}
className="w-full h-full object-cover"
/>
</div>
))}
{parentGen.sourceAssets.length > 4 && (
<div className="w-16 h-16 rounded border flex items-center justify-center bg-gray-100 text-xs text-gray-500">
+{parentGen.sourceAssets.length - 4}
</div>
)}
</div>
</div>
)}
</div>
)}
</div>