feat(server): visibility column (#17939)

* feat: private view

* pr feedback

* sql generation

* feat: visibility column

* fix: set visibility value as the same as the still part after unlinked live photos

* fix: test

* pr feedback
This commit is contained in:
Alex
2025-05-06 12:12:48 -05:00
committed by GitHub
parent 016d7a6ceb
commit d33ce13561
90 changed files with 1137 additions and 867 deletions
+9 -5
View File
@@ -14,6 +14,7 @@ import { AssetFaces, Exif, Person } from 'src/db';
import { OnEvent, OnJob } from 'src/decorators';
import {
AssetType,
AssetVisibility,
DatabaseLock,
ExifOrientation,
ImmichWorker,
@@ -156,7 +157,7 @@ export class MetadataService extends BaseService {
const [photoAsset, motionAsset] = asset.type === AssetType.IMAGE ? [asset, match] : [match, asset];
await Promise.all([
this.assetRepository.update({ id: photoAsset.id, livePhotoVideoId: motionAsset.id }),
this.assetRepository.update({ id: motionAsset.id, isVisible: false }),
this.assetRepository.update({ id: motionAsset.id, visibility: AssetVisibility.HIDDEN }),
this.albumRepository.removeAsset(motionAsset.id),
]);
@@ -527,8 +528,11 @@ export class MetadataService extends BaseService {
});
// Hide the motion photo video asset if it's not already hidden to prepare for linking
if (motionAsset.isVisible) {
await this.assetRepository.update({ id: motionAsset.id, isVisible: false });
if (motionAsset.visibility === AssetVisibility.TIMELINE) {
await this.assetRepository.update({
id: motionAsset.id,
visibility: AssetVisibility.HIDDEN,
});
this.logger.log(`Hid unlinked motion photo video asset (${motionAsset.id})`);
}
} else {
@@ -544,7 +548,7 @@ export class MetadataService extends BaseService {
ownerId: asset.ownerId,
originalPath: StorageCore.getAndroidMotionPath(asset, motionAssetId),
originalFileName: `${path.parse(asset.originalFileName).name}.mp4`,
isVisible: false,
visibility: AssetVisibility.HIDDEN,
deviceAssetId: 'NONE',
deviceId: 'NONE',
});
@@ -863,7 +867,7 @@ export class MetadataService extends BaseService {
return JobStatus.FAILED;
}
if (!isSync && (!asset.isVisible || asset.sidecarPath) && !asset.isExternal) {
if (!isSync && (asset.visibility === AssetVisibility.HIDDEN || asset.sidecarPath) && !asset.isExternal) {
return JobStatus.FAILED;
}