1
0
mirror of https://github.com/immich-app/immich.git synced 2024-12-25 10:43:13 +02:00

fix(server): Correctly set album start and end dates (#4698)

* fix(server): Correctly set album start and end dates

Currently, the query that retrieves album assets uses
`ORDER BY assets.fileCreatedAt DESC`, which makes the existing logic
return the start/end dates reversed (with `startDate` being taken from
the first asset in the array).

Instead of using the index-based approach, this change iterates through
assets to get the min/max `fileCreatedAt`. This will avoid any future
issues, if the query ordering changes, or becomes customizable (e.g. in
case the user prefers to visualize older assets first).

* fix: Maintain constant cost and only swap variables if needed
This commit is contained in:
Michael Manganiello 2023-10-31 06:08:34 -04:00 committed by GitHub
parent 87a0ba3db3
commit b6f18cbe81
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 33 additions and 8 deletions

View File

@ -0,0 +1,16 @@
import { albumStub } from '@test';
import { mapAlbum } from './album-response.dto';
describe('mapAlbum', () => {
it('should set start and end dates', () => {
const dto = mapAlbum(albumStub.twoAssets, false);
expect(dto.startDate).toEqual(new Date('2023-02-22T05:06:29.716Z'));
expect(dto.endDate).toEqual(new Date('2023-02-23T05:06:29.716Z'));
});
it('should not set start and end dates for empty assets', () => {
const dto = mapAlbum(albumStub.empty, false);
expect(dto.startDate).toBeUndefined();
expect(dto.endDate).toBeUndefined();
});
});

View File

@ -36,6 +36,15 @@ export const mapAlbum = (entity: AlbumEntity, withAssets: boolean): AlbumRespons
const hasSharedLink = entity.sharedLinks?.length > 0;
const hasSharedUser = sharedUsers.length > 0;
let startDate = assets.at(0)?.fileCreatedAt || undefined;
let endDate = assets.at(-1)?.fileCreatedAt || undefined;
// Swap dates if start date is greater than end date.
if (startDate && endDate && startDate > endDate) {
const temp = startDate;
startDate = endDate;
endDate = temp;
}
return {
albumName: entity.albumName,
description: entity.description,
@ -48,8 +57,8 @@ export const mapAlbum = (entity: AlbumEntity, withAssets: boolean): AlbumRespons
sharedUsers,
shared: hasSharedUser || hasSharedLink,
hasSharedLink,
startDate: assets.at(0)?.fileCreatedAt || undefined,
endDate: assets.at(-1)?.fileCreatedAt || undefined,
startDate,
endDate,
assets: (withAssets ? assets : []).map((asset) => mapAsset(asset)),
assetCount: entity.assets?.length || 0,
};

View File

@ -277,7 +277,7 @@ describe(MetadataService.name, () => {
id: assetStub.withLocation.id,
duration: null,
fileCreatedAt: assetStub.withLocation.createdAt,
localDateTime: new Date('2023-02-23T05:06:29.716Z'),
localDateTime: new Date('2023-02-22T05:06:29.716Z'),
});
});

View File

@ -434,8 +434,8 @@ export const assetStub = {
withLocation: Object.freeze<AssetEntity>({
id: 'asset-with-favorite-id',
deviceAssetId: 'device-asset-id',
fileModifiedAt: new Date('2023-02-23T05:06:29.716Z'),
fileCreatedAt: new Date('2023-02-23T05:06:29.716Z'),
fileModifiedAt: new Date('2023-02-22T05:06:29.716Z'),
fileCreatedAt: new Date('2023-02-22T05:06:29.716Z'),
owner: userStub.user1,
ownerId: 'user-id',
deviceId: 'device-id',
@ -447,9 +447,9 @@ export const assetStub = {
webpPath: null,
thumbhash: null,
encodedVideoPath: null,
createdAt: new Date('2023-02-23T05:06:29.716Z'),
updatedAt: new Date('2023-02-23T05:06:29.716Z'),
localDateTime: new Date('2023-02-23T05:06:29.716Z'),
createdAt: new Date('2023-02-22T05:06:29.716Z'),
updatedAt: new Date('2023-02-22T05:06:29.716Z'),
localDateTime: new Date('2023-02-22T05:06:29.716Z'),
isFavorite: false,
isArchived: false,
isReadOnly: false,