fix(server): refresh unedited asset dimensions on metadata extraction (#27220)

This commit is contained in:
Michel Heusschen 2026-03-26 18:17:32 +01:00 committed by GitHub
parent 8f01d06927
commit 4812a2e2d8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 28 additions and 6 deletions

View File

@ -345,6 +345,7 @@ export const columns = {
'asset.type',
'asset.width',
'asset.height',
'asset.isEdited',
],
assetFiles: ['asset_file.id', 'asset_file.path', 'asset_file.type', 'asset_file.isEdited'],
assetFilesForThumbnail: [

View File

@ -264,6 +264,7 @@ select
"asset"."type",
"asset"."width",
"asset"."height",
"asset"."isEdited",
(
select
coalesce(json_agg(agg), '[]')

View File

@ -1641,12 +1641,32 @@ describe(MetadataService.name, () => {
);
});
it('should not overwrite existing width/height if they already exist', async () => {
const asset = AssetFactory.create({ width: 1920, height: 1080 });
it('should overwrite existing width/height for unedited assets', async () => {
const asset = AssetFactory.create({ width: 1920, height: 1080, isEdited: false });
mocks.assetJob.getForMetadataExtraction.mockResolvedValue(getForMetadataExtraction(asset));
mockReadTags({ ImageWidth: 1280, ImageHeight: 720 });
await sut.handleMetadataExtraction({ id: asset.id });
expect(mocks.asset.update).toHaveBeenCalledWith(
expect.objectContaining({
width: 1280,
height: 720,
}),
);
});
it('should not overwrite existing width/height for edited assets', async () => {
const asset = AssetFactory.create({ width: 1920, height: 1080, isEdited: true });
mocks.assetJob.getForMetadataExtraction.mockResolvedValue(getForMetadataExtraction(asset));
mockReadTags({ ImageWidth: 1280, ImageHeight: 720 });
await sut.handleMetadataExtraction({ id: asset.id });
expect(mocks.asset.update).toHaveBeenCalledWith(
expect.objectContaining({
width: undefined,
height: undefined,
}),
);
expect(mocks.asset.update).not.toHaveBeenCalledWith(
expect.objectContaining({
width: 1280,

View File

@ -327,10 +327,9 @@ export class MetadataService extends BaseService {
fileCreatedAt: dates.dateTimeOriginal ?? undefined,
fileModifiedAt: stats.mtime,
// only update the dimensions if they don't already exist
// we don't want to overwrite width/height that are modified by edits
width: asset.width == null ? assetWidth : undefined,
height: asset.height == null ? assetHeight : undefined,
// Keep unedited assets in sync with the file on disk, but don't overwrite edited dimensions.
width: !asset.isEdited || asset.width == null ? assetWidth : undefined,
height: !asset.isEdited || asset.height == null ? assetHeight : undefined,
}),
async () => {
await this.assetRepository.upsertExif(exifData, { lockedPropertiesBehavior: 'skip' });

View File

@ -138,6 +138,7 @@ export const getForMetadataExtraction = (asset: ReturnType<AssetFactory['build']
originalPath: asset.originalPath,
ownerId: asset.ownerId,
type: asset.type,
isEdited: asset.isEdited,
width: asset.width,
height: asset.height,
faces: asset.faces.map((face) => getDehydrated(face)),