mirror of
https://github.com/immich-app/immich.git
synced 2026-03-22 20:39:58 +03:00
fix: missing deletedAt and isVisible columns on mobile (#26414)
* feat: SyncAssetV2 * feat: mobile sync handling * feat: request correct sync object based on server version * fix: mobile queries * chore: sync sql * fix: test * chore: switch to mapper * fix: sql sync
This commit is contained in:
@@ -422,6 +422,20 @@ export class SyncAssetFaceV1 {
|
||||
sourceType!: string;
|
||||
}
|
||||
|
||||
@ExtraModel()
|
||||
export class SyncAssetFaceV2 extends SyncAssetFaceV1 {
|
||||
@ApiProperty({ description: 'Face deleted at' })
|
||||
deletedAt!: Date | null;
|
||||
@ApiProperty({ description: 'Is the face visible in the asset' })
|
||||
isVisible!: boolean;
|
||||
}
|
||||
|
||||
export function syncAssetFaceV2ToV1(faceV2: SyncAssetFaceV2): SyncAssetFaceV1 {
|
||||
const { deletedAt: _, isVisible: __, ...faceV1 } = faceV2;
|
||||
|
||||
return faceV1;
|
||||
}
|
||||
|
||||
@ExtraModel()
|
||||
export class SyncAssetFaceDeleteV1 {
|
||||
@ApiProperty({ description: 'Asset face ID' })
|
||||
@@ -497,6 +511,7 @@ export type SyncItem = {
|
||||
[SyncEntityType.PersonV1]: SyncPersonV1;
|
||||
[SyncEntityType.PersonDeleteV1]: SyncPersonDeleteV1;
|
||||
[SyncEntityType.AssetFaceV1]: SyncAssetFaceV1;
|
||||
[SyncEntityType.AssetFaceV2]: SyncAssetFaceV2;
|
||||
[SyncEntityType.AssetFaceDeleteV1]: SyncAssetFaceDeleteV1;
|
||||
[SyncEntityType.UserMetadataV1]: SyncUserMetadataV1;
|
||||
[SyncEntityType.UserMetadataDeleteV1]: SyncUserMetadataDeleteV1;
|
||||
|
||||
@@ -732,6 +732,7 @@ export enum SyncRequestType {
|
||||
UsersV1 = 'UsersV1',
|
||||
PeopleV1 = 'PeopleV1',
|
||||
AssetFacesV1 = 'AssetFacesV1',
|
||||
AssetFacesV2 = 'AssetFacesV2',
|
||||
UserMetadataV1 = 'UserMetadataV1',
|
||||
}
|
||||
|
||||
@@ -790,6 +791,7 @@ export enum SyncEntityType {
|
||||
PersonDeleteV1 = 'PersonDeleteV1',
|
||||
|
||||
AssetFaceV1 = 'AssetFaceV1',
|
||||
AssetFaceV2 = 'AssetFaceV2',
|
||||
AssetFaceDeleteV1 = 'AssetFaceDeleteV1',
|
||||
|
||||
UserMetadataV1 = 'UserMetadataV1',
|
||||
|
||||
@@ -540,6 +540,8 @@ select
|
||||
"boundingBoxX2",
|
||||
"boundingBoxY2",
|
||||
"sourceType",
|
||||
"isVisible",
|
||||
"asset_face"."deletedAt",
|
||||
"asset_face"."updateId"
|
||||
from
|
||||
"asset_face" as "asset_face"
|
||||
|
||||
@@ -479,6 +479,8 @@ class AssetFaceSync extends BaseSync {
|
||||
'boundingBoxX2',
|
||||
'boundingBoxY2',
|
||||
'sourceType',
|
||||
'isVisible',
|
||||
'asset_face.deletedAt',
|
||||
'asset_face.updateId',
|
||||
])
|
||||
.leftJoin('asset', 'asset.id', 'asset_face.assetId')
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
AssetFullSyncDto,
|
||||
SyncAckDeleteDto,
|
||||
SyncAckSetDto,
|
||||
syncAssetFaceV2ToV1,
|
||||
SyncAssetV1,
|
||||
SyncItem,
|
||||
SyncStreamDto,
|
||||
@@ -85,6 +86,7 @@ export const SYNC_TYPES_ORDER = [
|
||||
SyncRequestType.MemoryToAssetsV1,
|
||||
SyncRequestType.PeopleV1,
|
||||
SyncRequestType.AssetFacesV1,
|
||||
SyncRequestType.AssetFacesV2,
|
||||
SyncRequestType.UserMetadataV1,
|
||||
SyncRequestType.AssetMetadataV1,
|
||||
];
|
||||
@@ -189,6 +191,7 @@ export class SyncService extends BaseService {
|
||||
[SyncRequestType.PartnerStacksV1]: () => this.syncPartnerStackV1(options, response, checkpointMap, session.id),
|
||||
[SyncRequestType.PeopleV1]: () => this.syncPeopleV1(options, response, checkpointMap),
|
||||
[SyncRequestType.AssetFacesV1]: async () => this.syncAssetFacesV1(options, response, checkpointMap),
|
||||
[SyncRequestType.AssetFacesV2]: async () => this.syncAssetFacesV2(options, response, checkpointMap),
|
||||
[SyncRequestType.UserMetadataV1]: () => this.syncUserMetadataV1(options, response, checkpointMap),
|
||||
};
|
||||
|
||||
@@ -789,6 +792,21 @@ export class SyncService extends BaseService {
|
||||
|
||||
const upsertType = SyncEntityType.AssetFaceV1;
|
||||
const upserts = this.syncRepository.assetFace.getUpserts({ ...options, ack: checkpointMap[upsertType] });
|
||||
for await (const { updateId, ...data } of upserts) {
|
||||
const v1 = syncAssetFaceV2ToV1(data);
|
||||
send(response, { type: upsertType, ids: [updateId], data: v1 });
|
||||
}
|
||||
}
|
||||
|
||||
private async syncAssetFacesV2(options: SyncQueryOptions, response: Writable, checkpointMap: CheckpointMap) {
|
||||
const deleteType = SyncEntityType.AssetFaceDeleteV1;
|
||||
const deletes = this.syncRepository.assetFace.getDeletes({ ...options, ack: checkpointMap[deleteType] });
|
||||
for await (const { id, ...data } of deletes) {
|
||||
send(response, { type: deleteType, ids: [id], data });
|
||||
}
|
||||
|
||||
const upsertType = SyncEntityType.AssetFaceV2;
|
||||
const upserts = this.syncRepository.assetFace.getUpserts({ ...options, ack: checkpointMap[upsertType] });
|
||||
for await (const { updateId, ...data } of upserts) {
|
||||
send(response, { type: upsertType, ids: [updateId], data });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user