@acorex-platform/module-conversation-client 0.0.63 → 0.0.66

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/fesm2022/{acorex-platform-module-conversation-client-acorex-platform-module-conversation-client-CmRULmpl.mjs → acorex-platform-module-conversation-client-acorex-platform-module-conversation-client-Be9CB1WQ.mjs} +251 -67
  2. package/fesm2022/acorex-platform-module-conversation-client-acorex-platform-module-conversation-client-Be9CB1WQ.mjs.map +1 -0
  3. package/fesm2022/{acorex-platform-module-conversation-client-after-message-sent.command-JjZrYD2R.mjs → acorex-platform-module-conversation-client-after-message-sent.command-D21Bwrrp.mjs} +2 -2
  4. package/fesm2022/{acorex-platform-module-conversation-client-after-message-sent.command-JjZrYD2R.mjs.map → acorex-platform-module-conversation-client-after-message-sent.command-D21Bwrrp.mjs.map} +1 -1
  5. package/fesm2022/{acorex-platform-module-conversation-client-assist-delegated-agent-detail-popup.component-BhED754u.mjs → acorex-platform-module-conversation-client-assist-delegated-agent-detail-popup.component-BG2obGE8.mjs} +3 -3
  6. package/fesm2022/{acorex-platform-module-conversation-client-assist-delegated-agent-detail-popup.component-BhED754u.mjs.map → acorex-platform-module-conversation-client-assist-delegated-agent-detail-popup.component-BG2obGE8.mjs.map} +1 -1
  7. package/fesm2022/{acorex-platform-module-conversation-client-assist-message-renderer.component-CR4OxDV6.mjs → acorex-platform-module-conversation-client-assist-message-renderer.component-CyTzYVsZ.mjs} +3 -3
  8. package/fesm2022/{acorex-platform-module-conversation-client-assist-message-renderer.component-CR4OxDV6.mjs.map → acorex-platform-module-conversation-client-assist-message-renderer.component-CyTzYVsZ.mjs.map} +1 -1
  9. package/fesm2022/{acorex-platform-module-conversation-client-chat-call-session-page.component-DJreBgNo.mjs → acorex-platform-module-conversation-client-chat-call-session-page.component-BbtiucQD.mjs} +2 -2
  10. package/fesm2022/{acorex-platform-module-conversation-client-chat-call-session-page.component-DJreBgNo.mjs.map → acorex-platform-module-conversation-client-chat-call-session-page.component-BbtiucQD.mjs.map} +1 -1
  11. package/fesm2022/{acorex-platform-module-conversation-client-chat-call-start-popup.component-BEa8wEJt.mjs → acorex-platform-module-conversation-client-chat-call-start-popup.component-C-YXNbrC.mjs} +2 -2
  12. package/fesm2022/{acorex-platform-module-conversation-client-chat-call-start-popup.component-BEa8wEJt.mjs.map → acorex-platform-module-conversation-client-chat-call-start-popup.component-C-YXNbrC.mjs.map} +1 -1
  13. package/fesm2022/{acorex-platform-module-conversation-client-comments-page.component-BsE6bCZT.mjs → acorex-platform-module-conversation-client-comments-page.component-Cgw3yLDs.mjs} +2 -2
  14. package/fesm2022/{acorex-platform-module-conversation-client-comments-page.component-BsE6bCZT.mjs.map → acorex-platform-module-conversation-client-comments-page.component-Cgw3yLDs.mjs.map} +1 -1
  15. package/fesm2022/acorex-platform-module-conversation-client-contracts.mjs +6 -1
  16. package/fesm2022/acorex-platform-module-conversation-client-contracts.mjs.map +1 -1
  17. package/fesm2022/{acorex-platform-module-conversation-client-mark-conversation-unread.command-B1mvtbaA.mjs → acorex-platform-module-conversation-client-mark-conversation-unread.command-Cp6nnN8B.mjs} +2 -2
  18. package/fesm2022/{acorex-platform-module-conversation-client-mark-conversation-unread.command-B1mvtbaA.mjs.map → acorex-platform-module-conversation-client-mark-conversation-unread.command-Cp6nnN8B.mjs.map} +1 -1
  19. package/fesm2022/{acorex-platform-module-conversation-client-open-chat.command-CbJ0gXZq.mjs → acorex-platform-module-conversation-client-open-chat.command-Cyes1BAz.mjs} +2 -2
  20. package/fesm2022/{acorex-platform-module-conversation-client-open-chat.command-CbJ0gXZq.mjs.map → acorex-platform-module-conversation-client-open-chat.command-Cyes1BAz.mjs.map} +1 -1
  21. package/fesm2022/{acorex-platform-module-conversation-client-retry-assist-response.command-BvzWaKX4.mjs → acorex-platform-module-conversation-client-retry-assist-response.command-CaxrqIvP.mjs} +2 -2
  22. package/fesm2022/{acorex-platform-module-conversation-client-retry-assist-response.command-BvzWaKX4.mjs.map → acorex-platform-module-conversation-client-retry-assist-response.command-CaxrqIvP.mjs.map} +1 -1
  23. package/fesm2022/{acorex-platform-module-conversation-client-sync-read-state.command-DQXezGRu.mjs → acorex-platform-module-conversation-client-sync-read-state.command-BFuJeJb5.mjs} +2 -2
  24. package/fesm2022/{acorex-platform-module-conversation-client-sync-read-state.command-DQXezGRu.mjs.map → acorex-platform-module-conversation-client-sync-read-state.command-BFuJeJb5.mjs.map} +1 -1
  25. package/fesm2022/acorex-platform-module-conversation-client.mjs +1 -1
  26. package/package.json +2 -2
  27. package/types/acorex-platform-module-conversation-client-contracts.d.ts +16 -2
  28. package/types/acorex-platform-module-conversation-client.d.ts +23 -1
  29. package/fesm2022/acorex-platform-module-conversation-client-acorex-platform-module-conversation-client-CmRULmpl.mjs.map +0 -1
@@ -1,5 +1,5 @@
1
1
  import { AXPSessionService, AXP_PERMISSION_DEFINITION_PROVIDER } from '@acorex-platform/framework-client/auth';
2
- import { AXPFilterOperatorMiddlewareService, AXPSearchCommandProvider, createEntityCommandOptions, AXP_PROTECTED_ROUTE_GUARDS, AXPBackgroundOperationHandler, AXP_BACKGROUND_OPERATION_HANDLERS, AXPSettingsService, AXPCommonSettings, AXP_IN_APP_NOTIFICATION_SERVICE, AXPFileStorageService, normalizeStoredImageRef, isStoredImageFileId, AXP_MENU_PROVIDER, AXP_SETTING_DEFINITION_PROVIDER, AXP_SEARCH_PROVIDER } from '@acorex-platform/framework-client/common';
2
+ import { AXPFilterOperatorMiddlewareService, AXPSearchCommandProvider, createEntityCommandOptions, AXP_PROTECTED_ROUTE_GUARDS, AXPBackgroundOperationHandler, AXP_BACKGROUND_OPERATION_HANDLERS, AXPSettingsService, AXPCommonSettings, AXPFileStorageService, normalizeStoredImageRef, isStoredImageFileId, AXP_MENU_PROVIDER, AXP_SETTING_DEFINITION_PROVIDER, AXP_SEARCH_PROVIDER } from '@acorex-platform/framework-client/common';
3
3
  import { AXPEntityBroadcastService, AXPTagService, AXPPageContextRegistry, AXPDialogOpener, AXPDeviceService, provideAppStartUpTask, AXP_APP_STARTUP_PRIORITY, AXP_HOOK_PROVIDER } from '@acorex-platform/framework-client/core';
4
4
  import { USER_CARD_ITEMS_HOOK, AXPTaskBadgeProvider, AXPFileViewerService, AXPUserAvatarService, AXPUserAvatarComponent, AXPUserCardDirective, mergeInfiniteScrollPage, AXPThemeLayoutBlockComponent, AXPInfiniteScrollDirective, AXPStateMessageComponent, AXPAvatarComponent, AXPMarkdownViewerComponent, AXPTaskBadgeService, AXPThemeLayoutStartSideComponent, AXP_PAGE_COMPONENT_PROVIDER, AXP_TASK_BADGE_PROVIDERS } from '@acorex-platform/framework-client/layout/components';
5
5
  import { AXPEntityService, AXPFileListComponent, AXPEntityDefinitionRegistryService, cloneLayoutArrays, ensureLayoutSection, ensureLayoutPropertyView, resolveEntityPluginDetailPageOrder, ensureListActions, actionExists, AXP_ENTITY_ACTION_PLUGIN } from '@acorex-platform/framework-client/layout/entity';
@@ -12,13 +12,13 @@ import { CommonModule, DOCUMENT, AsyncPipe, NgTemplateOutlet, isPlatformBrowser,
12
12
  import * as i0 from '@angular/core';
13
13
  import { inject, Injectable, signal, DestroyRef, input, computed, ChangeDetectionStrategy, Component, ElementRef, Injector, output, viewChild, afterNextRender, effect, untracked, InjectionToken, Directive, ViewContainerRef, EnvironmentInjector, ViewEncapsulation, PLATFORM_ID, NgZone, NgModule } from '@angular/core';
14
14
  import { Router, ActivatedRoute, NavigationEnd, ROUTES } from '@angular/router';
15
- import { RootConfig, axmIsCommentRoom, AXPCollaborationPermissionKeys, AXPConversationMenuKeys, AXMMiniChatSettings, AXPConversationQueryKeys, AXPConversationCommandKeys, AXM_COMMENT_LIKE_EMOJI, CHANNEL_POST_ENTITY_NAME, axmIsChannelRoom, AXM_CONVERSATION_ANNOUNCEMENT_FEED_ITEM_META_KEY, AXM_CONVERSATION_ANNOUNCEMENT_MESSAGE_TYPE, AXM_CONVERSATION_CHANNEL_POST_ID_META_KEY, axmIsAnnouncementChannel, axmAnnouncementChannelMetadata, AXM_CONVERSATION_ANNOUNCEMENT_CHANNEL_NAME, axmAiChatConversationUiMetadata as axmAiChatConversationUiMetadata$1, axmMessagesAfterId, axmChannelPostIdFromMessage, extractMessageTextFromPayload, AXMPermissionsKeys } from '@acorex-platform/module-conversation-client/contracts';
15
+ import { RootConfig, axmIsCommentRoom, AXPCollaborationPermissionKeys, AXPConversationMenuKeys, AXMMiniChatSettings, AXPConversationQueryKeys, AXPConversationCommandKeys, AXM_REALTIME_TOPIC_CONVERSATION_COMMENT, AXM_COMMENT_LIKE_EMOJI, CHANNEL_POST_ENTITY_NAME, axmIsChannelRoom, AXM_CONVERSATION_ANNOUNCEMENT_FEED_ITEM_META_KEY, AXM_CONVERSATION_ANNOUNCEMENT_MESSAGE_TYPE, AXM_CONVERSATION_CHANNEL_POST_ID_META_KEY, axmIsAnnouncementChannel, axmAnnouncementChannelMetadata, AXM_CONVERSATION_ANNOUNCEMENT_CHANNEL_NAME, axmAiChatConversationUiMetadata as axmAiChatConversationUiMetadata$1, axmMessagesAfterId, axmChannelPostIdFromMessage, extractMessageTextFromPayload, AXMPermissionsKeys } from '@acorex-platform/module-conversation-client/contracts';
16
16
  import { AXPCommonMenuKeys, AXPCommonPermissionGroupKeys } from '@acorex-platform/module-common-client/contracts';
17
17
  import { axmAiChatConversationUiMetadata, axmBuildHeuristicConversationTitleFallback, axmCompareMessagesChronologically, AXM_CONTEXTUAL_ASSIST_KIND_ENTITY_RECORD, AXM_ASSIST_LAUNCH_CONTEXT_METADATA_KEY, axmExtractAssistLaunchContextFromMetadata, axmSanitizeContextualAssistContext, AXM_CONTEXTUAL_ASSIST_ACTION_ENTITY_RECORD, RootConfig as RootConfig$1 } from '@acorex-platform/module-conversation-client/contracts';
18
18
  import { coerceUnknownToTrimmedString, runtimeQueryCollectionData, AXPWidgetsList, runtimeQueryObjectData, resolveMultiLanguageString, coerceUnknownToMultiLanguageString, AXP_QUERY_QUICK_SEARCH_FIELD, AXPPlatformScope, AXPFileStorageStatus, runtimeCommandPayloadData, createRandomUuid, AXPRegionalSetting } from '@acorex-platform/framework-shared/core';
19
19
  import { trim, isEmpty, get, isNil, isString, orderBy } from 'lodash';
20
20
  import { AXConversationUserApi, AXConversationApi, AXConversationMessageApi, AXConversationRealtimeApi, AX_CONVERSATION_DEFAULT_ROOM_PREFERENCES, AXConversationService, AXConversationComposerService, AXConversationContainerDirective, AXConversationInfoBarComponent, AXConversationMessageListComponent, AXConversationComposerComponent, AXConversationNewDialogComponent, AXConversationInfoBarService, AXConversationSidebarComponent, AXConversationComposerGenerationStateService, AX_CONVERSATION_ERROR_HANDLER_CONFIG, provideConversation, AX_CONVERSATION_ITEM_MUTE_ACTION, AX_CONVERSATION_ITEM_PIN_ACTION, AX_CONVERSATION_ITEM_MARK_READ_ACTION, AX_CONVERSATION_ITEM_DIVIDER, AX_CONVERSATION_ITEM_DELETE_ACTION, AX_CONVERSATION_INFO_BAR_SEARCH_ACTION, AX_CONVERSATION_INFO_BAR_MUTE_ACTION, AX_CONVERSATION_INFO_BAR_DIVIDER, AX_CONVERSATION_INFO_BAR_DELETE_ACTION, AX_CONVERSATION_TAB_ALL, AX_CONVERSATION_TAB_PRIVATE, AX_CONVERSATION_TAB_GROUPS, AX_CONVERSATION_MESSAGE_REPLY_ACTION, AX_CONVERSATION_MESSAGE_FORWARD_ACTION, AX_CONVERSATION_MESSAGE_EDIT_ACTION, AX_CONVERSATION_MESSAGE_DELETE_ACTION, AX_CONVERSATION_IMAGE_RENDERER, AX_CONVERSATION_VIDEO_RENDERER, AX_CONVERSATION_AUDIO_RENDERER, AX_CONVERSATION_VOICE_RENDERER, AX_CONVERSATION_FILE_RENDERER, AX_CONVERSATION_LOCATION_RENDERER, AX_CONVERSATION_STICKER_RENDERER } from '@acorex/components/conversation';
21
- import { isWatchablePresenceUserId, AXPUserPresenceService, AXPRealtimeConnectionService, AXPRealtimeConnectionPort, AXPRealtimeDispatcherService, AXP_REALTIME_TOPIC_CONVERSATION_MESSAGE, AXP_REALTIME_TOPIC_CONVERSATION_TYPING, AXP_REALTIME_TOPIC_ENTITY_MUTATION, AXP_REALTIME_TOPIC_CONVERSATION_CALL } from '@acorex-platform/framework-client/realtime';
21
+ import { isWatchablePresenceUserId, AXPUserPresenceService, AXPRealtimeDispatcherService, AXPRealtimeConnectionService, AXPRealtimeConnectionPort, AXP_REALTIME_TOPIC_CONVERSATION_MESSAGE, AXP_REALTIME_TOPIC_CONVERSATION_TYPING, AXP_REALTIME_TOPIC_ENTITY_MUTATION, AXP_REALTIME_TOPIC_CONVERSATION_CALL } from '@acorex-platform/framework-client/realtime';
22
22
  import { PRESENCE_USER_CHAT_LAST_SEEN, resolveEntityActionCommandInput, entityActionDataRecord, defineCommand, AXP_COMMAND_DEFINITION_CATEGORY_UTILITY } from '@acorex-platform/framework-shared/runtime';
23
23
  import { BehaviorSubject, Subject, filter, map, pairwise, merge, distinctUntilChanged, interval, skip, switchMap, from, firstValueFrom } from 'rxjs';
24
24
  import { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';
@@ -3217,23 +3217,137 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
3217
3217
  }]
