@acorex-platform/module-conversation-client 0.0.59 → 0.0.61

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-1tv00m7Y.mjs → acorex-platform-module-conversation-client-acorex-platform-module-conversation-client-CmRULmpl.mjs} +379 -276
  2. package/fesm2022/acorex-platform-module-conversation-client-acorex-platform-module-conversation-client-CmRULmpl.mjs.map +1 -0
  3. package/fesm2022/{acorex-platform-module-conversation-client-after-message-sent.command-e_3t71gw.mjs → acorex-platform-module-conversation-client-after-message-sent.command-JjZrYD2R.mjs} +2 -2
  4. package/fesm2022/{acorex-platform-module-conversation-client-after-message-sent.command-e_3t71gw.mjs.map → acorex-platform-module-conversation-client-after-message-sent.command-JjZrYD2R.mjs.map} +1 -1
  5. package/fesm2022/{acorex-platform-module-conversation-client-assist-delegated-agent-detail-popup.component-BmfLuUaU.mjs → acorex-platform-module-conversation-client-assist-delegated-agent-detail-popup.component-BhED754u.mjs} +3 -3
  6. package/fesm2022/{acorex-platform-module-conversation-client-assist-delegated-agent-detail-popup.component-BmfLuUaU.mjs.map → acorex-platform-module-conversation-client-assist-delegated-agent-detail-popup.component-BhED754u.mjs.map} +1 -1
  7. package/fesm2022/{acorex-platform-module-conversation-client-assist-message-renderer.component-jsHo7NZq.mjs → acorex-platform-module-conversation-client-assist-message-renderer.component-CR4OxDV6.mjs} +3 -3
  8. package/fesm2022/{acorex-platform-module-conversation-client-assist-message-renderer.component-jsHo7NZq.mjs.map → acorex-platform-module-conversation-client-assist-message-renderer.component-CR4OxDV6.mjs.map} +1 -1
  9. package/fesm2022/{acorex-platform-module-conversation-client-chat-call-session-page.component-ePQikBd2.mjs → acorex-platform-module-conversation-client-chat-call-session-page.component-DJreBgNo.mjs} +2 -2
  10. package/fesm2022/{acorex-platform-module-conversation-client-chat-call-session-page.component-ePQikBd2.mjs.map → acorex-platform-module-conversation-client-chat-call-session-page.component-DJreBgNo.mjs.map} +1 -1
  11. package/fesm2022/{acorex-platform-module-conversation-client-chat-call-start-popup.component-ooiJkC8U.mjs → acorex-platform-module-conversation-client-chat-call-start-popup.component-BEa8wEJt.mjs} +2 -2
  12. package/fesm2022/{acorex-platform-module-conversation-client-chat-call-start-popup.component-ooiJkC8U.mjs.map → acorex-platform-module-conversation-client-chat-call-start-popup.component-BEa8wEJt.mjs.map} +1 -1
  13. package/fesm2022/{acorex-platform-module-conversation-client-comments-page.component-BW_XRzT6.mjs → acorex-platform-module-conversation-client-comments-page.component-BsE6bCZT.mjs} +2 -2
  14. package/fesm2022/{acorex-platform-module-conversation-client-comments-page.component-BW_XRzT6.mjs.map → acorex-platform-module-conversation-client-comments-page.component-BsE6bCZT.mjs.map} +1 -1
  15. package/fesm2022/{acorex-platform-module-conversation-client-mark-conversation-unread.command-Cdd6Cxkf.mjs → acorex-platform-module-conversation-client-mark-conversation-unread.command-B1mvtbaA.mjs} +2 -2
  16. package/fesm2022/{acorex-platform-module-conversation-client-mark-conversation-unread.command-Cdd6Cxkf.mjs.map → acorex-platform-module-conversation-client-mark-conversation-unread.command-B1mvtbaA.mjs.map} +1 -1
  17. package/fesm2022/{acorex-platform-module-conversation-client-open-chat.command-TfSLQn3K.mjs → acorex-platform-module-conversation-client-open-chat.command-CbJ0gXZq.mjs} +2 -2
  18. package/fesm2022/{acorex-platform-module-conversation-client-open-chat.command-TfSLQn3K.mjs.map → acorex-platform-module-conversation-client-open-chat.command-CbJ0gXZq.mjs.map} +1 -1
  19. package/fesm2022/{acorex-platform-module-conversation-client-retry-assist-response.command-CC0jPXGP.mjs → acorex-platform-module-conversation-client-retry-assist-response.command-BvzWaKX4.mjs} +2 -2
  20. package/fesm2022/{acorex-platform-module-conversation-client-retry-assist-response.command-CC0jPXGP.mjs.map → acorex-platform-module-conversation-client-retry-assist-response.command-BvzWaKX4.mjs.map} +1 -1
  21. package/fesm2022/{acorex-platform-module-conversation-client-sync-read-state.command-BUtdyniC.mjs → acorex-platform-module-conversation-client-sync-read-state.command-DQXezGRu.mjs} +2 -2
  22. package/fesm2022/{acorex-platform-module-conversation-client-sync-read-state.command-BUtdyniC.mjs.map → acorex-platform-module-conversation-client-sync-read-state.command-DQXezGRu.mjs.map} +1 -1
  23. package/fesm2022/acorex-platform-module-conversation-client.mjs +1 -1
  24. package/i18n/en-AU/conversation.json +6 -1
  25. package/i18n/en-US/conversation.json +6 -1
  26. package/i18n/fa-IR/conversation.json +6 -1
  27. package/package.json +2 -2
  28. package/types/acorex-platform-module-conversation-client.d.ts +41 -44
  29. package/fesm2022/acorex-platform-module-conversation-client-acorex-platform-module-conversation-client-1tv00m7Y.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, 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, AXP_IN_APP_NOTIFICATION_SERVICE, 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';
@@ -34,7 +34,7 @@ import { AXBadgeModule } from '@acorex/components/badge';
34
34
  import * as i2 from '@acorex/components/decorators';
35
35
  import { AXDecoratorModule } from '@acorex/components/decorators';
36
36
  import * as i5 from '@acorex/core/format';
37
- import { AXFormatModule } from '@acorex/core/format';
37
+ import { AXFormatModule, AXFormatService } from '@acorex/core/format';
38
38
  import { AXDialogService } from '@acorex/components/dialog';
39
39
  import { AXPopupService, AXPopupCaptionIconComponent, AXPopupComponentBase, AXPopupDockComponent } from '@acorex/components/popup';
40
40
  import { AXDragHandleDirective } from '@acorex/cdk/drag-drop';
@@ -46,21 +46,14 @@ import { AXPlatform } from '@acorex/core/platform';
46
46
  import { AXFabComponent, AXFabItemComponent } from '@acorex/components/fab';
47
47
  import { AXPInAppInboxConnectorService, isInAppInboxUnread, AXPCommunicationManagementClient, AXPInAppInboxRealtimeService } from '@acorex-platform/module-communication-management-client';
48
48
  import { axpAiChatMessageIsDelegatedReflectionExcluded, axpAiExtractChatWidgetNodeFromUnknown, axpAiDelegatedAgentResultSegments, AXPAiManagerService, AXPAiChatToolRunContextService, AXPAiPlatformRuntimeContextBuilder, AIMANAGEMENT_STRUCTURED_TEXT_COMPLETION_COMMAND_KEY, axpAiChatTextMessage, persistAiChatAttachmentImage, AIMANAGEMENT_CHAT_TRANSCRIBE_SPEECH_COMMAND_KEY, AXPAiAssistChatModelCatalogService } from '@acorex-platform/module-ai-management-client';
49
- import * as i1$3 from '@acorex/components/text-editor';
50
- import { AXTextEditorModule } from '@acorex/components/text-editor';
51
- import { trigger, transition, style, animate } from '@angular/animations';
52
- import { DomSanitizer } from '@angular/platform-browser';
53
- import { AXAvatarModule } from '@acorex/components/avatar';
54
49
  import * as i4 from '@acorex/components/comment';
55
- import { AXCommentModule } from '@acorex/components/comment';
56
- import * as i7 from '@acorex/components/dropdown';
57
- import { AXDropdownModule } from '@acorex/components/dropdown';
50
+ import { AXCommentViewComponent, AXCommentContainerComponent, AXCommentModule } from '@acorex/components/comment';
51
+ import * as i7 from '@acorex/components/dropdown-button';
58
52
  import { AXDropdownButtonModule } from '@acorex/components/dropdown-button';
59
- import { AXFormModule } from '@acorex/components/form';
60
- import { AXImageModule } from '@acorex/components/image';
61
- import * as i6 from '@acorex/components/loading';
53
+ import * as i8 from '@acorex/components/loading';
62
54
  import { AXLoadingModule } from '@acorex/components/loading';
63
- import { AXToolBarModule } from '@acorex/components/toolbar';
55
+ import * as i1$3 from '@acorex/components/text-editor';
56
+ import { AXTextEditorComponent, AXTextEditorModule } from '@acorex/components/text-editor';
64
57
  import * as i1$4 from '@angular/forms';
65
58
  import { FormsModule } from '@angular/forms';
66
59
  import { AXPEntityCommandScope } from '@acorex-platform/framework-shared/entity';
@@ -12393,11 +12386,16 @@ function buildCommentInAppNotificationRequest(thread, comment, receiver) {
12393
12386
  }
12394
12387
  //#endregion
12395
12388
 
12396
- const HIGHLIGHT_DURATION_MS = 2500;
12389
+ //#region ----- Imports -----
12390
+ //#endregion
12391
+ //#region ----- Constants -----
12397
12392
  const SUBMIT_COOLDOWN_MS = 100;
