From 4c9ac82fdcff34eb7464ff68756d6e5f9e82fff1 Mon Sep 17 00:00:00 2001 From: Alex Tran Date: Wed, 21 Feb 2024 12:38:31 -0600 Subject: [PATCH 1/6] fix(server): stack info in asset response for mobile --- server/src/domain/repositories/search.repository.ts | 4 +++- server/src/immich/api-v1/asset/asset.service.ts | 12 ++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/server/src/domain/repositories/search.repository.ts b/server/src/domain/repositories/search.repository.ts index 7183e9e3fe26..50dc46c9d41b 100644 --- a/server/src/domain/repositories/search.repository.ts +++ b/server/src/domain/repositories/search.repository.ts @@ -157,7 +157,9 @@ type BaseAssetSearchOptions = SearchDateOptions & export type AssetSearchOptions = BaseAssetSearchOptions & SearchRelationOptions; -export type AssetSearchOneToOneRelationOptions = BaseAssetSearchOptions & SearchOneToOneRelationOptions; +export type AssetSearchOneToOneRelationOptions = BaseAssetSearchOptions & + SearchOneToOneRelationOptions & + SearchRelationOptions; export type AssetSearchBuilderOptions = Omit; diff --git a/server/src/immich/api-v1/asset/asset.service.ts b/server/src/immich/api-v1/asset/asset.service.ts index 17488016c9f8..f8a56dc8c556 100644 --- a/server/src/immich/api-v1/asset/asset.service.ts +++ b/server/src/immich/api-v1/asset/asset.service.ts @@ -116,9 +116,17 @@ export class AssetService { await this.access.requirePermission(auth, Permission.TIMELINE_READ, userId); const assets = await this.assetRepository.getAllByFileCreationDate( { take: dto.take ?? 1000, skip: dto.skip }, - { ...dto, userIds: [userId], withDeleted: true, orderDirection: 'DESC', withExif: true, isVisible: true }, + { + ...dto, + userIds: [userId], + withDeleted: true, + orderDirection: 'DESC', + withExif: true, + isVisible: true, + withStacked: true, + }, ); - return assets.items.map((asset) => mapAsset(asset)); + return assets.items.map((asset) => mapAsset(asset, { withStack: true })); } async serveThumbnail(auth: AuthDto, assetId: string, dto: GetAssetThumbnailDto): Promise { From 7d51fba1c0b16fe0cb65155d26b22668b2f70173 Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 21 Feb 2024 16:27:09 -0600 Subject: [PATCH 2/6] log to track --- mobile/lib/shared/services/asset.service.dart | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/mobile/lib/shared/services/asset.service.dart b/mobile/lib/shared/services/asset.service.dart index 64a0f28ab7d3..66ef080239f9 100644 --- a/mobile/lib/shared/services/asset.service.dart +++ b/mobile/lib/shared/services/asset.service.dart @@ -58,11 +58,19 @@ class AssetService { final assetDto = await _apiService.assetApi .getAllAssets(userId: user.id, updatedAfter: since); if (assetDto == null) return (null, null); + + print("AssetDto length: ${assetDto.length} "); + for (final e in assetDto) { + print("AssetDto: ${e.stackParentId}"); + var b = Asset.remote(e); + print("Mapped asset ${b.stackParentId}"); + } return (assetDto.map(Asset.remote).toList(), deleted.ids); } /// Returns `null` if the server state did not change, else list of assets Future?> _getRemoteAssets(User user) async { + print("GTE REMOTE ASSETS"); const int chunkSize = 10000; try { final DateTime now = DateTime.now().toUtc(); @@ -82,6 +90,13 @@ class AssetService { if (assets == null) { return null; } + + print("get remote asset"); + assets.map((e) { + if (e.stackParentId != null) { + print("Stack Parent Id: $e"); + } + }); allAssets.addAll(assets.map(Asset.remote)); if (assets.length < chunkSize) { break; From 692b8b189a9f50b8cb1b1acb3f210583561b22b9 Mon Sep 17 00:00:00 2001 From: Alex Tran Date: Wed, 21 Feb 2024 22:12:50 -0600 Subject: [PATCH 3/6] fixed --- mobile/.fvm/release | 1 + mobile/.fvm/version | 1 + mobile/.fvm/versions/3.13.6 | 1 + mobile/lib/shared/models/asset.dart | 6 +++--- mobile/lib/shared/services/asset.service.dart | 5 +++++ 5 files changed, 11 insertions(+), 3 deletions(-) create mode 100644 mobile/.fvm/release create mode 100644 mobile/.fvm/version create mode 120000 mobile/.fvm/versions/3.13.6 diff --git a/mobile/.fvm/release b/mobile/.fvm/release new file mode 100644 index 000000000000..78472f99752d --- /dev/null +++ b/mobile/.fvm/release @@ -0,0 +1 @@ +3.13.6 \ No newline at end of file diff --git a/mobile/.fvm/version b/mobile/.fvm/version new file mode 100644 index 000000000000..78472f99752d --- /dev/null +++ b/mobile/.fvm/version @@ -0,0 +1 @@ +3.13.6 \ No newline at end of file diff --git a/mobile/.fvm/versions/3.13.6 b/mobile/.fvm/versions/3.13.6 new file mode 120000 index 000000000000..055a33fd3fa1 --- /dev/null +++ b/mobile/.fvm/versions/3.13.6 @@ -0,0 +1 @@ +C:/Users/alext/fvm/versions/3.13.6 \ No newline at end of file diff --git a/mobile/lib/shared/models/asset.dart b/mobile/lib/shared/models/asset.dart index afd49adc6a9b..5be514ee5b90 100644 --- a/mobile/lib/shared/models/asset.dart +++ b/mobile/lib/shared/models/asset.dart @@ -37,7 +37,7 @@ class Asset { // workaround to nullify stackParentId for the parent asset until we refactor the mobile app // stack handling to properly handle it stackParentId = - remote.stackParentId == remote.id ? null : remote.stackParentId, + remote.stackParentId == remote.id ? remote.stackParentId : null, stackCount = remote.stackCount; Asset.local(AssetEntity local, List hash) @@ -309,7 +309,7 @@ class Asset { livePhotoVideoId: livePhotoVideoId, // workaround to nullify stackParentId for the parent asset until we refactor the mobile app // stack handling to properly handle it - stackParentId: stackParentId == remoteId ? null : stackParentId, + stackParentId: stackParentId == remoteId ? stackParentId : null, stackCount: stackCount, isFavorite: isFavorite, isArchived: isArchived, @@ -329,7 +329,7 @@ class Asset { livePhotoVideoId: a.livePhotoVideoId, // workaround to nullify stackParentId for the parent asset until we refactor the mobile app // stack handling to properly handle it - stackParentId: a.stackParentId == a.remoteId ? null : a.stackParentId, + stackParentId: a.stackParentId == a.remoteId ? a.stackParentId : null, stackCount: a.stackCount, // isFavorite + isArchived are not set by device-only assets isFavorite: a.isFavorite, diff --git a/mobile/lib/shared/services/asset.service.dart b/mobile/lib/shared/services/asset.service.dart index 66ef080239f9..d9ede048a129 100644 --- a/mobile/lib/shared/services/asset.service.dart +++ b/mobile/lib/shared/services/asset.service.dart @@ -63,6 +63,11 @@ class AssetService { for (final e in assetDto) { print("AssetDto: ${e.stackParentId}"); var b = Asset.remote(e); + print("e.stackParentId ${e.stackParentId}"); + print("e.id ${e.id}"); + print( + "e.stackParentId == e.id ? null : e.stackParentId, ${e.stackParentId == e.id ? null : e.stackParentId}", + ); print("Mapped asset ${b.stackParentId}"); } return (assetDto.map(Asset.remote).toList(), deleted.ids); From 2d95715ae8911441580c14fa2cd38b7da478223f Mon Sep 17 00:00:00 2001 From: Alex Tran Date: Wed, 21 Feb 2024 22:18:53 -0600 Subject: [PATCH 4/6] revert --- mobile/ios/Podfile.lock | 2 +- mobile/lib/shared/models/asset.dart | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mobile/ios/Podfile.lock b/mobile/ios/Podfile.lock index a9ac5b33817e..6081988b7aaf 100644 --- a/mobile/ios/Podfile.lock +++ b/mobile/ios/Podfile.lock @@ -180,4 +180,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: 64c9b5291666c0ca3caabdfe9865c141ac40321d -COCOAPODS: 1.12.1 +COCOAPODS: 1.11.3 diff --git a/mobile/lib/shared/models/asset.dart b/mobile/lib/shared/models/asset.dart index 5be514ee5b90..afd49adc6a9b 100644 --- a/mobile/lib/shared/models/asset.dart +++ b/mobile/lib/shared/models/asset.dart @@ -37,7 +37,7 @@ class Asset { // workaround to nullify stackParentId for the parent asset until we refactor the mobile app // stack handling to properly handle it stackParentId = - remote.stackParentId == remote.id ? remote.stackParentId : null, + remote.stackParentId == remote.id ? null : remote.stackParentId, stackCount = remote.stackCount; Asset.local(AssetEntity local, List hash) @@ -309,7 +309,7 @@ class Asset { livePhotoVideoId: livePhotoVideoId, // workaround to nullify stackParentId for the parent asset until we refactor the mobile app // stack handling to properly handle it - stackParentId: stackParentId == remoteId ? stackParentId : null, + stackParentId: stackParentId == remoteId ? null : stackParentId, stackCount: stackCount, isFavorite: isFavorite, isArchived: isArchived, @@ -329,7 +329,7 @@ class Asset { livePhotoVideoId: a.livePhotoVideoId, // workaround to nullify stackParentId for the parent asset until we refactor the mobile app // stack handling to properly handle it - stackParentId: a.stackParentId == a.remoteId ? a.stackParentId : null, + stackParentId: a.stackParentId == a.remoteId ? null : a.stackParentId, stackCount: a.stackCount, // isFavorite + isArchived are not set by device-only assets isFavorite: a.isFavorite, From d51a666692607ebc06e8c565609ca7e41c6cca1a Mon Sep 17 00:00:00 2001 From: Alex Tran Date: Thu, 22 Feb 2024 09:10:58 -0600 Subject: [PATCH 5/6] revert --- mobile/lib/shared/models/asset.dart | 6 +++--- mobile/lib/shared/services/asset.service.dart | 7 ------- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/mobile/lib/shared/models/asset.dart b/mobile/lib/shared/models/asset.dart index 5be514ee5b90..afd49adc6a9b 100644 --- a/mobile/lib/shared/models/asset.dart +++ b/mobile/lib/shared/models/asset.dart @@ -37,7 +37,7 @@ class Asset { // workaround to nullify stackParentId for the parent asset until we refactor the mobile app // stack handling to properly handle it stackParentId = - remote.stackParentId == remote.id ? remote.stackParentId : null, + remote.stackParentId == remote.id ? null : remote.stackParentId, stackCount = remote.stackCount; Asset.local(AssetEntity local, List hash) @@ -309,7 +309,7 @@ class Asset { livePhotoVideoId: livePhotoVideoId, // workaround to nullify stackParentId for the parent asset until we refactor the mobile app // stack handling to properly handle it - stackParentId: stackParentId == remoteId ? stackParentId : null, + stackParentId: stackParentId == remoteId ? null : stackParentId, stackCount: stackCount, isFavorite: isFavorite, isArchived: isArchived, @@ -329,7 +329,7 @@ class Asset { livePhotoVideoId: a.livePhotoVideoId, // workaround to nullify stackParentId for the parent asset until we refactor the mobile app // stack handling to properly handle it - stackParentId: a.stackParentId == a.remoteId ? a.stackParentId : null, + stackParentId: a.stackParentId == a.remoteId ? null : a.stackParentId, stackCount: a.stackCount, // isFavorite + isArchived are not set by device-only assets isFavorite: a.isFavorite, diff --git a/mobile/lib/shared/services/asset.service.dart b/mobile/lib/shared/services/asset.service.dart index d9ede048a129..7710a500a040 100644 --- a/mobile/lib/shared/services/asset.service.dart +++ b/mobile/lib/shared/services/asset.service.dart @@ -75,7 +75,6 @@ class AssetService { /// Returns `null` if the server state did not change, else list of assets Future?> _getRemoteAssets(User user) async { - print("GTE REMOTE ASSETS"); const int chunkSize = 10000; try { final DateTime now = DateTime.now().toUtc(); @@ -96,12 +95,6 @@ class AssetService { return null; } - print("get remote asset"); - assets.map((e) { - if (e.stackParentId != null) { - print("Stack Parent Id: $e"); - } - }); allAssets.addAll(assets.map(Asset.remote)); if (assets.length < chunkSize) { break; From 26c3635291e9479e0bb6e931228c618ff28644d9 Mon Sep 17 00:00:00 2001 From: Alex Tran Date: Thu, 22 Feb 2024 09:20:16 -0600 Subject: [PATCH 6/6] Revert "fix(server): on_asset_update event sends varying data types (#7179)" This reverts commit 4b46bb49d7e2e73054693c203b5292cdbafe9e9a. --- .../shared/providers/websocket.provider.dart | 1 - server/src/domain/asset/asset.service.spec.ts | 2 +- server/src/domain/asset/asset.service.ts | 8 ++----- .../repositories/communication.repository.ts | 21 ++----------------- .../src/domain/server-info/server-info.dto.ts | 10 +-------- web/src/lib/stores/websocket.ts | 1 - 6 files changed, 6 insertions(+), 37 deletions(-) diff --git a/mobile/lib/shared/providers/websocket.provider.dart b/mobile/lib/shared/providers/websocket.provider.dart index 89f99dc6df49..c0c11c761c36 100644 --- a/mobile/lib/shared/providers/websocket.provider.dart +++ b/mobile/lib/shared/providers/websocket.provider.dart @@ -162,7 +162,6 @@ class WebsocketNotifier extends StateNotifier { socket.on('on_asset_trash', _handleServerUpdates); socket.on('on_asset_restore', _handleServerUpdates); socket.on('on_asset_update', _handleServerUpdates); - socket.on('on_asset_stack_update', _handleServerUpdates); socket.on('on_asset_hidden', _handleOnAssetHidden); socket.on('on_new_release', _handleReleaseUpdates); } catch (e) { diff --git a/server/src/domain/asset/asset.service.spec.ts b/server/src/domain/asset/asset.service.spec.ts index 9f077835a50a..d8f24dec674b 100644 --- a/server/src/domain/asset/asset.service.spec.ts +++ b/server/src/domain/asset/asset.service.spec.ts @@ -706,7 +706,7 @@ describe(AssetService.name, () => { stackParentId: 'parent', }); - expect(communicationMock.send).toHaveBeenCalledWith(ClientEvent.ASSET_STACK_UPDATE, authStub.user1.user.id, [ + expect(communicationMock.send).toHaveBeenCalledWith(ClientEvent.ASSET_UPDATE, authStub.user1.user.id, [ 'asset-1', 'parent', ]); diff --git a/server/src/domain/asset/asset.service.ts b/server/src/domain/asset/asset.service.ts index f328b5dcf683..8cdef5e297ff 100644 --- a/server/src/domain/asset/asset.service.ts +++ b/server/src/domain/asset/asset.service.ts @@ -381,7 +381,7 @@ export class AssetService { .flatMap((stack) => (stack ? [stack] : [])) .filter((stack) => stack.assets.length < 2); await Promise.all(stacksToDelete.map((as) => this.assetStackRepository.delete(as.id))); - this.communicationRepository.send(ClientEvent.ASSET_STACK_UPDATE, auth.user.id, ids); + this.communicationRepository.send(ClientEvent.ASSET_UPDATE, auth.user.id, ids); } async handleAssetDeletionCheck() { @@ -499,11 +499,7 @@ export class AssetService { primaryAssetId: newParentId, }); - this.communicationRepository.send(ClientEvent.ASSET_STACK_UPDATE, auth.user.id, [ - ...childIds, - newParentId, - oldParentId, - ]); + this.communicationRepository.send(ClientEvent.ASSET_UPDATE, auth.user.id, [...childIds, newParentId, oldParentId]); await this.assetRepository.updateAll([oldParentId, newParentId, ...childIds], { updatedAt: new Date() }); } diff --git a/server/src/domain/repositories/communication.repository.ts b/server/src/domain/repositories/communication.repository.ts index daf0aef0a4bd..29617f031079 100644 --- a/server/src/domain/repositories/communication.repository.ts +++ b/server/src/domain/repositories/communication.repository.ts @@ -1,5 +1,3 @@ -import { AssetResponseDto, ReleaseNotification, ServerVersionResponseDto } from '@app/domain'; - export const ICommunicationRepository = 'ICommunicationRepository'; export enum ClientEvent { @@ -9,7 +7,6 @@ export enum ClientEvent { ASSET_UPDATE = 'on_asset_update', ASSET_HIDDEN = 'on_asset_hidden', ASSET_RESTORE = 'on_asset_restore', - ASSET_STACK_UPDATE = 'on_asset_stack_update', PERSON_THUMBNAIL = 'on_person_thumbnail', SERVER_VERSION = 'on_server_version', CONFIG_UPDATE = 'on_config_update', @@ -20,26 +17,12 @@ export enum ServerEvent { CONFIG_UPDATE = 'config:update', } -export interface ClientEventMap { - [ClientEvent.UPLOAD_SUCCESS]: AssetResponseDto; - [ClientEvent.ASSET_DELETE]: string; - [ClientEvent.ASSET_TRASH]: string[]; - [ClientEvent.ASSET_UPDATE]: AssetResponseDto; - [ClientEvent.ASSET_HIDDEN]: string; - [ClientEvent.ASSET_RESTORE]: string[]; - [ClientEvent.ASSET_STACK_UPDATE]: string[]; - [ClientEvent.PERSON_THUMBNAIL]: string; - [ClientEvent.SERVER_VERSION]: ServerVersionResponseDto; - [ClientEvent.CONFIG_UPDATE]: Record; - [ClientEvent.NEW_RELEASE]: ReleaseNotification; -} - export type OnConnectCallback = (userId: string) => Promise; export type OnServerEventCallback = () => Promise; export interface ICommunicationRepository { - send(event: E, userId: string, data: ClientEventMap[E]): void; - broadcast(event: E, data: ClientEventMap[E]): void; + send(event: ClientEvent, userId: string, data: any): void; + broadcast(event: ClientEvent, data: any): void; on(event: 'connect', callback: OnConnectCallback): void; on(event: ServerEvent, callback: OnServerEventCallback): void; sendServerEvent(event: ServerEvent): void; diff --git a/server/src/domain/server-info/server-info.dto.ts b/server/src/domain/server-info/server-info.dto.ts index b3ef426daead..b631bdc7efc6 100644 --- a/server/src/domain/server-info/server-info.dto.ts +++ b/server/src/domain/server-info/server-info.dto.ts @@ -1,6 +1,5 @@ -import { FeatureFlags, IVersion, type VersionType } from '@app/domain'; +import { FeatureFlags, IVersion } from '@app/domain'; import { ApiProperty, ApiResponseProperty } from '@nestjs/swagger'; -import type { DateTime } from 'luxon'; import { SystemConfigThemeDto } from '../system-config/dto/system-config-theme.dto'; export class ServerPingResponse { @@ -106,10 +105,3 @@ export class ServerFeaturesDto implements FeatureFlags { sidecar!: boolean; search!: boolean; } - -export interface ReleaseNotification { - isAvailable: VersionType; - checkedAt: DateTime | null; - serverVersion: ServerVersionResponseDto; - releaseVersion: ServerVersionResponseDto; -} diff --git a/web/src/lib/stores/websocket.ts b/web/src/lib/stores/websocket.ts index a025ef8cdac8..33748f35fe5b 100644 --- a/web/src/lib/stores/websocket.ts +++ b/web/src/lib/stores/websocket.ts @@ -17,7 +17,6 @@ export interface Events { on_asset_update: (asset: AssetResponseDto) => void; on_asset_hidden: (assetId: string) => void; on_asset_restore: (assetIds: string[]) => void; - on_asset_stack_update: (assetIds: string[]) => void; on_person_thumbnail: (personId: string) => void; on_server_version: (serverVersion: ServerVersionResponseDto) => void; on_config_update: () => void;