diff --git a/server/src/domain/asset/asset.service.spec.ts b/server/src/domain/asset/asset.service.spec.ts index 8ba5d93ba0..361946f615 100644 --- a/server/src/domain/asset/asset.service.spec.ts +++ b/server/src/domain/asset/asset.service.spec.ts @@ -15,6 +15,8 @@ import { newStorageRepositoryMock, newSystemConfigRepositoryMock, newUserRepositoryMock, + partnerStub, + userStub, } from '@test'; import { when } from 'jest-when'; import { JobName } from '../job'; @@ -317,6 +319,7 @@ describe(AssetService.name, () => { }); it('should set the title correctly', async () => { + partnerMock.getAll.mockResolvedValue([]); assetMock.getByDayOfYear.mockResolvedValue([assetStub.image, assetStub.imageFrom2015]); await expect(sut.getMemoryLane(authStub.admin, { day: 15, month: 1 })).resolves.toEqual([ @@ -324,7 +327,17 @@ describe(AssetService.name, () => { { title: '9 years since...', assets: [mapAsset(assetStub.imageFrom2015)] }, ]); - expect(assetMock.getByDayOfYear.mock.calls).toEqual([[authStub.admin.user.id, { day: 15, month: 1 }]]); + expect(assetMock.getByDayOfYear.mock.calls).toEqual([[[authStub.admin.user.id], { day: 15, month: 1 }]]); + }); + + it('should get memories with partners with inTimeline enabled', async () => { + partnerMock.getAll.mockResolvedValue([partnerStub.user1ToAdmin1]); + + await sut.getMemoryLane(authStub.admin, { day: 15, month: 1 }); + + expect(assetMock.getByDayOfYear.mock.calls).toEqual([ + [[authStub.admin.user.id, userStub.user1.id], { day: 15, month: 1 }], + ]); }); }); diff --git a/server/src/domain/asset/asset.service.ts b/server/src/domain/asset/asset.service.ts index 857f1648fa..e54eb84391 100644 --- a/server/src/domain/asset/asset.service.ts +++ b/server/src/domain/asset/asset.service.ts @@ -172,7 +172,16 @@ export class AssetService { async getMemoryLane(auth: AuthDto, dto: MemoryLaneDto): Promise { const currentYear = new Date().getFullYear(); - const assets = await this.assetRepository.getByDayOfYear(auth.user.id, dto); + + // get partners id + const userIds: string[] = [auth.user.id]; + const partners = await this.partnerRepository.getAll(auth.user.id); + const partnersIds = partners + .filter((partner) => partner.sharedBy && partner.inTimeline) + .map((partner) => partner.sharedById); + userIds.push(...partnersIds); + + const assets = await this.assetRepository.getByDayOfYear(userIds, dto); return _.chain(assets) .filter((asset) => asset.localDateTime.getFullYear() < currentYear) diff --git a/server/src/domain/repositories/asset.repository.ts b/server/src/domain/repositories/asset.repository.ts index 8b14ce597e..c4ddb31076 100644 --- a/server/src/domain/repositories/asset.repository.ts +++ b/server/src/domain/repositories/asset.repository.ts @@ -123,7 +123,7 @@ export interface IAssetRepository { select?: FindOptionsSelect, ): Promise; getByIdsWithAllRelations(ids: string[]): Promise; - getByDayOfYear(ownerId: string, monthDay: MonthDay): Promise; + getByDayOfYear(ownerIds: string[], monthDay: MonthDay): Promise; getByChecksum(userId: string, checksum: Buffer): Promise; getByAlbumId(pagination: PaginationOptions, albumId: string): Paginated; getByUserId(pagination: PaginationOptions, userId: string, options?: AssetSearchOptions): Paginated; diff --git a/server/src/infra/repositories/asset.repository.ts b/server/src/infra/repositories/asset.repository.ts index 871a44460b..09cf2c7794 100644 --- a/server/src/infra/repositories/asset.repository.ts +++ b/server/src/infra/repositories/asset.repository.ts @@ -109,18 +109,18 @@ export class AssetRepository implements IAssetRepository { } @GenerateSql({ params: [DummyValue.UUID, { day: 1, month: 1 }] }) - getByDayOfYear(ownerId: string, { day, month }: MonthDay): Promise { + getByDayOfYear(ownerIds: string[], { day, month }: MonthDay): Promise { return this.repository .createQueryBuilder('entity') .where( - `entity.ownerId = :ownerId + `entity.ownerId IN (:...ownerIds) AND entity.isVisible = true AND entity.isArchived = false AND entity.resizePath IS NOT NULL AND EXTRACT(DAY FROM entity.localDateTime AT TIME ZONE 'UTC') = :day AND EXTRACT(MONTH FROM entity.localDateTime AT TIME ZONE 'UTC') = :month`, { - ownerId, + ownerIds, day, month, }, diff --git a/server/src/infra/sql/asset.repository.sql b/server/src/infra/sql/asset.repository.sql index 39f46e0d0d..e230a73464 100644 --- a/server/src/infra/sql/asset.repository.sql +++ b/server/src/infra/sql/asset.repository.sql @@ -76,89 +76,6 @@ WHERE ORDER BY "AssetEntity"."fileCreatedAt" DESC --- AssetRepository.getByDayOfYear -SELECT - "entity"."id" AS "entity_id", - "entity"."deviceAssetId" AS "entity_deviceAssetId", - "entity"."ownerId" AS "entity_ownerId", - "entity"."libraryId" AS "entity_libraryId", - "entity"."deviceId" AS "entity_deviceId", - "entity"."type" AS "entity_type", - "entity"."originalPath" AS "entity_originalPath", - "entity"."resizePath" AS "entity_resizePath", - "entity"."webpPath" AS "entity_webpPath", - "entity"."thumbhash" AS "entity_thumbhash", - "entity"."encodedVideoPath" AS "entity_encodedVideoPath", - "entity"."createdAt" AS "entity_createdAt", - "entity"."updatedAt" AS "entity_updatedAt", - "entity"."deletedAt" AS "entity_deletedAt", - "entity"."fileCreatedAt" AS "entity_fileCreatedAt", - "entity"."localDateTime" AS "entity_localDateTime", - "entity"."fileModifiedAt" AS "entity_fileModifiedAt", - "entity"."isFavorite" AS "entity_isFavorite", - "entity"."isArchived" AS "entity_isArchived", - "entity"."isExternal" AS "entity_isExternal", - "entity"."isReadOnly" AS "entity_isReadOnly", - "entity"."isOffline" AS "entity_isOffline", - "entity"."checksum" AS "entity_checksum", - "entity"."duration" AS "entity_duration", - "entity"."isVisible" AS "entity_isVisible", - "entity"."livePhotoVideoId" AS "entity_livePhotoVideoId", - "entity"."originalFileName" AS "entity_originalFileName", - "entity"."sidecarPath" AS "entity_sidecarPath", - "entity"."stackId" AS "entity_stackId", - "exifInfo"."assetId" AS "exifInfo_assetId", - "exifInfo"."description" AS "exifInfo_description", - "exifInfo"."exifImageWidth" AS "exifInfo_exifImageWidth", - "exifInfo"."exifImageHeight" AS "exifInfo_exifImageHeight", - "exifInfo"."fileSizeInByte" AS "exifInfo_fileSizeInByte", - "exifInfo"."orientation" AS "exifInfo_orientation", - "exifInfo"."dateTimeOriginal" AS "exifInfo_dateTimeOriginal", - "exifInfo"."modifyDate" AS "exifInfo_modifyDate", - "exifInfo"."timeZone" AS "exifInfo_timeZone", - "exifInfo"."latitude" AS "exifInfo_latitude", - "exifInfo"."longitude" AS "exifInfo_longitude", - "exifInfo"."projectionType" AS "exifInfo_projectionType", - "exifInfo"."city" AS "exifInfo_city", - "exifInfo"."livePhotoCID" AS "exifInfo_livePhotoCID", - "exifInfo"."autoStackId" AS "exifInfo_autoStackId", - "exifInfo"."state" AS "exifInfo_state", - "exifInfo"."country" AS "exifInfo_country", - "exifInfo"."make" AS "exifInfo_make", - "exifInfo"."model" AS "exifInfo_model", - "exifInfo"."lensModel" AS "exifInfo_lensModel", - "exifInfo"."fNumber" AS "exifInfo_fNumber", - "exifInfo"."focalLength" AS "exifInfo_focalLength", - "exifInfo"."iso" AS "exifInfo_iso", - "exifInfo"."exposureTime" AS "exifInfo_exposureTime", - "exifInfo"."profileDescription" AS "exifInfo_profileDescription", - "exifInfo"."colorspace" AS "exifInfo_colorspace", - "exifInfo"."bitsPerSample" AS "exifInfo_bitsPerSample", - "exifInfo"."fps" AS "exifInfo_fps" -FROM - "assets" "entity" - LEFT JOIN "exif" "exifInfo" ON "exifInfo"."assetId" = "entity"."id" -WHERE - ( - "entity"."ownerId" = $1 - AND "entity"."isVisible" = true - AND "entity"."isArchived" = false - AND "entity"."resizePath" IS NOT NULL - AND EXTRACT( - DAY - FROM - "entity"."localDateTime" AT TIME ZONE 'UTC' - ) = $2 - AND EXTRACT( - MONTH - FROM - "entity"."localDateTime" AT TIME ZONE 'UTC' - ) = $3 - ) - AND ("entity"."deletedAt" IS NULL) -ORDER BY - "entity"."localDateTime" DESC - -- AssetRepository.getByIds SELECT "AssetEntity"."id" AS "AssetEntity_id",