fix: rebuild images with title
This commit is contained in:
@@ -958,6 +958,7 @@ export class MediaEngine extends EventEmitter {
|
||||
size: stats.size,
|
||||
width: metadata.width,
|
||||
height: metadata.height,
|
||||
title: metadata.title,
|
||||
alt: metadata.alt,
|
||||
caption: metadata.caption,
|
||||
filePath: mediaFilePath,
|
||||
@@ -973,6 +974,7 @@ export class MediaEngine extends EventEmitter {
|
||||
id: metadata.id,
|
||||
projectId: this.currentProjectId,
|
||||
originalName: metadata.originalName,
|
||||
title: metadata.title,
|
||||
alt: metadata.alt,
|
||||
caption: metadata.caption,
|
||||
tags: metadata.tags,
|
||||
|
||||
@@ -18,6 +18,11 @@ import { parseMacros, getMacro } from '../../macros/registry';
|
||||
import { InsertModal } from '../InsertModal';
|
||||
import './Editor.css';
|
||||
|
||||
/** Get display name for media: prefer title over originalName */
|
||||
function getMediaDisplayName(media: { title?: string; originalName: string }): string {
|
||||
return media.title || media.originalName;
|
||||
}
|
||||
|
||||
// Module-level AutoSaveManager for idle-time based auto-saving
|
||||
const autoSaveManager = new AutoSaveManager({
|
||||
idleTimeMs: 3000, // Save after 3 seconds of idle time
|
||||
@@ -207,7 +212,7 @@ const hydrateGalleries = async (
|
||||
<img
|
||||
src="bds-media://${link.media.id}"
|
||||
alt="${link.media.alt || link.media.originalName}"
|
||||
title="${link.media.originalName}"
|
||||
title="${link.media.title || link.media.originalName}"
|
||||
/>
|
||||
</div>
|
||||
`).join('');
|
||||
@@ -558,7 +563,7 @@ function buildMonthGallery(
|
||||
<img
|
||||
src="bds-media://${img.id}"
|
||||
alt="${img.alt || img.originalName}"
|
||||
title="${img.originalName}"
|
||||
title="${img.title || img.originalName}"
|
||||
/>
|
||||
</div>
|
||||
`).join('')}
|
||||
@@ -976,7 +981,7 @@ const PostEditor: React.FC<PostEditorProps> = ({ postId }) => {
|
||||
if (mediaItem) {
|
||||
references.push({
|
||||
id: mediaItem.id,
|
||||
title: mediaItem.originalName,
|
||||
title: getMediaDisplayName(mediaItem),
|
||||
type: 'media',
|
||||
});
|
||||
}
|
||||
@@ -1642,7 +1647,7 @@ const MediaEditor: React.FC<{ mediaId: string }> = ({ mediaId }) => {
|
||||
// Show confirmation modal
|
||||
showConfirmDeleteModal({
|
||||
itemType: 'media',
|
||||
itemTitle: item.originalName,
|
||||
itemTitle: getMediaDisplayName(item),
|
||||
references,
|
||||
onConfirm: async () => {
|
||||
try {
|
||||
@@ -1676,7 +1681,7 @@ const MediaEditor: React.FC<{ mediaId: string }> = ({ mediaId }) => {
|
||||
<div className="editor-header">
|
||||
<div className="editor-tabs">
|
||||
<div className="editor-tab active">
|
||||
<span className="editor-tab-title">{item.originalName}</span>
|
||||
<span className="editor-tab-title">{getMediaDisplayName(item)}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="editor-actions">
|
||||
|
||||
@@ -774,6 +774,43 @@ linkedPostIds: ["post-a", "post-b", "post-c"]`;
|
||||
expect(postMediaInserts[1].sortOrder).toBe(1);
|
||||
expect(postMediaInserts[2].sortOrder).toBe(2);
|
||||
});
|
||||
|
||||
it('should restore title from sidecar metadata during rebuild', async () => {
|
||||
const fs = await import('fs/promises');
|
||||
|
||||
vi.mocked(fs.readdir).mockImplementation(async (dir: string, options?: any) => {
|
||||
if (typeof dir === 'string' && dir.includes('media')) {
|
||||
return [
|
||||
{ name: 'media-1.jpg', isFile: () => true, isDirectory: () => false },
|
||||
{ name: 'media-1.jpg.meta', isFile: () => true, isDirectory: () => false },
|
||||
] as any;
|
||||
}
|
||||
return [];
|
||||
});
|
||||
|
||||
// Sidecar with title field
|
||||
const sidecarContent = `id: media-1
|
||||
originalName: test-image.jpg
|
||||
mimeType: image/jpeg
|
||||
size: 1024
|
||||
title: My Beautiful Sunset Photo
|
||||
alt: A sunset over the ocean
|
||||
caption: Taken during vacation
|
||||
createdAt: 2024-01-15T10:00:00.000Z
|
||||
updatedAt: 2024-01-15T10:00:00.000Z
|
||||
tags: ["nature", "sunset"]`;
|
||||
mockFiles.set('/mock/userData/projects/test-project/media/media-1.jpg.meta', sidecarContent);
|
||||
mockFiles.set('/mock/userData/projects/test-project/media/media-1.jpg', Buffer.from('image-data'));
|
||||
|
||||
await mediaEngine.rebuildDatabaseFromFiles();
|
||||
|
||||
// Verify title is stored in database
|
||||
const insertedMedia = mockMedia.get('media-1');
|
||||
expect(insertedMedia).toBeDefined();
|
||||
expect(insertedMedia.title).toBe('My Beautiful Sunset Photo');
|
||||
expect(insertedMedia.alt).toBe('A sunset over the ocean');
|
||||
expect(insertedMedia.caption).toBe('Taken during vacation');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Full-Text Search', () => {
|
||||
|
||||
Reference in New Issue
Block a user