12393
+ const AVATAR_COLORS = ['primary', 'success', 'warning', 'danger'];
12394
+ //#endregion
12395
+ //#region ----- Component -----
12398
12396
  class AXMCommentComponent {
12399
12397
  constructor() {
12400
- //#region ---- Inputs ----
12398
+ //#region ----- Inputs -----
12401
12399
  this.refrenceType = input.required(/* @ts-ignore */
12402
12400
  ...(ngDevMode ? [{ debugName: "refrenceType" }] : /* istanbul ignore next */ []));
12403
12401
  this.refrenceId = input.required(/* @ts-ignore */
@@ -12405,45 +12403,41 @@ class AXMCommentComponent {
12405
12403
  this.subject = input.required(/* @ts-ignore */
12406
12404
  ...(ngDevMode ? [{ debugName: "subject" }] : /* istanbul ignore next */ []));
12407
12405
  //#endregion
12408
- //#region ---- State Signals ----
12406
+ //#region ----- State Signals -----
12409
12407
  this.moduleName = signal(undefined, /* @ts-ignore */
12410
12408
  ...(ngDevMode ? [{ debugName: "moduleName" }] : /* istanbul ignore next */ []));
12411
12409
  this.entityName = signal(undefined, /* @ts-ignore */
12412
12410
  ...(ngDevMode ? [{ debugName: "entityName" }] : /* istanbul ignore next */ []));
12413
12411
  this.hasCooldown = signal(false, /* @ts-ignore */
12414
12412
  ...(ngDevMode ? [{ debugName: "hasCooldown" }] : /* istanbul ignore next */ []));
12415
- this.commentContent = signal('', /* @ts-ignore */
12416
- ...(ngDevMode ? [{ debugName: "commentContent" }] : /* istanbul ignore next */ []));
12413
+ this.draft = signal('', /* @ts-ignore */
12414
+ ...(ngDevMode ? [{ debugName: "draft" }] : /* istanbul ignore next */ []));
12417
12415
  this.isSubmitting = signal(false, /* @ts-ignore */
12418
12416
  ...(ngDevMode ? [{ debugName: "isSubmitting" }] : /* istanbul ignore next */ []));
12419
- this.isReplyingMode = signal(false, /* @ts-ignore */
12420
- ...(ngDevMode ? [{ debugName: "isReplyingMode" }] : /* istanbul ignore next */ []));
12421
- this.isEditingMode = signal(false, /* @ts-ignore */
12422
- ...(ngDevMode ? [{ debugName: "isEditingMode" }] : /* istanbul ignore next */ []));
12423
12417
  this.isLoading = signal(true, /* @ts-ignore */
12424
12418
  ...(ngDevMode ? [{ debugName: "isLoading" }] : /* istanbul ignore next */ []));
12425
- this.activeReplyComment = signal(undefined, /* @ts-ignore */
12426
- ...(ngDevMode ? [{ debugName: "activeReplyComment" }] : /* istanbul ignore next */ []));
12427
- this.activeEditComment = signal(undefined, /* @ts-ignore */
12428
- ...(ngDevMode ? [{ debugName: "activeEditComment" }] : /* istanbul ignore next */ []));
12429
- this.highlightedCommentId = signal(null, /* @ts-ignore */
12430
- ...(ngDevMode ? [{ debugName: "highlightedCommentId" }] : /* istanbul ignore next */ []));
12419
+ this.replyingTo = signal(null, /* @ts-ignore */
12420
+ ...(ngDevMode ? [{ debugName: "replyingTo" }] : /* istanbul ignore next */ []));
12421
+ this.editing = signal(null, /* @ts-ignore */
12422
+ ...(ngDevMode ? [{ debugName: "editing" }] : /* istanbul ignore next */ []));
12431
12423
  this.expandedCommentIds = signal(new Set(), /* @ts-ignore */
12432
12424
  ...(ngDevMode ? [{ debugName: "expandedCommentIds" }] : /* istanbul ignore next */ []));
12433
12425
  this.comments = signal([], /* @ts-ignore */
12434
12426
  ...(ngDevMode ? [{ debugName: "comments" }] : /* istanbul ignore next */ []));
12427
+ this.commentItems = signal([], /* @ts-ignore */
12428
+ ...(ngDevMode ? [{ debugName: "commentItems" }] : /* istanbul ignore next */ []));
12435
12429
  this.thread = signal(undefined, /* @ts-ignore */
12436
12430
  ...(ngDevMode ? [{ debugName: "thread" }] : /* istanbul ignore next */ []));
12437
- this.editorOptions = signal({
12438
- look: 'solid',
12439
- }, /* @ts-ignore */
12440
- ...(ngDevMode ? [{ debugName: "editorOptions" }] : /* istanbul ignore next */ []));
12431
+ this.commentActions = signal([], /* @ts-ignore */
12432
+ ...(ngDevMode ? [{ debugName: "commentActions" }] : /* istanbul ignore next */ []));
12433
+ this.refreshGeneration = 0;
12441
12434
  //#endregion
12442
- //#region ---- View Children ----
12443
- this.editorRef = viewChild.required('editorRef', /* @ts-ignore */
12444
- ...(ngDevMode ? [{ debugName: "editorRef" }] : /* istanbul ignore next */ []));
12435
+ //#region ----- View Children -----
12436
+ this.commentsView = viewChild('commentsView', { ...(ngDevMode ? { debugName: "commentsView" } : /* istanbul ignore next */ {}), read: AXCommentViewComponent });
12437
+ this.commentContainer = viewChild('commentContainer', { ...(ngDevMode ? { debugName: "commentContainer" } : /* istanbul ignore next */ {}), read: AXCommentContainerComponent });
12438
+ this.editor = viewChild('commentEditor', { ...(ngDevMode ? { debugName: "editor" } : /* istanbul ignore next */ {}), read: AXTextEditorComponent });
12445
12439
  //#endregion
12446
- //#region ---- Services & Dependencies ----
12440
+ //#region ----- Services & Dependencies -----
12447
12441
  this.commentService = inject(AXMCommentManagementService);
12448
12442
  this.realtimeService = inject(AXMCommentRealtimeService);
12449
12443
  this.sessionService = inject(AXPSessionService);
@@ -12452,39 +12446,43 @@ class AXMCommentComponent {
12452
12446
  this.inAppNotificationService = inject(AXP_IN_APP_NOTIFICATION_SERVICE, {
12453
12447
  optional: true,
12454
12448
  });
12455
- this.router = inject(Router);
12456
12449
  this.activatedRoute = inject(ActivatedRoute);
12457
- this.sanitizer = inject(DomSanitizer);
12458
12450
  this.translationService = inject(AXTranslationService);
12459
12451
  this.destroyRef = inject(DestroyRef);
12460
- this.elementRef = inject(ElementRef);
12452
+ this.userAvatarService = inject(AXPUserAvatarService);
12453
+ this.fileStorage = inject(AXPFileStorageService);
12454
+ this.formatService = inject(AXFormatService);
12455
+ this.profileCache = new Map();
12461
12456
  }
12462
12457
  //#endregion
12463
- //#region ---- Lifecycle ----
12458
+ //#region ----- Lifecycle -----
12464
12459
  ngOnInit() {
12465
12460
  this.moduleName.set(this.activatedRoute.snapshot.params['module'] || null);
12466
12461
  this.entityName.set(this.activatedRoute.snapshot.params['entity'] || null);
12467
- this.loadComments().finally(() => {
12468
- setTimeout(() => this.isLoading.set(false), 250);
12469
- });
12462
+ void this.initialize();
12470
12463
  this.realtimeService.comment$
12471
12464
  .pipe(takeUntilDestroyed(this.destroyRef), filter((event) => !!event))
12472
12465
  .subscribe((event) => {
12473
12466
  switch (event.type) {
12474
12467
  case 'add':
12475
- this.handleAddComment(event.payload);
12468
+ void this.handleAddComment(event.payload);
12476
12469
  break;
12477
12470
  case 'update':
12478
- this.handleUpdateComment(event.payload);
12471
+ void this.handleUpdateComment(event.payload);
12479
12472
  break;
12480
12473
  case 'remove':
12481
- this.removeMessageById(event.payload);
12474
+ void this.removeMessageById(event.payload);
12482
12475
  break;
12483
12476
  }
12484
12477
  });
12485
12478
  }
12486
12479
  //#endregion
12487
- //#region ---- Data Loading ----
12480
+ //#region ----- Data Loading -----
12481
+ async initialize() {
12482
+ await this.loadActionItems();
12483
+ await this.loadComments();
12484
+ this.isLoading.set(false);
12485
+ }
12488
12486
  async loadComments() {
12489
12487
  try {
12490
12488
  const entityRef = {
@@ -12503,44 +12501,138 @@ class AXMCommentComponent {
12503
12501
  this.thread.set(newThread);
12504
12502
  this.comments.set(newThread.comments || []);
12505
12503
  }
12504
+ await this.refreshItems();
12506
12505
  }
12507
12506
  catch (error) {
12508
12507
  console.error('Failed to load comments:', error);
12509
12508
  this.showTranslatedToast('messages.error.load-comments', 'danger');
12510
12509
  this.comments.set([]);
12510
+ this.commentItems.set([]);
12511
12511
  }
12512
12512
  }
12513
12513
  //#endregion
12514
- //#region ---- Comment Actions ----
12515
- /** Opens edit mode for the target comment (or its reply). */
12516
- editMessage(comment, reply, userName) {
12517
- const target = reply || comment;
12518
- this.isReplyingMode.set(false);
12519
- this.activeReplyComment.set(undefined);
12520
- this.isEditingMode.set(true);
12521
- this.activeEditComment.set({ ...target, userName: userName || '' });
12522
- this.commentContent.set(axmExtractTextFromPayload(target.payload));
12523
- this.editorRef()
12524
- .getHostElement()
12525
- .scrollIntoView({ behavior: 'smooth', block: 'start' });
12526
- }
12527
- /** Opens reply mode, optionally mentioning a specific reply author. */
12528
- replyMessage(comment, reply, userName) {
12529
- this.isEditingMode.set(false);
12530
- this.activeEditComment.set(undefined);
12531
- this.isReplyingMode.set(true);
12532
- this.activeReplyComment.set({ ...comment, userName: userName || '' });
12533
- if (reply) {
12534
- const mention = `<strong><a data-id="${reply.senderId}">@${userName || reply.senderId}</a></strong> `;
12535
- this.commentContent.set(mention);
12536
- this.setEditorContent(mention);
12537
- this.editorRef()?.focus();
12538
- }
12539
- this.editorRef()
12540
- .getHostElement()
12541
- .scrollIntoView({ behavior: 'smooth', block: 'start' });
12514
+ //#region ----- Event Handlers -----
12515
+ onReply(event) {
12516
+ const wasEditing = this.editing();
12517
+ this.editing.set(null);
12518
+ this.replyingTo.set(event.item);
12519
+ if (wasEditing) {
12520
+ this.draft.set('');
12521
+ this.editor()?.setContent('', true);
12522
+ return;
12523
+ }
12524
+ setTimeout(() => this.editor()?.focus());
12542
12525
  }
12543
- async deleteComment(commentId) {
12526
+ cancelReply() {
12527
+ this.replyingTo.set(null);
12528
+ }
12529
+ cancelEdit() {
12530
+ this.editing.set(null);
12531
+ this.draft.set('');
12532
+ this.editor()?.setContent('', false);
12533
+ }
12534
+ onLikeChange(event) {
12535
+ void this.persistLikeChange(event);
12536
+ }
12537
+ onRepliesToggle(event) {
12538
+ this.onRepliesExpandedChange(String(event.item.id), event.expanded);
12539
+ }
12540
+ onAction(event) {
12541
+ if (event.action.name === 'edit') {
12542
+ this.edit(event.item);
12543
+ }
12544
+ if (event.action.name === 'delete') {
12545
+ void this.remove(event.item);
12546
+ }
12547
+ }
12548
+ commentSenderId(item) {
12549
+ const data = item.data;
12550
+ return data?.senderId ?? '';
12551
+ }
12552
+ onOverflowAction(item, name) {
12553
+ if (name === 'edit') {
12554
+ this.edit(item);
12555
+ }
12556
+ if (name === 'delete') {
12557
+ void this.remove(item);
12558
+ }
12559
+ }
12560
+ scrollToCommentContext(item) {
12561
+ this.commentContainer()?.scrollToReply(String(item.id));
12562
+ }
12563
+ commentContextPreview(content) {
12564
+ return stripHtmlToPlainText(content ?? '');
12565
+ }
12566
+ async submitComment() {
12567
+ this.isSubmitting.set(true);
12568
+ try {
12569
+ const currentThread = this.thread();
12570
+ if (!currentThread) {
12571
+ return;
12572
+ }
12573
+ const content = this.readEditorHtml();
12574
+ if (stripHtmlToPlainText(content).length === 0) {
12575
+ return;
12576
+ }
12577
+ if (this.editing()?.id) {
12578
+ const commentId = String(this.editing().id);
12579
+ const updated = await this.commentService.editComment(commentId, content);
12580
+ await this.handleUpdateComment(updated);
12581
+ this.hasCooldown.set(true);
12582
+ this.editing.set(null);
12583
+ }
12584
+ else {
12585
+ const parent = this.replyingTo();
12586
+ const parentCommentId = parent ? String(parent.id) : undefined;
12587
+ if (parent && this.commentsView() && !this.commentsView()?.findItem(parentCommentId)) {
12588
+ return;
12589
+ }
12590
+ const newComment = await this.commentService.addComment(currentThread.id, content, parentCommentId);
12591
+ this.hasCooldown.set(true);
12592
+ if (parentCommentId) {
12593
+ this.expandReplies(parentCommentId);
12594
+ this.replyingTo.set(null);
12595
+ }
12596
+ if (newComment?.id) {
12597
+ await this.refreshItems();
12598
+ setTimeout(() => this.commentContainer()?.scrollToReply(String(newComment.id)));
12599
+ }
12600
+ }
12601
+ this.draft.set('');
12602
+ this.editor()?.setContent('', false);
12603
+ setTimeout(() => this.hasCooldown.set(false), SUBMIT_COOLDOWN_MS);
12604
+ }
12605
+ catch (error) {
12606
+ console.error('Error submitting comment:', error);
12607
+ if (typeof error === 'string') {
12608
+ this.showToast(error, 'danger');
12609
+ }
12610
+ else {
12611
+ this.showTranslatedToast('messages.error.submit-comment', 'danger');
12612
+ }
12613
+ }
12614
+ finally {
12615
+ this.isSubmitting.set(false);
12616
+ }
12617
+ }
12618
+ isCommentDraftEmpty() {
12619
+ const service = this.editor()?.getEditorService();
12620
+ if (service) {
12621
+ return service.isEmpty() || service.getText().trim().length === 0;
12622
+ }
12623
+ return stripHtmlToPlainText(this.draft()).length === 0;
12624
+ }
12625
+ //#endregion
12626
+ //#region ----- Edit & Delete -----
12627
+ edit(item) {
12628
+ this.replyingTo.set(null);
12629
+ this.editing.set(item);
12630
+ const html = item.content ?? '';
12631
+ this.draft.set(html);
12632
+ this.editor()?.setContent(html, true);
12633
+ }
12634
+ async remove(item) {
12635
+ const commentId = String(item.id);
12544
12636
  const [dialogTitle, dialogMessage, deleteText, deletingText, cancelText] = await Promise.all([
12545
12637
  this.t('confirmations.delete-comment.title'),
12546
12638
  this.t('confirmations.delete-comment.message'),
@@ -12548,6 +12640,13 @@ class AXMCommentComponent {
12548
12640
  this.t('confirmations.delete-comment.deleting'),
12549
12641
  this.t('actions.cancel.title'),
12550
12642
  ]);
12643
+ const cancelButton = {
12644
+ text: cancelText,
12645
+ color: 'default',
12646
+ autofocus: true,
12647
+ disabled: false,
12648
+ onClick: () => dialog.close(),
12649
+ };
12551
12650
  const dialog = this.dialogService.open({
12552
12651
  icon: 'fa-regular fa-warning',
12553
12652
  content: dialogMessage,
@@ -12559,21 +12658,30 @@ class AXMCommentComponent {
12559
12658
  text: deleteText,
12560
12659
  color: 'danger',
12561
12660
  onClick: async (e) => {
12661
+ if (!e) {
12662
+ return;
12663
+ }
12562
12664
  e.handled = true;
12563
12665
  e.source.text = deletingText;
12564
12666
  e.source.disabled = true;
12565
12667
  e.source.loading = true;
12668
+ cancelButton.disabled = true;
12566
12669
  try {
12567
12670
  await this.commentService.deleteComment(commentId);
12568
- this.removeMessageById(commentId);
12569
12671
  this.showTranslatedToast('messages.success.comment-deleted', 'success');
12570
- if (this.isEditingMode() &&
12571
- this.activeEditComment()?.id === commentId) {
12572
- this.resetReplyEditState();
12672
+ if (this.editing()?.id === commentId) {
12673
+ this.cancelEdit();
12674
+ }
12675
+ if (this.replyingTo()?.id === commentId) {
12676
+ this.cancelReply();
12573
12677
  }
12574
12678
  dialog.close();
12575
12679
  }
12576
12680
  catch (error) {
12681
+ cancelButton.disabled = false;
12682
+ e.source.text = deleteText;
12683
+ e.source.disabled = false;
12684
+ e.source.loading = false;
12577
12685
  if (typeof error === 'string') {
12578
12686
  this.showToast(error, 'danger');
12579
12687
  }
@@ -12583,98 +12691,43 @@ class AXMCommentComponent {
12583
12691
  }
12584
12692
  },
12585
12693
  },
12586
- {
12587
- text: cancelText,
12588
- color: 'default',
12589
- autofocus: true,
12590
- onClick: () => dialog.close(),
12591
- },
12694
+ cancelButton,
12592
12695
  ],
12593
12696
  closeButton: false,
12594
12697
  });
12595
12698
  }
12596
- resetReplyEditState() {
12597
- this.isEditingMode.set(false);
12598
- this.activeEditComment.set(undefined);
12599
- this.isReplyingMode.set(false);
12600
- this.activeReplyComment.set(undefined);
12601
- this.commentContent.set('');
12602
- this.clearEditorContent();
12603
- }
12604
- async submitComment() {
12605
- this.isSubmitting.set(true);
12606
- try {
12607
- const currentThread = this.thread();
12608
- if (!currentThread)
12609
- return;
12610
- if (this.isEditingMode() && this.activeEditComment()?.id) {
12611
- await this.commentService.editComment(this.activeEditComment().id, this.commentContent());
12612
- this.hasCooldown.set(true);
12613
- this.isEditingMode.set(false);
12614
- this.activeEditComment.set(undefined);
12615
- }
12616
- else {
12617
- const parentCommentId = this.activeReplyComment()?.id;
12618
- const newComment = await this.commentService.addComment(currentThread.id, this.commentContent(), parentCommentId);
12619
- this.hasCooldown.set(true);
12620
- if (parentCommentId) {
12621
- this.expandReplies(parentCommentId);
12622
- }
12623
- this.isReplyingMode.set(false);
12624
- this.activeReplyComment.set(undefined);
12625
- if (newComment?.id) {
12626
- this.scrollToAndHighlight(newComment.id);
12627
- }
12628
- }
12629
- this.commentContent.set('');
12630
- this.clearEditorContent();
12631
- setTimeout(() => this.hasCooldown.set(false), SUBMIT_COOLDOWN_MS);
12632
- }
12633
- catch (error) {
12634
- console.error('Error submitting comment:', error);
12635
- if (typeof error === 'string') {
12636
- this.showToast(error, 'danger');
12637
- }
12638
- else {
12639
- this.showTranslatedToast('messages.error.submit-comment', 'danger');
12640
- }
12641
- }
12642
- finally {
12643
- this.isSubmitting.set(false);
12644
- }
12645
- }
12646
12699
  //#endregion
12647
- //#region ---- Reactions ----
12648
- async toggleLike(comment) {
12649
- const isLiked = this.isLikedByUser(comment);
12650
- this.updateLikeStatus(comment.id, !isLiked);
12700
+ //#region ----- Reactions -----
12701
+ async persistLikeChange(event) {
12702
+ const commentId = String(event.item.id);
12651
12703
  try {
12652
- if (isLiked) {
12653
- await this.commentService.unlikeComment(comment.id);
12704
+ if (event.liked) {
12705
+ await this.commentService.likeComment(commentId);
12654
12706
  }
12655
12707
  else {
12656
- await this.commentService.likeComment(comment.id);
12708
+ await this.commentService.unlikeComment(commentId);
12657
12709
  }
12658
12710
  }
12659
12711
  catch (error) {
12660
12712
  console.error('Failed to toggle like:', error);
12661
- this.updateLikeStatus(comment.id, isLiked);
12713
+ this.commentsView()?.updateItem(commentId, {
12714
+ liked: !event.liked,
12715
+ likes: event.liked ? Math.max(0, (event.likes ?? 1) - 1) : (event.likes ?? 0) + 1,
12716
+ });
12662
12717
  }
12663
12718
  }
12664
12719
  isLikedByUser(comment) {
12665
12720
  const user = this.getCurrentUser();
12666
- if (!user)
12721
+ if (!user) {
12667
12722
  return false;
12723
+ }
12668
12724
  return (comment.reactions || []).some((r) => r.userId === user.id && r.emoji === AXM_COMMENT_LIKE_EMOJI);
12669
12725
  }
12670
12726
  getReactionsCount(comment) {
12671
12727
  return (comment.reactions || []).filter((r) => r.emoji === AXM_COMMENT_LIKE_EMOJI).length;
12672
12728
  }
12673
12729
  //#endregion
12674
- //#region ---- Replies Expansion ----
12675
- isRepliesExpanded(commentId) {
12676
- return this.expandedCommentIds().has(commentId);
12677
- }
12730
+ //#region ----- Replies Expansion -----
12678
12731
  onRepliesExpandedChange(commentId, expanded) {
12679
12732
  this.expandedCommentIds.update((ids) => {
12680
12733
  const next = new Set(ids);
@@ -12695,66 +12748,22 @@ class AXMCommentComponent {
12695
12748
  });
12696
12749
  }
12697
12750
  //#endregion
12698
- //#region ---- Scroll & Highlight ----
12699
- /**
12700
- * Scrolls to the referenced comment and triggers a highlight pulse animation.
12701
- * Expands parent replies if needed to ensure the target is in the DOM.
12702
- */
12703
- scrollMain() {
12704
- const comment = this.isReplyingMode()
12705
- ? this.activeReplyComment()
12706
- : this.activeEditComment();
12707
- if (!comment?.id)
12708
- return;
12709
- if (comment.replyTo?.id) {
12710
- this.expandReplies(comment.replyTo.id);
12711
- }
12712
- this.scrollToAndHighlight(comment.id);
12713
- }
12714
- /**
12715
- * Scrolls to a comment element and applies a highlight pulse animation.
12716
- * Uses setTimeout to wait for Angular to render after signal updates.
12717
- */
12718
- scrollToAndHighlight(commentId) {
12719
- this.highlightedCommentId.set(null);
12720
- setTimeout(() => {
12721
- const el = this.elementRef.nativeElement.querySelector(`ax-comment-item[id="${commentId}"]`);
12722
- if (!el)
12723
- return;
12724
- el.scrollIntoView({ behavior: 'smooth', block: 'center' });
12725
- this.highlightedCommentId.set(commentId);
12726
- setTimeout(() => this.highlightedCommentId.set(null), HIGHLIGHT_DURATION_MS);
12727
- });
12728
- }
12729
- //#endregion
12730
- //#region ---- HTML Sanitization ----
12731
- sanitizeHtml(htmlContent) {
12732
- if (!htmlContent)
12733
- return this.sanitizer.bypassSecurityTrustHtml('');
12734
- return this.sanitizer.bypassSecurityTrustHtml(htmlContent);
12735
- }
12736
- //#endregion
12737
- //#region ---- Realtime Event Handlers ----
12738
- handleAddComment(comment) {
12751
+ //#region ----- Realtime Event Handlers -----
12752
+ async handleAddComment(comment) {
12739
12753
  if (comment.senderId !== this.getCurrentUser()?.id && this.thread()) {
12740
12754
  void this.inAppNotificationService?.create(buildCommentInAppNotificationRequest(this.thread(), comment, this.sessionService.user));
12741
12755
  }
12742
12756
  const parentId = comment.replyTo?.id;
12743
12757
  if (parentId) {
12744
12758
  this.expandReplies(parentId);
12745
- this.comments.update((comments) => comments.map((c) => {
12746
- if (c.id === parentId) {
12747
- const newReplies = c.replies ? [...c.replies, comment] : [comment];
12748
- return { ...c, replies: newReplies, replyCount: newReplies.length };
12749
- }
12750
- return c;
12751
- }));
12759
+ this.comments.update((comments) => insertReply(comments, parentId, comment));
12752
12760
  }
12753
12761
  else {
12754
12762
  this.comments.update((comments) => [...comments, comment]);
12755
12763
  }
12764
+ await this.refreshItems();
12756
12765
  }
12757
- handleUpdateComment(updatedComment) {
12766
+ async handleUpdateComment(updatedComment) {
12758
12767
  const update = (list) => list.map((c) => {
12759
12768
  if (c.id === updatedComment.id) {
12760
12769
  return {
@@ -12771,39 +12780,15 @@ class AXMCommentComponent {
12771
12780
  return c;
12772
12781
  });
12773
12782
  this.comments.update((comments) => update(comments));
12783
+ await this.refreshItems();
12774
12784
  }
12775
12785
  //#endregion
12776
- //#region ---- Private Helpers ----
12786
+ //#region ----- Private Helpers -----
12777
12787
  getCurrentUser() {
12778
12788
  const user = this.sessionService.user;
12779
12789
  return user ? { id: user.id, type: 'user' } : null;
12780
12790
  }
12781
- updateLikeStatus(commentId, willBeLiked) {
12782
- const findAndToggle = (comments) => comments.map((c) => {
12783
- if (c.id === commentId) {
12784
- const user = this.getCurrentUser();
12785
- if (!user)
12786
- return c;
12787
- const reactions = willBeLiked
12788
- ? [
12789
- ...(c.reactions || []),
12790
- {
12791
- emoji: AXM_COMMENT_LIKE_EMOJI,
12792
- userId: user.id,
12793
- timestamp: new Date(),
12794
- },
12795
- ]
12796
- : (c.reactions || []).filter((r) => r.userId !== user.id || r.emoji !== AXM_COMMENT_LIKE_EMOJI);
12797
- return { ...c, reactions };
12798
- }
12799
- if (c.replies?.length) {
12800
- return { ...c, replies: findAndToggle(c.replies) };
12801
- }
12802
- return c;
12803
- });
12804
- this.comments.update((comments) => findAndToggle(comments));
12805
- }
12806
- removeMessageById(commentId) {
12791
+ async removeMessageById(commentId) {
12807
12792
  const filterOut = (comments) => comments
12808
12793
  .filter((c) => c.id !== commentId)
12809
12794
  .map((c) => {
@@ -12813,14 +12798,107 @@ class AXMCommentComponent {
12813
12798
  return c;
12814
12799
  });
12815
12800
  this.comments.update((comments) => filterOut(comments));
12801
+ await this.refreshItems();
12802
+ }
12803
+ readEditorHtml() {
12804
+ const service = this.editor()?.getEditorService();
12805
+ if (service && !service.isEmpty()) {
12806
+ return service.getHTML();
12807
+ }
12808
+ return this.draft();
12809
+ }
12810
+ async loadActionItems() {
12811
+ const [editText, deleteText] = await Promise.all([this.t('actions.edit.title'), this.t('actions.delete.title')]);
12812
+ this.commentActions.set([
12813
+ { name: 'edit', text: editText, icon: 'fa-light fa-pen', break: true },
12814
+ { name: 'delete', text: deleteText, icon: 'fa-light fa-trash-can', color: 'danger' },
12815
+ ]);
12816
+ }
12817
+ async refreshItems() {
12818
+ const generation = ++this.refreshGeneration;
12819
+ const items = await Promise.all(this.comments().map((comment) => this.mapComment(comment)));
12820
+ if (generation !== this.refreshGeneration) {
12821
+ return;
12822
+ }
12823
+ this.commentItems.set(items);
12824
+ }
12825
+ async mapComment(comment) {
12826
+ const profile = await this.resolveProfile(comment.senderId);
12827
+ const currentUserId = this.getCurrentUser()?.id;
12828
+ const replies = comment.replies?.length ? await Promise.all(comment.replies.map((reply) => this.mapComment(reply))) : undefined;
12829
+ const isYou = !!currentUserId && comment.senderId === currentUserId;
12830
+ const editedAt = comment.editedAt;
12831
+ return {
12832
+ id: comment.id,
12833
+ author: profile.author,
12834
+ avatar: profile.avatar,
12835
+ initials: profile.initials,
12836
+ color: profile.color,
12837
+ date: this.formatCommentDate(comment.timestamp),
12838
+ edited: !!editedAt,
12839
+ editedAt: editedAt ? this.formatCommentDate(editedAt) : undefined,
12840
+ content: axmExtractTextFromPayload(comment.payload),
12841
+ likes: this.getReactionsCount(comment),
12842
+ liked: this.isLikedByUser(comment),
12843
+ isYou,
12844
+ repliesExpanded: this.expandedCommentIds().has(comment.id),
12845
+ replies,
12846
+ replyCount: comment.replyCount ?? replies?.length ?? 0,
12847
+ actions: isYou ? this.commentActions() : undefined,
12848
+ data: comment,
12849
+ };
12850
+ }
12851
+ async resolveProfile(userId) {
12852
+ const cached = this.profileCache.get(userId);
12853
+ if (cached) {
12854
+ return cached;
12855
+ }
12856
+ try {
12857
+ const info = await this.userAvatarService.getUserInfo(userId);
12858
+ const author = resolveDisplayName(info) || userId;
12859
+ const avatar = this.resolveAvatarUrl(info.avatarUrl, userId) || undefined;
12860
+ const profile = {
12861
+ author,
12862
+ initials: toInitials(author),
12863
+ avatar,
12864
+ color: colorForUser(userId),
12865
+ };
12866
+ this.profileCache.set(userId, profile);
12867
+ return profile;
12868
+ }
12869
+ catch {
12870
+ return {
12871
+ author: userId,
12872
+ initials: toInitials(userId),
12873
+ color: colorForUser(userId),
12874
+ };
12875
+ }
12816
12876
  }
12817
- clearEditorContent() {
12818
- this.editorRef()?.getEditorService().clearContent();
12877
+ resolveAvatarUrl(avatarUrl, userId) {
12878
+ const sessionUser = this.sessionService.user;
12879
+ const isSessionUser = sessionUser?.id === userId;
12880
+ let ref = isSessionUser ? normalizeStoredImageRef(sessionUser.avatar) : null;
12881
+ if (!ref) {
12882
+ ref = normalizeStoredImageRef(avatarUrl);
12883
+ }
12884
+ if (!ref) {
12885
+ return '';
12886
+ }
12887
+ if (!isStoredImageFileId(ref)) {
12888
+ return ref;
12889
+ }
12890
+ return this.userAvatarService.resolveAvatarDisplayUrl(ref, (fileId) => this.fileStorage.getDownloadUrl(fileId));
12819
12891
  }
12820
- setEditorContent(html) {
12821
- this.editorRef()?.getEditorService().setContent(html || '', false);
12892
+ formatCommentDate(timestamp) {
12893
+ if (!timestamp) {
12894
+ return '';
12895
+ }
12896
+ const date = timestamp instanceof Date ? timestamp : new Date(timestamp);
12897
+ if (Number.isNaN(date.getTime())) {
12898
+ return '';
12899
+ }
12900
+ return this.formatService.format(date, 'timeleft');
12822
12901
  }
12823
- /** Shorthand translator scoped to the comments feature */
12824
12902
  t(key) {
12825
12903
  return this.translationService.translateAsync(`@conversation:comments.${key}`);
12826
12904
  }
@@ -12838,50 +12916,75 @@ class AXMCommentComponent {
12838
12916
  const content = await this.t(key);
12839
12917
  this.showToast(content, color);
12840
12918
  }
12841
- getCommentText(comment) {
12842
- return axmExtractTextFromPayload(comment.payload);
12843
- }
12844
12919
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMCommentComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
12845
- 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: "editorRef", first: true, predicate: ["editorRef"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"axm-comment size-full flex flex-col overflow-hidden\">\n <div class=\"axm-comment__list flex-1 min-h-0 overflow-y-auto\">\n <ax-comment-container>\n @if (isLoading()) {\n <div class=\"axm-comment__skeleton\">\n <ax-skeleton class=\"size-10 shrink-0 rounded-full\"></ax-skeleton>\n <div class=\"axm-comment__skeleton-body\">\n <ax-skeleton class=\"h-4 w-32 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 <ax-skeleton class=\"h-3 w-4/5 rounded-full\"></ax-skeleton>\n </div>\n </div>\n } @else if (comments().length > 0) {\n <ax-comment-view class=\"axm-comment__view\">\n @for (comment of comments(); track comment.id) {\n <ax-comment-item\n [id]=\"comment.id!\"\n [replyCount]=\"comment.replyCount\"\n [repliesExpanded]=\"isRepliesExpanded(comment.id!)\"\n (repliesExpandedChange)=\"\n onRepliesExpandedChange(comment.id!, $event)\n \"\n [class.highlighted]=\"highlightedCommentId() === comment.id\"\n [@fadeIn]\n >\n <axp-user-avatar\n #user\n [size]=\"36\"\n [userId]=\"comment.senderId\"\n [axpUserCard]=\"comment.senderId\"\n ngProjectAs=\"'ax-avatar'\"\n ></axp-user-avatar>\n <ax-title class=\"axm-comment__author\" [axpUserCard]=\"comment.senderId\">{{\n user.title()\n }}</ax-title>\n <ax-comment-date class=\"axm-comment__date\">\n {{ comment.timestamp | format: 'timeleft' | async }}\n </ax-comment-date>\n <ax-comment-menu-options>\n <ax-button\n class=\"axm-comment__menu-btn ax-sm\"\n look=\"blank\"\n color=\"neutral\"\n >\n <ax-icon icon=\"fa-regular fa-ellipsis\"></ax-icon>\n </ax-button>\n <ax-dropdown-panel>\n <ax-button-item-list>\n <ax-button-item\n [text]=\"\n ('@conversation:comments.actions.edit.title'\n | translate\n | async) ?? ''\n \"\n color=\"neutral\"\n (click)=\"editMessage(comment, undefined, user.title())\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-pen\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n <ax-button-item\n [text]=\"\n ('@conversation:comments.actions.delete.title'\n | translate\n | async) ?? ''\n \"\n color=\"danger\"\n (click)=\"deleteComment(comment.id!)\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-trash-can\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-comment-menu-options>\n <ax-content\n [innerHTML]=\"sanitizeHtml(getCommentText(comment))\"\n ></ax-content>\n <ax-comment-like\n (click)=\"toggleLike(comment)\"\n [like]=\"isLikedByUser(comment)\"\n >\n {{ getReactionsCount(comment) }}\n </ax-comment-like>\n <ax-comment-reply-text\n (click)=\"replyMessage(comment, undefined, user.title())\"\n ></ax-comment-reply-text>\n\n @for (reply of comment.replies; track reply.id) {\n <ax-comment-item\n [id]=\"reply.id\"\n [class.highlighted]=\"highlightedCommentId() === reply.id\"\n [@fadeIn]\n >\n <axp-user-avatar\n #replyUser\n [size]=\"36\"\n [userId]=\"reply.senderId\"\n [axpUserCard]=\"reply.senderId\"\n ngProjectAs=\"'ax-avatar'\"\n ></axp-user-avatar>\n <ax-title class=\"axm-comment__author\" [axpUserCard]=\"reply.senderId\">{{\n replyUser.title()\n }}</ax-title>\n <ax-comment-date class=\"axm-comment__date\">\n {{ reply.timestamp | format: 'timeleft' | async }}\n </ax-comment-date>\n <ax-comment-menu-options>\n <ax-button\n class=\"axm-comment__menu-btn ax-sm\"\n look=\"blank\"\n color=\"neutral\"\n >\n <ax-icon icon=\"fa-regular fa-ellipsis\"></ax-icon>\n </ax-button>\n <ax-dropdown-panel>\n <ax-button-item-list>\n <ax-button-item\n [text]=\"\n ('@conversation:comments.actions.edit.title'\n | translate\n | async) ?? ''\n \"\n color=\"neutral\"\n (click)=\"\n editMessage(comment, reply, replyUser.title())\n \"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-pen\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n <ax-button-item\n [text]=\"\n ('@conversation:comments.actions.delete.title'\n | translate\n | async) ?? ''\n \"\n color=\"danger\"\n (click)=\"deleteComment(reply.id!)\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-trash-can\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-comment-menu-options>\n <ax-content\n [innerHTML]=\"sanitizeHtml(getCommentText(reply))\"\n ></ax-content>\n <ax-comment-like\n (click)=\"toggleLike(reply)\"\n [like]=\"isLikedByUser(reply)\"\n >\n {{ getReactionsCount(reply) }}\n </ax-comment-like>\n <ax-comment-reply-text\n (click)=\"replyMessage(comment, reply, replyUser.title())\"\n ></ax-comment-reply-text>\n </ax-comment-item>\n }\n </ax-comment-item>\n }\n </ax-comment-view>\n }\n <!-- ----- Empty state when no comments exist ----- -->\n @else {\n <axp-state-message\n icon=\"fa-light fa-comments\"\n [title]=\"\n '@conversation:comments.components.comment.empty-states.no-comments.title'\n \"\n [description]=\"\n '@conversation:comments.components.comment.empty-states.no-comments.description'\n \"\n >\n </axp-state-message>\n }\n </ax-comment-container>\n </div>\n\n <div class=\"axm-comment__composer\">\n @if (isReplyingMode() || isEditingMode()) {\n <div class=\"axm-comment__context\">\n <button\n type=\"button\"\n class=\"axm-comment__context-main\"\n (click)=\"scrollMain()\"\n >\n <i\n class=\"fa-light axm-comment__context-icon\"\n [class.fa-reply]=\"isReplyingMode()\"\n [class.fa-pen]=\"isEditingMode()\"\n ></i>\n <div class=\"axm-comment__context-copy\">\n <p class=\"axm-comment__context-label\">\n @if (isReplyingMode()) {\n {{\n '@conversation:comments.actions.reply-to' | translate | async\n }}\n <span>{{ activeReplyComment()?.userName }}</span>\n } @else {\n {{\n '@conversation:comments.actions.edit-message'\n | translate\n | async\n }}\n }\n </p>\n <div\n class=\"axm-comment__context-preview\"\n [innerHTML]=\"\n isReplyingMode()\n ? sanitizeHtml(getCommentText(activeReplyComment()!))\n : sanitizeHtml(getCommentText(activeEditComment()!))\n \"\n ></div>\n </div>\n </button>\n <button\n type=\"button\"\n class=\"axm-comment__context-close\"\n (click)=\"resetReplyEditState()\"\n [attr.aria-label]=\"\n ('@conversation:comments.actions.cancel.title'\n | translate\n | async) ?? 'Cancel'\n \"\n >\n <i class=\"fa-light fa-xmark\"></i>\n </button>\n </div>\n }\n\n <div class=\"axm-comment__editor\">\n <ax-text-editor\n #editorRef\n outputFormat=\"html\"\n [look]=\"editorOptions().look\"\n [(ngModel)]=\"commentContent\"\n >\n <ax-text-editor-content class=\"min-h-24\"></ax-text-editor-content>\n <ax-text-editor-toolbar>\n <ax-prefix>\n <ax-text-editor-history></ax-text-editor-history>\n <ax-text-editor-font-style></ax-text-editor-font-style>\n <ax-text-editor-colors></ax-text-editor-colors>\n <ax-text-editor-list></ax-text-editor-list>\n <ax-text-editor-alignment></ax-text-editor-alignment>\n </ax-prefix>\n </ax-text-editor-toolbar>\n </ax-text-editor>\n <!-- ----- Send sits under the editor, aligned to the inline end ----- -->\n <div class=\"axm-comment__editor-actions\">\n <ax-button\n look=\"solid\"\n color=\"primary\"\n class=\"ax-sm\"\n [disabled]=\"hasCooldown() || !commentContent()\"\n (click)=\"submitComment()\"\n [text]=\"\n '@conversation:comments.actions.send.title' | translate | async\n \"\n >\n @if (isSubmitting()) {\n <ax-loading></ax-loading>\n }\n </ax-button>\n </div>\n </div>\n </div>\n</div>\n", styles: ["@layer properties;:host{display:block;height:100%;min-height:0px;width:100%}.axm-comment{min-height:0px;height:calc(100vh - 210px);background-color:rgb(var(--ax-sys-color-lightest-surface))}.axm-comment .axm-comment__list{min-height:0px}.axm-comment .axm-comment__skeleton{display:flex;align-items:flex-start;gap:.875rem;padding:1.25rem 1.25rem 1.5rem}.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__composer{flex-shrink:0;background-color:rgb(var(--ax-sys-color-surface-surface))}.axm-comment .axm-comment__context{display:flex;align-items:center;justify-content:space-between;gap:calc(var(--spacing, .25rem) * 3);padding:.625rem .75rem;border:1px solid rgb(var(--ax-sys-color-border-light-surface));border-bottom:none;border-inline-start:3px solid rgb(var(--ax-sys-color-primary-surface));background-color:rgba(var(--ax-sys-color-primary-lightest-surface),.35);font-size:.8125rem;line-height:1.4}.axm-comment .axm-comment__context-main{display:flex;min-width:0px;flex:1;cursor:pointer;align-items:center;gap:.625rem}.axm-comment .axm-comment__context-icon{flex-shrink:0;font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));color:rgb(var(--ax-sys-color-primary-surface))}.axm-comment .axm-comment__context-copy{display:flex;min-width:0px;flex-direction:column;gap:.125rem}.axm-comment .axm-comment__context-label{margin:0;--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600);color:rgb(var(--ax-sys-color-primary-surface))}.axm-comment .axm-comment__context-preview{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:start;color:rgb(var(--ax-sys-color-neutral-600-surface, 107 114 128))}.axm-comment .axm-comment__context-close{flex-shrink:0;cursor:pointer;border-radius:var(--radius-md, .375rem);--tw-border-style: none;border-style:none;padding:.25rem;background:transparent;color:rgb(var(--ax-sys-color-neutral-500-surface, 107 114 128));font-size:1rem;line-height:1}.axm-comment .axm-comment__context-close:hover{background-color:rgba(var(--ax-sys-color-neutral-100-surface, 243 244 246),.8)}.axm-comment .axm-comment__editor{overflow:hidden;border:1px solid rgb(var(--ax-sys-color-border-light-surface));background-color:rgb(var(--ax-sys-color-lightest-surface));box-shadow:0 1px 2px #0f172a0a}.axm-comment .axm-comment__editor-actions{display:flex;justify-content:flex-end;padding:.5rem .75rem;border-top:1px solid rgb(var(--ax-sys-color-border-light-surface))}.axm-comment .axm-comment__author{font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600)}.axm-comment .axm-comment__date{font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));color:rgb(var(--ax-sys-color-neutral-500-surface, 107 114 128))}.axm-comment .axm-comment__menu-btn{opacity:0;transition:opacity .15s ease}ax-comment-item{border-radius:.75rem;transition:background-color .2s ease}ax-comment-item:hover{background-color:rgba(var(--ax-sys-color-neutral-100-surface, 243 244 246),.45)}ax-comment-item:hover .axm-comment__menu-btn{opacity:1}ax-comment-item.highlighted{animation:axm-comment-highlight 2.5s cubic-bezier(.4,0,.2,1) forwards}ax-text-editor{flex-shrink:0}ax-text-editor .ax-editor-container{border:none!important;border-radius:0!important;box-shadow:none!important}ax-text-editor .ax-error-message{padding-inline-start:.75rem}@keyframes axm-comment-highlight{0%{background-color:transparent;box-shadow:inset 3px 0 0 0 transparent}10%{background-color:rgba(var(--ax-sys-color-primary-lightest-surface),.5);box-shadow:inset 3px 0 rgb(var(--ax-sys-color-primary-surface))}35%{background-color:rgba(var(--ax-sys-color-primary-lightest-surface),.3);box-shadow:inset 3px 0 rgba(var(--ax-sys-color-primary-lighter-surface),.8)}60%{background-color:rgba(var(--ax-sys-color-primary-lightest-surface),.4);box-shadow:inset 3px 0 rgba(var(--ax-sys-color-primary-lightest-surface),.6)}to{background-color:transparent;box-shadow:inset 3px 0 0 0 transparent}}@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-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.AXTextEditorContentComponent, selector: "ax-text-editor-content" }, { 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.AXCommentItemComponent, selector: "ax-comment-item", inputs: ["item", "replyCount", "repliesExpanded", "loading", "itemTemplate", "itemContext"], outputs: ["repliesExpandedChange", "likeChange", "replyClick", "actionClick"] }, { kind: "component", type: i4.AXCommentLikeComponent, selector: "ax-comment-like", inputs: ["like"], outputs: ["likeChange"] }, { kind: "component", type: i4.AXMenuOptionsComponent, selector: "ax-comment-menu-options" }, { kind: "component", type: i4.AXCommentReplyTextComponent, selector: "ax-comment-reply-text" }, { kind: "component", type: i4.AXCommentDateComponent, selector: "ax-comment-date" }, { 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: AXAvatarModule }, { kind: "ngmodule", type: AXImageModule }, { kind: "ngmodule", type: AXLoadingModule }, { kind: "component", type: i6.AXLoadingComponent, selector: "ax-loading", inputs: ["visible", "type", "context"], outputs: ["visibleChange"] }, { kind: "ngmodule", type: AXDropdownModule }, { kind: "component", type: i7.AXDropdownPanelComponent, selector: "ax-dropdown-panel", inputs: ["isOpen", "fitParent", "dropdownWidth", "position", "placement", "_target", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "ngmodule", type: AXFormatModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: AXFormModule }, { kind: "ngmodule", type: AXToolBarModule }, { 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: "ngmodule", type: AXDropdownButtonModule }, { 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: "component", type: AXPStateMessageComponent, selector: "axp-state-message", inputs: ["mode", "icon", "title", "description", "titleParams", "descriptionParams", "look"] }, { kind: "pipe", type: i5.AXFormatPipe, name: "format" }, { kind: "pipe", type: i1$2.AXTranslatorPipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }], animations: [
12846
- trigger('fadeIn', [
12847
- transition(':enter', [
12848
- style({ opacity: 0, transform: 'translateY(10px)' }),
12849
- animate('300ms ease-out', style({ opacity: 1, transform: 'translateY(0)' })),
12850
- ]),
12851
- ]),
12852
- ], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
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 }); }
12853
12921
  }
12854
12922
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMCommentComponent, decorators: [{
12855
12923
  type: Component,
12856
- args: [{ selector: 'axm-comment', encapsulation: ViewEncapsulation.None, animations: [
12857
- trigger('fadeIn', [
12858
- transition(':enter', [
12859
- style({ opacity: 0, transform: 'translateY(10px)' }),
12860
- animate('300ms ease-out', style({ opacity: 1, transform: 'translateY(0)' })),
12861
- ]),
12862
- ]),
12863
- ], imports: [
12924
+ args: [{ selector: 'axm-comment', encapsulation: ViewEncapsulation.None, imports: [
12864
12925
  AXTextEditorModule,
12865
12926
  AXSkeletonModule,
12866
12927
  AXDecoratorModule,
12867
12928
  AXCommentModule,
12929
+ AXBadgeModule,
12868
12930
  AXButtonModule,
12869
- AXAvatarModule,
12870
- AXImageModule,
12931
+ AXDropdownButtonModule,
12871
12932
  AXLoadingModule,
12872
- AXDropdownModule,
12873
- AXFormatModule,
12874
12933
  AXTranslationModule,
12875
12934
  AsyncPipe,
12876
- AXFormModule,
12877
- AXToolBarModule,
12878
12935
  FormsModule,
12879
- AXDropdownButtonModule,
12936
+ AXPStateMessageComponent,
12880
12937
  AXPUserAvatarComponent,
12881
12938
  AXPUserCardDirective,
12882
- AXPStateMessageComponent,
12883
- ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"axm-comment size-full flex flex-col overflow-hidden\">\n <div class=\"axm-comment__list flex-1 min-h-0 overflow-y-auto\">\n <ax-comment-container>\n @if (isLoading()) {\n <div class=\"axm-comment__skeleton\">\n <ax-skeleton class=\"size-10 shrink-0 rounded-full\"></ax-skeleton>\n <div class=\"axm-comment__skeleton-body\">\n <ax-skeleton class=\"h-4 w-32 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 <ax-skeleton class=\"h-3 w-4/5 rounded-full\"></ax-skeleton>\n </div>\n </div>\n } @else if (comments().length > 0) {\n <ax-comment-view class=\"axm-comment__view\">\n @for (comment of comments(); track comment.id) {\n <ax-comment-item\n [id]=\"comment.id!\"\n [replyCount]=\"comment.replyCount\"\n [repliesExpanded]=\"isRepliesExpanded(comment.id!)\"\n (repliesExpandedChange)=\"\n onRepliesExpandedChange(comment.id!, $event)\n \"\n [class.highlighted]=\"highlightedCommentId() === comment.id\"\n [@fadeIn]\n >\n <axp-user-avatar\n #user\n [size]=\"36\"\n [userId]=\"comment.senderId\"\n [axpUserCard]=\"comment.senderId\"\n ngProjectAs=\"'ax-avatar'\"\n ></axp-user-avatar>\n <ax-title class=\"axm-comment__author\" [axpUserCard]=\"comment.senderId\">{{\n user.title()\n }}</ax-title>\n <ax-comment-date class=\"axm-comment__date\">\n {{ comment.timestamp | format: 'timeleft' | async }}\n </ax-comment-date>\n <ax-comment-menu-options>\n <ax-button\n class=\"axm-comment__menu-btn ax-sm\"\n look=\"blank\"\n color=\"neutral\"\n >\n <ax-icon icon=\"fa-regular fa-ellipsis\"></ax-icon>\n </ax-button>\n <ax-dropdown-panel>\n <ax-button-item-list>\n <ax-button-item\n [text]=\"\n ('@conversation:comments.actions.edit.title'\n | translate\n | async) ?? ''\n \"\n color=\"neutral\"\n (click)=\"editMessage(comment, undefined, user.title())\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-pen\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n <ax-button-item\n [text]=\"\n ('@conversation:comments.actions.delete.title'\n | translate\n | async) ?? ''\n \"\n color=\"danger\"\n (click)=\"deleteComment(comment.id!)\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-trash-can\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-comment-menu-options>\n <ax-content\n [innerHTML]=\"sanitizeHtml(getCommentText(comment))\"\n ></ax-content>\n <ax-comment-like\n (click)=\"toggleLike(comment)\"\n [like]=\"isLikedByUser(comment)\"\n >\n {{ getReactionsCount(comment) }}\n </ax-comment-like>\n <ax-comment-reply-text\n (click)=\"replyMessage(comment, undefined, user.title())\"\n ></ax-comment-reply-text>\n\n @for (reply of comment.replies; track reply.id) {\n <ax-comment-item\n [id]=\"reply.id\"\n [class.highlighted]=\"highlightedCommentId() === reply.id\"\n [@fadeIn]\n >\n <axp-user-avatar\n #replyUser\n [size]=\"36\"\n [userId]=\"reply.senderId\"\n [axpUserCard]=\"reply.senderId\"\n ngProjectAs=\"'ax-avatar'\"\n ></axp-user-avatar>\n <ax-title class=\"axm-comment__author\" [axpUserCard]=\"reply.senderId\">{{\n replyUser.title()\n }}</ax-title>\n <ax-comment-date class=\"axm-comment__date\">\n {{ reply.timestamp | format: 'timeleft' | async }}\n </ax-comment-date>\n <ax-comment-menu-options>\n <ax-button\n class=\"axm-comment__menu-btn ax-sm\"\n look=\"blank\"\n color=\"neutral\"\n >\n <ax-icon icon=\"fa-regular fa-ellipsis\"></ax-icon>\n </ax-button>\n <ax-dropdown-panel>\n <ax-button-item-list>\n <ax-button-item\n [text]=\"\n ('@conversation:comments.actions.edit.title'\n | translate\n | async) ?? ''\n \"\n color=\"neutral\"\n (click)=\"\n editMessage(comment, reply, replyUser.title())\n \"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-pen\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n <ax-button-item\n [text]=\"\n ('@conversation:comments.actions.delete.title'\n | translate\n | async) ?? ''\n \"\n color=\"danger\"\n (click)=\"deleteComment(reply.id!)\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-trash-can\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-comment-menu-options>\n <ax-content\n [innerHTML]=\"sanitizeHtml(getCommentText(reply))\"\n ></ax-content>\n <ax-comment-like\n (click)=\"toggleLike(reply)\"\n [like]=\"isLikedByUser(reply)\"\n >\n {{ getReactionsCount(reply) }}\n </ax-comment-like>\n <ax-comment-reply-text\n (click)=\"replyMessage(comment, reply, replyUser.title())\"\n ></ax-comment-reply-text>\n </ax-comment-item>\n }\n </ax-comment-item>\n }\n </ax-comment-view>\n }\n <!-- ----- Empty state when no comments exist ----- -->\n @else {\n <axp-state-message\n icon=\"fa-light fa-comments\"\n [title]=\"\n '@conversation:comments.components.comment.empty-states.no-comments.title'\n \"\n [description]=\"\n '@conversation:comments.components.comment.empty-states.no-comments.description'\n \"\n >\n </axp-state-message>\n }\n </ax-comment-container>\n </div>\n\n <div class=\"axm-comment__composer\">\n @if (isReplyingMode() || isEditingMode()) {\n <div class=\"axm-comment__context\">\n <button\n type=\"button\"\n class=\"axm-comment__context-main\"\n (click)=\"scrollMain()\"\n >\n <i\n class=\"fa-light axm-comment__context-icon\"\n [class.fa-reply]=\"isReplyingMode()\"\n [class.fa-pen]=\"isEditingMode()\"\n ></i>\n <div class=\"axm-comment__context-copy\">\n <p class=\"axm-comment__context-label\">\n @if (isReplyingMode()) {\n {{\n '@conversation:comments.actions.reply-to' | translate | async\n }}\n <span>{{ activeReplyComment()?.userName }}</span>\n } @else {\n {{\n '@conversation:comments.actions.edit-message'\n | translate\n | async\n }}\n }\n </p>\n <div\n class=\"axm-comment__context-preview\"\n [innerHTML]=\"\n isReplyingMode()\n ? sanitizeHtml(getCommentText(activeReplyComment()!))\n : sanitizeHtml(getCommentText(activeEditComment()!))\n \"\n ></div>\n </div>\n </button>\n <button\n type=\"button\"\n class=\"axm-comment__context-close\"\n (click)=\"resetReplyEditState()\"\n [attr.aria-label]=\"\n ('@conversation:comments.actions.cancel.title'\n | translate\n | async) ?? 'Cancel'\n \"\n >\n <i class=\"fa-light fa-xmark\"></i>\n </button>\n </div>\n }\n\n <div class=\"axm-comment__editor\">\n <ax-text-editor\n #editorRef\n outputFormat=\"html\"\n [look]=\"editorOptions().look\"\n [(ngModel)]=\"commentContent\"\n >\n <ax-text-editor-content class=\"min-h-24\"></ax-text-editor-content>\n <ax-text-editor-toolbar>\n <ax-prefix>\n <ax-text-editor-history></ax-text-editor-history>\n <ax-text-editor-font-style></ax-text-editor-font-style>\n <ax-text-editor-colors></ax-text-editor-colors>\n <ax-text-editor-list></ax-text-editor-list>\n <ax-text-editor-alignment></ax-text-editor-alignment>\n </ax-prefix>\n </ax-text-editor-toolbar>\n </ax-text-editor>\n <!-- ----- Send sits under the editor, aligned to the inline end ----- -->\n <div class=\"axm-comment__editor-actions\">\n <ax-button\n look=\"solid\"\n color=\"primary\"\n class=\"ax-sm\"\n [disabled]=\"hasCooldown() || !commentContent()\"\n (click)=\"submitComment()\"\n [text]=\"\n '@conversation:comments.actions.send.title' | translate | async\n \"\n >\n @if (isSubmitting()) {\n <ax-loading></ax-loading>\n }\n </ax-button>\n </div>\n </div>\n </div>\n</div>\n", styles: ["@layer properties;:host{display:block;height:100%;min-height:0px;width:100%}.axm-comment{min-height:0px;height:calc(100vh - 210px);background-color:rgb(var(--ax-sys-color-lightest-surface))}.axm-comment .axm-comment__list{min-height:0px}.axm-comment .axm-comment__skeleton{display:flex;align-items:flex-start;gap:.875rem;padding:1.25rem 1.25rem 1.5rem}.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__composer{flex-shrink:0;background-color:rgb(var(--ax-sys-color-surface-surface))}.axm-comment .axm-comment__context{display:flex;align-items:center;justify-content:space-between;gap:calc(var(--spacing, .25rem) * 3);padding:.625rem .75rem;border:1px solid rgb(var(--ax-sys-color-border-light-surface));border-bottom:none;border-inline-start:3px solid rgb(var(--ax-sys-color-primary-surface));background-color:rgba(var(--ax-sys-color-primary-lightest-surface),.35);font-size:.8125rem;line-height:1.4}.axm-comment .axm-comment__context-main{display:flex;min-width:0px;flex:1;cursor:pointer;align-items:center;gap:.625rem}.axm-comment .axm-comment__context-icon{flex-shrink:0;font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));color:rgb(var(--ax-sys-color-primary-surface))}.axm-comment .axm-comment__context-copy{display:flex;min-width:0px;flex-direction:column;gap:.125rem}.axm-comment .axm-comment__context-label{margin:0;--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600);color:rgb(var(--ax-sys-color-primary-surface))}.axm-comment .axm-comment__context-preview{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:start;color:rgb(var(--ax-sys-color-neutral-600-surface, 107 114 128))}.axm-comment .axm-comment__context-close{flex-shrink:0;cursor:pointer;border-radius:var(--radius-md, .375rem);--tw-border-style: none;border-style:none;padding:.25rem;background:transparent;color:rgb(var(--ax-sys-color-neutral-500-surface, 107 114 128));font-size:1rem;line-height:1}.axm-comment .axm-comment__context-close:hover{background-color:rgba(var(--ax-sys-color-neutral-100-surface, 243 244 246),.8)}.axm-comment .axm-comment__editor{overflow:hidden;border:1px solid rgb(var(--ax-sys-color-border-light-surface));background-color:rgb(var(--ax-sys-color-lightest-surface));box-shadow:0 1px 2px #0f172a0a}.axm-comment .axm-comment__editor-actions{display:flex;justify-content:flex-end;padding:.5rem .75rem;border-top:1px solid rgb(var(--ax-sys-color-border-light-surface))}.axm-comment .axm-comment__author{font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600)}.axm-comment .axm-comment__date{font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));color:rgb(var(--ax-sys-color-neutral-500-surface, 107 114 128))}.axm-comment .axm-comment__menu-btn{opacity:0;transition:opacity .15s ease}ax-comment-item{border-radius:.75rem;transition:background-color .2s ease}ax-comment-item:hover{background-color:rgba(var(--ax-sys-color-neutral-100-surface, 243 244 246),.45)}ax-comment-item:hover .axm-comment__menu-btn{opacity:1}ax-comment-item.highlighted{animation:axm-comment-highlight 2.5s cubic-bezier(.4,0,.2,1) forwards}ax-text-editor{flex-shrink:0}ax-text-editor .ax-editor-container{border:none!important;border-radius:0!important;box-shadow:none!important}ax-text-editor .ax-error-message{padding-inline-start:.75rem}@keyframes axm-comment-highlight{0%{background-color:transparent;box-shadow:inset 3px 0 0 0 transparent}10%{background-color:rgba(var(--ax-sys-color-primary-lightest-surface),.5);box-shadow:inset 3px 0 rgb(var(--ax-sys-color-primary-surface))}35%{background-color:rgba(var(--ax-sys-color-primary-lightest-surface),.3);box-shadow:inset 3px 0 rgba(var(--ax-sys-color-primary-lighter-surface),.8)}60%{background-color:rgba(var(--ax-sys-color-primary-lightest-surface),.4);box-shadow:inset 3px 0 rgba(var(--ax-sys-color-primary-lightest-surface),.6)}to{background-color:transparent;box-shadow:inset 3px 0 0 0 transparent}}@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-font-weight: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
12884
- }], 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 }] }], editorRef: [{ type: i0.ViewChild, args: ['editorRef', { isSignal: true }] }] } });
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"] }]
12940
+ }], 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
+ //#endregion
12942
+ //#region ----- Local helpers -----
12943
+ function stripHtmlToPlainText(html) {
12944
+ return html
12945
+ .replace(/<[^>]+>/g, '')
12946
+ .replace(/&nbsp;/gi, ' ')
12947
+ .trim();
12948
+ }
12949
+ function toInitials(name) {
12950
+ const parts = name.trim().split(/\s+/).filter(Boolean);
12951
+ if (parts.length === 0) {
12952
+ return '?';
12953
+ }
12954
+ if (parts.length === 1) {
12955
+ return parts[0].slice(0, 1).toUpperCase();
12956
+ }
12957
+ return (parts[0].slice(0, 1) + parts[1].slice(0, 1)).toUpperCase();
12958
+ }
12959
+ function colorForUser(userId) {
12960
+ let hash = 0;
12961
+ for (let i = 0; i < userId.length; i++) {
12962
+ hash = (hash + userId.charCodeAt(i)) % AVATAR_COLORS.length;
12963
+ }
12964
+ return AVATAR_COLORS[hash];
12965
+ }
12966
+ function insertReply(list, parentId, comment) {
12967
+ return list.map((c) => {
12968
+ if (c.id === parentId) {
12969
+ const newReplies = c.replies ? [...c.replies, comment] : [comment];
12970
+ return { ...c, replies: newReplies, replyCount: newReplies.length };
12971
+ }
12972
+ if (c.replies?.length) {
12973
+ return { ...c, replies: insertReply(c.replies, parentId, comment) };
12974
+ }
12975
+ return c;
12976
+ });
12977
+ }
12978
+ function resolveDisplayName(info) {
12979
+ if (!info) {
12980
+ return '';
12981
+ }
12982
+ const parts = [info.firstName, info.lastName].map((part) => part?.trim()).filter(Boolean);
12983
+ if (parts.length > 0) {
12984
+ return parts.join(' ');
12985
+ }
12986
+ return info.username?.trim() || '';
12987
+ }
12885
12988
 
12886
12989
  var comment_component = /*#__PURE__*/Object.freeze({
12887
12990
  __proto__: null,
@@ -14190,7 +14293,7 @@ class AXMChatVoiceRecorderComponent {
14190
14293
  this.discardActiveRecorder();
14191
14294
  }
14192
14295
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMChatVoiceRecorderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
14193
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXMChatVoiceRecorderComponent, isStandalone: true, selector: "axm-chat-voice-recorder", inputs: { conversation: { classPropertyName: "conversation", publicName: "conversation", isSignal: true, isRequired: true, transformFunction: null }, service: { classPropertyName: "service", publicName: "service", isSignal: true, isRequired: false, transformFunction: null }, initialFiles: { classPropertyName: "initialFiles", publicName: "initialFiles", isSignal: true, isRequired: false, transformFunction: null }, autoRun: { classPropertyName: "autoRun", publicName: "autoRun", isSignal: true, isRequired: false, transformFunction: null }, __popup__: { classPropertyName: "__popup__", publicName: "__popup__", isSignal: true, isRequired: false, transformFunction: null }, __actionSheet__: { classPropertyName: "__actionSheet__", publicName: "__actionSheet__", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { recordingComplete: "recordingComplete", recordingCancelled: "recordingCancelled" }, viewQueries: [{ propertyName: "waveWrapRef", first: true, predicate: ["waveWrap"], descendants: true, isSignal: true }, { propertyName: "waveRef", first: true, predicate: AXAudioWaveComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"voice-recorder\" [class.voice-recorder--preview]=\"isPreview()\" role=\"dialog\" aria-modal=\"true\" [attr.aria-label]=\"translation.translateSync('@conversation:chat.voice-recorder.title')\">\n @if (isUploading()) {\n <!-- ----- Upload progress while the voice file is sent ----- -->\n <div class=\"voice-recorder__upload\">\n <span class=\"voice-recorder__upload-label\">{{ getUploadingLabel() }}</span>\n <ax-progress-bar [progress]=\"uploadProgress()\" [mode]=\"'determinate'\" [height]=\"6\" />\n </div>\n }\n <!-- ----- Speech-to-text overlay while the recording is transcribed ----- -->\n @else if (isTranscribing()) {\n <div class=\"voice-recorder__upload\">\n <ax-loading></ax-loading>\n <span class=\"voice-recorder__upload-label\">{{ '@conversation:chat.voice-recorder.transcribing' | translate | async }}</span>\n </div>\n }\n <!-- ----- Idle microphone before recording starts ----- -->\n @else if (!isRecording() && !isPreview()) {\n <div class=\"voice-recorder__idle\">\n <button type=\"button\" class=\"voice-recorder__mic\" [attr.aria-label]=\"translation.translateSync('@conversation:chat.voice-recorder.tap-to-start')\" (click)=\"startRecording()\">\n <i class=\"fa-light fa-microphone\" aria-hidden=\"true\"></i>\n </button>\n <span class=\"voice-recorder__hint\">{{ '@conversation:chat.voice-recorder.tap-to-start' | translate | async }}</span>\n </div>\n }\n <!-- ----- Live waveform or paused preview with send actions ----- -->\n @else {\n <div class=\"voice-recorder__body\">\n <div class=\"voice-recorder__visual\">\n <div class=\"voice-recorder__wave-wrap\" #waveWrap>\n <!-- ----- Live bars while the microphone is capturing ----- -->\n @if (isRecording()) {\n <div class=\"voice-recorder__live-wave\" aria-hidden=\"true\">\n @for (bar of liveDisplayBars(); track bar.index) {\n <span class=\"voice-recorder__bar\" [class.voice-recorder__bar--recorded]=\"bar.recorded\" [style.height.px]=\"bar.height\"></span>\n }\n </div>\n }\n <!-- ----- Preview waveform after recording is paused ----- -->\n @else if (waveConfig(); as config) {\n <ax-audio-wave class=\"voice-recorder__audio-wave\" [config]=\"config\" (onStatusChanged)=\"onWaveStatusChanged($event)\" />\n }\n </div>\n <!-- ----- Play or pause the recorded preview ----- -->\n @if (isPreview()) {\n <ax-button\n class=\"voice-recorder__play rounded-full\"\n look=\"twotone\"\n [iconOnly]=\"true\"\n [text]=\"isPlayingPreview() ? translation.translateSync('@conversation:chat.media.pause') : translation.translateSync('@conversation:chat.media.play')\"\n (onClick)=\"togglePreview()\"\n >\n <ax-icon>\n <i class=\"fa-solid\" [class.fa-pause]=\"isPlayingPreview()\" [class.fa-play]=\"!isPlayingPreview()\"></i>\n </ax-icon>\n </ax-button>\n }\n </div>\n\n <div class=\"voice-recorder__time\" aria-live=\"polite\">\n {{ formattedTime() }}\n <span class=\"sr-only\">{{ '@conversation:chat.voice-recorder.recording' | translate | async }}</span>\n </div>\n </div>\n\n <footer class=\"voice-recorder__footer\">\n <div class=\"voice-recorder__footer-start\">\n <!-- ----- Delete the current recording ----- -->\n @if (isPreview()) {\n <ax-button class=\"voice-recorder__delete\" look=\"blank\" color=\"danger\" [iconOnly]=\"true\" [text]=\"translation.translateSync('@acorex:chat.actions.delete')\" (onClick)=\"deleteRecording()\">\n <ax-icon><i class=\"fa-light fa-trash-can\"></i></ax-icon>\n </ax-button>\n }\n <!-- ----- Pause recording or continue from preview ----- -->\n @if (isRecording() || isPreview()) {\n <ax-button\n class=\"voice-recorder__stop\"\n look=\"blank\"\n [iconOnly]=\"true\"\n [text]=\"isPreview() ? translation.translateSync('@conversation:chat.voice-recorder.continue-recording') : translation.translateSync('@conversation:chat.voice-recorder.stop-recording')\"\n (onClick)=\"toggleStopOrContinue()\"\n >\n <ax-icon>\n <i class=\"fa-solid\" [class.fa-pause]=\"isRecording()\" [class.fa-microphone]=\"isPreview()\"></i>\n </ax-icon>\n </ax-button>\n }\n </div>\n\n <div class=\"voice-recorder__footer-end\">\n <!-- ----- Convert the paused recording into composer text ----- -->\n @if (isPreview()) {\n <ax-button class=\"voice-recorder__transcribe\" look=\"outline\" color=\"secondary\" [text]=\"translation.translateSync('@conversation:chat.voice-recorder.transcribe')\" [disabled]=\"!canTranscribe()\" (onClick)=\"applySpeechToText()\">\n <ax-prefix>\n <ax-icon><i class=\"fa-light fa-waveform-lines\"></i></ax-icon>\n </ax-prefix>\n </ax-button>\n }\n <ax-button class=\"voice-recorder__send\" look=\"solid\" color=\"primary\" [text]=\"translation.translateSync('@acorex:chat.actions.send')\" [disabled]=\"!canSend()\" (onClick)=\"sendRecording()\">\n <ax-prefix>\n <ax-icon><i class=\"fa-light fa-paper-plane-top\"></i></ax-icon>\n </ax-prefix>\n </ax-button>\n </div>\n </footer>\n }\n</div>\n", styles: ["@layer properties;@layer components{axm-chat-voice-recorder{display:flex;width:100%;flex-direction:column;container-type:inline-size}axm-chat-voice-recorder .voice-recorder{display:flex;width:100%;flex-direction:column;background-color:rgba(var(--ax-sys-color-lightest-surface));padding-inline:calc(var(--spacing, .25rem) * 5);padding-top:calc(var(--spacing, .25rem) * 5);padding-bottom:calc(var(--spacing, .25rem) * 5)}axm-chat-voice-recorder .voice-recorder__idle,axm-chat-voice-recorder .voice-recorder__upload{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:calc(var(--spacing, .25rem) * 3);padding-block:calc(var(--spacing, .25rem) * 6);text-align:center}axm-chat-voice-recorder .voice-recorder__mic{display:flex;height:calc(var(--spacing, .25rem) * 16);width:calc(var(--spacing, .25rem) * 16);cursor:pointer;align-items:center;justify-content:center;border-radius:calc(infinity * 1px);--tw-border-style: none;border-style:none;padding:0;font-size:var(--text-2xl, 1.5rem);line-height:var(--tw-leading, var(--text-2xl--line-height, calc(2 / 1.5)));color:rgb(var(--ax-sys-color-on-primary-500));background:rgb(var(--ax-sys-color-primary-500));box-shadow:0 .5rem 1.25rem rgba(var(--ax-sys-color-primary-500),.28)}axm-chat-voice-recorder .voice-recorder__mic:hover,axm-chat-voice-recorder .voice-recorder__mic:focus-visible{--tw-outline-style: none;outline-style:none;background:rgb(var(--ax-sys-color-primary-600))}axm-chat-voice-recorder .voice-recorder__hint,axm-chat-voice-recorder .voice-recorder__upload-label{margin:0;font-size:.8125rem;--tw-leading: var(--leading-snug, 1.375);line-height:var(--leading-snug, 1.375);color:rgba(var(--ax-sys-color-on-surface),.62)}axm-chat-voice-recorder .voice-recorder__upload{width:100%;max-width:calc(var(--spacing, .25rem) * 72);gap:calc(var(--spacing, .25rem) * 2.5)}axm-chat-voice-recorder .voice-recorder__body{display:flex;width:100%;flex-direction:column;align-items:center}axm-chat-voice-recorder .voice-recorder__visual{display:flex;width:100%;min-width:0px;align-items:center;gap:calc(var(--spacing, .25rem) * 3)}axm-chat-voice-recorder .voice-recorder__wave-wrap{position:relative;display:flex;min-height:calc(var(--spacing, .25rem) * 14);min-width:0px;flex:1;align-items:center}axm-chat-voice-recorder .voice-recorder--preview .voice-recorder__wave-wrap{border-radius:var(--radius-xl, .75rem);padding-inline:calc(var(--spacing, .25rem) * 2);padding-block:calc(var(--spacing, .25rem) * 2);background:rgba(var(--ax-sys-color-primary-500),.08)}axm-chat-voice-recorder .voice-recorder__live-wave{display:flex;height:calc(var(--spacing, .25rem) * 9);width:100%;min-width:0px;align-items:center;gap:2px}axm-chat-voice-recorder .voice-recorder__bar{display:block;flex:1 1 0;min-width:0;border-radius:2px;background:rgba(var(--ax-sys-color-on-surface),.16);transform-origin:center}axm-chat-voice-recorder .voice-recorder__bar--recorded{background:rgb(var(--ax-sys-color-primary-500))}axm-chat-voice-recorder .voice-recorder__audio-wave{display:block;min-height:calc(var(--spacing, .25rem) * 9);width:100%;min-width:0px;flex:1}axm-chat-voice-recorder .voice-recorder__audio-wave .ax-audio-wave,axm-chat-voice-recorder .voice-recorder__audio-wave .ax-audio-wave-host{display:block;width:100%}axm-chat-voice-recorder .voice-recorder__play{position:relative;z-index:1;flex-shrink:0}axm-chat-voice-recorder .voice-recorder__play .fa-play{padding-inline-start:.12rem;font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)))}axm-chat-voice-recorder .voice-recorder__play .fa-pause{font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)))}axm-chat-voice-recorder .voice-recorder__time{margin-top:calc(var(--spacing, .25rem) * 4);font-size:1.25rem;--tw-leading: 1;line-height:1;--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600);color:rgba(var(--ax-sys-color-on-surface));--tw-numeric-spacing: tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}axm-chat-voice-recorder .voice-recorder__footer{margin-top:calc(var(--spacing, .25rem) * 6);display:flex;align-items:center;justify-content:space-between;gap:calc(var(--spacing, .25rem) * 3)}axm-chat-voice-recorder .voice-recorder__footer:dir(rtl){flex-direction:row-reverse}axm-chat-voice-recorder .voice-recorder__footer-start,axm-chat-voice-recorder .voice-recorder__footer-end{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 3)}axm-chat-voice-recorder .voice-recorder__footer-end,axm-chat-voice-recorder .voice-recorder__transcribe,axm-chat-voice-recorder .voice-recorder__send{min-width:0px}axm-chat-voice-recorder .voice-recorder__transcribe>button,axm-chat-voice-recorder .voice-recorder__send>button{display:flex;height:calc(var(--spacing, .25rem) * 12);align-items:center;justify-content:center;gap:calc(var(--spacing, .25rem) * 2);border-radius:var(--radius-xl, .75rem);padding-inline:calc(var(--spacing, .25rem) * 3);font-size:.9375rem;--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);box-shadow:none;background-image:none}axm-chat-voice-recorder .voice-recorder__send .fa-paper-plane-top:dir(rtl){transform:scaleX(-1)}axm-chat-voice-recorder .voice-recorder__delete,axm-chat-voice-recorder .voice-recorder__stop{flex-shrink:0}axm-chat-voice-recorder .voice-recorder__delete>button,axm-chat-voice-recorder .voice-recorder__stop>button{display:flex;height:calc(var(--spacing, .25rem) * 12);width:calc(var(--spacing, .25rem) * 12);align-items:center;justify-content:center;border-radius:var(--radius-xl, .75rem);--tw-border-style: none;border-style:none;padding:0;font-size:var(--text-lg, 1.125rem);line-height:var(--tw-leading, var(--text-lg--line-height, calc(1.75 / 1.125)));box-shadow:none}axm-chat-voice-recorder .voice-recorder__delete>button{color:rgb(var(--ax-sys-color-danger-600));background:rgba(var(--ax-sys-color-danger-500),.14)}axm-chat-voice-recorder .voice-recorder__stop>button{color:rgb(var(--ax-sys-color-on-surface));background:rgba(var(--ax-sys-color-on-surface),.08)}axm-chat-voice-recorder .voice-recorder__delete:hover>button,axm-chat-voice-recorder .voice-recorder__delete>button:hover{background:rgba(var(--ax-sys-color-danger-500),.22)}axm-chat-voice-recorder .voice-recorder__stop:hover>button,axm-chat-voice-recorder .voice-recorder__stop>button:hover{background:rgba(var(--ax-sys-color-on-surface),.14)}}@property --tw-leading{syntax: \"*\"; inherits: false;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-ordinal{syntax: \"*\"; inherits: false;}@property --tw-slashed-zero{syntax: \"*\"; inherits: false;}@property --tw-numeric-figure{syntax: \"*\"; inherits: false;}@property --tw-numeric-spacing{syntax: \"*\"; inherits: false;}@property --tw-numeric-fraction{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;--tw-ordinal: initial;--tw-slashed-zero: initial;--tw-numeric-figure: initial;--tw-numeric-spacing: initial;--tw-numeric-fraction: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "component", type: AXAudioWaveComponent, selector: "ax-audio-wave", inputs: ["config"], outputs: ["onStatusChanged"] }, { kind: "component", type: 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: "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: AXLoadingModule }, { kind: "component", type: i6.AXLoadingComponent, selector: "ax-loading", inputs: ["visible", "type", "context"], outputs: ["visibleChange"] }, { kind: "ngmodule", type: AXProgressBarModule }, { kind: "component", type: i3$1.AXProgressBarComponent, selector: "ax-progress-bar", inputs: ["color", "mode", "progress", "height"], outputs: ["ValueChange", "sizeChange"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: i1$2.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
14296
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXMChatVoiceRecorderComponent, isStandalone: true, selector: "axm-chat-voice-recorder", inputs: { conversation: { classPropertyName: "conversation", publicName: "conversation", isSignal: true, isRequired: true, transformFunction: null }, service: { classPropertyName: "service", publicName: "service", isSignal: true, isRequired: false, transformFunction: null }, initialFiles: { classPropertyName: "initialFiles", publicName: "initialFiles", isSignal: true, isRequired: false, transformFunction: null }, autoRun: { classPropertyName: "autoRun", publicName: "autoRun", isSignal: true, isRequired: false, transformFunction: null }, __popup__: { classPropertyName: "__popup__", publicName: "__popup__", isSignal: true, isRequired: false, transformFunction: null }, __actionSheet__: { classPropertyName: "__actionSheet__", publicName: "__actionSheet__", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { recordingComplete: "recordingComplete", recordingCancelled: "recordingCancelled" }, viewQueries: [{ propertyName: "waveWrapRef", first: true, predicate: ["waveWrap"], descendants: true, isSignal: true }, { propertyName: "waveRef", first: true, predicate: AXAudioWaveComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"voice-recorder\" [class.voice-recorder--preview]=\"isPreview()\" role=\"dialog\" aria-modal=\"true\" [attr.aria-label]=\"translation.translateSync('@conversation:chat.voice-recorder.title')\">\n @if (isUploading()) {\n <!-- ----- Upload progress while the voice file is sent ----- -->\n <div class=\"voice-recorder__upload\">\n <span class=\"voice-recorder__upload-label\">{{ getUploadingLabel() }}</span>\n <ax-progress-bar [progress]=\"uploadProgress()\" [mode]=\"'determinate'\" [height]=\"6\" />\n </div>\n }\n <!-- ----- Speech-to-text overlay while the recording is transcribed ----- -->\n @else if (isTranscribing()) {\n <div class=\"voice-recorder__upload\">\n <ax-loading></ax-loading>\n <span class=\"voice-recorder__upload-label\">{{ '@conversation:chat.voice-recorder.transcribing' | translate | async }}</span>\n </div>\n }\n <!-- ----- Idle microphone before recording starts ----- -->\n @else if (!isRecording() && !isPreview()) {\n <div class=\"voice-recorder__idle\">\n <button type=\"button\" class=\"voice-recorder__mic\" [attr.aria-label]=\"translation.translateSync('@conversation:chat.voice-recorder.tap-to-start')\" (click)=\"startRecording()\">\n <i class=\"fa-light fa-microphone\" aria-hidden=\"true\"></i>\n </button>\n <span class=\"voice-recorder__hint\">{{ '@conversation:chat.voice-recorder.tap-to-start' | translate | async }}</span>\n </div>\n }\n <!-- ----- Live waveform or paused preview with send actions ----- -->\n @else {\n <div class=\"voice-recorder__body\">\n <div class=\"voice-recorder__visual\">\n <div class=\"voice-recorder__wave-wrap\" #waveWrap>\n <!-- ----- Live bars while the microphone is capturing ----- -->\n @if (isRecording()) {\n <div class=\"voice-recorder__live-wave\" aria-hidden=\"true\">\n @for (bar of liveDisplayBars(); track bar.index) {\n <span class=\"voice-recorder__bar\" [class.voice-recorder__bar--recorded]=\"bar.recorded\" [style.height.px]=\"bar.height\"></span>\n }\n </div>\n }\n <!-- ----- Preview waveform after recording is paused ----- -->\n @else if (waveConfig(); as config) {\n <ax-audio-wave class=\"voice-recorder__audio-wave\" [config]=\"config\" (onStatusChanged)=\"onWaveStatusChanged($event)\" />\n }\n </div>\n <!-- ----- Play or pause the recorded preview ----- -->\n @if (isPreview()) {\n <ax-button\n class=\"voice-recorder__play rounded-full\"\n look=\"twotone\"\n [iconOnly]=\"true\"\n [text]=\"isPlayingPreview() ? translation.translateSync('@conversation:chat.media.pause') : translation.translateSync('@conversation:chat.media.play')\"\n (onClick)=\"togglePreview()\"\n >\n <ax-icon>\n <i class=\"fa-solid\" [class.fa-pause]=\"isPlayingPreview()\" [class.fa-play]=\"!isPlayingPreview()\"></i>\n </ax-icon>\n </ax-button>\n }\n </div>\n\n <div class=\"voice-recorder__time\" aria-live=\"polite\">\n {{ formattedTime() }}\n <span class=\"sr-only\">{{ '@conversation:chat.voice-recorder.recording' | translate | async }}</span>\n </div>\n </div>\n\n <footer class=\"voice-recorder__footer\">\n <div class=\"voice-recorder__footer-start\">\n <!-- ----- Delete the current recording ----- -->\n @if (isPreview()) {\n <ax-button class=\"voice-recorder__delete\" look=\"blank\" color=\"danger\" [iconOnly]=\"true\" [text]=\"translation.translateSync('@acorex:chat.actions.delete')\" (onClick)=\"deleteRecording()\">\n <ax-icon><i class=\"fa-light fa-trash-can\"></i></ax-icon>\n </ax-button>\n }\n <!-- ----- Pause recording or continue from preview ----- -->\n @if (isRecording() || isPreview()) {\n <ax-button\n class=\"voice-recorder__stop\"\n look=\"blank\"\n [iconOnly]=\"true\"\n [text]=\"isPreview() ? translation.translateSync('@conversation:chat.voice-recorder.continue-recording') : translation.translateSync('@conversation:chat.voice-recorder.stop-recording')\"\n (onClick)=\"toggleStopOrContinue()\"\n >\n <ax-icon>\n <i class=\"fa-solid\" [class.fa-pause]=\"isRecording()\" [class.fa-microphone]=\"isPreview()\"></i>\n </ax-icon>\n </ax-button>\n }\n </div>\n\n <div class=\"voice-recorder__footer-end\">\n <!-- ----- Convert the paused recording into composer text ----- -->\n @if (isPreview()) {\n <ax-button class=\"voice-recorder__transcribe\" look=\"outline\" color=\"secondary\" [text]=\"translation.translateSync('@conversation:chat.voice-recorder.transcribe')\" [disabled]=\"!canTranscribe()\" (onClick)=\"applySpeechToText()\">\n <ax-prefix>\n <ax-icon><i class=\"fa-light fa-waveform-lines\"></i></ax-icon>\n </ax-prefix>\n </ax-button>\n }\n <ax-button class=\"voice-recorder__send\" look=\"solid\" color=\"primary\" [text]=\"translation.translateSync('@acorex:chat.actions.send')\" [disabled]=\"!canSend()\" (onClick)=\"sendRecording()\">\n <ax-prefix>\n <ax-icon><i class=\"fa-light fa-paper-plane-top\"></i></ax-icon>\n </ax-prefix>\n </ax-button>\n </div>\n </footer>\n }\n</div>\n", styles: ["@layer properties;@layer components{axm-chat-voice-recorder{display:flex;width:100%;flex-direction:column;container-type:inline-size}axm-chat-voice-recorder .voice-recorder{display:flex;width:100%;flex-direction:column;background-color:rgba(var(--ax-sys-color-lightest-surface));padding-inline:calc(var(--spacing, .25rem) * 5);padding-top:calc(var(--spacing, .25rem) * 5);padding-bottom:calc(var(--spacing, .25rem) * 5)}axm-chat-voice-recorder .voice-recorder__idle,axm-chat-voice-recorder .voice-recorder__upload{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:calc(var(--spacing, .25rem) * 3);padding-block:calc(var(--spacing, .25rem) * 6);text-align:center}axm-chat-voice-recorder .voice-recorder__mic{display:flex;height:calc(var(--spacing, .25rem) * 16);width:calc(var(--spacing, .25rem) * 16);cursor:pointer;align-items:center;justify-content:center;border-radius:calc(infinity * 1px);--tw-border-style: none;border-style:none;padding:0;font-size:var(--text-2xl, 1.5rem);line-height:var(--tw-leading, var(--text-2xl--line-height, calc(2 / 1.5)));color:rgb(var(--ax-sys-color-on-primary-500));background:rgb(var(--ax-sys-color-primary-500));box-shadow:0 .5rem 1.25rem rgba(var(--ax-sys-color-primary-500),.28)}axm-chat-voice-recorder .voice-recorder__mic:hover,axm-chat-voice-recorder .voice-recorder__mic:focus-visible{--tw-outline-style: none;outline-style:none;background:rgb(var(--ax-sys-color-primary-600))}axm-chat-voice-recorder .voice-recorder__hint,axm-chat-voice-recorder .voice-recorder__upload-label{margin:0;font-size:.8125rem;--tw-leading: var(--leading-snug, 1.375);line-height:var(--leading-snug, 1.375);color:rgba(var(--ax-sys-color-on-surface),.62)}axm-chat-voice-recorder .voice-recorder__upload{width:100%;max-width:calc(var(--spacing, .25rem) * 72);gap:calc(var(--spacing, .25rem) * 2.5)}axm-chat-voice-recorder .voice-recorder__body{display:flex;width:100%;flex-direction:column;align-items:center}axm-chat-voice-recorder .voice-recorder__visual{display:flex;width:100%;min-width:0px;align-items:center;gap:calc(var(--spacing, .25rem) * 3)}axm-chat-voice-recorder .voice-recorder__wave-wrap{position:relative;display:flex;min-height:calc(var(--spacing, .25rem) * 14);min-width:0px;flex:1;align-items:center}axm-chat-voice-recorder .voice-recorder--preview .voice-recorder__wave-wrap{border-radius:var(--radius-xl, .75rem);padding-inline:calc(var(--spacing, .25rem) * 2);padding-block:calc(var(--spacing, .25rem) * 2);background:rgba(var(--ax-sys-color-primary-500),.08)}axm-chat-voice-recorder .voice-recorder__live-wave{display:flex;height:calc(var(--spacing, .25rem) * 9);width:100%;min-width:0px;align-items:center;gap:2px}axm-chat-voice-recorder .voice-recorder__bar{display:block;flex:1 1 0;min-width:0;border-radius:2px;background:rgba(var(--ax-sys-color-on-surface),.16);transform-origin:center}axm-chat-voice-recorder .voice-recorder__bar--recorded{background:rgb(var(--ax-sys-color-primary-500))}axm-chat-voice-recorder .voice-recorder__audio-wave{display:block;min-height:calc(var(--spacing, .25rem) * 9);width:100%;min-width:0px;flex:1}axm-chat-voice-recorder .voice-recorder__audio-wave .ax-audio-wave,axm-chat-voice-recorder .voice-recorder__audio-wave .ax-audio-wave-host{display:block;width:100%}axm-chat-voice-recorder .voice-recorder__play{position:relative;z-index:1;flex-shrink:0}axm-chat-voice-recorder .voice-recorder__play .fa-play{padding-inline-start:.12rem;font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)))}axm-chat-voice-recorder .voice-recorder__play .fa-pause{font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)))}axm-chat-voice-recorder .voice-recorder__time{margin-top:calc(var(--spacing, .25rem) * 4);font-size:1.25rem;--tw-leading: 1;line-height:1;--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600);color:rgba(var(--ax-sys-color-on-surface));--tw-numeric-spacing: tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}axm-chat-voice-recorder .voice-recorder__footer{margin-top:calc(var(--spacing, .25rem) * 6);display:flex;align-items:center;justify-content:space-between;gap:calc(var(--spacing, .25rem) * 3)}axm-chat-voice-recorder .voice-recorder__footer:dir(rtl){flex-direction:row-reverse}axm-chat-voice-recorder .voice-recorder__footer-start,axm-chat-voice-recorder .voice-recorder__footer-end{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 3)}axm-chat-voice-recorder .voice-recorder__footer-end,axm-chat-voice-recorder .voice-recorder__transcribe,axm-chat-voice-recorder .voice-recorder__send{min-width:0px}axm-chat-voice-recorder .voice-recorder__transcribe>button,axm-chat-voice-recorder .voice-recorder__send>button{display:flex;height:calc(var(--spacing, .25rem) * 12);align-items:center;justify-content:center;gap:calc(var(--spacing, .25rem) * 2);border-radius:var(--radius-xl, .75rem);padding-inline:calc(var(--spacing, .25rem) * 3);font-size:.9375rem;--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);box-shadow:none;background-image:none}axm-chat-voice-recorder .voice-recorder__send .fa-paper-plane-top:dir(rtl){transform:scaleX(-1)}axm-chat-voice-recorder .voice-recorder__delete,axm-chat-voice-recorder .voice-recorder__stop{flex-shrink:0}axm-chat-voice-recorder .voice-recorder__delete>button,axm-chat-voice-recorder .voice-recorder__stop>button{display:flex;height:calc(var(--spacing, .25rem) * 12);width:calc(var(--spacing, .25rem) * 12);align-items:center;justify-content:center;border-radius:var(--radius-xl, .75rem);--tw-border-style: none;border-style:none;padding:0;font-size:var(--text-lg, 1.125rem);line-height:var(--tw-leading, var(--text-lg--line-height, calc(1.75 / 1.125)));box-shadow:none}axm-chat-voice-recorder .voice-recorder__delete>button{color:rgb(var(--ax-sys-color-danger-600));background:rgba(var(--ax-sys-color-danger-500),.14)}axm-chat-voice-recorder .voice-recorder__stop>button{color:rgb(var(--ax-sys-color-on-surface));background:rgba(var(--ax-sys-color-on-surface),.08)}axm-chat-voice-recorder .voice-recorder__delete:hover>button,axm-chat-voice-recorder .voice-recorder__delete>button:hover{background:rgba(var(--ax-sys-color-danger-500),.22)}axm-chat-voice-recorder .voice-recorder__stop:hover>button,axm-chat-voice-recorder .voice-recorder__stop>button:hover{background:rgba(var(--ax-sys-color-on-surface),.14)}}@property --tw-leading{syntax: \"*\"; inherits: false;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-ordinal{syntax: \"*\"; inherits: false;}@property --tw-slashed-zero{syntax: \"*\"; inherits: false;}@property --tw-numeric-figure{syntax: \"*\"; inherits: false;}@property --tw-numeric-spacing{syntax: \"*\"; inherits: false;}@property --tw-numeric-fraction{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;--tw-ordinal: initial;--tw-slashed-zero: initial;--tw-numeric-figure: initial;--tw-numeric-spacing: initial;--tw-numeric-fraction: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "component", type: AXAudioWaveComponent, selector: "ax-audio-wave", inputs: ["config"], outputs: ["onStatusChanged"] }, { kind: "component", type: 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: "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: AXLoadingModule }, { kind: "component", type: i8.AXLoadingComponent, selector: "ax-loading", inputs: ["visible", "type", "context"], outputs: ["visibleChange"] }, { kind: "ngmodule", type: AXProgressBarModule }, { kind: "component", type: i3$1.AXProgressBarComponent, selector: "ax-progress-bar", inputs: ["color", "mode", "progress", "height"], outputs: ["ValueChange", "sizeChange"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: i1$2.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
14194
14297
  }
14195
14298
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMChatVoiceRecorderComponent, decorators: [{
14196
14299
  type: Component,
@@ -14315,7 +14418,7 @@ async function axmOpenChatCallStartDialog(options) {
14315
14418
  const dialogOpener = options.dialogOpener ?? inject(AXPDialogOpener);
14316
14419
  const data = { conversation };
14317
14420
  await dialogOpener.openPopup({
14318
- load: () => import('./acorex-platform-module-conversation-client-chat-call-start-popup.component-ooiJkC8U.mjs').then((module) => module.AXMChatCallStartPopupComponent),
14421
+ load: () => import('./acorex-platform-module-conversation-client-chat-call-start-popup.component-BEa8wEJt.mjs').then((module) => module.AXMChatCallStartPopupComponent),
14319
14422
  data: { conversationId: conversation.id },
14320
14423
  show: (component) => popupService.open(component, {
14321
14424
  header: false,
@@ -14597,7 +14700,7 @@ const AXM_CHAT_INFO_BAR_CALL_ACTION = {
14597
14700
  */
14598
14701
  const AXM_CONVERSATION_BOT_RENDERER = {
14599
14702
  type: 'assist-response',
14600
- componentLoader: () => import('./acorex-platform-module-conversation-client-assist-message-renderer.component-jsHo7NZq.mjs').then(function (n) { return n.b; }).then((m) => m.AXMAssistMessageRendererComponent),
14703
+ componentLoader: () => import('./acorex-platform-module-conversation-client-assist-message-renderer.component-CR4OxDV6.mjs').then(function (n) { return n.b; }).then((m) => m.AXMAssistMessageRendererComponent),
14601
14704
  canHandle: (message) => message.type === 'assist-response' || !!message.metadata?.['isAssistResponse'],
14602
14705
  capabilities: {
14603
14706
  supportsReactions: false,
@@ -14741,7 +14844,7 @@ async function axmOpenChatCallSessionDialog(options) {
14741
14844
  let scopedCallId = options.callId?.trim() || '';
14742
14845
  try {
14743
14846
  const opened = await dialogOpener.openPopup({
14744
- load: () => import('./acorex-platform-module-conversation-client-chat-call-session-page.component-ePQikBd2.mjs').then((module) => module.AXMChatCallSessionPageComponent),
14847
+ load: () => import('./acorex-platform-module-conversation-client-chat-call-session-page.component-DJreBgNo.mjs').then((module) => module.AXMChatCallSessionPageComponent),
14745
14848
  data: {
14746
14849
  conversationId: conversation.id,
14747
14850
  callId: scopedCallId,
@@ -16861,7 +16964,7 @@ class AXMCommentsPageComponentProvider {
16861
16964
  return [
16862
16965
  {
16863
16966
  key: COMMENTS_PAGE_COMPONENT_KEY,
16864
- loader: () => import('./acorex-platform-module-conversation-client-comments-page.component-BW_XRzT6.mjs').then((m) => m.AXMCommentsPageComponent),
16967
+ loader: () => import('./acorex-platform-module-conversation-client-comments-page.component-BsE6bCZT.mjs').then((m) => m.AXMCommentsPageComponent),
16865
16968
  },
16866
16969
  ];
16867
16970
  }
@@ -17167,19 +17270,19 @@ class AXMConversationModule {
17167
17270
  provideCommandSetups([
17168
17271
  {
17169
17272
  key: CONVERSATION_AFTER_MESSAGE_SENT_COMMAND,
17170
- command: () => import('./acorex-platform-module-conversation-client-after-message-sent.command-e_3t71gw.mjs').then((m) => m.AXMConversationAfterMessageSentCommand),
17273
+ command: () => import('./acorex-platform-module-conversation-client-after-message-sent.command-JjZrYD2R.mjs').then((m) => m.AXMConversationAfterMessageSentCommand),
17171
17274
  },
17172
17275
  {
17173
17276
  key: CONVERSATION_RETRY_ASSIST_RESPONSE_COMMAND,
17174
- command: () => import('./acorex-platform-module-conversation-client-retry-assist-response.command-CC0jPXGP.mjs').then((m) => m.AXMConversationRetryAssistResponseCommand),
17277
+ command: () => import('./acorex-platform-module-conversation-client-retry-assist-response.command-BvzWaKX4.mjs').then((m) => m.AXMConversationRetryAssistResponseCommand),
17175
17278
  },
17176
17279
  {
17177
17280
  key: CONVERSATION_SYNC_READ_STATE_COMMAND,
17178
- command: () => import('./acorex-platform-module-conversation-client-sync-read-state.command-BUtdyniC.mjs').then((m) => m.AXMConversationSyncReadStateCommand),
17281
+ command: () => import('./acorex-platform-module-conversation-client-sync-read-state.command-DQXezGRu.mjs').then((m) => m.AXMConversationSyncReadStateCommand),
17179
17282
  },
17180
17283
  {
17181
17284
  key: CONVERSATION_MARK_CONVERSATION_UNREAD_COMMAND,
17182
- command: () => import('./acorex-platform-module-conversation-client-mark-conversation-unread.command-Cdd6Cxkf.mjs').then((m) => m.AXMConversationMarkConversationUnreadCommand),
17285
+ command: () => import('./acorex-platform-module-conversation-client-mark-conversation-unread.command-B1mvtbaA.mjs').then((m) => m.AXMConversationMarkConversationUnreadCommand),
17183
17286
  },
17184
17287
  {
17185
17288
  key: CONVERSATION_EMIT_TYPING_INDICATOR_COMMAND,
@@ -17191,7 +17294,7 @@ class AXMConversationModule {
17191
17294
  },
17192
17295
  {
17193
17296
  key: CONVERSATION_OPEN_CHAT_COMMAND,
17194
- command: () => import('./acorex-platform-module-conversation-client-open-chat.command-TfSLQn3K.mjs').then((m) => m.AXMConversationOpenChatCommand),
17297
+ command: () => import('./acorex-platform-module-conversation-client-open-chat.command-CbJ0gXZq.mjs').then((m) => m.AXMConversationOpenChatCommand),
17195
17298
  },
17196
17299
  {
17197
17300
  key: 'show-comment-popup',
@@ -17310,19 +17413,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
17310
17413
  provideCommandSetups([
17311
17414
  {
17312
17415
  key: CONVERSATION_AFTER_MESSAGE_SENT_COMMAND,
17313
- command: () => import('./acorex-platform-module-conversation-client-after-message-sent.command-e_3t71gw.mjs').then((m) => m.AXMConversationAfterMessageSentCommand),
17416
+ command: () => import('./acorex-platform-module-conversation-client-after-message-sent.command-JjZrYD2R.mjs').then((m) => m.AXMConversationAfterMessageSentCommand),
17314
17417
  },
17315
17418
  {
17316
17419
  key: CONVERSATION_RETRY_ASSIST_RESPONSE_COMMAND,
17317
- command: () => import('./acorex-platform-module-conversation-client-retry-assist-response.command-CC0jPXGP.mjs').then((m) => m.AXMConversationRetryAssistResponseCommand),
17420
+ command: () => import('./acorex-platform-module-conversation-client-retry-assist-response.command-BvzWaKX4.mjs').then((m) => m.AXMConversationRetryAssistResponseCommand),
17318
17421
  },
17319
17422
  {
17320
17423
  key: CONVERSATION_SYNC_READ_STATE_COMMAND,
17321
- command: () => import('./acorex-platform-module-conversation-client-sync-read-state.command-BUtdyniC.mjs').then((m) => m.AXMConversationSyncReadStateCommand),
17424
+ command: () => import('./acorex-platform-module-conversation-client-sync-read-state.command-DQXezGRu.mjs').then((m) => m.AXMConversationSyncReadStateCommand),
17322
17425
  },
17323
17426
  {
17324
17427
  key: CONVERSATION_MARK_CONVERSATION_UNREAD_COMMAND,
17325
- command: () => import('./acorex-platform-module-conversation-client-mark-conversation-unread.command-Cdd6Cxkf.mjs').then((m) => m.AXMConversationMarkConversationUnreadCommand),
17428
+ command: () => import('./acorex-platform-module-conversation-client-mark-conversation-unread.command-B1mvtbaA.mjs').then((m) => m.AXMConversationMarkConversationUnreadCommand),
17326
17429
  },
17327
17430
  {
17328
17431
  key: CONVERSATION_EMIT_TYPING_INDICATOR_COMMAND,
@@ -17334,7 +17437,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
17334
17437
  },
17335
17438
  {
17336
17439
  key: CONVERSATION_OPEN_CHAT_COMMAND,
17337
- command: () => import('./acorex-platform-module-conversation-client-open-chat.command-TfSLQn3K.mjs').then((m) => m.AXMConversationOpenChatCommand),
17440
+ command: () => import('./acorex-platform-module-conversation-client-open-chat.command-CbJ0gXZq.mjs').then((m) => m.AXMConversationOpenChatCommand),
17338
17441
  },
17339
17442
  {
17340
17443
  key: 'show-comment-popup',
@@ -17370,4 +17473,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
17370
17473
  */
17371
17474
 
17372
17475
  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 };
17373
- //# sourceMappingURL=acorex-platform-module-conversation-client-acorex-platform-module-conversation-client-1tv00m7Y.mjs.map
17476
+ //# sourceMappingURL=acorex-platform-module-conversation-client-acorex-platform-module-conversation-client-CmRULmpl.mjs.map