3218
3218
  }] });
3219
3219
 
3220
+ //#region ---- Imports ----
3221
+ //#endregion
3222
+ //#region ---- Realtime snapshot mapping ----
3223
+ /** Maps a comment socket snapshot onto the thread model, without nested replies. */
3224
+ function axmCommentFromRealtimePayload(payload) {
3225
+ const messageId = payload.messageId?.trim() ?? '';
3226
+ const conversationId = payload.conversationId?.trim() ?? '';
3227
+ const message = axmHydrateRealtimeConversationMessage(payload.message, messageId, conversationId);
3228
+ if (!message?.id || !message.conversationId) {
3229
+ return null;
3230
+ }
3231
+ return {
3232
+ ...message,
3233
+ id: message.id,
3234
+ conversationId: message.conversationId,
3235
+ senderId: message.senderId,
3236
+ timestamp: axmCoerceDate(message.timestamp),
3237
+ editedAt: message.editedAt ? axmCoerceDate(message.editedAt) : undefined,
3238
+ deletedAt: message.deletedAt ? axmCoerceDate(message.deletedAt) : undefined,
3239
+ reactions: (message.reactions ?? []).map((reaction) => ({
3240
+ ...reaction,
3241
+ timestamp: axmCoerceDate(reaction.timestamp),
3242
+ })),
3243
+ replyTo: message.replyTo?.id ? { id: message.replyTo.id } : undefined,
3244
+ depth: 0,
3245
+ replies: [],
3246
+ replyCount: 0,
3247
+ };
3248
+ }
3249
+ //#endregion
3250
+
3251
+ //#region ---- Imports ----
3252
+ //#endregion
3253
+ //#region ---- Abstract service ----
3220
3254
  class AXMCommentRealtimeService {
3221
3255
  }
3256
+ //#endregion
3257
+ //#region ---- Implementation ----
3222
3258
  class AXMCommentRealtimeServiceImpl extends AXMCommentRealtimeService {
3259
+ //#endregion
3223
3260
  constructor() {
3224
- super(...arguments);
3261
+ super();
3262
+ //#region ---- Services & Dependencies ----
3263
+ this.dispatcher = inject(AXPRealtimeDispatcherService, { optional: true });
3264
+ this.connection = inject(AXPRealtimeConnectionService, { optional: true });
3265
+ //#endregion
3266
+ //#region ---- State ----
3225
3267
  this._comment$ = new Subject();
3226
3268
  this.comment$ = this._comment$.asObservable();
3227
3269
  this._thread$ = new Subject();
3228
3270
  this.thread$ = this._thread$.asObservable();
3271
+ this.watchedThreads = new Map();
3272
+ this.remoteHandlerRegistered = false;
3273
+ this.registerRemoteHandler();
3229
3274
  }
3275
+ //#region ---- Local publish ----
3230
3276
  notifyComment(event) {
3231
3277
  this._comment$.next(event);
3232
3278
  }
3233
3279
  notifyThread(event) {
3234
3280
  this._thread$.next(event);
3235
3281
  }
3236
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMCommentRealtimeServiceImpl, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
3282
+ //#endregion
3283
+ //#region ---- Thread subscription ----
3284
+ watchThread(threadId) {
3285
+ const id = threadId?.trim();
3286
+ if (!id) {
3287
+ return;
3288
+ }
3289
+ const next = (this.watchedThreads.get(id) ?? 0) + 1;
3290
+ this.watchedThreads.set(id, next);
3291
+ if (next === 1) {
3292
+ this.connection?.subscribeConversation(id);
3293
+ }
3294
+ }
3295
+ unwatchThread(threadId) {
3296
+ const id = threadId?.trim();
3297
+ if (!id) {
3298
+ return;
3299
+ }
3300
+ const current = this.watchedThreads.get(id) ?? 0;
3301
+ if (current <= 1) {
3302
+ this.watchedThreads.delete(id);
3303
+ this.connection?.unsubscribeConversation(id);
3304
+ return;
3305
+ }
3306
+ this.watchedThreads.set(id, current - 1);
3307
+ }
3308
+ //#endregion
3309
+ //#region ---- Socket handler ----
3310
+ registerRemoteHandler() {
3311
+ if (this.remoteHandlerRegistered || !this.dispatcher) {
3312
+ return;
3313
+ }
3314
+ this.remoteHandlerRegistered = true;
3315
+ this.dispatcher.register({
3316
+ topic: AXM_REALTIME_TOPIC_CONVERSATION_COMMENT,
3317
+ handle: (envelope) => {
3318
+ this.applyRemotePayload(envelope.payload);
3319
+ },
3320
+ });
3321
+ }
3322
+ applyRemotePayload(payload) {
3323
+ const messageId = payload?.messageId?.trim() ?? '';
3324
+ const threadId = payload?.conversationId?.trim() ?? '';
3325
+ const op = payload?.op;
3326
+ if (!messageId || !threadId || !op) {
3327
+ return;
3328
+ }
3329
+ if ((this.watchedThreads.get(threadId) ?? 0) < 1) {
3330
+ return;
3331
+ }
3332
+ if (op === 'deleted') {
3333
+ this.notifyComment({ type: 'remove', payload: messageId, threadId });
3334
+ return;
3335
+ }
3336
+ const comment = payload ? axmCommentFromRealtimePayload(payload) : null;
3337
+ if (!comment) {
3338
+ return;
3339
+ }
3340
+ if (comment.deleted) {
3341
+ this.notifyComment({ type: 'remove', payload: messageId, threadId });
3342
+ return;
3343
+ }
3344
+ this.notifyComment({
3345
+ type: op === 'created' ? 'add' : 'update',
3346
+ payload: comment,
3347
+ threadId,
3348
+ });
3349
+ }
3350
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMCommentRealtimeServiceImpl, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
3237
3351
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMCommentRealtimeServiceImpl, providedIn: 'root' }); }
3238
3352
  }
3239
3353
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMCommentRealtimeServiceImpl, decorators: [{
@@ -3241,7 +3355,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
3241
3355
  args: [{
3242
3356
  providedIn: 'root',
3243
3357
  }]
3244
- }] });
3358
+ }], ctorParameters: () => [] });
3245
3359
 
3246
3360
  //#region ---- Comment Management Service ----
3247
3361
  class AXMCommentManagementService {
@@ -3341,6 +3455,10 @@ class AXMCommentManagementService {
3341
3455
  }
3342
3456
  return this.formatThread(room);
3343
3457
  }
3458
+ /** Room row only, so the view can join realtime before messages are loaded. */
3459
+ findThreadRoom(entityRef, topic) {
3460
+ return this.commentImplService.getThread(entityRef, topic);
3461
+ }
3344
3462
  async countCommentsForEntity(entityRef) {
3345
3463
  const rooms = await this.commentImplService.listRoomsForEntity(entityRef);
3346
3464
  let total = 0;
@@ -3379,7 +3497,7 @@ class AXMCommentManagementService {
3379
3497
  const author = userId ? await this.getUserInfo(userId) : this.getCurrentUser();
3380
3498
  const rawComment = await this.commentImplService.addComment(threadId, content, author, parentCommentId, contentType);
3381
3499
  const formattedComment = this.formatComment(rawComment);
3382
- this.realtimeService.notifyComment({ type: 'add', payload: formattedComment });
3500
+ this.emitComment('add', formattedComment);
3383
3501
  return formattedComment;
3384
3502
  }
3385
3503
  async getComments(threadId, nested) {
@@ -3398,13 +3516,21 @@ class AXMCommentManagementService {
3398
3516
  const editor = this.getCurrentUser();
3399
3517
  const rawComment = await this.commentImplService.editComment(commentId, content, editor, contentType);
3400
3518
  const formattedComment = this.formatComment(rawComment);
3401
- this.realtimeService.notifyComment({ type: 'update', payload: formattedComment });
3519
+ this.emitComment('update', formattedComment);
3402
3520
  return formattedComment;
3403
3521
  }
3404
3522
  async deleteComment(commentId) {
3523
+ let threadId = '';
3524
+ try {
3525
+ const existing = await this.commentImplService.getComment(commentId);
3526
+ threadId = existing.conversationId?.trim() ?? '';
3527
+ }
3528
+ catch {
3529
+ threadId = '';
3530
+ }
3405
3531
  const result = await this.commentImplService.deleteComment(commentId);
3406
3532
  if (result) {
3407
- this.realtimeService.notifyComment({ type: 'remove', payload: commentId });
3533
+ this.realtimeService.notifyComment({ type: 'remove', payload: commentId, threadId });
3408
3534
  }
3409
3535
  return result;
3410
3536
  }
@@ -3423,7 +3549,7 @@ class AXMCommentManagementService {
3423
3549
  ];
3424
3550
  const rawComment = await this.commentImplService.updateReactions(commentId, updatedReactions);
3425
3551
  const formattedComment = this.formatComment(rawComment);
3426
- this.realtimeService.notifyComment({ type: 'update', payload: formattedComment });
3552
+ this.emitComment('update', formattedComment);
3427
3553
  return formattedComment;
3428
3554
  }
3429
3555
  async removeReaction(commentId, emoji) {
@@ -3432,7 +3558,7 @@ class AXMCommentManagementService {
3432
3558
  const updatedReactions = (comment.reactions || []).filter((r) => !(r.userId === author.id && r.emoji === emoji));
3433
3559
  const rawComment = await this.commentImplService.updateReactions(commentId, updatedReactions);
3434
3560
  const formattedComment = this.formatComment(rawComment);
3435
- this.realtimeService.notifyComment({ type: 'update', payload: formattedComment });
3561
+ this.emitComment('update', formattedComment);
3436
3562
  return formattedComment;
3437
3563
  }
3438
3564
  getReactions(commentId) {
@@ -3449,15 +3575,24 @@ class AXMCommentManagementService {
3449
3575
  async pinComment(commentId) {
3450
3576
  const rawComment = await this.commentImplService.pinComment(commentId, true);
3451
3577
  const formattedComment = this.formatComment(rawComment);
3452
- this.realtimeService.notifyComment({ type: 'update', payload: formattedComment });
3578
+ this.emitComment('update', formattedComment);
3453
3579
  return formattedComment;
3454
3580
  }
3455
3581
  async unpinComment(commentId) {
3456
3582
  const rawComment = await this.commentImplService.pinComment(commentId, false);
3457
3583
  const formattedComment = this.formatComment(rawComment);
3458
- this.realtimeService.notifyComment({ type: 'update', payload: formattedComment });
3584
+ this.emitComment('update', formattedComment);
3459
3585
  return formattedComment;
3460
3586
  }
3587
+ //#endregion
3588
+ //#region ---- Realtime publish ----
3589
+ emitComment(type, comment) {
3590
+ this.realtimeService.notifyComment({
3591
+ type,
3592
+ payload: comment,
3593
+ threadId: comment.conversationId,
3594
+ });
3595
+ }
3461
3596
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMCommentManagementService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
3462
3597
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMCommentManagementService, providedIn: 'root' }); }
3463
3598
  }
@@ -12364,28 +12499,6 @@ function createConversationServiceSessionAdapter(service) {
12364
12499
  }
12365
12500
  //#endregion
12366
12501
 
12367
- //#region ---- Comment in-app notification helper ----
12368
- function buildCommentInAppNotificationRequest(thread, comment, receiver) {
12369
- const body = axmExtractTextFromPayload(comment.payload) || 'New comment';
12370
- return {
12371
- id: `comment-in-app:${comment.id}`,
12372
- name: thread.title || 'Comment',
12373
- title: thread.title || 'New comment',
12374
- body,
12375
- icon: 'fa-light fa-comment',
12376
- priority: 'Notice',
12377
- receiver,
12378
- data: {
12379
- threadId: thread.id,
12380
- entityTypeId: thread.entityRef?.entityTypeId,
12381
- entityId: thread.entityRef?.entityId,
12382
- moduleName: thread.entityRef?.moduleName,
12383
- entityName: thread.entityRef?.entityName,
12384
- },
12385
- };
12386
- }
12387
- //#endregion
12388
-
12389
12502
  //#region ----- Imports -----
12390
12503
  //#endregion
12391
12504
  //#region ----- Constants -----
