diff --git a/server/apps/microservices/src/processors/metadata-extraction.processor.ts b/server/apps/microservices/src/processors/metadata-extraction.processor.ts index a6b6d11e70..82975d80f2 100644 --- a/server/apps/microservices/src/processors/metadata-extraction.processor.ts +++ b/server/apps/microservices/src/processors/metadata-extraction.processor.ts @@ -229,7 +229,12 @@ export class MetadataExtractionProcessor { newExif.livePhotoCID = exifData?.MediaGroupUUID || null; if (newExif.livePhotoCID && !asset.livePhotoVideoId) { - const motionAsset = await this.assetCore.findLivePhotoMatch(newExif.livePhotoCID, asset.id, AssetType.VIDEO); + const motionAsset = await this.assetCore.findLivePhotoMatch({ + livePhotoCID: newExif.livePhotoCID, + otherAssetId: asset.id, + ownerId: asset.ownerId, + type: AssetType.VIDEO, + }); if (motionAsset) { await this.assetCore.save({ id: asset.id, livePhotoVideoId: motionAsset.id }); await this.assetCore.save({ id: motionAsset.id, isVisible: false }); @@ -331,7 +336,12 @@ export class MetadataExtractionProcessor { newExif.livePhotoCID = exifData?.ContentIdentifier || null; if (newExif.livePhotoCID) { - const photoAsset = await this.assetCore.findLivePhotoMatch(newExif.livePhotoCID, asset.id, AssetType.IMAGE); + const photoAsset = await this.assetCore.findLivePhotoMatch({ + livePhotoCID: newExif.livePhotoCID, + ownerId: asset.ownerId, + otherAssetId: asset.id, + type: AssetType.IMAGE, + }); if (photoAsset) { await this.assetCore.save({ id: photoAsset.id, livePhotoVideoId: asset.id }); await this.assetCore.save({ id: asset.id, isVisible: false }); diff --git a/server/libs/domain/src/asset/asset.core.ts b/server/libs/domain/src/asset/asset.core.ts index 308cbd48f6..13eff52e87 100644 --- a/server/libs/domain/src/asset/asset.core.ts +++ b/server/libs/domain/src/asset/asset.core.ts @@ -1,6 +1,6 @@ -import { AssetEntity, AssetType } from '@app/infra/entities'; +import { AssetEntity } from '@app/infra/entities'; import { IJobRepository, JobName } from '../job'; -import { AssetSearchOptions, IAssetRepository } from './asset.repository'; +import { AssetSearchOptions, IAssetRepository, LivePhotoSearchOptions } from './asset.repository'; export class AssetCore { constructor(private assetRepository: IAssetRepository, private jobRepository: IJobRepository) {} @@ -18,7 +18,7 @@ export class AssetCore { return _asset; } - findLivePhotoMatch(livePhotoCID: string, otherAssetId: string, type: AssetType): Promise { - return this.assetRepository.findLivePhotoMatch(livePhotoCID, otherAssetId, type); + findLivePhotoMatch(options: LivePhotoSearchOptions): Promise { + return this.assetRepository.findLivePhotoMatch(options); } } diff --git a/server/libs/domain/src/asset/asset.repository.ts b/server/libs/domain/src/asset/asset.repository.ts index c8ab4dd155..0df1a40ee8 100644 --- a/server/libs/domain/src/asset/asset.repository.ts +++ b/server/libs/domain/src/asset/asset.repository.ts @@ -5,6 +5,13 @@ export interface AssetSearchOptions { type?: AssetType; } +export interface LivePhotoSearchOptions { + ownerId: string; + livePhotoCID: string; + otherAssetId: string; + type: AssetType; +} + export enum WithoutProperty { THUMBNAIL = 'thumbnail', ENCODED_VIDEO = 'encoded-video', @@ -22,5 +29,5 @@ export interface IAssetRepository { deleteAll(ownerId: string): Promise; getAll(options?: AssetSearchOptions): Promise; save(asset: Partial): Promise; - findLivePhotoMatch(livePhotoCID: string, otherAssetId: string, type: AssetType): Promise; + findLivePhotoMatch(options: LivePhotoSearchOptions): Promise; } diff --git a/server/libs/infra/src/repositories/asset.repository.ts b/server/libs/infra/src/repositories/asset.repository.ts index 4bbaf1ae51..4861b9c4e2 100644 --- a/server/libs/infra/src/repositories/asset.repository.ts +++ b/server/libs/infra/src/repositories/asset.repository.ts @@ -1,4 +1,4 @@ -import { AssetSearchOptions, IAssetRepository, WithoutProperty } from '@app/domain'; +import { AssetSearchOptions, IAssetRepository, LivePhotoSearchOptions, WithoutProperty } from '@app/domain'; import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { FindOptionsRelations, FindOptionsWhere, In, IsNull, Not, Repository } from 'typeorm'; @@ -52,10 +52,13 @@ export class AssetRepository implements IAssetRepository { }); } - findLivePhotoMatch(livePhotoCID: string, otherAssetId: string, type: AssetType): Promise { + findLivePhotoMatch(options: LivePhotoSearchOptions): Promise { + const { ownerId, otherAssetId, livePhotoCID, type } = options; + return this.repository.findOne({ where: { id: Not(otherAssetId), + ownerId, type, exifInfo: { livePhotoCID,