From 92ec1ce77fa47369e0763a6613a66440cf23b6c5 Mon Sep 17 00:00:00 2001 From: martin <74269598+martabal@users.noreply.github.com> Date: Fri, 10 Nov 2023 03:32:31 +0100 Subject: [PATCH] fix(server,web): correctly show album level like (#4916) * fix: like in global activity * refactor: rename isGlobal to ReactionLevel.Album * chore: open api * chore: e2e test for album vs comment duplicate like checking --------- Co-authored-by: Jason Rasmussen --- cli/src/api/open-api/api.ts | 37 +++++++++++++++--- mobile/openapi/.openapi-generator/FILES | 3 ++ mobile/openapi/README.md | Bin 22967 -> 23009 bytes mobile/openapi/doc/ActivityApi.md | Bin 8917 -> 9021 bytes mobile/openapi/doc/ReactionLevel.md | Bin 0 -> 379 bytes mobile/openapi/lib/api.dart | Bin 7460 -> 7494 bytes mobile/openapi/lib/api/activity_api.dart | Bin 7364 -> 7587 bytes mobile/openapi/lib/api_client.dart | Bin 21998 -> 22091 bytes mobile/openapi/lib/api_helper.dart | Bin 5524 -> 5628 bytes mobile/openapi/lib/model/reaction_level.dart | Bin 0 -> 2616 bytes mobile/openapi/test/activity_api_test.dart | Bin 1106 -> 1127 bytes mobile/openapi/test/reaction_level_test.dart | Bin 0 -> 423 bytes server/immich-openapi-specs.json | 15 +++++++ server/src/domain/activity/activity.dto.ts | 10 +++++ .../src/domain/activity/activity.service.ts | 8 ++-- .../infra/repositories/activity.repository.ts | 7 ++-- server/test/e2e/activity.e2e-spec.ts | 14 +++++++ web/src/api/open-api/api.ts | 37 +++++++++++++++--- .../asset-viewer/activity-viewer.svelte | 3 +- .../asset-viewer/asset-viewer.svelte | 1 + .../(user)/albums/[albumId]/+page.svelte | 5 ++- 21 files changed, 120 insertions(+), 20 deletions(-) create mode 100644 mobile/openapi/doc/ReactionLevel.md create mode 100644 mobile/openapi/lib/model/reaction_level.dart create mode 100644 mobile/openapi/test/reaction_level_test.dart diff --git a/cli/src/api/open-api/api.ts b/cli/src/api/open-api/api.ts index 5bcfe0f078..798d388d7b 100644 --- a/cli/src/api/open-api/api.ts +++ b/cli/src/api/open-api/api.ts @@ -2570,6 +2570,20 @@ export interface QueueStatusDto { */ 'isPaused': boolean; } +/** + * + * @export + * @enum {string} + */ + +export const ReactionLevel = { + Album: 'album', + Asset: 'asset' +} as const; + +export type ReactionLevel = typeof ReactionLevel[keyof typeof ReactionLevel]; + + /** * * @export @@ -5065,11 +5079,12 @@ export const ActivityApiAxiosParamCreator = function (configuration?: Configurat * @param {string} albumId * @param {string} [assetId] * @param {ReactionType} [type] + * @param {ReactionLevel} [level] * @param {string} [userId] * @param {*} [options] Override http request option. * @throws {RequiredError} */ - getActivities: async (albumId: string, assetId?: string, type?: ReactionType, userId?: string, options: AxiosRequestConfig = {}): Promise => { + getActivities: async (albumId: string, assetId?: string, type?: ReactionType, level?: ReactionLevel, userId?: string, options: AxiosRequestConfig = {}): Promise => { // verify required parameter 'albumId' is not null or undefined assertParamExists('getActivities', 'albumId', albumId) const localVarPath = `/activity`; @@ -5105,6 +5120,10 @@ export const ActivityApiAxiosParamCreator = function (configuration?: Configurat localVarQueryParameter['type'] = type; } + if (level !== undefined) { + localVarQueryParameter['level'] = level; + } + if (userId !== undefined) { localVarQueryParameter['userId'] = userId; } @@ -5205,12 +5224,13 @@ export const ActivityApiFp = function(configuration?: Configuration) { * @param {string} albumId * @param {string} [assetId] * @param {ReactionType} [type] + * @param {ReactionLevel} [level] * @param {string} [userId] * @param {*} [options] Override http request option. * @throws {RequiredError} */ - async getActivities(albumId: string, assetId?: string, type?: ReactionType, userId?: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise>> { - const localVarAxiosArgs = await localVarAxiosParamCreator.getActivities(albumId, assetId, type, userId, options); + async getActivities(albumId: string, assetId?: string, type?: ReactionType, level?: ReactionLevel, userId?: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise>> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getActivities(albumId, assetId, type, level, userId, options); return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); }, /** @@ -5259,7 +5279,7 @@ export const ActivityApiFactory = function (configuration?: Configuration, baseP * @throws {RequiredError} */ getActivities(requestParameters: ActivityApiGetActivitiesRequest, options?: AxiosRequestConfig): AxiosPromise> { - return localVarFp.getActivities(requestParameters.albumId, requestParameters.assetId, requestParameters.type, requestParameters.userId, options).then((request) => request(axios, basePath)); + return localVarFp.getActivities(requestParameters.albumId, requestParameters.assetId, requestParameters.type, requestParameters.level, requestParameters.userId, options).then((request) => request(axios, basePath)); }, /** * @@ -5328,6 +5348,13 @@ export interface ActivityApiGetActivitiesRequest { */ readonly type?: ReactionType + /** + * + * @type {ReactionLevel} + * @memberof ActivityApiGetActivities + */ + readonly level?: ReactionLevel + /** * * @type {string} @@ -5394,7 +5421,7 @@ export class ActivityApi extends BaseAPI { * @memberof ActivityApi */ public getActivities(requestParameters: ActivityApiGetActivitiesRequest, options?: AxiosRequestConfig) { - return ActivityApiFp(this.configuration).getActivities(requestParameters.albumId, requestParameters.assetId, requestParameters.type, requestParameters.userId, options).then((request) => request(this.axios, this.basePath)); + return ActivityApiFp(this.configuration).getActivities(requestParameters.albumId, requestParameters.assetId, requestParameters.type, requestParameters.level, requestParameters.userId, options).then((request) => request(this.axios, this.basePath)); } /** diff --git a/mobile/openapi/.openapi-generator/FILES b/mobile/openapi/.openapi-generator/FILES index 18dc395b57..57854e1b79 100644 --- a/mobile/openapi/.openapi-generator/FILES +++ b/mobile/openapi/.openapi-generator/FILES @@ -101,6 +101,7 @@ doc/PersonResponseDto.md doc/PersonStatisticsResponseDto.md doc/PersonUpdateDto.md doc/QueueStatusDto.md +doc/ReactionLevel.md doc/ReactionType.md doc/RecognitionConfig.md doc/ScanLibraryDto.md @@ -281,6 +282,7 @@ lib/model/person_response_dto.dart lib/model/person_statistics_response_dto.dart lib/model/person_update_dto.dart lib/model/queue_status_dto.dart +lib/model/reaction_level.dart lib/model/reaction_type.dart lib/model/recognition_config.dart lib/model/scan_library_dto.dart @@ -440,6 +442,7 @@ test/person_response_dto_test.dart test/person_statistics_response_dto_test.dart test/person_update_dto_test.dart test/queue_status_dto_test.dart +test/reaction_level_test.dart test/reaction_type_test.dart test/recognition_config_test.dart test/scan_library_dto_test.dart diff --git a/mobile/openapi/README.md b/mobile/openapi/README.md index d62d95cb501393ca9f5f74a91adcc67146c035dc..0bc2cc1e333bd10ee293d344c537cb4fc4aa66ee 100644 GIT binary patch delta 40 tcmdnKnepLf#tk36C4ExMQgdQ8Qu34a^@CCqlS?x5^T1-8A9!Eq1pr}n5e5JN delta 14 WcmaF3nQ{AO#tk36H%t2*;{^aXqz2jm diff --git a/mobile/openapi/doc/ActivityApi.md b/mobile/openapi/doc/ActivityApi.md index 1af3f1f496f70a1d437255561d548627878fcea8..6221ef5e4f01e12ca93cf7886cdd806a6c0225d5 100644 GIT binary patch delta 106 zcmccWy4P*PHbL&3)UwnZ9fi{3)S}H7q*ky@mKS52oFS$p1(r~-Rj^jj*H;KiO-wGy n%+K=ysh->*HklPHy;)E^ixHwyOG}|fAzDidMdjvri83w#-!CMo delta 35 rcmdn%cGY#mHo?t%1+TD7-YV9~Qd*o^G+A3Ae)9@(R>sYbC8D?h9$pS# diff --git a/mobile/openapi/doc/ReactionLevel.md b/mobile/openapi/doc/ReactionLevel.md new file mode 100644 index 0000000000000000000000000000000000000000..a53955cb0a101786df1c222a8ce3de856d644270 GIT binary patch literal 379 zcma)1!HNPg487+o0&{RZwBFs5q6a}mWN#u&nMN&6o6?Dbuphtetgx;Z%_Y3#<-NQL zIZ`muY0s8gy(QC#n3Dw2gT z_$<_3X_N9YiK7nI#uI+y*DaPdqpnFV7T=84ESaGmDi0r!Qm-(;Za2+;qA;#XENopT z`~8R3qwRb$Tg|n%mF4E*DTpb)>cC0$3A-WwT~9WPH*a%ZMZrdPLH1Cp|4y3B4z~T diff --git a/mobile/openapi/lib/api/activity_api.dart b/mobile/openapi/lib/api/activity_api.dart index 458538a5d28d14715f9238c2ad6c3ddfb569849e..8e2354e20114d6b94585d6409d9cde826dbdda01 100644 GIT binary patch delta 175 zcmX?Nx!8JxIQunGvc&aB`AR NB2ZPu=6GQjE&vET7ncA4 diff --git a/mobile/openapi/lib/api_client.dart b/mobile/openapi/lib/api_client.dart index e3b881ccdc9f25267dd2e25d58d5809b53beca1e..dfdd5b4efecb24f0f574264992fb5409319c6cba 100644 GIT binary patch delta 36 rcmaF2n(_1+#tqlaS$$H=QgbF7s)$T}Z_dFCDn+ zJJ_Wy60m0HeV%!S@pv#E!}a6x;g>(>_w$d}%lQr5F7DD!}qWZb&*>Y35b3++>xlS5fZv_ajSb*7|7mnx&TB<6QQr@#N2W;kSXCDd_<9XY4jaFp@OdifH9@Nh`y!p2m&-70Cly8gY-M_ zJA~4jCyFbF)ss*at`pJ=0e9^s>Co?_OM=i9IgQqrWTDbIT6L6q3*nXnWZCFwkNXW; zwpvIn6nyfwl?-Oyn%X1R{YxsbmsuUVP#a2e`b`e@ zGTdBJ1^`_R=g^@9@G8kM zGdT`VdRu$oRC}?_K+%u4eP91lM@H~^{!>z?Tq zWyguj0)}i42t%RRuU`W{C(_*;Ki`-B*cc>}#=`H}y=7f>EJq&SSUN(7+@YUcg3VUs$?l zAUVe^JphH?7Q{Wq9)E%~#$wvWJDW| z+R?rVgW!lLS50*S4Av_aUUPv&H$^5kYFGS(1$BUE!5r=hGi%1Lw-xa&m7Tfvyiw|> zHXb$zu`@ZiD$CHhf{Yw_>KPBDuLBg>YD5&~3H)UaME7>YL(_8|X79(oYui7GAo^z1 zJ!;yLac^Qix7OI0(<#&+!jDG8|W0eNW)fR*D_bUGj$%Rhh9DfR)@&DVPiZ3)4x!mUle&f7P?A9Tkp!7g8kMkszNf;M zFDf|}g2;73SvD^Y^`cGWG$fYr+&j3o+lv1Ug`N&CAN3ba9gQ12HiDoZ;W>dH1}AM69z diff --git a/mobile/openapi/test/reaction_level_test.dart b/mobile/openapi/test/reaction_level_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..6fcba58b1adfb3e27bfc604f190704e346b04492 GIT binary patch literal 423 zcmZvYQA@)x6oudOE3Qx7pf0*6*$^DGlfhhJ)CZr!rM>NfZ4#4oBC`K(qVz%5hkGsu zzLS%LbH+JrUd!V4IX~pbO_^t~-R<)fvH}i82`@#q+rHfdERs((TK~9Q+%H+QvQ^rW zXtWiL>}Ump8XVPvI_gRJbo8<}+WN@^cAxm=gc-cB^f5>q;tKnq25s1$tP6)*Hyy9E zavqfzvJQo^kz{}4ZnCVCik#@QY6Ip^sKmpas7`1dV}Eyq#9;M~Ev>X6g+}r)i}>nf zeT8^(o<|vhSQ@>9@Fj30ti04}PiN}bS<4!FlxjAIZ^i&xs|PbnBL5#vQW%-be9hQ} F{Q$z;k6!=) literal 0 HcmV?d00001 diff --git a/server/immich-openapi-specs.json b/server/immich-openapi-specs.json index 53d1e962e9..193586cbd4 100644 --- a/server/immich-openapi-specs.json +++ b/server/immich-openapi-specs.json @@ -31,6 +31,14 @@ "$ref": "#/components/schemas/ReactionType" } }, + { + "name": "level", + "required": false, + "in": "query", + "schema": { + "$ref": "#/components/schemas/ReactionLevel" + } + }, { "name": "userId", "required": false, @@ -7728,6 +7736,13 @@ ], "type": "object" }, + "ReactionLevel": { + "enum": [ + "album", + "asset" + ], + "type": "string" + }, "ReactionType": { "enum": [ "comment", diff --git a/server/src/domain/activity/activity.dto.ts b/server/src/domain/activity/activity.dto.ts index e1a163b814..a5a5bd3dfd 100644 --- a/server/src/domain/activity/activity.dto.ts +++ b/server/src/domain/activity/activity.dto.ts @@ -9,6 +9,11 @@ export enum ReactionType { LIKE = 'like', } +export enum ReactionLevel { + ALBUM = 'album', + ASSET = 'asset', +} + export type MaybeDuplicate = { duplicate: boolean; value: T }; export class ActivityResponseDto { @@ -39,6 +44,11 @@ export class ActivitySearchDto extends ActivityDto { @ApiProperty({ enumName: 'ReactionType', enum: ReactionType }) type?: ReactionType; + @IsEnum(ReactionLevel) + @Optional() + @ApiProperty({ enumName: 'ReactionLevel', enum: ReactionLevel }) + level?: ReactionLevel; + @ValidateUUID({ optional: true }) userId?: string; } diff --git a/server/src/domain/activity/activity.service.ts b/server/src/domain/activity/activity.service.ts index 44362f3fc0..8b601558df 100644 --- a/server/src/domain/activity/activity.service.ts +++ b/server/src/domain/activity/activity.service.ts @@ -10,6 +10,7 @@ import { ActivitySearchDto, ActivityStatisticsResponseDto, MaybeDuplicate, + ReactionLevel, ReactionType, mapActivity, } from './activity.dto'; @@ -30,7 +31,7 @@ export class ActivityService { const activities = await this.repository.search({ userId: dto.userId, albumId: dto.albumId, - assetId: dto.assetId, + assetId: dto.level === ReactionLevel.ALBUM ? null : dto.assetId, isLiked: dto.type && dto.type === ReactionType.LIKE, }); @@ -54,11 +55,12 @@ export class ActivityService { let activity: ActivityEntity | null = null; let duplicate = false; - if (dto.type === 'like') { + if (dto.type === ReactionType.LIKE) { delete dto.comment; [activity] = await this.repository.search({ ...common, - isGlobal: !dto.assetId, + // `null` will search for an album like + assetId: dto.assetId ?? null, isLiked: true, }); duplicate = !!activity; diff --git a/server/src/infra/repositories/activity.repository.ts b/server/src/infra/repositories/activity.repository.ts index 138d963815..25fd5fa7ac 100644 --- a/server/src/infra/repositories/activity.repository.ts +++ b/server/src/infra/repositories/activity.repository.ts @@ -6,10 +6,9 @@ import { ActivityEntity } from '../entities/activity.entity'; export interface ActivitySearch { albumId?: string; - assetId?: string; + assetId?: string | null; userId?: string; isLiked?: boolean; - isGlobal?: boolean; } @Injectable() @@ -17,11 +16,11 @@ export class ActivityRepository implements IActivityRepository { constructor(@InjectRepository(ActivityEntity) private repository: Repository) {} search(options: ActivitySearch): Promise { - const { userId, assetId, albumId, isLiked, isGlobal } = options; + const { userId, assetId, albumId, isLiked } = options; return this.repository.find({ where: { userId, - assetId: isGlobal ? IsNull() : assetId, + assetId: assetId === null ? IsNull() : assetId, albumId, isLiked, }, diff --git a/server/test/e2e/activity.e2e-spec.ts b/server/test/e2e/activity.e2e-spec.ts index 5cc86fc6aa..0bb8aa2c9a 100644 --- a/server/test/e2e/activity.e2e-spec.ts +++ b/server/test/e2e/activity.e2e-spec.ts @@ -247,6 +247,20 @@ describe(`${ActivityController.name} (e2e)`, () => { expect(body).toEqual(reaction); }); + it('should not confuse an album like with an asset like', async () => { + const reaction = await api.activityApi.create(server, admin.accessToken, { + albumId: album.id, + assetId: asset.id, + type: ReactionType.LIKE, + }); + const { status, body } = await request(server) + .post('/activity') + .set('Authorization', `Bearer ${admin.accessToken}`) + .send({ albumId: album.id, type: 'like' }); + expect(status).toEqual(201); + expect(body.id).not.toEqual(reaction.id); + }); + it('should add a comment to an asset', async () => { const { status, body } = await request(server) .post('/activity') diff --git a/web/src/api/open-api/api.ts b/web/src/api/open-api/api.ts index 5bcfe0f078..798d388d7b 100644 --- a/web/src/api/open-api/api.ts +++ b/web/src/api/open-api/api.ts @@ -2570,6 +2570,20 @@ export interface QueueStatusDto { */ 'isPaused': boolean; } +/** + * + * @export + * @enum {string} + */ + +export const ReactionLevel = { + Album: 'album', + Asset: 'asset' +} as const; + +export type ReactionLevel = typeof ReactionLevel[keyof typeof ReactionLevel]; + + /** * * @export @@ -5065,11 +5079,12 @@ export const ActivityApiAxiosParamCreator = function (configuration?: Configurat * @param {string} albumId * @param {string} [assetId] * @param {ReactionType} [type] + * @param {ReactionLevel} [level] * @param {string} [userId] * @param {*} [options] Override http request option. * @throws {RequiredError} */ - getActivities: async (albumId: string, assetId?: string, type?: ReactionType, userId?: string, options: AxiosRequestConfig = {}): Promise => { + getActivities: async (albumId: string, assetId?: string, type?: ReactionType, level?: ReactionLevel, userId?: string, options: AxiosRequestConfig = {}): Promise => { // verify required parameter 'albumId' is not null or undefined assertParamExists('getActivities', 'albumId', albumId) const localVarPath = `/activity`; @@ -5105,6 +5120,10 @@ export const ActivityApiAxiosParamCreator = function (configuration?: Configurat localVarQueryParameter['type'] = type; } + if (level !== undefined) { + localVarQueryParameter['level'] = level; + } + if (userId !== undefined) { localVarQueryParameter['userId'] = userId; } @@ -5205,12 +5224,13 @@ export const ActivityApiFp = function(configuration?: Configuration) { * @param {string} albumId * @param {string} [assetId] * @param {ReactionType} [type] + * @param {ReactionLevel} [level] * @param {string} [userId] * @param {*} [options] Override http request option. * @throws {RequiredError} */ - async getActivities(albumId: string, assetId?: string, type?: ReactionType, userId?: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise>> { - const localVarAxiosArgs = await localVarAxiosParamCreator.getActivities(albumId, assetId, type, userId, options); + async getActivities(albumId: string, assetId?: string, type?: ReactionType, level?: ReactionLevel, userId?: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise>> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getActivities(albumId, assetId, type, level, userId, options); return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); }, /** @@ -5259,7 +5279,7 @@ export const ActivityApiFactory = function (configuration?: Configuration, baseP * @throws {RequiredError} */ getActivities(requestParameters: ActivityApiGetActivitiesRequest, options?: AxiosRequestConfig): AxiosPromise> { - return localVarFp.getActivities(requestParameters.albumId, requestParameters.assetId, requestParameters.type, requestParameters.userId, options).then((request) => request(axios, basePath)); + return localVarFp.getActivities(requestParameters.albumId, requestParameters.assetId, requestParameters.type, requestParameters.level, requestParameters.userId, options).then((request) => request(axios, basePath)); }, /** * @@ -5328,6 +5348,13 @@ export interface ActivityApiGetActivitiesRequest { */ readonly type?: ReactionType + /** + * + * @type {ReactionLevel} + * @memberof ActivityApiGetActivities + */ + readonly level?: ReactionLevel + /** * * @type {string} @@ -5394,7 +5421,7 @@ export class ActivityApi extends BaseAPI { * @memberof ActivityApi */ public getActivities(requestParameters: ActivityApiGetActivitiesRequest, options?: AxiosRequestConfig) { - return ActivityApiFp(this.configuration).getActivities(requestParameters.albumId, requestParameters.assetId, requestParameters.type, requestParameters.userId, options).then((request) => request(this.axios, this.basePath)); + return ActivityApiFp(this.configuration).getActivities(requestParameters.albumId, requestParameters.assetId, requestParameters.type, requestParameters.level, requestParameters.userId, options).then((request) => request(this.axios, this.basePath)); } /** diff --git a/web/src/lib/components/asset-viewer/activity-viewer.svelte b/web/src/lib/components/asset-viewer/activity-viewer.svelte index dfe285b3eb..f8663ecebc 100644 --- a/web/src/lib/components/asset-viewer/activity-viewer.svelte +++ b/web/src/lib/components/asset-viewer/activity-viewer.svelte @@ -39,6 +39,7 @@ export let assetType: AssetTypeEnum | undefined = undefined; export let albumOwnerId: string; export let disabled: boolean; + export let isLiked: ActivityResponseDto | null; let textArea: HTMLTextAreaElement; let innerHeight: number; @@ -105,7 +106,7 @@ reactions.splice(index, 1); showDeleteReaction.splice(index, 1); reactions = reactions; - if (reaction.type === 'like' && reaction.user.id === user.id) { + if (isLiked && reaction.type === 'like' && reaction.id == isLiked.id) { dispatch('deleteLike'); } else { dispatch('deleteComment'); diff --git a/web/src/lib/components/asset-viewer/asset-viewer.svelte b/web/src/lib/components/asset-viewer/asset-viewer.svelte index 86a86c9aec..0194596f6a 100644 --- a/web/src/lib/components/asset-viewer/asset-viewer.svelte +++ b/web/src/lib/components/asset-viewer/asset-viewer.svelte @@ -756,6 +756,7 @@ albumOwnerId={album.ownerId} albumId={album.id} assetId={asset.id} + {isLiked} bind:reactions on:addComment={handleAddComment} on:deleteComment={handleRemoveComment} diff --git a/web/src/routes/(user)/albums/[albumId]/+page.svelte b/web/src/routes/(user)/albums/[albumId]/+page.svelte index 5525156bf5..09eb66e95f 100644 --- a/web/src/routes/(user)/albums/[albumId]/+page.svelte +++ b/web/src/routes/(user)/albums/[albumId]/+page.svelte @@ -35,7 +35,7 @@ import { downloadArchive } from '$lib/utils/asset-utils'; import { openFileUploadDialog } from '$lib/utils/file-uploader'; import { handleError } from '$lib/utils/handle-error'; - import { ActivityResponseDto, ReactionType, UserResponseDto, api } from '@api'; + import { ActivityResponseDto, ReactionLevel, ReactionType, UserResponseDto, api } from '@api'; import Icon from '$lib/components/elements/icon.svelte'; import type { PageData } from './$types'; import { clickOutside } from '$lib/utils/click-outside'; @@ -167,7 +167,6 @@ const { data } = await api.activityApi.createActivity({ activityCreateDto: { albumId: album.id, type: ReactionType.Like }, }); - isLiked = data; reactions = [...reactions, isLiked]; } @@ -183,6 +182,7 @@ userId: user.id, albumId: album.id, type: ReactionType.Like, + level: ReactionLevel.Album, }); if (data.length > 0) { isLiked = data[0]; @@ -687,6 +687,7 @@ disabled={!album.isActivityEnabled} albumOwnerId={album.ownerId} albumId={album.id} + {isLiked} bind:reactions on:addComment={() => updateNumberOfComments(1)} on:deleteComment={() => updateNumberOfComments(-1)}