@@ -12431,6 +12544,9 @@ class AXMCommentComponent {
12431
12544
  this.commentActions = signal([], /* @ts-ignore */
12432
12545
  ...(ngDevMode ? [{ debugName: "commentActions" }] : /* istanbul ignore next */ []));
12433
12546
  this.refreshGeneration = 0;
12547
+ this.liveRevision = 0;
12548
+ this.watchedThreadId = null;
12549
+ this.realtimeReady = false;
12434
12550
  //#endregion
12435
12551
  //#region ----- View Children -----
12436
12552
  this.commentsView = viewChild('commentsView', { ...(ngDevMode ? { debugName: "commentsView" } : /* istanbul ignore next */ {}), read: AXCommentViewComponent });
@@ -12440,12 +12556,10 @@ class AXMCommentComponent {
12440
12556
  //#region ----- Services & Dependencies -----
12441
12557
  this.commentService = inject(AXMCommentManagementService);
12442
12558
  this.realtimeService = inject(AXMCommentRealtimeService);
12559
+ this.realtimeConnection = inject(AXPRealtimeConnectionService, { optional: true });
12443
12560
  this.sessionService = inject(AXPSessionService);
12444
12561
  this.toastService = inject(AXToastService);
12445
12562
  this.dialogService = inject(AXDialogService);
12446
- this.inAppNotificationService = inject(AXP_IN_APP_NOTIFICATION_SERVICE, {
12447
- optional: true,
12448
- });
12449
12563
  this.activatedRoute = inject(ActivatedRoute);
12450
12564
  this.translationService = inject(AXTranslationService);
12451
12565
  this.destroyRef = inject(DestroyRef);
@@ -12460,9 +12574,19 @@ class AXMCommentComponent {
12460
12574
  this.moduleName.set(this.activatedRoute.snapshot.params['module'] || null);
12461
12575
  this.entityName.set(this.activatedRoute.snapshot.params['entity'] || null);
12462
12576
  void this.initialize();
12577
+ this.destroyRef.onDestroy(() => {
12578
+ if (this.watchedThreadId) {
12579
+ this.realtimeService.unwatchThread(this.watchedThreadId);
12580
+ this.watchedThreadId = null;
12581
+ }
12582
+ });
12463
12583
  this.realtimeService.comment$
12464
- .pipe(takeUntilDestroyed(this.destroyRef), filter((event) => !!event))
12584
+ .pipe(takeUntilDestroyed(this.destroyRef), filter((event) => {
12585
+ const threadId = this.thread()?.id;
12586
+ return !!event?.threadId && !!threadId && event.threadId === threadId;
12587
+ }))
12465
12588
  .subscribe((event) => {
12589
+ this.liveRevision++;
12466
12590
  switch (event.type) {
12467
12591
  case 'add':
12468
12592
  void this.handleAddComment(event.payload);
@@ -12475,6 +12599,16 @@ class AXMCommentComponent {
12475
12599
  break;
12476
12600
  }
12477
12601
  });
12602
+ this.realtimeConnection?.connectionStatus$
12603
+ .pipe(pairwise(), filter(([previous, current]) => previous !== 'connected' && current === 'connected'), takeUntilDestroyed(this.destroyRef))
12604
+ .subscribe(() => {
12605
+ if (!this.realtimeReady || this.isLoading() || !this.thread()?.id) {
12606
+ return;
12607
+ }
12608
+ void this.applyServerComments().catch((error) => {
12609
+ console.error('Failed to refresh comments after reconnect:', error);
12610
+ });
12611
+ });
12478
12612
  }
12479
12613
  //#endregion
12480
12614
  //#region ----- Data Loading -----
@@ -12482,6 +12616,7 @@ class AXMCommentComponent {
12482
12616
  await this.loadActionItems();
12483
12617
  await this.loadComments();
12484
12618
  this.isLoading.set(false);
12619
+ this.realtimeReady = true;
12485
12620
  }
12486
12621
  async loadComments() {
12487
12622
  try {
@@ -12491,17 +12626,17 @@ class AXMCommentComponent {
12491
12626
  moduleName: this.moduleName(),
12492
12627
  entityName: this.entityName(),
12493
12628
  };
12494
- const thread = await this.commentService.getThread(entityRef, this.subject());
12495
- if (thread) {
12496
- this.thread.set(thread);
12497
- this.comments.set(thread.comments || []);
12629
+ const room = await this.commentService.findThreadRoom(entityRef, this.subject());
12630
+ if (room) {
12631
+ this.thread.set({ ...room, comments: [], commentCount: 0 });
12632
+ this.bindRealtimeThread(room.id);
12498
12633
  }
12499
12634
  else {
12500
12635
  const newThread = await this.commentService.createThread(entityRef, this.subject());
12501
12636
  this.thread.set(newThread);
12502
- this.comments.set(newThread.comments || []);
12637
+ this.bindRealtimeThread(newThread.id);
12503
12638
  }
12504
- await this.refreshItems();
12639
+ await this.applyServerComments();
12505
12640
  }
12506
12641
  catch (error) {
12507
12642
  console.error('Failed to load comments:', error);
@@ -12750,10 +12885,15 @@ class AXMCommentComponent {
12750
12885
  //#endregion
12751
12886
  //#region ----- Realtime Event Handlers -----
12752
12887
  async handleAddComment(comment) {
12753
- if (comment.senderId !== this.getCurrentUser()?.id && this.thread()) {
12754
- void this.inAppNotificationService?.create(buildCommentInAppNotificationRequest(this.thread(), comment, this.sessionService.user));
12888
+ if (containsComment(this.comments(), comment.id)) {
12889
+ await this.handleUpdateComment(comment);
12890
+ return;
12755
12891
  }
12756
12892
  const parentId = comment.replyTo?.id;
12893
+ if (parentId && !containsComment(this.comments(), parentId)) {
12894
+ await this.applyServerComments();
12895
+ return;
12896
+ }
12757
12897
  if (parentId) {
12758
12898
  this.expandReplies(parentId);
12759
12899
  this.comments.update((comments) => insertReply(comments, parentId, comment));
@@ -12764,6 +12904,10 @@ class AXMCommentComponent {
12764
12904
  await this.refreshItems();
12765
12905
  }
12766
12906
  async handleUpdateComment(updatedComment) {
12907
+ if (!containsComment(this.comments(), updatedComment.id)) {
12908
+ await this.handleAddComment(updatedComment);
12909
+ return;
12910
+ }
12767
12911
  const update = (list) => list.map((c) => {
12768
12912
  if (c.id === updatedComment.id) {
12769
12913
  return {
@@ -12789,17 +12933,49 @@ class AXMCommentComponent {
12789
12933
  return user ? { id: user.id, type: 'user' } : null;
12790
12934
  }
12791
12935
  async removeMessageById(commentId) {
12936
+ if (this.editing()?.id === commentId) {
12937
+ this.cancelEdit();
12938
+ }
12939
+ if (this.replyingTo()?.id === commentId) {
12940
+ this.cancelReply();
12941
+ }
12792
12942
  const filterOut = (comments) => comments
12793
12943
  .filter((c) => c.id !== commentId)
12794
12944
  .map((c) => {
12795
- if (c.replies?.length) {
12796
- return { ...c, replies: filterOut(c.replies) };
12945
+ if (!c.replies?.length) {
12946
+ return c;
12797
12947
  }
12798
- return c;
12948
+ const replies = filterOut(c.replies);
12949
+ return { ...c, replies, replyCount: replies.length };
12799
12950
  });
12800
12951
  this.comments.update((comments) => filterOut(comments));
12801
12952
  await this.refreshItems();
12802
12953
  }
12954
+ bindRealtimeThread(threadId) {
12955
+ const next = threadId.trim();
12956
+ if (!next || this.watchedThreadId === next) {
12957
+ return;
12958
+ }
12959
+ if (this.watchedThreadId) {
12960
+ this.realtimeService.unwatchThread(this.watchedThreadId);
12961
+ }
12962
+ this.watchedThreadId = next;
12963
+ this.realtimeService.watchThread(next);
12964
+ }
12965
+ async applyServerComments(attempt = 0) {
12966
+ const threadId = this.thread()?.id;
12967
+ if (!threadId || attempt > 3) {
12968
+ return;
12969
+ }
12970
+ const seen = this.liveRevision;
12971
+ const comments = await this.commentService.getComments(threadId, true);
12972
+ if (seen !== this.liveRevision || this.thread()?.id !== threadId) {
12973
+ await this.applyServerComments(attempt + 1);
12974
+ return;
12975
+ }
12976
+ this.comments.set(comments);
12977
+ await this.refreshItems();
12978
+ }
12803
12979
  readEditorHtml() {
12804
12980
  const service = this.editor()?.getEditorService();
12805
12981
  if (service && !service.isEmpty()) {
@@ -12821,6 +12997,11 @@ class AXMCommentComponent {
12821
12997
  return;
12822
12998
  }
12823
12999
  this.commentItems.set(items);
13000
+ // The installed comment view can ignore a replaced datasource until reloadData
13001
+ // copies it into the list that the template actually renders.
13002
+ setTimeout(() => {
13003
+ void this.commentsView()?.reloadData();
13004
+ });
12824
13005
  }
12825
13006
  async mapComment(comment) {
12826
13007
  const profile = await this.resolveProfile(comment.senderId);
@@ -12917,7 +13098,7 @@ class AXMCommentComponent {
12917
13098
  this.showToast(content, color);
12918
13099
  }
12919
13100
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMCommentComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
12920
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXMCommentComponent, isStandalone: true, selector: "axm-comment", inputs: { refrenceType: { classPropertyName: "refrenceType", publicName: "refrenceType", isSignal: true, isRequired: true, transformFunction: null }, refrenceId: { classPropertyName: "refrenceId", publicName: "refrenceId", isSignal: true, isRequired: true, transformFunction: null }, subject: { classPropertyName: "subject", publicName: "subject", isSignal: true, isRequired: true, transformFunction: null } }, viewQueries: [{ propertyName: "commentsView", first: true, predicate: ["commentsView"], descendants: true, read: AXCommentViewComponent, isSignal: true }, { propertyName: "commentContainer", first: true, predicate: ["commentContainer"], descendants: true, read: AXCommentContainerComponent, isSignal: true }, { propertyName: "editor", first: true, predicate: ["commentEditor"], descendants: true, read: AXTextEditorComponent, isSignal: true }], ngImport: i0, template: "<div class=\"axm-comment\">\n <ax-comment-container #commentContainer>\n <!-- ----- Loading skeleton while comments are fetched ----- -->\n @if (isLoading()) {\n <div class=\"axm-comment__list axm-comment__list--loading\">\n @for (skeleton of [0, 1, 2]; track skeleton) {\n <div class=\"axm-comment__skeleton\" [class.axm-comment__skeleton--compact]=\"skeleton > 0\">\n <ax-skeleton class=\"size-9 shrink-0 rounded-full\"></ax-skeleton>\n <div class=\"axm-comment__skeleton-body\">\n <ax-skeleton class=\"h-3.5 w-28 rounded\"></ax-skeleton>\n <ax-skeleton class=\"h-3 w-full rounded-full\"></ax-skeleton>\n <ax-skeleton class=\"h-3 w-11/12 rounded-full\"></ax-skeleton>\n <!--------------------------------------------------------------->\n <!-- ----- Extra skeleton line on first row ----- -->\n @if (skeleton === 0) {\n <ax-skeleton class=\"h-3 w-2/3 rounded-full\"></ax-skeleton>\n }\n </div>\n </div>\n }\n </div>\n }\n <!-- ----- Empty state when the thread has no comments ----- -->\n @else if (comments().length === 0) {\n <div class=\"axm-comment__empty\">\n <axp-state-message\n icon=\"fa-light fa-comments\"\n [title]=\"'@conversation:comments.components.comment.empty-states.no-comments.title'\"\n [description]=\"'@conversation:comments.components.comment.empty-states.no-comments.description'\"\n ></axp-state-message>\n </div>\n }\n <!-- ----- Comment thread from the mapped datasource ----- -->\n @else {\n <div class=\"axm-comment__list\">\n <ax-comment-view #commentsView [datasource]=\"commentItems()\" (onReply)=\"onReply($event)\" (onLikeChange)=\"onLikeChange($event)\" (onRepliesToggle)=\"onRepliesToggle($event)\" (onAction)=\"onAction($event)\">\n <ng-template axCommentItem let-item>\n <div class=\"flex min-w-0 items-start gap-2\">\n <axp-user-avatar class=\"shrink-0\" [size]=\"42\" [userId]=\"commentSenderId(item)\" [axpUserCard]=\"commentSenderId(item)\"></axp-user-avatar>\n <div class=\"min-w-0 flex-1\">\n <div class=\"flex min-w-0 items-center justify-between gap-2\">\n <div class=\"flex min-w-0 flex-wrap items-center\">\n <ax-title [axpUserCard]=\"commentSenderId(item)\">{{ item.author }}</ax-title>\n <!--------------------------------------------------------------->\n <!-- ----- You badge for the current user's comment ----- -->\n @if (item.isYou) {\n <ax-badge class=\"ax-sm ax-pill ax-comment-you-badge\" look=\"twotone\" color=\"primary\" [text]=\"('@acorex:comment.you' | translate | async) ?? 'You'\"></ax-badge>\n }\n <!--------------------------------------------------------------->\n <!-- ----- Edited label (before timestamp) ----- -->\n @if (item.edited) {\n <ax-comment-edited [editedAt]=\"item.editedAt\" />\n }\n <!--------------------------------------------------------------->\n <!-- ----- Relative timestamp for this comment ----- -->\n @if (item.date) {\n <ax-comment-date>{{ item.date }}</ax-comment-date>\n }\n </div>\n <!--------------------------------------------------------------->\n <!-- ----- Overflow menu from item actions ----- -->\n @if (item.actions?.length) {\n <ax-dropdown-button class=\"ax-sm\" mode=\"dropdown\" look=\"blank\" [iconOnly]=\"true\" [text]=\"('@conversation:comments.actions.more' | translate | async) ?? ''\">\n <ax-prefix>\n <ax-icon icon=\"ax-icon ax-icon-more-horizontal\"></ax-icon>\n </ax-prefix>\n <ax-button-item-list>\n @for (action of item.actions; track action.name ?? action.text) {\n <ax-button-item [text]=\"action.text\" [color]=\"action.color\" (onClick)=\"onOverflowAction(item, action.name ?? action.text)\">\n <!--------------------------------------------------------------->\n <!-- ----- Action icon when the menu item has one ----- -->\n @if (action.icon) {\n <ax-prefix>\n <ax-icon [icon]=\"action.icon\"></ax-icon>\n </ax-prefix>\n }\n </ax-button-item>\n }\n </ax-button-item-list>\n </ax-dropdown-button>\n }\n </div>\n <ax-content>\n <div [innerHTML]=\"item.content\"></div>\n </ax-content>\n </div>\n </div>\n </ng-template>\n </ax-comment-view>\n </div>\n }\n\n <ax-footer style=\"padding: 0.1rem\">\n <!-- ----- Edit context above the composer ----- -->\n @if (editing(); as editItem) {\n <div class=\"axm-comment__context-bar\" tabindex=\"0\" (click)=\"scrollToCommentContext(editItem)\" (keydown.enter)=\"scrollToCommentContext(editItem)\" (keydown.space)=\"$event.preventDefault(); scrollToCommentContext(editItem)\">\n <div class=\"axm-comment__context-bar-body\">\n <i class=\"fa-light fa-pen axm-comment__context-bar-icon\" aria-hidden=\"true\"></i>\n <span class=\"axm-comment__context-bar-copy\">\n <span class=\"axm-comment__context-bar-label\">{{ '@conversation:comments.actions.edit-message' | translate | async }}</span>\n @if (commentContextPreview(editItem.content); as preview) {\n <span class=\"axm-comment__context-bar-preview\" [title]=\"preview\">{{ preview }}</span>\n }\n </span>\n </div>\n <button type=\"button\" class=\"axm-comment__context-bar-close\" (click)=\"$event.stopPropagation(); cancelEdit()\" [attr.aria-label]=\"('@conversation:comments.actions.cancel.title' | translate | async) ?? 'Cancel'\">\n <i class=\"fa-light fa-xmark\" aria-hidden=\"true\"></i>\n </button>\n </div>\n }\n <!-- ----- Reply context above the composer ----- -->\n @else if (replyingTo(); as replyItem) {\n <div class=\"axm-comment__context-bar\" tabindex=\"0\" (click)=\"scrollToCommentContext(replyItem)\" (keydown.enter)=\"scrollToCommentContext(replyItem)\" (keydown.space)=\"$event.preventDefault(); scrollToCommentContext(replyItem)\">\n <div class=\"axm-comment__context-bar-body\">\n <i class=\"fa-light fa-reply axm-comment__context-bar-icon\" aria-hidden=\"true\"></i>\n <span class=\"axm-comment__context-bar-copy\">\n <span class=\"axm-comment__context-bar-label\">\n {{ '@conversation:comments.actions.reply-to' | translate | async }}\n <span class=\"axm-comment__context-bar-name\">\n @if (replyItem.isYou) {\n {{ '@acorex:comment.you' | translate | async }}\n } @else {\n {{ replyItem.author }}\n }\n </span>\n </span>\n @if (commentContextPreview(replyItem.content); as preview) {\n <span class=\"axm-comment__context-bar-preview\" [title]=\"preview\">{{ preview }}</span>\n }\n </span>\n </div>\n <button type=\"button\" class=\"axm-comment__context-bar-close\" (click)=\"$event.stopPropagation(); cancelReply()\" [attr.aria-label]=\"('@conversation:comments.actions.cancel.title' | translate | async) ?? 'Cancel'\">\n <i class=\"fa-light fa-xmark\" aria-hidden=\"true\"></i>\n </button>\n </div>\n }\n\n <ax-comment-reply>\n <ax-text-editor\n #commentEditor\n look=\"solid\"\n outputFormat=\"html\"\n [initialLine]=\"3\"\n [ngModel]=\"draft()\"\n (ngModelChange)=\"draft.set($event)\"\n [placeHolder]=\"((editing() ? '@conversation:comments.actions.edit-message' : replyingTo() ? '@conversation:comments.composer.reply-placeholder' : '@conversation:comments.composer.placeholder') | translate | async) ?? ''\"\n >\n <ax-footer>\n <div class=\"axm-comment__editor-actions\">\n <ax-button\n class=\"axm-comment__send ax-sm\"\n look=\"solid\"\n color=\"primary\"\n [disabled]=\"hasCooldown() || isCommentDraftEmpty() || isSubmitting()\"\n [text]=\"(editing() ? '@conversation:comments.actions.edit.title' : '@conversation:comments.actions.send.title') | translate | async\"\n (onClick)=\"submitComment()\"\n >\n @if (isSubmitting()) {\n <ax-loading></ax-loading>\n } @else {\n <!-- ----- Send icon when not submitting ----- -->\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-paper-plane-top\"></ax-icon>\n </ax-prefix>\n }\n </ax-button>\n </div>\n </ax-footer>\n <ax-text-editor-toolbar class=\"border-b\">\n <ax-text-editor-history></ax-text-editor-history>\n <ax-divider></ax-divider>\n <ax-text-editor-font-style></ax-text-editor-font-style>\n <ax-divider></ax-divider>\n <ax-text-editor-colors></ax-text-editor-colors>\n <ax-divider></ax-divider>\n <ax-text-editor-list></ax-text-editor-list>\n <ax-divider></ax-divider>\n <ax-text-editor-alignment></ax-text-editor-alignment>\n </ax-text-editor-toolbar>\n </ax-text-editor>\n </ax-comment-reply>\n </ax-footer>\n </ax-comment-container>\n</div>\n", styles: ["@layer properties;:host{display:block;height:100%;min-height:0px;width:100%}ax-comment-container{display:flex;flex-direction:column;justify-content:space-between;height:100%}.axm-comment{display:flex;width:100%;height:100%;min-height:0px;flex-direction:column;overflow:hidden;background-color:rgb(var(--ax-sys-color-lightest-surface))}.axm-comment .axm-comment__list{min-height:0px;flex:1;overflow-y:auto;padding:1rem 1rem 1.25rem;scroll-behavior:smooth}.axm-comment .axm-comment__list.axm-comment__list--loading{display:flex;flex-direction:column;gap:1.25rem}.axm-comment .axm-comment__empty{display:flex;min-height:min(16rem,40vh);flex:1;flex-direction:column;align-items:center;justify-content:center;padding:2rem 1.25rem}.axm-comment .axm-comment__skeleton{display:flex;align-items:flex-start;gap:.75rem}.axm-comment .axm-comment__skeleton.axm-comment__skeleton--compact .axm-comment__skeleton-body{gap:.375rem}.axm-comment .axm-comment__skeleton-body{display:flex;min-width:0px;flex:1;flex-direction:column;gap:calc(var(--spacing, .25rem) * 2)}.axm-comment .axm-comment__context-bar{display:flex;min-width:0px;cursor:pointer;align-items:flex-start;gap:calc(var(--spacing, .25rem) * 2);margin-block-end:8px;padding:.5rem .75rem;border:1px solid rgb(var(--ax-sys-color-border-light-surface));border-radius:6px;border-inline-start:3px solid rgb(var(--ax-sys-color-primary-surface));background-color:rgba(var(--ax-sys-color-primary-lightest-surface),.4);font-size:.8125rem;line-height:1.45}.axm-comment .axm-comment__context-bar:hover{background-color:rgba(var(--ax-sys-color-primary-lightest-surface),.55)}.axm-comment .axm-comment__context-bar:focus-visible{outline:2px solid rgb(var(--ax-sys-color-primary-surface));outline-offset:2px}.axm-comment .axm-comment__context-bar-body{display:flex;min-width:0px;flex:1;align-items:flex-start;text-align:start;gap:.625rem;overflow:hidden;pointer-events:none}.axm-comment .axm-comment__context-bar-icon{flex-shrink:0;font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-leading: 1;line-height:1;margin-top:.125rem;color:rgb(var(--ax-sys-color-primary-surface))}.axm-comment .axm-comment__context-bar-copy{display:flex;min-width:0px;flex:1;flex-direction:column;gap:.125rem;overflow:hidden}.axm-comment .axm-comment__context-bar-label{flex-shrink:0;font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-leading: calc(var(--spacing, .25rem) * 4);line-height:calc(var(--spacing, .25rem) * 4);color:rgb(var(--ax-sys-color-neutral-700-surface, 55 65 81))}.axm-comment .axm-comment__context-bar-name{--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:rgb(var(--ax-sys-color-neutral-900-surface, 17 24 39))}.axm-comment .axm-comment__context-bar-preview{min-width:0px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:start;font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-leading: calc(var(--spacing, .25rem) * 4);line-height:calc(var(--spacing, .25rem) * 4);color:rgb(var(--ax-sys-color-neutral-600-surface, 107 114 128))}.axm-comment .axm-comment__context-bar-close{position:relative;z-index:1;display:inline-flex;flex-shrink:0;align-items:center;justify-content:center;align-self:flex-start;border-radius:var(--radius-sm, .25rem);width:1.75rem;height:1.75rem;margin-inline-start:-.25rem;padding:0;border:none;background:transparent;color:rgb(var(--ax-sys-color-neutral-500-surface, 107 114 128));font-size:1rem;line-height:1;cursor:pointer}.axm-comment .axm-comment__context-bar-close:hover{background-color:rgba(var(--ax-sys-color-neutral-100-surface, 243 244 246),.9);color:rgb(var(--ax-sys-color-neutral-700-surface, 55 65 81))}.axm-comment .axm-comment__context-bar-close:focus-visible{outline:2px solid rgb(var(--ax-sys-color-primary-surface));outline-offset:2px}.axm-comment .axm-comment__editor-actions{display:flex;align-items:center;justify-content:flex-end;gap:calc(var(--spacing, .25rem) * 2);padding:var(--spacing, .25rem)}.axm-comment .axm-comment__send{min-width:5.5rem}@property --tw-leading{syntax: \"*\"; inherits: false;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-leading: initial;--tw-font-weight: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: AXTextEditorModule }, { kind: "component", type: i1$3.AXTextEditorComponent, selector: "ax-text-editor", inputs: ["disabled", "tabIndex", "readonly", "value", "state", "name", "look", "placeHolder", "outputFormat", "line", "initialLine", "maxLine"], outputs: ["onBlur", "onFocus", "valueChange", "stateChange", "onValueChanged", "readonlyChange", "disabledChange"] }, { kind: "component", type: i1$3.AXTextEditorToolbarComponent, selector: "ax-text-editor-toolbar", inputs: ["orientation"] }, { kind: "component", type: i1$3.AXTextEditorHistoryComponent, selector: "ax-text-editor-history" }, { kind: "component", type: i1$3.AXTextEditorFontStyleComponent, selector: "ax-text-editor-font-style" }, { kind: "component", type: i1$3.AXTextEditorAlignmentComponent, selector: "ax-text-editor-alignment" }, { kind: "component", type: i1$3.AXTextEditorColorsComponent, selector: "ax-text-editor-colors" }, { kind: "component", type: i1$3.AXTextEditorListComponent, selector: "ax-text-editor-list" }, { kind: "ngmodule", type: AXSkeletonModule }, { kind: "component", type: i2$1.AXSkeletonComponent, selector: "ax-skeleton", inputs: ["animated"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i2.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXCommentModule }, { kind: "component", type: i4.AXCommentViewComponent, selector: "ax-comment-view", inputs: ["datasource", "itemTemplate"], outputs: ["datasourceChange", "onReply", "onLikeChange", "onRepliesToggle", "onAction"] }, { kind: "component", type: i4.AXCommentContainerComponent, selector: "ax-comment-container" }, { kind: "component", type: i4.AXCommentReplyComponent, selector: "ax-comment-reply", inputs: ["item"], outputs: ["onClose", "onTargetClick"] }, { kind: "component", type: i4.AXCommentDateComponent, selector: "ax-comment-date" }, { kind: "component", type: i4.AXCommentEditedComponent, selector: "ax-comment-edited", inputs: ["editedAt"] }, { kind: "directive", type: i4.AXCommentItemTemplateDirective, selector: "ng-template[axCommentItem]" }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "component", type: i1.AXBadgeComponent, selector: "ax-badge", inputs: ["color", "look", "text"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1$1.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "component", type: i1$1.AXButtonItemComponent, selector: "ax-button-item", inputs: ["color", "disabled", "text", "selected", "divided", "data", "name"], outputs: ["onClick", "onFocus", "onBlur", "disabledChange"] }, { kind: "component", type: i1$1.AXButtonItemListComponent, selector: "ax-button-item-list", inputs: ["items", "closeParentOnClick", "lockOnLoading"], outputs: ["onItemClick"] }, { kind: "ngmodule", type: AXDropdownButtonModule }, { kind: "component", type: i7.AXDropdownButtonComponent, selector: "ax-dropdown-button", inputs: ["disabled", "size", "text", "selected", "color", "look", "type", "mode", "iconOnly"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "lookChange", "colorChange", "disabledChange"] }, { kind: "ngmodule", type: AXLoadingModule }, { kind: "component", type: i8.AXLoadingComponent, selector: "ax-loading", inputs: ["visible", "type", "context"], outputs: ["visibleChange"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: AXPStateMessageComponent, selector: "axp-state-message", inputs: ["mode", "icon", "title", "description", "titleParams", "descriptionParams", "look"] }, { kind: "component", type: AXPUserAvatarComponent, selector: "axp-user-avatar", inputs: ["size", "userId", "showPresence", "displayName", "displayAvatar"] }, { kind: "directive", type: AXPUserCardDirective, selector: "[axpUserCard]", inputs: ["axpUserCard", "axpUserCardDisabled", "axpUserCardTrigger"] }, { kind: "pipe", type: i1$2.AXTranslatorPipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
13101
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXMCommentComponent, isStandalone: true, selector: "axm-comment", inputs: { refrenceType: { classPropertyName: "refrenceType", publicName: "refrenceType", isSignal: true, isRequired: true, transformFunction: null }, refrenceId: { classPropertyName: "refrenceId", publicName: "refrenceId", isSignal: true, isRequired: true, transformFunction: null }, subject: { classPropertyName: "subject", publicName: "subject", isSignal: true, isRequired: true, transformFunction: null } }, viewQueries: [{ propertyName: "commentsView", first: true, predicate: ["commentsView"], descendants: true, read: AXCommentViewComponent, isSignal: true }, { propertyName: "commentContainer", first: true, predicate: ["commentContainer"], descendants: true, read: AXCommentContainerComponent, isSignal: true }, { propertyName: "editor", first: true, predicate: ["commentEditor"], descendants: true, read: AXTextEditorComponent, isSignal: true }], ngImport: i0, template: "<div class=\"axm-comment\">\n <ax-comment-container #commentContainer>\n <!-- ----- Loading skeleton while comments are fetched ----- -->\n @if (isLoading()) {\n <div class=\"axm-comment__list axm-comment__list--loading\">\n @for (skeleton of [0, 1, 2]; track skeleton) {\n <div class=\"axm-comment__skeleton\" [class.axm-comment__skeleton--compact]=\"skeleton > 0\">\n <ax-skeleton class=\"size-9 shrink-0 rounded-full\"></ax-skeleton>\n <div class=\"axm-comment__skeleton-body\">\n <ax-skeleton class=\"h-3.5 w-28 rounded\"></ax-skeleton>\n <ax-skeleton class=\"h-3 w-full rounded-full\"></ax-skeleton>\n <ax-skeleton class=\"h-3 w-11/12 rounded-full\"></ax-skeleton>\n <!--------------------------------------------------------------->\n <!-- ----- Extra skeleton line on first row ----- -->\n @if (skeleton === 0) {\n <ax-skeleton class=\"h-3 w-2/3 rounded-full\"></ax-skeleton>\n }\n </div>\n </div>\n }\n </div>\n }\n <!-- ----- Empty state when the thread has no comments ----- -->\n @else if (comments().length === 0) {\n <div class=\"axm-comment__empty\">\n <axp-state-message\n icon=\"fa-light fa-comments\"\n [title]=\"'@conversation:comments.components.comment.empty-states.no-comments.title'\"\n [description]=\"'@conversation:comments.components.comment.empty-states.no-comments.description'\"\n ></axp-state-message>\n </div>\n }\n <!-- ----- Comment thread from the mapped datasource ----- -->\n @else {\n <div class=\"axm-comment__list\">\n <ax-comment-view #commentsView [datasource]=\"commentItems()\" (onReply)=\"onReply($event)\" (onLikeChange)=\"onLikeChange($event)\" (onRepliesToggle)=\"onRepliesToggle($event)\" (onAction)=\"onAction($event)\">\n <ng-template axCommentItem let-item>\n <div class=\"flex min-w-0 items-start gap-2\">\n <axp-user-avatar class=\"shrink-0\" [size]=\"42\" [userId]=\"commentSenderId(item)\" [axpUserCard]=\"commentSenderId(item)\"></axp-user-avatar>\n <div class=\"min-w-0 flex-1\">\n <div class=\"flex min-w-0 items-center justify-between gap-2\">\n <div class=\"flex min-w-0 flex-wrap items-center\">\n <ax-title [axpUserCard]=\"commentSenderId(item)\">{{ item.author }}</ax-title>\n <!--------------------------------------------------------------->\n <!-- ----- You badge for the current user's comment ----- -->\n @if (item.isYou) {\n <ax-badge class=\"ax-sm ax-pill ax-comment-you-badge\" look=\"twotone\" color=\"primary\" [text]=\"('@acorex:comment.you' | translate | async) ?? 'You'\"></ax-badge>\n }\n <!--------------------------------------------------------------->\n <!-- ----- Edited label (before timestamp) ----- -->\n @if (item.edited) {\n <ax-comment-edited [editedAt]=\"item.editedAt\" />\n }\n <!--------------------------------------------------------------->\n <!-- ----- Relative timestamp for this comment ----- -->\n @if (item.date) {\n <ax-comment-date>{{ item.date }}</ax-comment-date>\n }\n </div>\n <!--------------------------------------------------------------->\n <!-- ----- Overflow menu from item actions ----- -->\n @if (item.actions?.length) {\n <ax-dropdown-button class=\"ax-sm\" mode=\"dropdown\" look=\"blank\" [iconOnly]=\"true\" [text]=\"('@conversation:comments.actions.more' | translate | async) ?? ''\">\n <ax-prefix>\n <ax-icon icon=\"ax-icon ax-icon-more-horizontal\"></ax-icon>\n </ax-prefix>\n <ax-button-item-list>\n @for (action of item.actions; track action.name ?? action.text) {\n <ax-button-item [text]=\"action.text\" [color]=\"action.color\" (onClick)=\"onOverflowAction(item, action.name ?? action.text)\">\n <!--------------------------------------------------------------->\n <!-- ----- Action icon when the menu item has one ----- -->\n @if (action.icon) {\n <ax-prefix>\n <ax-icon [icon]=\"action.icon\"></ax-icon>\n </ax-prefix>\n }\n </ax-button-item>\n }\n </ax-button-item-list>\n </ax-dropdown-button>\n }\n </div>\n <ax-content>\n <div [innerHTML]=\"item.content\"></div>\n </ax-content>\n </div>\n </div>\n </ng-template>\n </ax-comment-view>\n </div>\n }\n\n <ax-footer style=\"padding: 0.1rem\">\n <!-- ----- Edit context above the composer ----- -->\n @if (editing(); as editItem) {\n <div class=\"axm-comment__context-bar\" tabindex=\"0\" (click)=\"scrollToCommentContext(editItem)\" (keydown.enter)=\"scrollToCommentContext(editItem)\" (keydown.space)=\"$event.preventDefault(); scrollToCommentContext(editItem)\">\n <div class=\"axm-comment__context-bar-body\">\n <i class=\"fa-light fa-pen axm-comment__context-bar-icon\" aria-hidden=\"true\"></i>\n <span class=\"axm-comment__context-bar-copy\">\n <span class=\"axm-comment__context-bar-label\">{{ '@conversation:comments.actions.edit-message' | translate | async }}</span>\n @if (commentContextPreview(editItem.content); as preview) {\n <span class=\"axm-comment__context-bar-preview\" [title]=\"preview\">{{ preview }}</span>\n }\n </span>\n </div>\n <button type=\"button\" class=\"axm-comment__context-bar-close\" (click)=\"$event.stopPropagation(); cancelEdit()\" [attr.aria-label]=\"('@conversation:comments.actions.cancel.title' | translate | async) ?? 'Cancel'\">\n <i class=\"fa-light fa-xmark\" aria-hidden=\"true\"></i>\n </button>\n </div>\n }\n <!-- ----- Reply context above the composer ----- -->\n @else if (replyingTo(); as replyItem) {\n <div class=\"axm-comment__context-bar\" tabindex=\"0\" (click)=\"scrollToCommentContext(replyItem)\" (keydown.enter)=\"scrollToCommentContext(replyItem)\" (keydown.space)=\"$event.preventDefault(); scrollToCommentContext(replyItem)\">\n <div class=\"axm-comment__context-bar-body\">\n <i class=\"fa-light fa-reply axm-comment__context-bar-icon\" aria-hidden=\"true\"></i>\n <span class=\"axm-comment__context-bar-copy\">\n <span class=\"axm-comment__context-bar-label\">\n {{ '@conversation:comments.actions.reply-to' | translate | async }}\n <span class=\"axm-comment__context-bar-name\">\n @if (replyItem.isYou) {\n {{ '@acorex:comment.you' | translate | async }}\n } @else {\n {{ replyItem.author }}\n }\n </span>\n </span>\n @if (commentContextPreview(replyItem.content); as preview) {\n <span class=\"axm-comment__context-bar-preview\" [title]=\"preview\">{{ preview }}</span>\n }\n </span>\n </div>\n <button type=\"button\" class=\"axm-comment__context-bar-close\" (click)=\"$event.stopPropagation(); cancelReply()\" [attr.aria-label]=\"('@conversation:comments.actions.cancel.title' | translate | async) ?? 'Cancel'\">\n <i class=\"fa-light fa-xmark\" aria-hidden=\"true\"></i>\n </button>\n </div>\n }\n\n <ax-comment-reply>\n <ax-text-editor\n #commentEditor\n look=\"solid\"\n outputFormat=\"html\"\n [initialLine]=\"3\"\n [ngModel]=\"draft()\"\n (ngModelChange)=\"draft.set($event)\"\n [placeHolder]=\"((editing() ? '@conversation:comments.actions.edit-message' : replyingTo() ? '@conversation:comments.composer.reply-placeholder' : '@conversation:comments.composer.placeholder') | translate | async) ?? ''\"\n >\n <ax-footer>\n <div class=\"axm-comment__editor-actions\">\n <ax-button\n class=\"axm-comment__send ax-sm\"\n look=\"solid\"\n color=\"primary\"\n [disabled]=\"hasCooldown() || isCommentDraftEmpty() || isSubmitting()\"\n [text]=\"(editing() ? '@conversation:comments.actions.edit.title' : '@conversation:comments.actions.send.title') | translate | async\"\n (onClick)=\"submitComment()\"\n >\n @if (isSubmitting()) {\n <ax-loading></ax-loading>\n } @else {\n <!-- ----- Send icon when not submitting ----- -->\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-paper-plane-top\"></ax-icon>\n </ax-prefix>\n }\n </ax-button>\n </div>\n </ax-footer>\n <ax-text-editor-toolbar class=\"border-b\">\n <ax-text-editor-history></ax-text-editor-history>\n <ax-divider></ax-divider>\n <ax-text-editor-font-style></ax-text-editor-font-style>\n <ax-divider></ax-divider>\n <ax-text-editor-colors></ax-text-editor-colors>\n <ax-divider></ax-divider>\n <ax-text-editor-list></ax-text-editor-list>\n <ax-divider></ax-divider>\n <ax-text-editor-alignment></ax-text-editor-alignment>\n </ax-text-editor-toolbar>\n </ax-text-editor>\n </ax-comment-reply>\n </ax-footer>\n </ax-comment-container>\n</div>\n", styles: ["@layer properties;:host{display:block;height:100%;min-height:0px;width:100%}ax-comment-container{display:flex;flex-direction:column;justify-content:space-between;height:100%}.ax-comment-replies{padding-inline-start:1.75rem!important}.axm-comment{display:flex;width:100%;height:100%;min-height:0px;flex-direction:column;overflow:hidden;background-color:rgb(var(--ax-sys-color-lightest-surface))}.axm-comment .axm-comment__list{min-height:0px;flex:1;overflow-y:auto;padding:1rem 1rem 1.25rem;scroll-behavior:smooth}.axm-comment .axm-comment__list.axm-comment__list--loading{display:flex;flex-direction:column;gap:1.25rem}.axm-comment .axm-comment__empty{display:flex;min-height:min(16rem,40vh);flex:1;flex-direction:column;align-items:center;justify-content:center;padding:2rem 1.25rem}.axm-comment .axm-comment__skeleton{display:flex;align-items:flex-start;gap:.75rem}.axm-comment .axm-comment__skeleton.axm-comment__skeleton--compact .axm-comment__skeleton-body{gap:.375rem}.axm-comment .axm-comment__skeleton-body{display:flex;min-width:0px;flex:1;flex-direction:column;gap:calc(var(--spacing, .25rem) * 2)}.axm-comment .axm-comment__context-bar{display:flex;min-width:0px;cursor:pointer;align-items:flex-start;gap:calc(var(--spacing, .25rem) * 2);margin-block-end:8px;padding:.5rem .75rem;border:1px solid rgb(var(--ax-sys-color-border-light-surface));border-radius:6px;border-inline-start:3px solid rgb(var(--ax-sys-color-primary-surface));background-color:rgba(var(--ax-sys-color-primary-lightest-surface),.4);font-size:.8125rem;line-height:1.45}.axm-comment .axm-comment__context-bar:hover{background-color:rgba(var(--ax-sys-color-primary-lightest-surface),.55)}.axm-comment .axm-comment__context-bar:focus-visible{outline:2px solid rgb(var(--ax-sys-color-primary-surface));outline-offset:2px}.axm-comment .axm-comment__context-bar-body{display:flex;min-width:0px;flex:1;align-items:flex-start;text-align:start;gap:.625rem;overflow:hidden;pointer-events:none}.axm-comment .axm-comment__context-bar-icon{flex-shrink:0;font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-leading: 1;line-height:1;margin-top:.125rem;color:rgb(var(--ax-sys-color-primary-surface))}.axm-comment .axm-comment__context-bar-copy{display:flex;min-width:0px;flex:1;flex-direction:column;gap:.125rem;overflow:hidden}.axm-comment .axm-comment__context-bar-label{flex-shrink:0;font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-leading: calc(var(--spacing, .25rem) * 4);line-height:calc(var(--spacing, .25rem) * 4);color:rgb(var(--ax-sys-color-neutral-700-surface, 55 65 81))}.axm-comment .axm-comment__context-bar-name{--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:rgb(var(--ax-sys-color-neutral-900-surface, 17 24 39))}.axm-comment .axm-comment__context-bar-preview{min-width:0px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:start;font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-leading: calc(var(--spacing, .25rem) * 4);line-height:calc(var(--spacing, .25rem) * 4);color:rgb(var(--ax-sys-color-neutral-600-surface, 107 114 128))}.axm-comment .axm-comment__context-bar-close{position:relative;z-index:1;display:inline-flex;flex-shrink:0;align-items:center;justify-content:center;align-self:flex-start;border-radius:var(--radius-sm, .25rem);width:1.75rem;height:1.75rem;margin-inline-start:-.25rem;padding:0;border:none;background:transparent;color:rgb(var(--ax-sys-color-neutral-500-surface, 107 114 128));font-size:1rem;line-height:1;cursor:pointer}.axm-comment .axm-comment__context-bar-close:hover{background-color:rgba(var(--ax-sys-color-neutral-100-surface, 243 244 246),.9);color:rgb(var(--ax-sys-color-neutral-700-surface, 55 65 81))}.axm-comment .axm-comment__context-bar-close:focus-visible{outline:2px solid rgb(var(--ax-sys-color-primary-surface));outline-offset:2px}.axm-comment .axm-comment__editor-actions{display:flex;align-items:center;justify-content:flex-end;gap:calc(var(--spacing, .25rem) * 2);padding:var(--spacing, .25rem)}.axm-comment .axm-comment__send{min-width:5.5rem}@property --tw-leading{syntax: \"*\"; inherits: false;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-leading: initial;--tw-font-weight: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: AXTextEditorModule }, { kind: "component", type: i1$3.AXTextEditorComponent, selector: "ax-text-editor", inputs: ["disabled", "tabIndex", "readonly", "value", "state", "name", "look", "placeHolder", "outputFormat", "line", "initialLine", "maxLine"], outputs: ["onBlur", "onFocus", "valueChange", "stateChange", "onValueChanged", "readonlyChange", "disabledChange"] }, { kind: "component", type: i1$3.AXTextEditorToolbarComponent, selector: "ax-text-editor-toolbar", inputs: ["orientation"] }, { kind: "component", type: i1$3.AXTextEditorHistoryComponent, selector: "ax-text-editor-history" }, { kind: "component", type: i1$3.AXTextEditorFontStyleComponent, selector: "ax-text-editor-font-style" }, { kind: "component", type: i1$3.AXTextEditorAlignmentComponent, selector: "ax-text-editor-alignment" }, { kind: "component", type: i1$3.AXTextEditorColorsComponent, selector: "ax-text-editor-colors" }, { kind: "component", type: i1$3.AXTextEditorListComponent, selector: "ax-text-editor-list" }, { kind: "ngmodule", type: AXSkeletonModule }, { kind: "component", type: i2$1.AXSkeletonComponent, selector: "ax-skeleton", inputs: ["animated"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i2.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXCommentModule }, { kind: "component", type: i4.AXCommentViewComponent, selector: "ax-comment-view", inputs: ["datasource", "itemTemplate"], outputs: ["datasourceChange", "onReply", "onLikeChange", "onRepliesToggle", "onAction"] }, { kind: "component", type: i4.AXCommentContainerComponent, selector: "ax-comment-container" }, { kind: "component", type: i4.AXCommentReplyComponent, selector: "ax-comment-reply", inputs: ["item"], outputs: ["onClose", "onTargetClick"] }, { kind: "component", type: i4.AXCommentDateComponent, selector: "ax-comment-date" }, { kind: "component", type: i4.AXCommentEditedComponent, selector: "ax-comment-edited", inputs: ["editedAt"] }, { kind: "directive", type: i4.AXCommentItemTemplateDirective, selector: "ng-template[axCommentItem]" }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "component", type: i1.AXBadgeComponent, selector: "ax-badge", inputs: ["color", "look", "text"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1$1.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "component", type: i1$1.AXButtonItemComponent, selector: "ax-button-item", inputs: ["color", "disabled", "text", "selected", "divided", "data", "name"], outputs: ["onClick", "onFocus", "onBlur", "disabledChange"] }, { kind: "component", type: i1$1.AXButtonItemListComponent, selector: "ax-button-item-list", inputs: ["items", "closeParentOnClick", "lockOnLoading"], outputs: ["onItemClick"] }, { kind: "ngmodule", type: AXDropdownButtonModule }, { kind: "component", type: i7.AXDropdownButtonComponent, selector: "ax-dropdown-button", inputs: ["disabled", "size", "text", "selected", "color", "look", "type", "mode", "iconOnly"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "lookChange", "colorChange", "disabledChange"] }, { kind: "ngmodule", type: AXLoadingModule }, { kind: "component", type: i8.AXLoadingComponent, selector: "ax-loading", inputs: ["visible", "type", "context"], outputs: ["visibleChange"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: AXPStateMessageComponent, selector: "axp-state-message", inputs: ["mode", "icon", "title", "description", "titleParams", "descriptionParams", "look"] }, { kind: "component", type: AXPUserAvatarComponent, selector: "axp-user-avatar", inputs: ["size", "userId", "showPresence", "displayName", "displayAvatar"] }, { kind: "directive", type: AXPUserCardDirective, selector: "[axpUserCard]", inputs: ["axpUserCard", "axpUserCardDisabled", "axpUserCardTrigger"] }, { kind: "pipe", type: i1$2.AXTranslatorPipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
12921
13102
  }
12922
13103
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMCommentComponent, decorators: [{
12923
13104
  type: Component,
@@ -12936,7 +13117,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
12936
13117
  AXPStateMessageComponent,
12937
13118
  AXPUserAvatarComponent,
12938
13119
  AXPUserCardDirective,
12939
- ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"axm-comment\">\n <ax-comment-container #commentContainer>\n <!-- ----- Loading skeleton while comments are fetched ----- -->\n @if (isLoading()) {\n <div class=\"axm-comment__list axm-comment__list--loading\">\n @for (skeleton of [0, 1, 2]; track skeleton) {\n <div class=\"axm-comment__skeleton\" [class.axm-comment__skeleton--compact]=\"skeleton > 0\">\n <ax-skeleton class=\"size-9 shrink-0 rounded-full\"></ax-skeleton>\n <div class=\"axm-comment__skeleton-body\">\n <ax-skeleton class=\"h-3.5 w-28 rounded\"></ax-skeleton>\n <ax-skeleton class=\"h-3 w-full rounded-full\"></ax-skeleton>\n <ax-skeleton class=\"h-3 w-11/12 rounded-full\"></ax-skeleton>\n <!--------------------------------------------------------------->\n <!-- ----- Extra skeleton line on first row ----- -->\n @if (skeleton === 0) {\n <ax-skeleton class=\"h-3 w-2/3 rounded-full\"></ax-skeleton>\n }\n </div>\n </div>\n }\n </div>\n }\n <!-- ----- Empty state when the thread has no comments ----- -->\n @else if (comments().length === 0) {\n <div class=\"axm-comment__empty\">\n <axp-state-message\n icon=\"fa-light fa-comments\"\n [title]=\"'@conversation:comments.components.comment.empty-states.no-comments.title'\"\n [description]=\"'@conversation:comments.components.comment.empty-states.no-comments.description'\"\n ></axp-state-message>\n </div>\n }\n <!-- ----- Comment thread from the mapped datasource ----- -->\n @else {\n <div class=\"axm-comment__list\">\n <ax-comment-view #commentsView [datasource]=\"commentItems()\" (onReply)=\"onReply($event)\" (onLikeChange)=\"onLikeChange($event)\" (onRepliesToggle)=\"onRepliesToggle($event)\" (onAction)=\"onAction($event)\">\n <ng-template axCommentItem let-item>\n <div class=\"flex min-w-0 items-start gap-2\">\n <axp-user-avatar class=\"shrink-0\" [size]=\"42\" [userId]=\"commentSenderId(item)\" [axpUserCard]=\"commentSenderId(item)\"></axp-user-avatar>\n <div class=\"min-w-0 flex-1\">\n <div class=\"flex min-w-0 items-center justify-between gap-2\">\n <div class=\"flex min-w-0 flex-wrap items-center\">\n <ax-title [axpUserCard]=\"commentSenderId(item)\">{{ item.author }}</ax-title>\n <!--------------------------------------------------------------->\n <!-- ----- You badge for the current user's comment ----- -->\n @if (item.isYou) {\n <ax-badge class=\"ax-sm ax-pill ax-comment-you-badge\" look=\"twotone\" color=\"primary\" [text]=\"('@acorex:comment.you' | translate | async) ?? 'You'\"></ax-badge>\n }\n <!--------------------------------------------------------------->\n <!-- ----- Edited label (before timestamp) ----- -->\n @if (item.edited) {\n <ax-comment-edited [editedAt]=\"item.editedAt\" />\n }\n <!--------------------------------------------------------------->\n <!-- ----- Relative timestamp for this comment ----- -->\n @if (item.date) {\n <ax-comment-date>{{ item.date }}</ax-comment-date>\n }\n </div>\n <!--------------------------------------------------------------->\n <!-- ----- Overflow menu from item actions ----- -->\n @if (item.actions?.length) {\n <ax-dropdown-button class=\"ax-sm\" mode=\"dropdown\" look=\"blank\" [iconOnly]=\"true\" [text]=\"('@conversation:comments.actions.more' | translate | async) ?? ''\">\n <ax-prefix>\n <ax-icon icon=\"ax-icon ax-icon-more-horizontal\"></ax-icon>\n </ax-prefix>\n <ax-button-item-list>\n @for (action of item.actions; track action.name ?? action.text) {\n <ax-button-item [text]=\"action.text\" [color]=\"action.color\" (onClick)=\"onOverflowAction(item, action.name ?? action.text)\">\n <!--------------------------------------------------------------->\n <!-- ----- Action icon when the menu item has one ----- -->\n @if (action.icon) {\n <ax-prefix>\n <ax-icon [icon]=\"action.icon\"></ax-icon>\n </ax-prefix>\n }\n </ax-button-item>\n }\n </ax-button-item-list>\n </ax-dropdown-button>\n }\n </div>\n <ax-content>\n <div [innerHTML]=\"item.content\"></div>\n </ax-content>\n </div>\n </div>\n </ng-template>\n </ax-comment-view>\n </div>\n }\n\n <ax-footer style=\"padding: 0.1rem\">\n <!-- ----- Edit context above the composer ----- -->\n @if (editing(); as editItem) {\n <div class=\"axm-comment__context-bar\" tabindex=\"0\" (click)=\"scrollToCommentContext(editItem)\" (keydown.enter)=\"scrollToCommentContext(editItem)\" (keydown.space)=\"$event.preventDefault(); scrollToCommentContext(editItem)\">\n <div class=\"axm-comment__context-bar-body\">\n <i class=\"fa-light fa-pen axm-comment__context-bar-icon\" aria-hidden=\"true\"></i>\n <span class=\"axm-comment__context-bar-copy\">\n <span class=\"axm-comment__context-bar-label\">{{ '@conversation:comments.actions.edit-message' | translate | async }}</span>\n @if (commentContextPreview(editItem.content); as preview) {\n <span class=\"axm-comment__context-bar-preview\" [title]=\"preview\">{{ preview }}</span>\n }\n </span>\n </div>\n <button type=\"button\" class=\"axm-comment__context-bar-close\" (click)=\"$event.stopPropagation(); cancelEdit()\" [attr.aria-label]=\"('@conversation:comments.actions.cancel.title' | translate | async) ?? 'Cancel'\">\n <i class=\"fa-light fa-xmark\" aria-hidden=\"true\"></i>\n </button>\n </div>\n }\n <!-- ----- Reply context above the composer ----- -->\n @else if (replyingTo(); as replyItem) {\n <div class=\"axm-comment__context-bar\" tabindex=\"0\" (click)=\"scrollToCommentContext(replyItem)\" (keydown.enter)=\"scrollToCommentContext(replyItem)\" (keydown.space)=\"$event.preventDefault(); scrollToCommentContext(replyItem)\">\n <div class=\"axm-comment__context-bar-body\">\n <i class=\"fa-light fa-reply axm-comment__context-bar-icon\" aria-hidden=\"true\"></i>\n <span class=\"axm-comment__context-bar-copy\">\n <span class=\"axm-comment__context-bar-label\">\n {{ '@conversation:comments.actions.reply-to' | translate | async }}\n <span class=\"axm-comment__context-bar-name\">\n @if (replyItem.isYou) {\n {{ '@acorex:comment.you' | translate | async }}\n } @else {\n {{ replyItem.author }}\n }\n </span>\n </span>\n @if (commentContextPreview(replyItem.content); as preview) {\n <span class=\"axm-comment__context-bar-preview\" [title]=\"preview\">{{ preview }}</span>\n }\n </span>\n </div>\n <button type=\"button\" class=\"axm-comment__context-bar-close\" (click)=\"$event.stopPropagation(); cancelReply()\" [attr.aria-label]=\"('@conversation:comments.actions.cancel.title' | translate | async) ?? 'Cancel'\">\n <i class=\"fa-light fa-xmark\" aria-hidden=\"true\"></i>\n </button>\n </div>\n }\n\n <ax-comment-reply>\n <ax-text-editor\n #commentEditor\n look=\"solid\"\n outputFormat=\"html\"\n [initialLine]=\"3\"\n [ngModel]=\"draft()\"\n (ngModelChange)=\"draft.set($event)\"\n [placeHolder]=\"((editing() ? '@conversation:comments.actions.edit-message' : replyingTo() ? '@conversation:comments.composer.reply-placeholder' : '@conversation:comments.composer.placeholder') | translate | async) ?? ''\"\n >\n <ax-footer>\n <div class=\"axm-comment__editor-actions\">\n <ax-button\n class=\"axm-comment__send ax-sm\"\n look=\"solid\"\n color=\"primary\"\n [disabled]=\"hasCooldown() || isCommentDraftEmpty() || isSubmitting()\"\n [text]=\"(editing() ? '@conversation:comments.actions.edit.title' : '@conversation:comments.actions.send.title') | translate | async\"\n (onClick)=\"submitComment()\"\n >\n @if (isSubmitting()) {\n <ax-loading></ax-loading>\n } @else {\n <!-- ----- Send icon when not submitting ----- -->\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-paper-plane-top\"></ax-icon>\n </ax-prefix>\n }\n </ax-button>\n </div>\n </ax-footer>\n <ax-text-editor-toolbar class=\"border-b\">\n <ax-text-editor-history></ax-text-editor-history>\n <ax-divider></ax-divider>\n <ax-text-editor-font-style></ax-text-editor-font-style>\n <ax-divider></ax-divider>\n <ax-text-editor-colors></ax-text-editor-colors>\n <ax-divider></ax-divider>\n <ax-text-editor-list></ax-text-editor-list>\n <ax-divider></ax-divider>\n <ax-text-editor-alignment></ax-text-editor-alignment>\n </ax-text-editor-toolbar>\n </ax-text-editor>\n </ax-comment-reply>\n </ax-footer>\n </ax-comment-container>\n</div>\n", styles: ["@layer properties;:host{display:block;height:100%;min-height:0px;width:100%}ax-comment-container{display:flex;flex-direction:column;justify-content:space-between;height:100%}.axm-comment{display:flex;width:100%;height:100%;min-height:0px;flex-direction:column;overflow:hidden;background-color:rgb(var(--ax-sys-color-lightest-surface))}.axm-comment .axm-comment__list{min-height:0px;flex:1;overflow-y:auto;padding:1rem 1rem 1.25rem;scroll-behavior:smooth}.axm-comment .axm-comment__list.axm-comment__list--loading{display:flex;flex-direction:column;gap:1.25rem}.axm-comment .axm-comment__empty{display:flex;min-height:min(16rem,40vh);flex:1;flex-direction:column;align-items:center;justify-content:center;padding:2rem 1.25rem}.axm-comment .axm-comment__skeleton{display:flex;align-items:flex-start;gap:.75rem}.axm-comment .axm-comment__skeleton.axm-comment__skeleton--compact .axm-comment__skeleton-body{gap:.375rem}.axm-comment .axm-comment__skeleton-body{display:flex;min-width:0px;flex:1;flex-direction:column;gap:calc(var(--spacing, .25rem) * 2)}.axm-comment .axm-comment__context-bar{display:flex;min-width:0px;cursor:pointer;align-items:flex-start;gap:calc(var(--spacing, .25rem) * 2);margin-block-end:8px;padding:.5rem .75rem;border:1px solid rgb(var(--ax-sys-color-border-light-surface));border-radius:6px;border-inline-start:3px solid rgb(var(--ax-sys-color-primary-surface));background-color:rgba(var(--ax-sys-color-primary-lightest-surface),.4);font-size:.8125rem;line-height:1.45}.axm-comment .axm-comment__context-bar:hover{background-color:rgba(var(--ax-sys-color-primary-lightest-surface),.55)}.axm-comment .axm-comment__context-bar:focus-visible{outline:2px solid rgb(var(--ax-sys-color-primary-surface));outline-offset:2px}.axm-comment .axm-comment__context-bar-body{display:flex;min-width:0px;flex:1;align-items:flex-start;text-align:start;gap:.625rem;overflow:hidden;pointer-events:none}.axm-comment .axm-comment__context-bar-icon{flex-shrink:0;font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-leading: 1;line-height:1;margin-top:.125rem;color:rgb(var(--ax-sys-color-primary-surface))}.axm-comment .axm-comment__context-bar-copy{display:flex;min-width:0px;flex:1;flex-direction:column;gap:.125rem;overflow:hidden}.axm-comment .axm-comment__context-bar-label{flex-shrink:0;font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-leading: calc(var(--spacing, .25rem) * 4);line-height:calc(var(--spacing, .25rem) * 4);color:rgb(var(--ax-sys-color-neutral-700-surface, 55 65 81))}.axm-comment .axm-comment__context-bar-name{--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:rgb(var(--ax-sys-color-neutral-900-surface, 17 24 39))}.axm-comment .axm-comment__context-bar-preview{min-width:0px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:start;font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-leading: calc(var(--spacing, .25rem) * 4);line-height:calc(var(--spacing, .25rem) * 4);color:rgb(var(--ax-sys-color-neutral-600-surface, 107 114 128))}.axm-comment .axm-comment__context-bar-close{position:relative;z-index:1;display:inline-flex;flex-shrink:0;align-items:center;justify-content:center;align-self:flex-start;border-radius:var(--radius-sm, .25rem);width:1.75rem;height:1.75rem;margin-inline-start:-.25rem;padding:0;border:none;background:transparent;color:rgb(var(--ax-sys-color-neutral-500-surface, 107 114 128));font-size:1rem;line-height:1;cursor:pointer}.axm-comment .axm-comment__context-bar-close:hover{background-color:rgba(var(--ax-sys-color-neutral-100-surface, 243 244 246),.9);color:rgb(var(--ax-sys-color-neutral-700-surface, 55 65 81))}.axm-comment .axm-comment__context-bar-close:focus-visible{outline:2px solid rgb(var(--ax-sys-color-primary-surface));outline-offset:2px}.axm-comment .axm-comment__editor-actions{display:flex;align-items:center;justify-content:flex-end;gap:calc(var(--spacing, .25rem) * 2);padding:var(--spacing, .25rem)}.axm-comment .axm-comment__send{min-width:5.5rem}@property --tw-leading{syntax: \"*\"; inherits: false;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-leading: initial;--tw-font-weight: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
13120
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"axm-comment\">\n <ax-comment-container #commentContainer>\n <!-- ----- Loading skeleton while comments are fetched ----- -->\n @if (isLoading()) {\n <div class=\"axm-comment__list axm-comment__list--loading\">\n @for (skeleton of [0, 1, 2]; track skeleton) {\n <div class=\"axm-comment__skeleton\" [class.axm-comment__skeleton--compact]=\"skeleton > 0\">\n <ax-skeleton class=\"size-9 shrink-0 rounded-full\"></ax-skeleton>\n <div class=\"axm-comment__skeleton-body\">\n <ax-skeleton class=\"h-3.5 w-28 rounded\"></ax-skeleton>\n <ax-skeleton class=\"h-3 w-full rounded-full\"></ax-skeleton>\n <ax-skeleton class=\"h-3 w-11/12 rounded-full\"></ax-skeleton>\n <!--------------------------------------------------------------->\n <!-- ----- Extra skeleton line on first row ----- -->\n @if (skeleton === 0) {\n <ax-skeleton class=\"h-3 w-2/3 rounded-full\"></ax-skeleton>\n }\n </div>\n </div>\n }\n </div>\n }\n <!-- ----- Empty state when the thread has no comments ----- -->\n @else if (comments().length === 0) {\n <div class=\"axm-comment__empty\">\n <axp-state-message\n icon=\"fa-light fa-comments\"\n [title]=\"'@conversation:comments.components.comment.empty-states.no-comments.title'\"\n [description]=\"'@conversation:comments.components.comment.empty-states.no-comments.description'\"\n ></axp-state-message>\n </div>\n }\n <!-- ----- Comment thread from the mapped datasource ----- -->\n @else {\n <div class=\"axm-comment__list\">\n <ax-comment-view #commentsView [datasource]=\"commentItems()\" (onReply)=\"onReply($event)\" (onLikeChange)=\"onLikeChange($event)\" (onRepliesToggle)=\"onRepliesToggle($event)\" (onAction)=\"onAction($event)\">\n <ng-template axCommentItem let-item>\n <div class=\"flex min-w-0 items-start gap-2\">\n <axp-user-avatar class=\"shrink-0\" [size]=\"42\" [userId]=\"commentSenderId(item)\" [axpUserCard]=\"commentSenderId(item)\"></axp-user-avatar>\n <div class=\"min-w-0 flex-1\">\n <div class=\"flex min-w-0 items-center justify-between gap-2\">\n <div class=\"flex min-w-0 flex-wrap items-center\">\n <ax-title [axpUserCard]=\"commentSenderId(item)\">{{ item.author }}</ax-title>\n <!--------------------------------------------------------------->\n <!-- ----- You badge for the current user's comment ----- -->\n @if (item.isYou) {\n <ax-badge class=\"ax-sm ax-pill ax-comment-you-badge\" look=\"twotone\" color=\"primary\" [text]=\"('@acorex:comment.you' | translate | async) ?? 'You'\"></ax-badge>\n }\n <!--------------------------------------------------------------->\n <!-- ----- Edited label (before timestamp) ----- -->\n @if (item.edited) {\n <ax-comment-edited [editedAt]=\"item.editedAt\" />\n }\n <!--------------------------------------------------------------->\n <!-- ----- Relative timestamp for this comment ----- -->\n @if (item.date) {\n <ax-comment-date>{{ item.date }}</ax-comment-date>\n }\n </div>\n <!--------------------------------------------------------------->\n <!-- ----- Overflow menu from item actions ----- -->\n @if (item.actions?.length) {\n <ax-dropdown-button class=\"ax-sm\" mode=\"dropdown\" look=\"blank\" [iconOnly]=\"true\" [text]=\"('@conversation:comments.actions.more' | translate | async) ?? ''\">\n <ax-prefix>\n <ax-icon icon=\"ax-icon ax-icon-more-horizontal\"></ax-icon>\n </ax-prefix>\n <ax-button-item-list>\n @for (action of item.actions; track action.name ?? action.text) {\n <ax-button-item [text]=\"action.text\" [color]=\"action.color\" (onClick)=\"onOverflowAction(item, action.name ?? action.text)\">\n <!--------------------------------------------------------------->\n <!-- ----- Action icon when the menu item has one ----- -->\n @if (action.icon) {\n <ax-prefix>\n <ax-icon [icon]=\"action.icon\"></ax-icon>\n </ax-prefix>\n }\n </ax-button-item>\n }\n </ax-button-item-list>\n </ax-dropdown-button>\n }\n </div>\n <ax-content>\n <div [innerHTML]=\"item.content\"></div>\n </ax-content>\n </div>\n </div>\n </ng-template>\n </ax-comment-view>\n </div>\n }\n\n <ax-footer style=\"padding: 0.1rem\">\n <!-- ----- Edit context above the composer ----- -->\n @if (editing(); as editItem) {\n <div class=\"axm-comment__context-bar\" tabindex=\"0\" (click)=\"scrollToCommentContext(editItem)\" (keydown.enter)=\"scrollToCommentContext(editItem)\" (keydown.space)=\"$event.preventDefault(); scrollToCommentContext(editItem)\">\n <div class=\"axm-comment__context-bar-body\">\n <i class=\"fa-light fa-pen axm-comment__context-bar-icon\" aria-hidden=\"true\"></i>\n <span class=\"axm-comment__context-bar-copy\">\n <span class=\"axm-comment__context-bar-label\">{{ '@conversation:comments.actions.edit-message' | translate | async }}</span>\n @if (commentContextPreview(editItem.content); as preview) {\n <span class=\"axm-comment__context-bar-preview\" [title]=\"preview\">{{ preview }}</span>\n }\n </span>\n </div>\n <button type=\"button\" class=\"axm-comment__context-bar-close\" (click)=\"$event.stopPropagation(); cancelEdit()\" [attr.aria-label]=\"('@conversation:comments.actions.cancel.title' | translate | async) ?? 'Cancel'\">\n <i class=\"fa-light fa-xmark\" aria-hidden=\"true\"></i>\n </button>\n </div>\n }\n <!-- ----- Reply context above the composer ----- -->\n @else if (replyingTo(); as replyItem) {\n <div class=\"axm-comment__context-bar\" tabindex=\"0\" (click)=\"scrollToCommentContext(replyItem)\" (keydown.enter)=\"scrollToCommentContext(replyItem)\" (keydown.space)=\"$event.preventDefault(); scrollToCommentContext(replyItem)\">\n <div class=\"axm-comment__context-bar-body\">\n <i class=\"fa-light fa-reply axm-comment__context-bar-icon\" aria-hidden=\"true\"></i>\n <span class=\"axm-comment__context-bar-copy\">\n <span class=\"axm-comment__context-bar-label\">\n {{ '@conversation:comments.actions.reply-to' | translate | async }}\n <span class=\"axm-comment__context-bar-name\">\n @if (replyItem.isYou) {\n {{ '@acorex:comment.you' | translate | async }}\n } @else {\n {{ replyItem.author }}\n }\n </span>\n </span>\n @if (commentContextPreview(replyItem.content); as preview) {\n <span class=\"axm-comment__context-bar-preview\" [title]=\"preview\">{{ preview }}</span>\n }\n </span>\n </div>\n <button type=\"button\" class=\"axm-comment__context-bar-close\" (click)=\"$event.stopPropagation(); cancelReply()\" [attr.aria-label]=\"('@conversation:comments.actions.cancel.title' | translate | async) ?? 'Cancel'\">\n <i class=\"fa-light fa-xmark\" aria-hidden=\"true\"></i>\n </button>\n </div>\n }\n\n <ax-comment-reply>\n <ax-text-editor\n #commentEditor\n look=\"solid\"\n outputFormat=\"html\"\n [initialLine]=\"3\"\n [ngModel]=\"draft()\"\n (ngModelChange)=\"draft.set($event)\"\n [placeHolder]=\"((editing() ? '@conversation:comments.actions.edit-message' : replyingTo() ? '@conversation:comments.composer.reply-placeholder' : '@conversation:comments.composer.placeholder') | translate | async) ?? ''\"\n >\n <ax-footer>\n <div class=\"axm-comment__editor-actions\">\n <ax-button\n class=\"axm-comment__send ax-sm\"\n look=\"solid\"\n color=\"primary\"\n [disabled]=\"hasCooldown() || isCommentDraftEmpty() || isSubmitting()\"\n [text]=\"(editing() ? '@conversation:comments.actions.edit.title' : '@conversation:comments.actions.send.title') | translate | async\"\n (onClick)=\"submitComment()\"\n >\n @if (isSubmitting()) {\n <ax-loading></ax-loading>\n } @else {\n <!-- ----- Send icon when not submitting ----- -->\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-paper-plane-top\"></ax-icon>\n </ax-prefix>\n }\n </ax-button>\n </div>\n </ax-footer>\n <ax-text-editor-toolbar class=\"border-b\">\n <ax-text-editor-history></ax-text-editor-history>\n <ax-divider></ax-divider>\n <ax-text-editor-font-style></ax-text-editor-font-style>\n <ax-divider></ax-divider>\n <ax-text-editor-colors></ax-text-editor-colors>\n <ax-divider></ax-divider>\n <ax-text-editor-list></ax-text-editor-list>\n <ax-divider></ax-divider>\n <ax-text-editor-alignment></ax-text-editor-alignment>\n </ax-text-editor-toolbar>\n </ax-text-editor>\n </ax-comment-reply>\n </ax-footer>\n </ax-comment-container>\n</div>\n", styles: ["@layer properties;:host{display:block;height:100%;min-height:0px;width:100%}ax-comment-container{display:flex;flex-direction:column;justify-content:space-between;height:100%}.ax-comment-replies{padding-inline-start:1.75rem!important}.axm-comment{display:flex;width:100%;height:100%;min-height:0px;flex-direction:column;overflow:hidden;background-color:rgb(var(--ax-sys-color-lightest-surface))}.axm-comment .axm-comment__list{min-height:0px;flex:1;overflow-y:auto;padding:1rem 1rem 1.25rem;scroll-behavior:smooth}.axm-comment .axm-comment__list.axm-comment__list--loading{display:flex;flex-direction:column;gap:1.25rem}.axm-comment .axm-comment__empty{display:flex;min-height:min(16rem,40vh);flex:1;flex-direction:column;align-items:center;justify-content:center;padding:2rem 1.25rem}.axm-comment .axm-comment__skeleton{display:flex;align-items:flex-start;gap:.75rem}.axm-comment .axm-comment__skeleton.axm-comment__skeleton--compact .axm-comment__skeleton-body{gap:.375rem}.axm-comment .axm-comment__skeleton-body{display:flex;min-width:0px;flex:1;flex-direction:column;gap:calc(var(--spacing, .25rem) * 2)}.axm-comment .axm-comment__context-bar{display:flex;min-width:0px;cursor:pointer;align-items:flex-start;gap:calc(var(--spacing, .25rem) * 2);margin-block-end:8px;padding:.5rem .75rem;border:1px solid rgb(var(--ax-sys-color-border-light-surface));border-radius:6px;border-inline-start:3px solid rgb(var(--ax-sys-color-primary-surface));background-color:rgba(var(--ax-sys-color-primary-lightest-surface),.4);font-size:.8125rem;line-height:1.45}.axm-comment .axm-comment__context-bar:hover{background-color:rgba(var(--ax-sys-color-primary-lightest-surface),.55)}.axm-comment .axm-comment__context-bar:focus-visible{outline:2px solid rgb(var(--ax-sys-color-primary-surface));outline-offset:2px}.axm-comment .axm-comment__context-bar-body{display:flex;min-width:0px;flex:1;align-items:flex-start;text-align:start;gap:.625rem;overflow:hidden;pointer-events:none}.axm-comment .axm-comment__context-bar-icon{flex-shrink:0;font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-leading: 1;line-height:1;margin-top:.125rem;color:rgb(var(--ax-sys-color-primary-surface))}.axm-comment .axm-comment__context-bar-copy{display:flex;min-width:0px;flex:1;flex-direction:column;gap:.125rem;overflow:hidden}.axm-comment .axm-comment__context-bar-label{flex-shrink:0;font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-leading: calc(var(--spacing, .25rem) * 4);line-height:calc(var(--spacing, .25rem) * 4);color:rgb(var(--ax-sys-color-neutral-700-surface, 55 65 81))}.axm-comment .axm-comment__context-bar-name{--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:rgb(var(--ax-sys-color-neutral-900-surface, 17 24 39))}.axm-comment .axm-comment__context-bar-preview{min-width:0px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:start;font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-leading: calc(var(--spacing, .25rem) * 4);line-height:calc(var(--spacing, .25rem) * 4);color:rgb(var(--ax-sys-color-neutral-600-surface, 107 114 128))}.axm-comment .axm-comment__context-bar-close{position:relative;z-index:1;display:inline-flex;flex-shrink:0;align-items:center;justify-content:center;align-self:flex-start;border-radius:var(--radius-sm, .25rem);width:1.75rem;height:1.75rem;margin-inline-start:-.25rem;padding:0;border:none;background:transparent;color:rgb(var(--ax-sys-color-neutral-500-surface, 107 114 128));font-size:1rem;line-height:1;cursor:pointer}.axm-comment .axm-comment__context-bar-close:hover{background-color:rgba(var(--ax-sys-color-neutral-100-surface, 243 244 246),.9);color:rgb(var(--ax-sys-color-neutral-700-surface, 55 65 81))}.axm-comment .axm-comment__context-bar-close:focus-visible{outline:2px solid rgb(var(--ax-sys-color-primary-surface));outline-offset:2px}.axm-comment .axm-comment__editor-actions{display:flex;align-items:center;justify-content:flex-end;gap:calc(var(--spacing, .25rem) * 2);padding:var(--spacing, .25rem)}.axm-comment .axm-comment__send{min-width:5.5rem}@property --tw-leading{syntax: \"*\"; inherits: false;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-leading: initial;--tw-font-weight: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
12940
13121
  }], propDecorators: { refrenceType: [{ type: i0.Input, args: [{ isSignal: true, alias: "refrenceType", required: true }] }], refrenceId: [{ type: i0.Input, args: [{ isSignal: true, alias: "refrenceId", required: true }] }], subject: [{ type: i0.Input, args: [{ isSignal: true, alias: "subject", required: true }] }], commentsView: [{ type: i0.ViewChild, args: ['commentsView', { ...{ read: AXCommentViewComponent }, isSignal: true }] }], commentContainer: [{ type: i0.ViewChild, args: ['commentContainer', { ...{ read: AXCommentContainerComponent }, isSignal: true }] }], editor: [{ type: i0.ViewChild, args: ['commentEditor', { ...{ read: AXTextEditorComponent }, isSignal: true }] }] } });
12941
13122
  //#endregion
12942
13123
  //#region ----- Local helpers -----
@@ -12963,6 +13144,9 @@ function colorForUser(userId) {
12963
13144
  }
12964
13145
  return AVATAR_COLORS[hash];
12965
13146
  }
13147
+ function containsComment(list, commentId) {
13148
+ return list.some((comment) => comment.id === commentId || containsComment(comment.replies ?? [], commentId));
13149
+ }
12966
13150
  function insertReply(list, parentId, comment) {
12967
13151
  return list.map((c) => {
12968
13152
  if (c.id === parentId) {
@@ -14418,7 +14602,7 @@ async function axmOpenChatCallStartDialog(options) {
14418
14602
  const dialogOpener = options.dialogOpener ?? inject(AXPDialogOpener);
14419
14603
  const data = { conversation };
14420
14604
  await dialogOpener.openPopup({
14421
- load: () => import('./acorex-platform-module-conversation-client-chat-call-start-popup.component-BEa8wEJt.mjs').then((module) => module.AXMChatCallStartPopupComponent),
14605
+ load: () => import('./acorex-platform-module-conversation-client-chat-call-start-popup.component-C-YXNbrC.mjs').then((module) => module.AXMChatCallStartPopupComponent),
14422
14606
  data: { conversationId: conversation.id },
14423
14607
  show: (component) => popupService.open(component, {
14424
14608
  header: false,
@@ -14700,7 +14884,7 @@ const AXM_CHAT_INFO_BAR_CALL_ACTION = {
14700
14884
  */
14701
14885
  const AXM_CONVERSATION_BOT_RENDERER = {
14702
14886
  type: 'assist-response',
14703
- componentLoader: () => import('./acorex-platform-module-conversation-client-assist-message-renderer.component-CR4OxDV6.mjs').then(function (n) { return n.b; }).then((m) => m.AXMAssistMessageRendererComponent),
14887
+ componentLoader: () => import('./acorex-platform-module-conversation-client-assist-message-renderer.component-CyTzYVsZ.mjs').then(function (n) { return n.b; }).then((m) => m.AXMAssistMessageRendererComponent),
14704
14888
  canHandle: (message) => message.type === 'assist-response' || !!message.metadata?.['isAssistResponse'],
14705
14889
  capabilities: {
14706
14890
  supportsReactions: false,
@@ -14844,7 +15028,7 @@ async function axmOpenChatCallSessionDialog(options) {
14844
15028
  let scopedCallId = options.callId?.trim() || '';
14845
15029
  try {
14846
15030
  const opened = await dialogOpener.openPopup({
14847
- load: () => import('./acorex-platform-module-conversation-client-chat-call-session-page.component-DJreBgNo.mjs').then((module) => module.AXMChatCallSessionPageComponent),
15031
+ load: () => import('./acorex-platform-module-conversation-client-chat-call-session-page.component-BbtiucQD.mjs').then((module) => module.AXMChatCallSessionPageComponent),
14848
15032
  data: {
14849
15033
  conversationId: conversation.id,
14850
15034
  callId: scopedCallId,
@@ -16964,7 +17148,7 @@ class AXMCommentsPageComponentProvider {
16964
17148
  return [
16965
17149
  {
16966
17150
  key: COMMENTS_PAGE_COMPONENT_KEY,
16967
- loader: () => import('./acorex-platform-module-conversation-client-comments-page.component-BsE6bCZT.mjs').then((m) => m.AXMCommentsPageComponent),
17151
+ loader: () => import('./acorex-platform-module-conversation-client-comments-page.component-Cgw3yLDs.mjs').then((m) => m.AXMCommentsPageComponent),
16968
17152
  },
16969
17153
  ];
16970
17154
  }
@@ -17270,19 +17454,19 @@ class AXMConversationModule {
17270
17454
  provideCommandSetups([
17271
17455
  {
17272
17456
  key: CONVERSATION_AFTER_MESSAGE_SENT_COMMAND,
17273
- command: () => import('./acorex-platform-module-conversation-client-after-message-sent.command-JjZrYD2R.mjs').then((m) => m.AXMConversationAfterMessageSentCommand),
17457
+ command: () => import('./acorex-platform-module-conversation-client-after-message-sent.command-D21Bwrrp.mjs').then((m) => m.AXMConversationAfterMessageSentCommand),
17274
17458
  },
17275
17459
  {
17276
17460
  key: CONVERSATION_RETRY_ASSIST_RESPONSE_COMMAND,
17277
- command: () => import('./acorex-platform-module-conversation-client-retry-assist-response.command-BvzWaKX4.mjs').then((m) => m.AXMConversationRetryAssistResponseCommand),
17461
+ command: () => import('./acorex-platform-module-conversation-client-retry-assist-response.command-CaxrqIvP.mjs').then((m) => m.AXMConversationRetryAssistResponseCommand),
17278
17462
  },
17279
17463
  {
17280
17464
  key: CONVERSATION_SYNC_READ_STATE_COMMAND,
17281
- command: () => import('./acorex-platform-module-conversation-client-sync-read-state.command-DQXezGRu.mjs').then((m) => m.AXMConversationSyncReadStateCommand),
17465
+ command: () => import('./acorex-platform-module-conversation-client-sync-read-state.command-BFuJeJb5.mjs').then((m) => m.AXMConversationSyncReadStateCommand),
17282
17466
  },
17283
17467
  {
17284
17468
  key: CONVERSATION_MARK_CONVERSATION_UNREAD_COMMAND,
17285
- command: () => import('./acorex-platform-module-conversation-client-mark-conversation-unread.command-B1mvtbaA.mjs').then((m) => m.AXMConversationMarkConversationUnreadCommand),
17469
+ command: () => import('./acorex-platform-module-conversation-client-mark-conversation-unread.command-Cp6nnN8B.mjs').then((m) => m.AXMConversationMarkConversationUnreadCommand),
17286
17470
  },
17287
17471
  {
17288
17472
  key: CONVERSATION_EMIT_TYPING_INDICATOR_COMMAND,
@@ -17294,7 +17478,7 @@ class AXMConversationModule {
17294
17478
  },
17295
17479
  {
17296
17480
  key: CONVERSATION_OPEN_CHAT_COMMAND,
17297
- command: () => import('./acorex-platform-module-conversation-client-open-chat.command-CbJ0gXZq.mjs').then((m) => m.AXMConversationOpenChatCommand),
17481
+ command: () => import('./acorex-platform-module-conversation-client-open-chat.command-Cyes1BAz.mjs').then((m) => m.AXMConversationOpenChatCommand),
17298
17482
  },
17299
17483
  {
17300
17484
  key: 'show-comment-popup',
@@ -17413,19 +17597,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
17413
17597
  provideCommandSetups([
17414
17598
  {
17415
17599
  key: CONVERSATION_AFTER_MESSAGE_SENT_COMMAND,
17416
- command: () => import('./acorex-platform-module-conversation-client-after-message-sent.command-JjZrYD2R.mjs').then((m) => m.AXMConversationAfterMessageSentCommand),
17600
+ command: () => import('./acorex-platform-module-conversation-client-after-message-sent.command-D21Bwrrp.mjs').then((m) => m.AXMConversationAfterMessageSentCommand),
17417
17601
  },
17418
17602
  {
17419
17603
  key: CONVERSATION_RETRY_ASSIST_RESPONSE_COMMAND,
17420
- command: () => import('./acorex-platform-module-conversation-client-retry-assist-response.command-BvzWaKX4.mjs').then((m) => m.AXMConversationRetryAssistResponseCommand),
17604
+ command: () => import('./acorex-platform-module-conversation-client-retry-assist-response.command-CaxrqIvP.mjs').then((m) => m.AXMConversationRetryAssistResponseCommand),
17421
17605
  },
17422
17606
  {
17423
17607
  key: CONVERSATION_SYNC_READ_STATE_COMMAND,
17424
- command: () => import('./acorex-platform-module-conversation-client-sync-read-state.command-DQXezGRu.mjs').then((m) => m.AXMConversationSyncReadStateCommand),
17608
+ command: () => import('./acorex-platform-module-conversation-client-sync-read-state.command-BFuJeJb5.mjs').then((m) => m.AXMConversationSyncReadStateCommand),
17425
17609
  },
17426
17610
  {
17427
17611
  key: CONVERSATION_MARK_CONVERSATION_UNREAD_COMMAND,
17428
- command: () => import('./acorex-platform-module-conversation-client-mark-conversation-unread.command-B1mvtbaA.mjs').then((m) => m.AXMConversationMarkConversationUnreadCommand),
17612
+ command: () => import('./acorex-platform-module-conversation-client-mark-conversation-unread.command-Cp6nnN8B.mjs').then((m) => m.AXMConversationMarkConversationUnreadCommand),
17429
17613
  },
17430
17614
  {
17431
17615
  key: CONVERSATION_EMIT_TYPING_INDICATOR_COMMAND,
@@ -17437,7 +17621,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
17437
17621
  },
17438
17622
  {
17439
17623
  key: CONVERSATION_OPEN_CHAT_COMMAND,
17440
- command: () => import('./acorex-platform-module-conversation-client-open-chat.command-CbJ0gXZq.mjs').then((m) => m.AXMConversationOpenChatCommand),
17624
+ command: () => import('./acorex-platform-module-conversation-client-open-chat.command-Cyes1BAz.mjs').then((m) => m.AXMConversationOpenChatCommand),
17441
17625
  },
17442
17626
  {
17443
17627
  key: 'show-comment-popup',
@@ -17473,4 +17657,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
17473
17657
  */
17474
17658
 
17475
17659
  export { axmShouldForkPrivateToGroup as $, AXMConversationEntityStoreService as A, axmSanitizeAssistUserAnswerText as B, axmAssistUserVisibleItemsForLine as C, axmReadAssistFollowUpStatus as D, axmReadPlainTextMessagePayload as E, AXMNodeMessageRendererComponent as F, AXMAssistSuggestionChipsComponent as G, AXMChatCallActiveSessionService as H, axmResolveConversationListAvatar as I, axmEnsureChatCallRtcReady as J, axmOpenChatCallSessionDialog as K, axmChatCallMediaRoomName as L, axmResolveChatCallLiveKitServerUrl as M, axmChatCallRoomConnectOptions as N, loadLiveKitClient as O, AXM_CHAT_CALL_RTC_API_PROVIDERS as P, AXMConversationAppearanceSyncService as Q, axmCancelAssistComposerGeneration as R, AXMChatEmptyStateHostComponent as S, AXMChatComposerEnsureAssistConversationDirective as T, AXMChatUserApi as U, AXMChatEntityConversationApi as V, AXMChatConversationApi as W, AXMChatCallRtcSignalInboxService as X, AXMChatCallEventsService as Y, AXMConversationRealtimeBus as Z, axmReadChatCallLog as _, AXM_CONVERSATION_ASSIST_RESPONSE_PORT as a, CONVERSATION_SEND_ASSIST_CHAT_MESSAGE_COMMAND as a$, axmIsConversationParticipant as a0, axmBuildChatCallLogMessage as a1, axmMatchesForkedGroupForCall as a2, axmAssistWidgetNodeFromUnknown as a3, AXMAddReactionCommand as a4, AXMChannelFeedItemComponent as a5, AXMChannelFeedPage as a6, AXMChatAnnouncementChannelService as a7, AXMChatComponent as a8, AXMChatComposerAssistPickerComponent as a9, AXMMiniChatPanelService as aA, AXMMiniChatPopupWindowComponent as aB, AXMShowCommentPopupCommand as aC, AXM_AI_MANAGEMENT_ASSIST_ENTITY_NAME as aD, AXM_ASSIST_DEFAULT_RESOLVER_PORT as aE, AXM_ASSIST_TRANSCRIPT_LINE_PAYLOAD_TYPE as aF, AXM_CHAT_ASSIST_CATALOG_PORT as aG, AXM_CHAT_EMPTY_STATE_COMPONENT as aH, AXM_CHAT_SIDEBAR_ACTION_PROVIDER as aI, AXM_CONVERSATION_ASSIST_BACKGROUND_OPERATION_HANDLERS as aJ, AXM_CONVERSATION_ASSIST_BACKGROUND_OPERATION_KEY as aK, AXM_CONVERSATION_CHAT_ATTACHMENT_CATEGORY as aL, AXM_CONVERSATION_CHAT_ATTACHMENT_REF_TYPE as aM, AXM_CONVERSATION_TAB_BOT as aN, AXM_ENTITY_LIST_CHAT_ID as aO, AXM_MINI_CHAT_INBOX_CONVERSATION_FILTER as aP, AXM_MINI_CHAT_INBOX_SESSION_KEY as aQ, AXM_MINI_CHAT_POPUP_DOCK as aR, AXM_MINI_CHAT_SCOPE_ENTITY as aS, AXM_MINI_CHAT_SCOPE_METADATA_KEY as aT, AXPCommentWidget as aU, COMMENTS_PAGE_COMPONENT_KEY as aV, CONVERSATION_AFTER_MESSAGE_SENT_COMMAND as aW, CONVERSATION_EMIT_TYPING_INDICATOR_COMMAND as aX, CONVERSATION_MARK_CONVERSATION_UNREAD_COMMAND as aY, CONVERSATION_OPEN_CHAT_COMMAND as aZ, CONVERSATION_RETRY_ASSIST_RESPONSE_COMMAND as a_, AXMChatEmptyAssistSessionService as aa, AXMChatEntityConversationFocusHandler as ab, AXMChatEntityConversationRoomQueryService as ac, AXMChatEntityMessageApi as ad, AXMChatEntityRealtimeApi as ae, AXMChatEntityUserApi as af, AXMChatRealtimeApi as ag, AXMCommentManagementService as ah, AXMCommentPopupComponent as ai, AXMCommentRealtimeService as aj, AXMCommentRealtimeServiceImpl as ak, AXMCommentService as al, AXMCommentServiceImpl as am, AXMCommentWidgetViewComponent as an, AXMConversationAssistBackgroundOperationHandler as ao, AXMConversationModule as ap, AXMEntityChatService as aq, AXMMiniChatComponent as ar, AXMMiniChatFileDropService as as, AXMMiniChatFooterDockComponent as at, AXMMiniChatHeaderSlotComponent as au, AXMMiniChatHistoryComponent as av, AXMMiniChatInboxHistoryComponent as aw, AXMMiniChatLauncherComponent as ax, AXMMiniChatPageActionComponent as ay, AXMMiniChatPanelComponent as az, AXM_CONVERSATION_REGULAR_AUTO_REPLY_PORT as b, axmResolveChatAiTargetText as b$, CONVERSATION_START_ASSIST_CHAT_COMMAND as b0, CONVERSATION_START_DIRECT_CHAT_COMMAND as b1, CONVERSATION_SYNC_READ_STATE_COMMAND as b2, axmApplyAnswerTextToAssistPayloadLine as b3, axmAssistFollowUpItemsFromUnknown as b4, axmAssistLastTranscriptLine as b5, axmAssistNormalizeFollowUpItemForConversation as b6, axmAssistNormalizeFollowUpItemsForConversation as b7, axmAssistPersistedMessageLooksComplete as b8, axmAssistResolveFollowUpCommandName as b9, axmExtractAssistSnapshotFromMetadata as bA, axmExtractDirectAgentIdFromMetadata as bB, axmExtractEntityRefFromMetadata as bC, axmExtractModelEntityIdFromMetadata as bD, axmExtractTextFromPayload as bE, axmFilterChatAiTargets as bF, axmFlattenConversationCreateMetadata as bG, axmHydrateRealtimeConversationMessage as bH, axmInboxConversationTab as bI, axmIsAssistBotConversation as bJ, axmIsAssistPeerParticipant as bK, axmIsAssistResponseMessage as bL, axmIsAssistStreamingMessage as bM, axmIsAssistTerminalStatus as bN, axmIsUnsupportedLegacyAgentAssistConversation as bO, axmLoadChatAiTargets as bP, axmMessageEntityToMessage as bQ, axmMiniChatHistoryScopeFromDraft as bR, axmMiniChatHistoryScopeFromOpen as bS, axmMiniChatHistoryScopeKey as bT, axmMiniChatWindowOwnsRoute as bU, axmNormalizeAssistTranscriptForChatUi as bV, axmNormalizeAssistTranscriptLineResponses as bW, axmPreferLocalUnreadCount as bX, axmReadReplyToUserMessageId as bY, axmRemoveMiniChatHistoryItem as bZ, axmResolveAssistFinalAnswerText as b_, axmAssistStarterPromptChipItems as ba, axmAssistSuggestionIconForLabel as bb, axmAssistWidgetNodeDedupeKey as bc, axmBuildAiChatConversationMetadata as bd, axmBuildAssistPeerParticipantFromCreateData as be, axmBuildAssistPeerParticipantFromId as bf, axmBuildAssistTranscriptLinePayload as bg, axmBuildAutoTitleFromUserText as bh, axmBuildEntityChatConversationMetadata as bi, axmBuildEntityChatRoomEntityRef as bj, axmChatAiPeerParticipantId as bk, axmChatAiTargetAvatarUrl as bl, axmChatAiTargetDisplayDescription as bm, axmChatAiTargetDisplayName as bn, axmChatAiTargetShortcutDescriptionKey as bo, axmCoerceDate as bp, axmCoerceTimestampMs as bq, axmComputeConversationUnreadCount as br, axmConversationIsEntityChat as bs, axmConversationIsGlobalChat as bt, axmConversationMatchesEntity as bu, axmConversationMatchesHistoryScope as bv, axmEntityRefForMiniChatPageContext as bw, axmEntityRefFromLaunchContext as bx, axmExcludeEntityChatConversations as by, axmExtractAssistIdFromMetadata as bz, axmConversationHasAiChat$1 as c, axmRoomEntityToConversation as c0, axmRoomIsEntityChat as c1, axmRoomLaunchContext as c2, axmRoomMatchesEntity as c3, axmRoomWithAssistPeerDisplayName as c4, axmShouldPreferPersistedAssistOverLiveCache as c5, axmSortMessagesNewestFirst as c6, axmSyncAssistPeerDisplayName as c7, axmUpsertMiniChatHistoryItem as c8, axmUserRowToParticipant as c9, axpShowCommentPopupCommandDefinition as ca, channelFeedPageRoutes as cb, commentsPlugin as cc, createConversationServiceSessionAdapter as cd, persistChatAttachment as ce, AXMConversationFocusService as d, AXMConversationInAppNotificationSyncService as e, axmMessageCountsTowardUnread as f, buildConversationChatInAppCorrelationPrefix as g, AXMCommentComponent as h, axmResolveI18nLabel as i, axmSyntheticEmbedMessage as j, axmChatRenderableAssistWidgetNode as k, axmPartitionAssistAnswerText as l, axmParseAssistTranscriptTextEnvelope as m, AXMAssistChatDebugModeService as n, AXMChatMessageApi as o, AXM_AI_MANAGEMENT_MODULE_NAME as p, AXM_AI_MANAGEMENT_AGENT_ENTITY_NAME as q, axmReadAssistResponseStatus as r, axmIsAssistRetryableStatus as s, axmReadAssistResponseError as t, axmReadAssistAiTranscript as u, axmParseAssistTranscriptLinePayload as v, axmReadAssistAiTranscriptRaw as w, axmAssistUserFacingPayloadLine as x, axmIsAssistStreamingStatus as y, axmAssistHasFinalizeMetadata as z };
17476
- //# sourceMappingURL=acorex-platform-module-conversation-client-acorex-platform-module-conversation-client-CmRULmpl.mjs.map
17660
+ //# sourceMappingURL=acorex-platform-module-conversation-client-acorex-platform-module-conversation-client-Be9CB1WQ.mjs.map