@acorex/components 22.1.0-next.3 → 22.1.0-next.31

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 (53) hide show
  1. package/fesm2022/acorex-components-alert.mjs +2 -2
  2. package/fesm2022/acorex-components-alert.mjs.map +1 -1
  3. package/fesm2022/acorex-components-combo-box.mjs +229 -25
  4. package/fesm2022/acorex-components-combo-box.mjs.map +1 -1
  5. package/fesm2022/{acorex-components-conversation-open-composer-picker-for-files-BuNEjswI.mjs → acorex-components-conversation-open-composer-picker-for-files-DnSW908R.mjs} +6 -19
  6. package/fesm2022/acorex-components-conversation-open-composer-picker-for-files-DnSW908R.mjs.map +1 -0
  7. package/fesm2022/acorex-components-conversation.mjs +7568 -9585
  8. package/fesm2022/acorex-components-conversation.mjs.map +1 -1
  9. package/fesm2022/acorex-components-data-table.mjs +57 -23
  10. package/fesm2022/acorex-components-data-table.mjs.map +1 -1
  11. package/fesm2022/acorex-components-decorators.mjs +2 -2
  12. package/fesm2022/acorex-components-decorators.mjs.map +1 -1
  13. package/fesm2022/acorex-components-dropdown.mjs +2 -2
  14. package/fesm2022/acorex-components-dropdown.mjs.map +1 -1
  15. package/fesm2022/acorex-components-fab.mjs +5 -5
  16. package/fesm2022/acorex-components-fab.mjs.map +1 -1
  17. package/fesm2022/acorex-components-form.mjs +21 -5
  18. package/fesm2022/acorex-components-form.mjs.map +1 -1
  19. package/fesm2022/acorex-components-label.mjs +2 -2
  20. package/fesm2022/acorex-components-label.mjs.map +1 -1
  21. package/fesm2022/acorex-components-loading-dialog.mjs +59 -42
  22. package/fesm2022/acorex-components-loading-dialog.mjs.map +1 -1
  23. package/fesm2022/acorex-components-lookup.mjs +1191 -171
  24. package/fesm2022/acorex-components-lookup.mjs.map +1 -1
  25. package/fesm2022/acorex-components-menu.mjs +11 -5
  26. package/fesm2022/acorex-components-menu.mjs.map +1 -1
  27. package/fesm2022/acorex-components-notification.mjs +6 -6
  28. package/fesm2022/acorex-components-notification.mjs.map +1 -1
  29. package/fesm2022/acorex-components-popover.mjs +22 -0
  30. package/fesm2022/acorex-components-popover.mjs.map +1 -1
  31. package/fesm2022/acorex-components-select-box.mjs +38 -11
  32. package/fesm2022/acorex-components-select-box.mjs.map +1 -1
  33. package/fesm2022/acorex-components-tabs.mjs +2 -2
  34. package/fesm2022/acorex-components-tabs.mjs.map +1 -1
  35. package/fesm2022/acorex-components-tag-box.mjs +2 -2
  36. package/fesm2022/acorex-components-tag-box.mjs.map +1 -1
  37. package/fesm2022/acorex-components-tree-view.mjs +40 -3
  38. package/fesm2022/acorex-components-tree-view.mjs.map +1 -1
  39. package/lookup/README.md +19 -8
  40. package/package.json +4 -7
  41. package/types/acorex-components-combo-box.d.ts +46 -9
  42. package/types/acorex-components-conversation.d.ts +663 -1293
  43. package/types/acorex-components-data-table.d.ts +12 -2
  44. package/types/acorex-components-loading-dialog.d.ts +12 -4
  45. package/types/acorex-components-lookup.d.ts +258 -64
  46. package/types/acorex-components-popover.d.ts +6 -0
  47. package/types/acorex-components-select-box.d.ts +11 -0
  48. package/types/acorex-components-tree-view.d.ts +9 -1
  49. package/fesm2022/acorex-components-conversation-open-composer-picker-for-files-BuNEjswI.mjs.map +0 -1
  50. package/fesm2022/acorex-components-selection-list-2.mjs +0 -168
  51. package/fesm2022/acorex-components-selection-list-2.mjs.map +0 -1
  52. package/selection-list-2/README.md +0 -3
  53. package/types/acorex-components-selection-list-2.d.ts +0 -52
@@ -1,18 +1,21 @@
1
1
  import * as _acorex_components_conversation from '@acorex/components/conversation';
2
2
  import * as _angular_core from '@angular/core';
3
- import { OnDestroy, ViewContainerRef, Type, InputSignal, WritableSignal, Signal, Provider, OnInit, EventEmitter, TemplateRef, InjectionToken, ModuleWithProviders } from '@angular/core';
4
- import { AXComponentCloseEvent, AXHtmlEvent, AXDataSource, AXPlacement, AXClosableComponent } from '@acorex/cdk/common';
3
+ import { OnDestroy, ViewContainerRef, Type, InputSignal, WritableSignal, Signal, Provider, OnInit, EventEmitter, TemplateRef, ElementRef, InjectionToken, ModuleWithProviders } from '@angular/core';
4
+ import { AXComponentCloseEvent, AXHtmlEvent, AXClickEvent, AXDataSource, AXPlacement } from '@acorex/cdk/common';
5
+ import * as _acorex_components_action_sheet from '@acorex/components/action-sheet';
6
+ import { AXActionSheetRef } from '@acorex/components/action-sheet';
5
7
  import * as _acorex_components_popup from '@acorex/components/popup';
6
8
  import { AXPopupService, AXPopupRef } from '@acorex/components/popup';
7
9
  import { AXFileUploadOptions, AXUploadResult, AXUploadReference, AXUploaderService, AXUploaderFileChangeEvent } from '@acorex/cdk/uploader';
8
10
  import { AXListComponent } from '@acorex/components/list';
9
11
  import * as rxjs from 'rxjs';
10
- import { Observable, BehaviorSubject, Subject } from 'rxjs';
12
+ import { Observable } from 'rxjs';
11
13
  import { AXDialogService } from '@acorex/components/dialog';
12
14
  import { AXContextMenuOpeningEvent, AXContextMenuItemsClickEvent } from '@acorex/components/menu';
15
+ import { AXTabLocation } from '@acorex/components/tabs';
13
16
  import { AXBasePageComponent } from '@acorex/components/page';
14
17
  import * as _acorex_core_file from '@acorex/core/file';
15
- import { AXFileTypeInfoProvider, AXFileType, AXFileService, AXFileTypeRegistryService, AXFileTypeExtensionHint, AXFileTypeOpenContext } from '@acorex/core/file';
18
+ import { AXFileTypeInfoProvider, AXFileType, AXFileTypeRegistryService, AXFileService, AXFileTypeExtensionHint, AXFileTypeOpenContext } from '@acorex/core/file';
16
19
  import { AXTranslationService } from '@acorex/core/translation';
17
20
  import { AXToastService } from '@acorex/components/toast';
18
21
  import { AXValidationRuleResult } from '@acorex/core/validation';
@@ -26,6 +29,7 @@ declare class AXConversationComposerPopupComponent implements OnDestroy {
26
29
  private get registry();
27
30
  contentContainer: _angular_core.Signal<ViewContainerRef>;
28
31
  private currentComponentRef;
32
+ private tabItemSelectedSubscription;
29
33
  /** Popup open state (for backward compatibility) */
30
34
  readonly isOpen: _angular_core.InputSignal<boolean>;
31
35
  /** Close event (for backward compatibility) */
@@ -52,6 +56,7 @@ declare class AXConversationComposerPopupComponent implements OnDestroy {
52
56
  }): void;
53
57
  /** Load tab content component */
54
58
  private loadTabContent;
59
+ private clearTabContent;
55
60
  ngOnDestroy(): void;
56
61
  /** Close popup (for backward compatibility) */
57
62
  close(): void;
@@ -375,12 +380,31 @@ interface AXConversationDeleteMessageCommand {
375
380
  forEveryone?: boolean;
376
381
  }
377
382
 
383
+ /**
384
+ * Per-user preferences for a specific conversation (mute, notifications, etc.).
385
+ * Stored on the user account, keyed by conversation ID — not on the room entity.
386
+ */
387
+ interface AXConversationRoomPreferences {
388
+ /** Muted until timestamp */
389
+ mutedUntil?: Date;
390
+ /** Show notifications for this conversation */
391
+ notifications: boolean;
392
+ /** Custom notification sound */
393
+ notificationSound?: string;
394
+ /** Show message preview in notifications */
395
+ showPreview: boolean;
396
+ /** Custom settings */
397
+ custom?: Record<string, unknown>;
398
+ }
399
+ declare const AX_CONVERSATION_DEFAULT_ROOM_PREFERENCES: AXConversationRoomPreferences;
400
+ /** Map of conversation ID → user-specific room preferences. */
401
+ type AXConversationRoomPreferencesMap = Record<string, AXConversationRoomPreferences>;
402
+
378
403
  /**
379
404
  * Participant Model
380
- * Represents a user/member in a conversation
405
+ * Membership in a conversation (identity fields are snapshots; live presence is on the user store).
381
406
  */
382
- type AXConversationParticipantRole = 'admin' | 'moderator' | 'member';
383
- type AXConversationParticipantStatus = 'online' | 'offline' | 'away';
407
+ type AXConversationParticipantRole = 'owner' | 'admin' | 'moderator' | 'member' | 'guest';
384
408
  /** Extended profile fields shown in private-chat info panels. */
385
409
  interface AXConversationUserProfile {
386
410
  bio?: string;
@@ -391,6 +415,18 @@ interface AXConversationUserProfile {
391
415
  company?: string;
392
416
  title?: string;
393
417
  }
418
+ /** Authenticated user profile (includes per-room preferences). */
419
+ interface AXConversationUser {
420
+ id: string;
421
+ name: string;
422
+ description?: string;
423
+ profile?: AXConversationUserProfile;
424
+ avatar?: string;
425
+ icon?: string;
426
+ metadata?: Record<string, unknown>;
427
+ /** User-specific settings per conversation (key = conversationId). */
428
+ conversationPreferences?: AXConversationRoomPreferencesMap;
429
+ }
394
430
  interface AXConversationParticipant {
395
431
  /** Unique identifier for the participant */
396
432
  id: string;
@@ -411,10 +447,6 @@ interface AXConversationParticipant {
411
447
  icon?: string;
412
448
  /** Role in the conversation (for groups/channels) */
413
449
  role?: AXConversationParticipantRole;
414
- /** Current online status */
415
- status?: AXConversationParticipantStatus;
416
- /** Last seen timestamp (when offline/away) */
417
- lastSeen?: Date;
418
450
  /** Custom metadata */
419
451
  metadata?: Record<string, unknown>;
420
452
  }
@@ -425,34 +457,6 @@ interface AXConversationParticipant {
425
457
  */
426
458
 
427
459
  type AXConversationType = 'private' | 'group' | 'channel' | 'bot';
428
- /**
429
- * Conversation status information
430
- */
431
- interface AXConversationStatus {
432
- /** Whether someone is typing */
433
- isTyping: boolean;
434
- /** User IDs currently typing */
435
- typingUsers: string[];
436
- /** Online presence (for private chats) */
437
- presence?: 'online' | 'offline' | 'away';
438
- /** Last seen timestamp (for private chats when offline) */
439
- lastSeen?: Date;
440
- }
441
- /**
442
- * Conversation settings
443
- */
444
- interface AXConversationSettings {
445
- /** Muted until timestamp */
446
- mutedUntil?: Date;
447
- /** Show notifications */
448
- notifications: boolean;
449
- /** Custom notification sound */
450
- notificationSound?: string;
451
- /** Show message preview in notifications */
452
- showPreview: boolean;
453
- /** Custom settings */
454
- custom?: Record<string, unknown>;
455
- }
456
460
  /** Theme-specific CSS `background` values for the message list area. */
457
461
  interface AXConversationMessageListThemeBackground {
458
462
  light: string;
@@ -510,10 +514,6 @@ interface AXConversation {
510
514
  unreadCount: number;
511
515
  /** Number of unread mentions */
512
516
  unreadMentions?: number;
513
- /** Current status (typing, presence, etc.) */
514
- status: AXConversationStatus;
515
- /** User-specific settings */
516
- settings: AXConversationSettings;
517
517
  /** Pinned messages IDs */
518
518
  pinnedMessageIds?: string[];
519
519
  /** Conversation creation timestamp */
@@ -526,13 +526,11 @@ interface AXConversation {
526
526
  pinned?: boolean;
527
527
  /** Whether conversation is archived */
528
528
  archived?: boolean;
529
- /** Draft message text */
530
- draft?: string;
531
529
  /** Custom metadata */
532
530
  metadata?: AXConversationMetadata;
533
531
  }
534
532
  /**
535
- * Typing indicator
533
+ * Typing indicator (realtime event — ephemeral, not stored on the room entity).
536
534
  */
537
535
  interface AXConversationTypingIndicator {
538
536
  /** Conversation ID */
@@ -543,19 +541,8 @@ interface AXConversationTypingIndicator {
543
541
  userName?: string;
544
542
  /** Timestamp */
545
543
  timestamp: Date;
546
- }
547
- /**
548
- * Presence update
549
- */
550
- interface AXConversationPresenceUpdate {
551
- /** User ID */
552
- userId: string;
553
- /** Presence status */
554
- status: 'online' | 'offline' | 'away';
555
- /** Last seen timestamp */
556
- lastSeen?: Date;
557
- /** Custom status text */
558
- statusText?: string;
544
+ /** When false, user stopped typing */
545
+ isTyping?: boolean;
559
546
  }
560
547
  /**
561
548
  * Conversation filter options
@@ -595,6 +582,26 @@ declare const AX_CONVERSATION_MESSAGE_TYPE_FILE_TYPE: Partial<Record<AXConversat
595
582
  /** Resolves {@link AXConversationMessage.fileType} from command or message type. */
596
583
  declare function resolveConversationMessageFileType(type: AXConversationMessageType, fileType?: string): string | undefined;
597
584
 
585
+ /**
586
+ * User presence — global per-user live state (not room-scoped).
587
+ */
588
+ type AXConversationPresenceStatus = 'online' | 'offline' | 'away' | 'busy';
589
+ /** Live presence for a single user. */
590
+ interface AXConversationUserPresence {
591
+ userId: string;
592
+ status: AXConversationPresenceStatus;
593
+ lastSeen?: Date;
594
+ statusText?: string;
595
+ updatedAt?: Date;
596
+ }
597
+ /** Realtime / API presence event payload. */
598
+ interface AXConversationPresenceUpdate {
599
+ userId: string;
600
+ status: AXConversationPresenceStatus;
601
+ lastSeen?: Date;
602
+ statusText?: string;
603
+ }
604
+
598
605
  /**
599
606
  * Abstract Base Registry
600
607
  * Base class for all registries with common functionality
@@ -673,22 +680,17 @@ declare abstract class AXConversationBaseRegistry<T extends AXConversationRegist
673
680
  protected abstract getRegistryName(): string;
674
681
  }
675
682
 
676
- /**
677
- * Active component state in composer
678
- */
679
- interface AXConversationComposerActiveComponent {
680
- /** Action that triggered this component */
681
- action: AXConversationComposerAction;
682
- /** Component to render */
683
- component?: Type<unknown>;
684
- /** Lazy loader for the component */
685
- componentLoader?: () => Promise<Type<unknown>>;
686
- /** Component inputs */
687
- inputs?: Record<string, unknown>;
688
- }
683
+ /** Primary composer button mode (send / cancel / stopping / default action / locked). */
684
+ type AXConversationComposerPrimaryButtonMode = 'send' | 'cancel' | 'stopping' | 'default-action' | 'locked';
689
685
  declare class AXConversationComposerService {
690
686
  private readonly conversationService;
687
+ private readonly generationState;
691
688
  private readonly translation;
689
+ private readonly popupService;
690
+ private readonly actionSheetService;
691
+ private readonly platform;
692
+ private readonly config;
693
+ private readonly _activeActionOverlay;
692
694
  private get registry();
693
695
  private readonly _replyMessage;
694
696
  private readonly _editMessage;
@@ -696,15 +698,10 @@ declare class AXConversationComposerService {
696
698
  readonly editMessage: _angular_core.Signal<AXConversationMessage>;
697
699
  readonly activeConversation: _angular_core.Signal<_acorex_components_conversation.AXConversation>;
698
700
  readonly activeMessages: _angular_core.Signal<AXConversationMessage[]>;
699
- /** Active component being shown in composer (full-width mode) */
700
- private readonly _activeComponent;
701
- readonly activeComponent: _angular_core.Signal<AXConversationComposerActiveComponent>;
702
701
  /** Draft text */
703
702
  readonly draftText: _angular_core.WritableSignal<string>;
704
703
  /** Attachments */
705
704
  readonly attachments: _angular_core.WritableSignal<File[]>;
706
- /** Show typing indicator */
707
- readonly showTypingIndicator: _angular_core.WritableSignal<boolean>;
708
705
  /** Incremented to request focus on the composer text area (handled by AXConversationComposerComponent). */
709
706
  private readonly _focusRequest;
710
707
  readonly focusRequest: _angular_core.Signal<number>;
@@ -712,22 +709,31 @@ declare class AXConversationComposerService {
712
709
  readonly placeholder: _angular_core.Signal<string>;
713
710
  /** Number of input rows */
714
711
  readonly inputRows: _angular_core.Signal<number>;
715
- /** Can send message */
712
+ /** Can send message (draft has content; does not include generation state). */
716
713
  readonly canSend: _angular_core.Signal<boolean>;
714
+ /** Whether a background generation (e.g. AI response) is in progress. */
715
+ readonly isGenerating: _angular_core.Signal<boolean>;
716
+ /** Whether cancel cleanup is in progress (spinner on primary button). */
717
+ readonly isStopping: _angular_core.Signal<boolean>;
718
+ /** Primary end-button mode for send / cancel / stopping / voice / locked. */
719
+ readonly primaryButtonMode: _angular_core.Signal<AXConversationComposerPrimaryButtonMode>;
717
720
  /** Composer action context */
718
721
  readonly actionContext: _angular_core.Signal<AXConversationComposerActionContext>;
719
- /** Left actions from registry */
720
- readonly leftActions: _angular_core.Signal<AXConversationComposerAction[]>;
721
- /** Right actions from registry */
722
- readonly rightActions: _angular_core.Signal<AXConversationComposerAction[]>;
723
- /** Left inline actions (location = 'inline' or undefined) */
724
- readonly leftInlineActions: _angular_core.Signal<AXConversationComposerAction[]>;
725
- /** Left menu actions (location = 'menu') */
726
- readonly leftMenuActions: _angular_core.Signal<AXConversationComposerAction[]>;
727
- /** Right inline actions (location = 'inline' or undefined) */
728
- readonly rightInlineActions: _angular_core.Signal<AXConversationComposerAction[]>;
729
- /** Right menu actions (location = 'menu') */
730
- readonly rightMenuActions: _angular_core.Signal<AXConversationComposerAction[]>;
722
+ /** Start actions from registry */
723
+ readonly startActions: _angular_core.Signal<AXConversationComposerAction[]>;
724
+ /** End actions from registry */
725
+ readonly endActions: _angular_core.Signal<AXConversationComposerAction[]>;
726
+ /** Start inline actions (location = 'inline' or undefined) */
727
+ readonly startInlineActions: _angular_core.Signal<AXConversationComposerAction[]>;
728
+ /** Start menu actions shown in the attachment popup */
729
+ readonly startMenuActions: _angular_core.Signal<AXConversationComposerAction[]>;
730
+ /** End inline actions inside the input pill (excludes default action) */
731
+ readonly endInlineActions: _angular_core.Signal<AXConversationComposerAction[]>;
732
+ /** End menu actions (location = 'menu') */
733
+ readonly endMenuActions: _angular_core.Signal<AXConversationComposerAction[]>;
734
+ /** Default end action (voice/send morph button) */
735
+ readonly defaultAction: _angular_core.Signal<AXConversationComposerAction>;
736
+ cancelGeneration(): void;
731
737
  startReply(message: AXConversationMessage): void;
732
738
  startEdit(message: AXConversationMessage): void;
733
739
  /** Focus the composer text area when the composer component is mounted. */
@@ -744,21 +750,20 @@ declare class AXConversationComposerService {
744
750
  */
745
751
  clearComposerInput(conversationId?: string): void;
746
752
  /**
747
- * Show a component in the composer (full-width mode)
753
+ * Open a composer action component in a popup (desktop) or action sheet (mobile).
748
754
  */
749
- showComponent(action: AXConversationComposerAction, inputs?: Record<string, unknown>): void;
755
+ openActionComponent(action: AXConversationComposerAction, inputs?: Record<string, unknown>, options?: {
756
+ toggleable?: boolean;
757
+ initialFiles?: File[];
758
+ }): Promise<void>;
750
759
  /**
751
- * Hide the active component
760
+ * Hide the active action overlay.
752
761
  */
753
762
  hideComponent(): void;
754
- /**
755
- * Toggle component visibility
756
- */
757
- toggleComponent(action: AXConversationComposerAction, inputs?: Record<string, unknown>): void;
758
763
  /**
759
764
  * Get actions for the active conversation
760
765
  */
761
- getActionsForPosition(position: 'left' | 'right', context: AXConversationComposerActionContext): AXConversationComposerAction[];
766
+ getActionsForPosition(position: 'start' | 'end', context: AXConversationComposerActionContext): AXConversationComposerAction[];
762
767
  /**
763
768
  * Execute an action
764
769
  */
@@ -795,6 +800,10 @@ interface AXConversationComposerActionContext {
795
800
  isReplying: boolean;
796
801
  /** Message being replied to (if any) */
797
802
  replyingToMessageId?: string;
803
+ /** Whether a background generation (e.g. AI response) is in progress */
804
+ isGenerating?: boolean;
805
+ /** Whether cancel cleanup is in progress */
806
+ isStopping?: boolean;
798
807
  /** Custom context data */
799
808
  custom?: Record<string, unknown>;
800
809
  }
@@ -811,6 +820,15 @@ interface AXConversationComposerActionComponent {
811
820
  readonly initialFiles?: InputSignal<File[]>;
812
821
  /** Set by {@link AXPopupService} when the picker is shown in a popup. */
813
822
  readonly __popup__?: InputSignal<_acorex_components_popup.AXPopupRef | undefined>;
823
+ /** Set by {@link AXActionSheetService} when the picker is shown in an action sheet. */
824
+ readonly __actionSheet__?: InputSignal<_acorex_components_action_sheet.AXActionSheetRef | undefined>;
825
+ /**
826
+ * When true (from action {@link AXConversationComposerAction.autoRun}), runs {@link activate}
827
+ * once after the component is mounted.
828
+ */
829
+ readonly autoRun?: InputSignal<boolean>;
830
+ /** Primary action when opened from the composer (record, browse files, etc.). */
831
+ activate?(): void | Promise<void>;
814
832
  /** Cancel in-flight uploads when the picker is closed or replaced. */
815
833
  abortInProgressUploads?(): void;
816
834
  }
@@ -822,10 +840,15 @@ interface AXConversationComposerAction extends Omit<AXConversationRegistryItem,
822
840
  label: string;
823
841
  /** Icon name/class */
824
842
  icon: string;
825
- /** Position: left or right */
826
- position: 'left' | 'right';
827
- /** Location: inline (show as button) or menu (show in dropdown menu) */
843
+ /** Position: start or end of the composer */
844
+ position: 'start' | 'end';
845
+ /** Location: inline (show as button) or menu (show in attachment popup menu) */
828
846
  location?: 'inline' | 'menu';
847
+ /**
848
+ * Primary end action (e.g. voice record). Only one action may be default.
849
+ * Renders as the circular send-style button and morphs into send when the draft has content.
850
+ */
851
+ default?: boolean;
829
852
  /** Visibility condition */
830
853
  visible: (context: AXConversationComposerActionContext) => boolean;
831
854
  /** Enabled condition */
@@ -841,6 +864,11 @@ interface AXConversationComposerAction extends Omit<AXConversationRegistryItem,
841
864
  * Whether this action is toggleable (shows/hides component)
842
865
  */
843
866
  toggleable?: boolean;
867
+ /**
868
+ * When true, runs {@link AXConversationComposerActionComponent.activate} in
869
+ * {@link afterNextRender} after the upload panel is mounted.
870
+ */
871
+ autoRun?: boolean;
844
872
  /** Action handler (optional if component is provided) */
845
873
  handler?: (context: AXConversationComposerActionContext) => void | Promise<void>;
846
874
  /** Tooltip text */
@@ -869,18 +897,20 @@ declare class AXConversationComposerActionRegistry {
869
897
  constructor();
870
898
  /** All registered actions */
871
899
  readonly actions: _angular_core.Signal<AXConversationComposerAction[]>;
872
- /** Left-side actions sorted by priority */
873
- readonly leftActions: _angular_core.Signal<AXConversationComposerAction[]>;
874
- /** Right-side actions sorted by priority */
875
- readonly rightActions: _angular_core.Signal<AXConversationComposerAction[]>;
876
- /** Left-side inline actions (location = 'inline' or undefined) */
877
- readonly leftInlineActions: _angular_core.Signal<AXConversationComposerAction[]>;
878
- /** Left-side menu actions (location = 'menu') */
879
- readonly leftMenuActions: _angular_core.Signal<AXConversationComposerAction[]>;
880
- /** Right-side inline actions (location = 'inline' or undefined) */
881
- readonly rightInlineActions: _angular_core.Signal<AXConversationComposerAction[]>;
882
- /** Right-side menu actions (location = 'menu') */
883
- readonly rightMenuActions: _angular_core.Signal<AXConversationComposerAction[]>;
900
+ /** Start-side actions sorted by priority */
901
+ readonly startActions: _angular_core.Signal<AXConversationComposerAction[]>;
902
+ /** End-side actions sorted by priority */
903
+ readonly endActions: _angular_core.Signal<AXConversationComposerAction[]>;
904
+ /** Start-side inline actions (location = 'inline' or undefined) */
905
+ readonly startInlineActions: _angular_core.Signal<AXConversationComposerAction[]>;
906
+ /** Start-side menu actions (location = 'menu') — shown in the attachment popup */
907
+ readonly startMenuActions: _angular_core.Signal<AXConversationComposerAction[]>;
908
+ /** End-side inline actions inside the input pill (excludes default action) */
909
+ readonly endInlineActions: _angular_core.Signal<AXConversationComposerAction[]>;
910
+ /** End-side menu actions (location = 'menu') */
911
+ readonly endMenuActions: _angular_core.Signal<AXConversationComposerAction[]>;
912
+ /** The single default end action (voice/send morph button) */
913
+ readonly defaultAction: _angular_core.Signal<AXConversationComposerAction>;
884
914
  /**
885
915
  * Register a composer action
886
916
  */
@@ -895,11 +925,11 @@ declare class AXConversationComposerActionRegistry {
895
925
  /**
896
926
  * Get visible actions for a position
897
927
  */
898
- getVisibleActions(position: 'left' | 'right', context: AXConversationComposerActionContext): AXConversationComposerAction[];
928
+ getVisibleActions(position: 'start' | 'end', context: AXConversationComposerActionContext): AXConversationComposerAction[];
899
929
  /**
900
930
  * Get enabled actions for a position
901
931
  */
902
- getEnabledActions(position: 'left' | 'right', context: AXConversationComposerActionContext): AXConversationComposerAction[];
932
+ getEnabledActions(position: 'start' | 'end', context: AXConversationComposerActionContext): AXConversationComposerAction[];
903
933
  isActionEnabled(action: AXConversationComposerAction, context: AXConversationComposerActionContext): boolean;
904
934
  /**
905
935
  * Picker actions for a file catalog (by priority), when visible and enabled.
@@ -1228,6 +1258,7 @@ declare class AXConversationMessageRendererRegistry {
1228
1258
  private readonly _composerActions;
1229
1259
  constructor();
1230
1260
  private registerBuiltInRenderers;
1261
+ private registerBuiltInRendererIfMissing;
1231
1262
  /** All registered renderers */
1232
1263
  readonly renderers: Signal<AXConversationMessageRenderer[]>;
1233
1264
  /** Renderers sorted by priority (highest first) */
@@ -1317,10 +1348,6 @@ declare class AXConversationInfoBarService {
1317
1348
  * Reset info-bar overlays when the active conversation changes.
1318
1349
  */
1319
1350
  onConversationChanged(): void;
1320
- /**
1321
- * Open the Telegram-style conversation info panel for the active (or given) conversation.
1322
- */
1323
- openConversationInfoPanel(conversation?: AXConversation): Promise<void>;
1324
1351
  /**
1325
1352
  * Get actions for the active conversation
1326
1353
  */
@@ -1424,7 +1451,7 @@ interface AXConversationInfoBarAction extends AXConversationRegistryItem {
1424
1451
  /** Whether this is a divider */
1425
1452
  divider?: boolean;
1426
1453
  /** Display location: 'inline' for toolbar buttons, 'menu' for dropdown menu */
1427
- location?: 'inline' | 'menu';
1454
+ location?: 'inline' | 'menu' | ((context: AXConversationInfoBarActionContext) => 'inline' | 'menu');
1428
1455
  /**
1429
1456
  * Component to show when action is activated (for inline actions)
1430
1457
  * If provided, clicking the action will show this component in the info-bar
@@ -1474,6 +1501,10 @@ declare class AXConversationInfoBarActionRegistry extends AXConversationBaseRegi
1474
1501
  * Get actions for a specific conversation
1475
1502
  */
1476
1503
  getActionsForConversation(conversation: AXConversation, location?: 'inline' | 'menu'): AXConversationInfoBarAction[];
1504
+ /**
1505
+ * Resolve the display location for an action (supports dynamic location factories).
1506
+ */
1507
+ getActionLocation(action: AXConversationInfoBarAction, conversation: AXConversation): 'inline' | 'menu' | undefined;
1477
1508
  /**
1478
1509
  * Get inline actions (toolbar buttons)
1479
1510
  */
@@ -1591,14 +1622,13 @@ declare class AXConversationMessageActionRegistry {
1591
1622
  }
1592
1623
 
1593
1624
  declare class AXConversationComposerComponent implements OnDestroy {
1594
- #private;
1595
1625
  private readonly conversationService;
1596
1626
  private readonly composerService;
1597
1627
  private readonly messageListService;
1598
1628
  private readonly config;
1599
1629
  private readonly translation;
1600
1630
  /** Access registry through conversation service */
1601
- private get registry();
1631
+ protected get composerActionRegistry(): _acorex_components_conversation.AXConversationComposerActionRegistry;
1602
1632
  /** Composer text area reference */
1603
1633
  private readonly textAreaRef;
1604
1634
  /** Draft text - use service */
@@ -1609,10 +1639,10 @@ declare class AXConversationComposerComponent implements OnDestroy {
1609
1639
  readonly editingMessage: _angular_core.WritableSignal<any>;
1610
1640
  /** Replying to message */
1611
1641
  readonly replyingToMessage: _angular_core.WritableSignal<AXConversationMessage>;
1612
- /** Show typing indicator - use service */
1613
- readonly showTypingIndicator: _angular_core.WritableSignal<boolean>;
1614
1642
  /** Message sent event */
1615
1643
  readonly messageSent: _angular_core.OutputEmitterRef<AXConversationSendMessageCommand>;
1644
+ /** Emitted when the user cancels an in-progress generation from the composer. */
1645
+ readonly generationCancelled: _angular_core.OutputEmitterRef<void>;
1616
1646
  /** Emoji clicked event */
1617
1647
  readonly emojiClick: _angular_core.OutputEmitterRef<void>;
1618
1648
  /** Attach clicked event */
@@ -1622,46 +1652,53 @@ declare class AXConversationComposerComponent implements OnDestroy {
1622
1652
  /** Active conversation */
1623
1653
  readonly activeConversation: _angular_core.Signal<_acorex_components_conversation.AXConversation>;
1624
1654
  readonly activeMessages: _angular_core.Signal<AXConversationMessage[]>;
1625
- /** Active component from service */
1626
- readonly activeComponent: _angular_core.Signal<_acorex_components_conversation.AXConversationComposerActiveComponent>;
1627
1655
  /** Emoji popover state */
1628
1656
  private readonly emojiPopoverRef;
1629
1657
  readonly emojiPopoverTarget: _angular_core.WritableSignal<HTMLElement>;
1658
+ /** Attachment menu popover state */
1659
+ private readonly attachPopoverRef;
1660
+ private readonly attachMenuButtonRef;
1661
+ readonly attachMenuTarget: _angular_core.Signal<HTMLElement>;
1662
+ private attachMenuCloseTimer?;
1630
1663
  readonly composerPopupLoader: () => Promise<typeof _acorex_components_conversation.AXConversationComposerPopupComponent>;
1631
1664
  /** Input placeholder - use service */
1632
1665
  readonly placeholder: _angular_core.Signal<string>;
1633
- /** Typing indicator subject for rate limiting */
1634
- private readonly typingSubject;
1635
1666
  constructor();
1636
1667
  private draftSaveTimeout?;
1637
1668
  /** Number of input rows - use service */
1638
1669
  readonly inputRows: _angular_core.Signal<number>;
1639
1670
  /** Can send message - use service */
1640
1671
  readonly canSend: _angular_core.Signal<boolean>;
1641
- /** Left actions from registry - use service */
1642
- readonly leftActions: _angular_core.Signal<AXConversationComposerAction[]>;
1643
- /** Right actions from registry - use service */
1644
- readonly rightActions: _angular_core.Signal<AXConversationComposerAction[]>;
1645
- /** Left inline actions (location = 'inline' or undefined) */
1646
- readonly leftInlineActions: _angular_core.Signal<AXConversationComposerAction[]>;
1647
- /** Left menu actions (location = 'menu') */
1648
- readonly leftMenuActions: _angular_core.Signal<AXConversationComposerAction[]>;
1649
- /** Right inline actions (location = 'inline' or undefined) */
1650
- readonly rightInlineActions: _angular_core.Signal<AXConversationComposerAction[]>;
1651
- /** Right menu actions (location = 'menu') */
1652
- readonly rightMenuActions: _angular_core.Signal<AXConversationComposerAction[]>;
1653
- /** Handle key down */
1672
+ /** Whether AI/generation is in progress */
1673
+ readonly isGenerating: _angular_core.Signal<boolean>;
1674
+ /** Whether cancel cleanup is in progress */
1675
+ readonly isStopping: _angular_core.Signal<boolean>;
1676
+ /** Primary button mode */
1677
+ readonly primaryButtonMode: _angular_core.Signal<_acorex_components_conversation.AXConversationComposerPrimaryButtonMode>;
1678
+ /** Start actions from registry - use service */
1679
+ readonly startActions: _angular_core.Signal<AXConversationComposerAction[]>;
1680
+ /** End actions from registry - use service */
1681
+ readonly endActions: _angular_core.Signal<AXConversationComposerAction[]>;
1682
+ /** Start inline actions */
1683
+ readonly startInlineActions: _angular_core.Signal<AXConversationComposerAction[]>;
1684
+ /** Start menu actions (attachment popup) */
1685
+ readonly startMenuActions: _angular_core.Signal<AXConversationComposerAction[]>;
1686
+ /** End inline actions inside input pill */
1687
+ readonly endInlineActions: _angular_core.Signal<AXConversationComposerAction[]>;
1688
+ /** End menu actions */
1689
+ readonly endMenuActions: _angular_core.Signal<AXConversationComposerAction[]>;
1690
+ /** Default end action (voice/send morph) */
1691
+ readonly defaultAction: _angular_core.Signal<AXConversationComposerAction>;
1692
+ /** Handle key down (send on Enter; typing is driven by draft changes only). */
1654
1693
  onKeyDown(event: AXHtmlEvent<KeyboardEvent>): void;
1655
- /** Handle input */
1656
- onInput(): void;
1657
- /** Send typing indicator (throttled via RxJS) */
1658
- private sendTypingIndicator;
1694
+ /** Handle draft text changes — throttled typing indicator via conversation service. */
1695
+ onDraftChanged(): void;
1659
1696
  /** Cleanup on destroy */
1660
1697
  ngOnDestroy(): void;
1661
1698
  /** Handle send click */
1662
1699
  onSendClick(): Promise<void>;
1663
1700
  /** Handle emoji click */
1664
- onEmojiClick(event?: MouseEvent): Promise<void>;
1701
+ onEmojiClick(event?: AXClickEvent | MouseEvent): Promise<void>;
1665
1702
  /** Handle emoji popover closed */
1666
1703
  onEmojiPopoverClosed(): void;
1667
1704
  /** Handle emoji/sticker selection from popup */
@@ -1670,8 +1707,26 @@ declare class AXConversationComposerComponent implements OnDestroy {
1670
1707
  private sendSticker;
1671
1708
  /** Get inputs for emoji popup component */
1672
1709
  getEmojiPopupInputs(): Record<string, unknown>;
1673
- /** Handle attach click */
1674
- onAttachClick(): void;
1710
+ /** Handle attach menu hover */
1711
+ onAttachMenuMouseEnter(): void;
1712
+ onAttachMenuMouseLeave(): void;
1713
+ onAttachMenuPanelMouseEnter(): void;
1714
+ onAttachMenuPanelMouseLeave(): void;
1715
+ private scheduleAttachMenuClose;
1716
+ private clearAttachMenuCloseTimer;
1717
+ /** Handle attach menu click */
1718
+ onAttachMenuClick(event: AXClickEvent): void;
1719
+ /** Handle attachment menu action selection */
1720
+ onAttachMenuAction(actionId: string): Promise<void>;
1721
+ /** Handle primary button click (send / cancel / stopping / voice / locked). */
1722
+ onPrimaryButtonClick(): Promise<void>;
1723
+ /** @deprecated Use onPrimaryButtonClick */
1724
+ onDefaultActionClick(): Promise<void>;
1725
+ getPrimaryButtonIcon(): string;
1726
+ getPrimaryButtonLabel(): string;
1727
+ isPrimaryButtonDisabled(): boolean;
1728
+ /** @deprecated Use getPrimaryButtonIcon */
1729
+ getDefaultActionIcon(): string;
1675
1730
  /** Handle voice click */
1676
1731
  onVoiceClick(): void;
1677
1732
  /** Remove attachment */
@@ -1684,8 +1739,9 @@ declare class AXConversationComposerComponent implements OnDestroy {
1684
1739
  startReply(message: AXConversationMessage): void;
1685
1740
  /** Focus the native textarea inside ax-text-area */
1686
1741
  private focusTextArea;
1742
+ private getClickTarget;
1687
1743
  /** Handle action click */
1688
- onActionClick(actionId: string, event?: MouseEvent): Promise<void>;
1744
+ onActionClick(actionId: string, event?: AXClickEvent | MouseEvent, initialFiles?: File[]): Promise<void>;
1689
1745
  /** Check if action is enabled */
1690
1746
  isActionEnabled(action: any): boolean;
1691
1747
  /** Get replying sender name */
@@ -1693,6 +1749,9 @@ declare class AXConversationComposerComponent implements OnDestroy {
1693
1749
  getActionLabel(action: {
1694
1750
  label: string;
1695
1751
  }): string;
1752
+ getActionButtonClass(action: {
1753
+ className?: string;
1754
+ }): string;
1696
1755
  /** Get replying message text */
1697
1756
  getReplyingMessageText(): string;
1698
1757
  /** Preview object for replying banner (type, icon, value) */
@@ -1713,13 +1772,10 @@ declare class AXConversationComposerComponent implements OnDestroy {
1713
1772
  }): string;
1714
1773
  /** Handle reply preview click - scroll to original message */
1715
1774
  onReplyPreviewClick(): void;
1716
- /** Inputs for picker / full-width composer components */
1775
+ /** Inputs for picker components opened in popup / action sheet */
1717
1776
  private buildPickerInputs;
1718
- /** Get inputs for dynamic component */
1719
- getComponentInputs(): Record<string, unknown>;
1720
- onEnter(event: AXHtmlEvent<KeyboardEvent>): Promise<void>;
1721
1777
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<AXConversationComposerComponent, never>;
1722
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<AXConversationComposerComponent, "ax-conversation-composer", never, {}, { "messageSent": "messageSent"; "emojiClick": "emojiClick"; "attachClick": "attachClick"; "voiceClick": "voiceClick"; }, never, never, true, never>;
1778
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<AXConversationComposerComponent, "ax-conversation-composer", never, {}, { "messageSent": "messageSent"; "generationCancelled": "generationCancelled"; "emojiClick": "emojiClick"; "attachClick": "attachClick"; "voiceClick": "voiceClick"; }, never, never, true, never>;
1723
1779
  }
1724
1780
 
1725
1781
  declare class AXConversationContainerComponent {
@@ -1728,6 +1784,8 @@ declare class AXConversationContainerComponent {
1728
1784
  private readonly fileService;
1729
1785
  private readonly translation;
1730
1786
  private readonly toast;
1787
+ private readonly platform;
1788
+ private readonly actionSheetService;
1731
1789
  private readonly hostRef;
1732
1790
  private readonly platformId;
1733
1791
  protected readonly config: Required<_acorex_components_conversation.AXConversationConfig>;
@@ -1761,6 +1819,8 @@ declare class AXConversationContainerDirective {
1761
1819
  private readonly platformId;
1762
1820
  private readonly translation;
1763
1821
  private readonly toast;
1822
+ private readonly platform;
1823
+ private readonly actionSheetService;
1764
1824
  private readonly config;
1765
1825
  constructor();
1766
1826
  private get registry();
@@ -1788,59 +1848,51 @@ interface AXConversationDropdownMenuItem {
1788
1848
  declare class AXConversationInfoBarComponent {
1789
1849
  private readonly conversationService;
1790
1850
  private readonly infoBar;
1851
+ private readonly platform;
1852
+ private readonly destroyRef;
1853
+ private readonly customUserAvatarComponent;
1854
+ private readonly layoutTick;
1855
+ constructor();
1791
1856
  protected get registry(): _acorex_components_conversation.AXConversationRegistryService;
1792
- /** Active conversation */
1857
+ readonly hasCustomUserAvatar: _angular_core.Signal<boolean>;
1793
1858
  readonly activeConversation: _angular_core.Signal<AXConversation>;
1794
- /** Active component from service */
1795
1859
  readonly activeComponent: _angular_core.Signal<_acorex_components_conversation.AXConversationInfoBarActiveComponent>;
1796
- /** Active banner from service */
1797
1860
  readonly activeBanner: _angular_core.Signal<_acorex_components_conversation.AXConversationInfoBarActiveBanner>;
1798
- /** Members popover target element — retained for API compatibility */
1799
1861
  readonly membersPopoverTarget: _angular_core.WritableSignal<HTMLElement>;
1800
- /** Loading state for async actions */
1801
1862
  readonly actionLoading: _angular_core.WritableSignal<boolean>;
1802
- /** Info area clicked — opens conversation profile panel */
1803
1863
  readonly infoClick: _angular_core.OutputEmitterRef<void>;
1804
- /** @deprecated Use infoClick — kept for backward compatibility */
1805
- readonly avatarClick: _angular_core.OutputEmitterRef<void>;
1806
- /** Search clicked event */
1807
1864
  readonly searchClick: _angular_core.OutputEmitterRef<void>;
1808
- /** Search query changed event */
1809
1865
  readonly searchQuery: _angular_core.OutputEmitterRef<string>;
1810
- /** Menu item clicked event */
1811
1866
  readonly menuItemAction: _angular_core.OutputEmitterRef<string>;
1812
- /** Inline action buttons from registry */
1813
- readonly inlineActions: _angular_core.Signal<_acorex_components_conversation.AXConversationInfoBarAction[]>;
1814
- /** Dropdown menu items from registry */
1867
+ readonly inlineActions: _angular_core.Signal<AXConversationInfoBarAction[]>;
1815
1868
  readonly menuItems: _angular_core.Signal<AXConversationDropdownMenuItem[]>;
1816
- /** Get conversation status - delegate to utils */
1817
- getStatus(conversation: AXConversation): 'online' | 'offline' | 'away' | undefined;
1818
- /** Get subtitle text - delegate to utils */
1869
+ getStatus(conversation: AXConversation): _acorex_components_conversation.AXConversationPresenceStatus;
1819
1870
  getSubtitle(conversation: AXConversation): string;
1820
- /** Open conversation info panel when the left info area is clicked */
1821
1871
  onInfoLeftClick(): void;
1822
- /** Handle inline action click */
1823
1872
  onInlineActionClick(actionId: string): Promise<void>;
1824
- /** Get inputs for dynamic component */
1873
+ private activateAction;
1825
1874
  getComponentInputs(): Record<string, unknown>;
1826
1875
  getInlineComponentInputs(): Record<string, unknown>;
1827
1876
  isActiveComponentFullWidth(): boolean;
1828
- /** Handle close component */
1829
1877
  onCloseComponent(): void;
1830
1878
  getBannerInputs(): Record<string, unknown>;
1831
1879
  onCloseBanner(): void;
1832
- /** Handle menu item click */
1833
1880
  onMenuItemClick(item: AXConversationDropdownMenuItem): Promise<void>;
1834
1881
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<AXConversationInfoBarComponent, never>;
1835
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<AXConversationInfoBarComponent, "ax-conversation-info-bar", never, {}, { "infoClick": "infoClick"; "avatarClick": "avatarClick"; "searchClick": "searchClick"; "searchQuery": "searchQuery"; "menuItemAction": "menuItemAction"; }, never, ["ax-prefix"], true, never>;
1882
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<AXConversationInfoBarComponent, "ax-conversation-info-bar", never, {}, { "infoClick": "infoClick"; "searchClick": "searchClick"; "searchQuery": "searchQuery"; "menuItemAction": "menuItemAction"; }, never, ["ax-prefix"], true, never>;
1836
1883
  }
1837
1884
 
1838
1885
  /**
1886
+
1839
1887
  * Shared API Types
1888
+
1840
1889
  * Common types used across all API services
1890
+
1841
1891
  */
1842
1892
  /**
1893
+
1843
1894
  * Pagination parameters
1895
+
1844
1896
  */
1845
1897
  interface AXConversationPagination {
1846
1898
  /** Page number (0-based) */
@@ -1855,7 +1907,9 @@ interface AXConversationPagination {
1855
1907
  sortDirection?: 'asc' | 'desc';
1856
1908
  }
1857
1909
  /**
1910
+
1858
1911
  * Paginated response
1912
+
1859
1913
  */
1860
1914
  interface AXConversationPaginatedResult<T> {
1861
1915
  /** Result items */
@@ -1874,7 +1928,9 @@ interface AXConversationPaginatedResult<T> {
1874
1928
  totalPages?: number;
1875
1929
  }
1876
1930
  /**
1931
+
1877
1932
  * Pagination cursor state for a single list (conversations or messages).
1933
+
1878
1934
  */
1879
1935
  interface AXConversationPaginationState {
1880
1936
  page: number;
@@ -1882,11 +1938,15 @@ interface AXConversationPaginationState {
1882
1938
  nextCursor?: string;
1883
1939
  }
1884
1940
  /**
1941
+
1885
1942
  * Connection status
1943
+
1886
1944
  */
1887
1945
  type AXConversationConnectionStatus = 'disconnected' | 'connecting' | 'connected' | 'reconnecting' | 'error';
1888
1946
  /**
1947
+
1889
1948
  * API Error with details
1949
+
1890
1950
  */
1891
1951
  interface AXConversationApiError {
1892
1952
  /** Error code */
@@ -1900,14 +1960,6 @@ interface AXConversationApiError {
1900
1960
  /** Timestamp */
1901
1961
  timestamp?: Date;
1902
1962
  }
1903
- /**
1904
- * User presence status
1905
- */
1906
- type AXConversationPresenceStatus = 'online' | 'offline' | 'away' | 'busy' | 'invisible';
1907
- /**
1908
- * User role in conversation
1909
- */
1910
- type AXConversationUserRole = 'owner' | 'admin' | 'member' | 'guest';
1911
1963
 
1912
1964
  type AXConversationApiName = 'userApi' | 'conversationApi' | 'messageApi' | 'realtimeApi';
1913
1965
  interface AXConversationApiLogEntry {
@@ -1927,11 +1979,6 @@ declare class AXConversationApiLoggerService {
1927
1979
  static ɵprov: _angular_core.ɵɵInjectableDeclaration<AXConversationApiLoggerService>;
1928
1980
  }
1929
1981
 
1930
- /**
1931
- * Abstract Conversation Management API
1932
- * Handle conversation CRUD operations, participants, and settings
1933
- */
1934
-
1935
1982
  /**
1936
1983
  * Conversation creation data
1937
1984
  */
@@ -1999,20 +2046,9 @@ interface AXConversationFilters {
1999
2046
  custom?: Record<string, unknown>;
2000
2047
  }
2001
2048
  /**
2002
- * Conversation settings update
2049
+ * @deprecated Use {@link AXConversationRoomPreferences} on the user API instead.
2003
2050
  */
2004
- interface AXConversationSettingsUpdate {
2005
- /** Muted until timestamp */
2006
- mutedUntil?: Date;
2007
- /** Show notifications */
2008
- notifications?: boolean;
2009
- /** Custom notification sound */
2010
- notificationSound?: string;
2011
- /** Show message preview in notifications */
2012
- showPreview?: boolean;
2013
- /** Custom settings */
2014
- custom?: Record<string, unknown>;
2015
- }
2051
+ type AXConversationSettingsUpdate = AXConversationRoomPreferences;
2016
2052
  /**
2017
2053
  * Participant update data
2018
2054
  */
@@ -2020,7 +2056,7 @@ interface AXConversationParticipantUpdate {
2020
2056
  /** User ID */
2021
2057
  userId: string;
2022
2058
  /** New role */
2023
- role?: AXConversationUserRole;
2059
+ role?: AXConversationParticipantRole;
2024
2060
  }
2025
2061
  /**
2026
2062
  * Abstract Conversation Management API
@@ -2121,13 +2157,6 @@ declare abstract class AXConversationApi {
2121
2157
  * @throws {AXConversationApiError} If marking fails
2122
2158
  */
2123
2159
  abstract markConversationAsRead(conversationId: string): Promise<void>;
2124
- /**
2125
- * Mark conversation as unread
2126
- *
2127
- * @param conversationId - Conversation ID
2128
- * @throws {AXConversationApiError} If marking fails
2129
- */
2130
- abstract markConversationAsUnread(conversationId: string): Promise<void>;
2131
2160
  /**
2132
2161
  * Search conversations
2133
2162
  *
@@ -2187,37 +2216,6 @@ declare abstract class AXConversationApi {
2187
2216
  * @throws {AXConversationApiError} If update fails
2188
2217
  */
2189
2218
  abstract updateParticipant(conversationId: string, update: AXConversationParticipantUpdate): Promise<AXConversation>;
2190
- /**
2191
- * Get conversation settings
2192
- *
2193
- * @param conversationId - Conversation ID
2194
- * @returns Conversation settings
2195
- * @throws {AXConversationApiError} If request fails
2196
- */
2197
- abstract getConversationSettings(conversationId: string): Promise<AXConversationSettingsUpdate>;
2198
- /**
2199
- * Update conversation settings
2200
- *
2201
- * @param conversationId - Conversation ID
2202
- * @param settings - Settings to update
2203
- * @throws {AXConversationApiError} If update fails
2204
- */
2205
- abstract updateConversationSettings(conversationId: string, settings: AXConversationSettingsUpdate): Promise<void>;
2206
- /**
2207
- * Mute conversation
2208
- *
2209
- * @param conversationId - Conversation ID
2210
- * @param duration - Mute duration in milliseconds (undefined = forever)
2211
- * @throws {AXConversationApiError} If muting fails
2212
- */
2213
- abstract muteConversation(conversationId: string, duration?: number): Promise<void>;
2214
- /**
2215
- * Unmute conversation
2216
- *
2217
- * @param conversationId - Conversation ID
2218
- * @throws {AXConversationApiError} If unmuting fails
2219
- */
2220
- abstract unmuteConversation(conversationId: string): Promise<void>;
2221
2219
  /**
2222
2220
  * Upload conversation avatar
2223
2221
  *
@@ -2636,111 +2634,33 @@ declare abstract class AXConversationMessageApi {
2636
2634
 
2637
2635
  /**
2638
2636
  * Abstract Real-time Events API
2639
- * Handle WebSocket/SSE connections and real-time event subscriptions
2637
+ * Handle WebSocket/SSE event subscriptions for conversation domain updates
2640
2638
  */
2641
2639
 
2642
- /**
2643
- * Connection options
2644
- */
2645
- interface AXConversationConnectionOptions {
2646
- /** WebSocket/SSE endpoint URL */
2647
- url?: string;
2648
- /** Authentication token */
2649
- token?: string;
2650
- /** Reconnect automatically on disconnect */
2651
- autoReconnect?: boolean;
2652
- /** Reconnect delay in milliseconds */
2653
- reconnectDelay?: number;
2654
- /** Maximum reconnect attempts */
2655
- maxReconnectAttempts?: number;
2656
- /** Heartbeat interval in milliseconds */
2657
- heartbeatInterval?: number;
2658
- /** Custom headers */
2659
- headers?: Record<string, string>;
2660
- }
2661
- /**
2662
- * Connection event
2663
- */
2664
- interface AXConversationConnectionEvent {
2665
- /** Event type */
2666
- type: 'connected' | 'disconnected' | 'reconnecting' | 'error';
2667
- /** Timestamp */
2668
- timestamp: Date;
2669
- /** Error message if applicable */
2670
- error?: string;
2671
- /** Attempt number for reconnecting */
2672
- attempt?: number;
2673
- }
2674
- /**
2675
- * Notification event
2676
- */
2677
- interface AXConversationNotificationEvent {
2678
- /** Notification ID */
2679
- id: string;
2680
- /** Notification type */
2681
- type: 'message' | 'mention' | 'reaction' | 'call' | 'system';
2682
- /** Title */
2683
- title: string;
2684
- /** Body text */
2685
- body: string;
2686
- /** Related conversation ID */
2687
- conversationId?: string;
2688
- /** Related message ID */
2689
- messageId?: string;
2690
- /** Icon URL */
2691
- icon?: string;
2692
- /** Timestamp */
2693
- timestamp: Date;
2694
- /** Custom data */
2695
- data?: Record<string, unknown>;
2696
- }
2697
- /**
2698
- * Call event
2699
- */
2700
- interface AXConversationCallEvent {
2701
- /** Call ID */
2702
- callId: string;
2703
- /** Call type */
2704
- type: 'voice' | 'video';
2705
- /** Call status */
2706
- status: 'incoming' | 'outgoing' | 'accepted' | 'rejected' | 'ended' | 'missed';
2707
- /** Caller user ID */
2708
- callerId: string;
2709
- /** Conversation ID */
2710
- conversationId: string;
2711
- /** Timestamp */
2712
- timestamp: Date;
2713
- /** Call duration in seconds (for ended calls) */
2714
- duration?: number;
2715
- }
2716
2640
  /**
2717
2641
  * Abstract Real-time Events API
2718
2642
  *
2719
- * Implement this abstract class to handle real-time event subscriptions.
2720
- * Supports WebSocket, SSE, or any other real-time protocol.
2643
+ * Implement this abstract class to expose domain event streams from your WebSocket/SSE layer.
2644
+ * Connection lifecycle is owned by the implementation — this contract only covers subscriptions.
2645
+ *
2646
+ * Covered domains: message CRUD, conversation (room) CRUD, typing indicators, and presence.
2647
+ * Message updates include edits, reactions, delivery/read status, and other message field changes.
2721
2648
  *
2722
2649
  * @example
2723
2650
  * ```typescript
2724
2651
  * @Injectable()
2725
2652
  * export class MyRealtimeApi extends AXConversationRealtimeApi {
2726
- * private socket: WebSocket;
2727
- * private connectionStatus$ = new BehaviorSubject<AXConversationConnectionStatus>('disconnected');
2653
+ * private readonly messageCreated$ = new Subject<AXConversationMessage>();
2728
2654
  *
2729
- * async connect(options?: AXConversationConnectionOptions): Promise<void> {
2730
- * this.socket = new WebSocket(options?.url || 'ws://localhost:3000');
2731
- * this.socket.onopen = () => this.connectionStatus$.next('connected');
2732
- * // ... handle other events
2655
+ * constructor(private readonly socket: MyChatSocketService) {
2656
+ * super();
2657
+ * this.socket.on('message.created', (message) => this.messageCreated$.next(message));
2733
2658
  * }
2734
2659
  *
2735
2660
  * subscribeToMessages(conversationId: string): Observable<AXConversationMessage> {
2736
- * return new Observable(subscriber => {
2737
- * this.socket.addEventListener('message', (event) => {
2738
- * const data = JSON.parse(event.data);
2739
- * if (data.type === 'message' && data.conversationId === conversationId) {
2740
- * subscriber.next(data.message);
2741
- * }
2742
- * });
2743
- * });
2661
+ * return this.messageCreated$.pipe(
2662
+ * filter((message) => !conversationId || message.conversationId === conversationId),
2663
+ * );
2744
2664
  * }
2745
2665
  *
2746
2666
  * // ... implement other methods
@@ -2748,41 +2668,6 @@ interface AXConversationCallEvent {
2748
2668
  * ```
2749
2669
  */
2750
2670
  declare abstract class AXConversationRealtimeApi {
2751
- /**
2752
- * Current connection status
2753
- * Emit connection status changes through this observable
2754
- */
2755
- abstract readonly connectionStatus$: Observable<AXConversationConnectionStatus>;
2756
- /**
2757
- * Connect to real-time server
2758
- * Establish WebSocket/SSE connection
2759
- *
2760
- * @param options - Connection options
2761
- * @throws {Error} If connection fails
2762
- */
2763
- abstract connect(options?: AXConversationConnectionOptions): Promise<void>;
2764
- /**
2765
- * Disconnect from real-time server
2766
- * Close connection and clean up resources
2767
- */
2768
- abstract disconnect(): Promise<void>;
2769
- /**
2770
- * Check if currently connected
2771
- *
2772
- * @returns True if connected
2773
- */
2774
- abstract isConnected(): boolean;
2775
- /**
2776
- * Reconnect to server
2777
- * Manually trigger reconnection
2778
- */
2779
- abstract reconnect(): Promise<void>;
2780
- /**
2781
- * Subscribe to connection events
2782
- *
2783
- * @returns Observable of connection events
2784
- */
2785
- abstract subscribeToConnectionEvents(): Observable<AXConversationConnectionEvent>;
2786
2671
  /**
2787
2672
  * Subscribe to new messages in a conversation
2788
2673
  *
@@ -2791,7 +2676,7 @@ declare abstract class AXConversationRealtimeApi {
2791
2676
  */
2792
2677
  abstract subscribeToMessages(conversationId: string): Observable<AXConversationMessage>;
2793
2678
  /**
2794
- * Subscribe to message updates (edits, status changes)
2679
+ * Subscribe to message updates (edits, reactions, status changes, metadata, etc.)
2795
2680
  *
2796
2681
  * @param conversationId - Optional conversation ID to filter
2797
2682
  * @returns Observable stream of updated messages
@@ -2805,15 +2690,32 @@ declare abstract class AXConversationRealtimeApi {
2805
2690
  */
2806
2691
  abstract subscribeToMessageDeletions(conversationId?: string): Observable<string>;
2807
2692
  /**
2808
- * Subscribe to message reactions
2693
+ * Subscribe to message status changes
2694
+ * Fires when message status changes (sending -> sent -> delivered -> read)
2695
+ *
2696
+ * @param conversationId - Optional conversation ID to filter
2697
+ * @returns Observable stream of message status updates
2698
+ */
2699
+ abstract subscribeToMessageStatusChanges(conversationId?: string): Observable<{
2700
+ messageId: string;
2701
+ status: 'sending' | 'sent' | 'delivered' | 'read' | 'failed';
2702
+ timestamp: Date;
2703
+ }>;
2704
+ /**
2705
+ * Subscribe to read receipt updates
2706
+ * Fires when someone reads messages
2809
2707
  *
2810
2708
  * @param conversationId - Optional conversation ID to filter
2811
- * @returns Observable stream of updated messages with reactions
2709
+ * @returns Observable stream of message IDs that were read
2812
2710
  */
2813
- abstract subscribeToMessageReactions(conversationId?: string): Observable<AXConversationMessage>;
2711
+ abstract subscribeToReadReceipts(conversationId?: string): Observable<{
2712
+ messageId: string;
2713
+ userId: string;
2714
+ readAt: Date;
2715
+ }>;
2814
2716
  /**
2815
2717
  * Subscribe to conversation updates
2816
- * Fires when conversation details change (title, avatar, participants, etc.)
2718
+ * Fires when conversation details change (title, avatar, participants, last message, etc.)
2817
2719
  *
2818
2720
  * @returns Observable stream of updated conversations
2819
2721
  */
@@ -2846,97 +2748,6 @@ declare abstract class AXConversationRealtimeApi {
2846
2748
  * @returns Observable stream of presence updates
2847
2749
  */
2848
2750
  abstract subscribeToPresenceUpdates(userIds?: string[]): Observable<AXConversationPresenceUpdate>;
2849
- /**
2850
- * Subscribe to read receipt updates
2851
- * Fires when someone reads messages
2852
- *
2853
- * @param conversationId - Optional conversation ID to filter
2854
- * @returns Observable stream of message IDs that were read
2855
- */
2856
- abstract subscribeToReadReceipts(conversationId?: string): Observable<{
2857
- messageId: string;
2858
- userId: string;
2859
- readAt: Date;
2860
- }>;
2861
- /**
2862
- * Subscribe to push notifications
2863
- * Fires for mentions, calls, and other important events
2864
- *
2865
- * @returns Observable stream of notification events
2866
- */
2867
- abstract subscribeToNotifications(): Observable<AXConversationNotificationEvent>;
2868
- /**
2869
- * Subscribe to call events
2870
- * Fires for incoming/outgoing calls
2871
- *
2872
- * @returns Observable stream of call events
2873
- */
2874
- abstract subscribeToCallEvents?(): Observable<AXConversationCallEvent>;
2875
- /**
2876
- * Subscribe to user blocked/unblocked events
2877
- *
2878
- * @returns Observable stream of user IDs and block status
2879
- */
2880
- abstract subscribeToUserBlockEvents(): Observable<{
2881
- userId: string;
2882
- blocked: boolean;
2883
- }>;
2884
- /**
2885
- * Subscribe to participant added/removed events
2886
- *
2887
- * @param conversationId - Optional conversation ID to filter
2888
- * @returns Observable stream of participant changes
2889
- */
2890
- abstract subscribeToParticipantEvents(conversationId?: string): Observable<{
2891
- conversationId: string;
2892
- userId: string;
2893
- action: 'added' | 'removed';
2894
- }>;
2895
- /**
2896
- * Subscribe to system events
2897
- * Fires for maintenance, updates, or other system-wide events
2898
- *
2899
- * @returns Observable stream of system events
2900
- */
2901
- abstract subscribeToSystemEvents(): Observable<{
2902
- type: string;
2903
- message: string;
2904
- data?: unknown;
2905
- }>;
2906
- /**
2907
- * Subscribe to message status changes
2908
- * Fires when message status changes (sending -> sent -> delivered -> read)
2909
- *
2910
- * @param conversationId - Optional conversation ID to filter
2911
- * @returns Observable stream of message status updates
2912
- */
2913
- abstract subscribeToMessageStatusChanges(conversationId?: string): Observable<{
2914
- messageId: string;
2915
- status: 'sending' | 'sent' | 'delivered' | 'read' | 'failed';
2916
- timestamp: Date;
2917
- }>;
2918
- /**
2919
- * Subscribe to conversation settings changes
2920
- * Fires when conversation settings are updated
2921
- *
2922
- * @param conversationId - Optional conversation ID to filter
2923
- * @returns Observable stream of settings updates
2924
- */
2925
- abstract subscribeToConversationSettingsChanges(conversationId?: string): Observable<{
2926
- conversationId: string;
2927
- settings: Record<string, unknown>;
2928
- }>;
2929
- /**
2930
- * Subscribe to draft changes
2931
- * Fires when draft is saved/updated in a conversation
2932
- *
2933
- * @param conversationId - Optional conversation ID to filter
2934
- * @returns Observable stream of draft updates
2935
- */
2936
- abstract subscribeToDraftChanges(conversationId?: string): Observable<{
2937
- conversationId: string;
2938
- draft: string | null;
2939
- }>;
2940
2751
  }
2941
2752
 
2942
2753
  /**
@@ -3016,7 +2827,7 @@ declare abstract class AXConversationUserApi {
3016
2827
  * @returns Current user information
3017
2828
  * @throws {AXConversationApiError} If user is not authenticated
3018
2829
  */
3019
- abstract getCurrentUser(): Promise<AXConversationParticipant>;
2830
+ abstract getCurrentUser(): Promise<AXConversationUser>;
3020
2831
  /**
3021
2832
  * Update current user profile
3022
2833
  *
@@ -3024,7 +2835,7 @@ declare abstract class AXConversationUserApi {
3024
2835
  * @returns Updated user information
3025
2836
  * @throws {AXConversationApiError} If update fails
3026
2837
  */
3027
- abstract updateProfile(updates: AXConversationUserProfileUpdate): Promise<AXConversationParticipant>;
2838
+ abstract updateProfile(updates: AXConversationUserProfileUpdate): Promise<AXConversationUser>;
3028
2839
  /**
3029
2840
  * Upload user avatar
3030
2841
  *
@@ -3074,6 +2885,10 @@ declare abstract class AXConversationUserApi {
3074
2885
  * @throws {AXConversationApiError} If request fails
3075
2886
  */
3076
2887
  abstract getUserPresence(userId: string): Promise<AXConversationPresenceUpdate>;
2888
+ /**
2889
+ * Get presence for multiple users (bulk hydration).
2890
+ */
2891
+ abstract getUsersPresence(userIds: string[]): Promise<AXConversationPresenceUpdate[]>;
3077
2892
  /**
3078
2893
  * Update current user presence
3079
2894
  *
@@ -3126,6 +2941,18 @@ declare abstract class AXConversationUserApi {
3126
2941
  * @throws {AXConversationApiError} If update fails
3127
2942
  */
3128
2943
  abstract updateUserSettings(settings: Record<string, unknown>): Promise<void>;
2944
+ /**
2945
+ * Get all conversation preferences for the current user.
2946
+ */
2947
+ abstract getConversationPreferences(): Promise<AXConversationRoomPreferencesMap>;
2948
+ /**
2949
+ * Get preferences for a single conversation.
2950
+ */
2951
+ abstract getConversationPreferencesForRoom(conversationId: string): Promise<AXConversationRoomPreferences>;
2952
+ /**
2953
+ * Update preferences for a conversation (current user's view).
2954
+ */
2955
+ abstract updateConversationPreferences(conversationId: string, preferences: Partial<AXConversationRoomPreferences>): Promise<AXConversationRoomPreferences>;
3129
2956
  /**
3130
2957
  * Create an API error
3131
2958
  * Helper method for consistent error creation
@@ -3139,6 +2966,27 @@ declare abstract class AXConversationUserApi {
3139
2966
  protected createError(code: string, message: string, statusCode?: number, details?: unknown): AXConversationApiError;
3140
2967
  }
3141
2968
 
2969
+ type AXConversationComposerGenerationPhase = 'idle' | 'generating' | 'stopping';
2970
+ declare class AXConversationComposerGenerationStateService {
2971
+ private readonly _phase;
2972
+ private readonly _cancelled$;
2973
+ /** Current generation lifecycle phase. */
2974
+ readonly phase: _angular_core.Signal<AXConversationComposerGenerationPhase>;
2975
+ /** Whether a background generation (e.g. AI response) is in progress. */
2976
+ readonly isGenerating: _angular_core.Signal<boolean>;
2977
+ /** Whether generation is being cancelled (spinner / locked until API finishes). */
2978
+ readonly isStopping: _angular_core.Signal<boolean>;
2979
+ /** Whether generation or stop-cleanup is in progress. */
2980
+ readonly isBusy: _angular_core.Signal<boolean>;
2981
+ /** Emits when the user presses the composer cancel/stop button. */
2982
+ readonly onCancelled: rxjs.Observable<void>;
2983
+ setGenerating(value: boolean): void;
2984
+ /** User requested cancel — enters `stopping` until {@link setGenerating}(false) is called. */
2985
+ cancel(): void;
2986
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<AXConversationComposerGenerationStateService, never>;
2987
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<AXConversationComposerGenerationStateService>;
2988
+ }
2989
+
3142
2990
  /**
3143
2991
  * Central Registry Service
3144
2992
  * Provides unified access to all registries
@@ -3205,14 +3053,20 @@ declare class AXConversationService {
3205
3053
  private readonly destroy$;
3206
3054
  /** Registry service - exposed for child services */
3207
3055
  readonly registry: AXConversationRegistryService;
3056
+ private readonly composerGenerationState;
3057
+ /** Whether the composer primary button is in cancel (generation) mode. */
3058
+ readonly isGenerating: _angular_core.Signal<boolean>;
3059
+ /** Whether cancel cleanup is in progress. */
3060
+ readonly isStopping: _angular_core.Signal<boolean>;
3061
+ /** Emits when the user cancels an in-progress generation from the composer. */
3062
+ readonly onGenerationCancelled: rxjs.Observable<void>;
3208
3063
  private readonly _activeConversationId;
3209
3064
  private readonly _loading;
3210
3065
  private readonly _loadingActiveMessages;
3066
+ private readonly _isForwardingMessage;
3211
3067
  private readonly _error;
3212
3068
  private readonly _conversationsPagination;
3213
3069
  private readonly _messagesPaginationByConversation;
3214
- /** Emits when the active conversation changes, cancelling per-conversation subscriptions. */
3215
- private readonly _conversationSwitch$;
3216
3070
  private readonly _messageReceived$;
3217
3071
  private readonly _messageUpdated$;
3218
3072
  private readonly _messageDeleted$;
@@ -3230,14 +3084,14 @@ declare class AXConversationService {
3230
3084
  readonly loading: _angular_core.Signal<boolean>;
3231
3085
  /** Loading state for the active conversation's message history */
3232
3086
  readonly loadingActiveMessages: _angular_core.Signal<boolean>;
3087
+ /** Whether a message forward operation is in progress. */
3088
+ readonly isForwardingMessage: _angular_core.Signal<boolean>;
3233
3089
  /** Sidebar conversation list pagination */
3234
3090
  readonly conversationsPagination: _angular_core.Signal<AXConversationPaginationState>;
3235
3091
  /** Active conversation message pagination */
3236
3092
  readonly activeMessagesPagination: _angular_core.Signal<AXConversationPaginationState>;
3237
3093
  /** Error state */
3238
3094
  readonly error: _angular_core.Signal<Error>;
3239
- /** Connection status */
3240
- readonly connectionStatus$: rxjs.Observable<_acorex_components_conversation.AXConversationConnectionStatus>;
3241
3095
  /** Error stream */
3242
3096
  readonly errors$: rxjs.Observable<_acorex_components_conversation.AXConversationError>;
3243
3097
  readonly onMessageReceived: rxjs.Observable<AXConversationMessage>;
@@ -3246,7 +3100,10 @@ declare class AXConversationService {
3246
3100
  readonly onTypingIndicator: rxjs.Observable<AXConversationTypingIndicator>;
3247
3101
  readonly onPresenceChange: rxjs.Observable<AXConversationPresenceUpdate>;
3248
3102
  private _currentUser;
3249
- readonly currentUser: _angular_core.Signal<_acorex_components_conversation.AXConversationParticipant>;
3103
+ readonly currentUser: _angular_core.Signal<AXConversationUser>;
3104
+ readonly userPresenceMap: _angular_core.Signal<Map<string, AXConversationUserPresence>>;
3105
+ readonly presenceTimeTick: _angular_core.Signal<Map<string, AXConversationUserPresence>>;
3106
+ readonly typingRevision: _angular_core.Signal<Map<string, Map<string, number>>>;
3250
3107
  /** One-time async initialization (connect, user, conversations, realtime). */
3251
3108
  private initPromise;
3252
3109
  /** Generation counter — stale page-0 loads are ignored after conversation switches. */
@@ -3256,6 +3113,12 @@ declare class AXConversationService {
3256
3113
  /** Batched read-receipt queue keyed by conversation ID. */
3257
3114
  private readonly readQueue;
3258
3115
  private readFlushHandle;
3116
+ private presenceTickHandle?;
3117
+ private typingPruneHandle?;
3118
+ /** Outgoing typing indicator throttle state (composer -> API). */
3119
+ private readonly outgoingTypingLastEmitAt;
3120
+ private readonly outgoingTypingActive;
3121
+ private readonly outgoingTypingStopHandles;
3259
3122
  /** Session cache for available reaction emojis. */
3260
3123
  private availableReactionsCache;
3261
3124
  private availableReactionsPromise;
@@ -3275,10 +3138,18 @@ declare class AXConversationService {
3275
3138
  */
3276
3139
  private initializeService;
3277
3140
  /**
3278
- * Subscribe to real-time events
3279
- * All subscriptions include error handling to prevent stream termination
3141
+ * Subscribe to real-time events from {@link AXConversationRealtimeApi}.
3142
+ * Binds every abstract subscription: messages (create/update/delete/status/read),
3143
+ * conversations (create/update/delete), typing indicators, and presence.
3280
3144
  */
3281
3145
  private subscribeToEvents;
3146
+ getUserPresence(userId: string): AXConversationUserPresence | undefined;
3147
+ getRoomPreferences(conversationId: string): AXConversationRoomPreferences;
3148
+ isAnyoneTyping(conversationId: string): boolean;
3149
+ getActiveTypingUserIds(conversationId: string): string[];
3150
+ getPeerPresence(conversation: AXConversation): AXConversationUserPresence | undefined;
3151
+ private hydrateUserPresence;
3152
+ private loadRoomPreferences;
3282
3153
  /**
3283
3154
  * Load conversations from server
3284
3155
  * Includes comprehensive error handling
@@ -3311,6 +3182,7 @@ declare class AXConversationService {
3311
3182
  * Resolve a media reference to a playback/download URL.
3312
3183
  */
3313
3184
  resolveMediaUrl(reference: AXConversationUploaderReference, signal?: AbortSignal): Promise<string>;
3185
+ private resolveReplyTo;
3314
3186
  /**
3315
3187
  * Send a message
3316
3188
  * Uses optimistic UI updates - message appears immediately
@@ -3361,11 +3233,33 @@ declare class AXConversationService {
3361
3233
  * Marks messages locally and syncs with server
3362
3234
  */
3363
3235
  markAsRead(conversationId: string): Promise<void>;
3236
+ /**
3237
+ * Set composer generation mode (shows cancel button instead of send/voice).
3238
+ * Call from message APIs while an AI or async response is in progress.
3239
+ */
3240
+ setGenerating(value: boolean): void;
3241
+ /**
3242
+ * Cancel an in-progress generation from the composer UI or programmatically.
3243
+ */
3244
+ cancelGeneration(): void;
3245
+ /**
3246
+ * Notify that the composer has draft content.
3247
+ * Emits typing indicators at most once per {@link AXConversationConfig.typingIndicatorThrottle}.
3248
+ */
3249
+ notifyComposerTyping(conversationId: string): void;
3250
+ /**
3251
+ * Notify that the composer no longer has draft content (or user left the chat).
3252
+ * Sends a single stop event when a typing indicator was previously emitted.
3253
+ */
3254
+ notifyComposerStoppedTyping(conversationId: string): void;
3255
+ private scheduleOutgoingTypingStop;
3256
+ private clearOutgoingTypingStop;
3364
3257
  /**
3365
3258
  * Send typing indicator
3366
3259
  * Non-critical operation, doesn't throw on failure
3367
3260
  */
3368
3261
  sendTypingIndicator(conversationId: string): Promise<void>;
3262
+ stopTypingIndicator(conversationId: string): Promise<void>;
3369
3263
  /**
3370
3264
  * Search conversations
3371
3265
  * Returns empty array on failure
@@ -3401,15 +3295,24 @@ declare class AXConversationService {
3401
3295
  * Updates conversation metadata including unread count, last message, etc.
3402
3296
  */
3403
3297
  private handleConversationUpdate;
3298
+ private handleConversationCreated;
3299
+ private handleConversationDeleted;
3300
+ private handleReadReceipt;
3301
+ private handleMessageStatusChange;
3404
3302
  /**
3405
3303
  * Insert or refresh a conversation in the in-memory inbox.
3406
3304
  * @param promote When true, bumps activity so the chat sorts to the top (create / reopen).
3407
3305
  */
3408
3306
  private syncConversationToInbox;
3307
+ private finalizeSentMessage;
3409
3308
  /**
3410
3309
  * Update conversation's last message
3411
3310
  */
3412
3311
  private updateConversationLastMessage;
3312
+ /** Keep sidebar preview in sync when the last cached message is edited or deleted. */
3313
+ private syncLastMessageIfRelevant;
3314
+ /** Recompute conversation preview after a message is removed from the local cache. */
3315
+ private refreshConversationLastMessage;
3413
3316
  /**
3414
3317
  * Update conversation properties
3415
3318
  * @param conversationId - Conversation ID
@@ -3421,7 +3324,7 @@ declare class AXConversationService {
3421
3324
  * @param conversationId - Conversation ID
3422
3325
  * @param settings - Partial settings to update
3423
3326
  */
3424
- updateConversationSettings(conversationId: string, settings: Partial<AXConversation['settings']>): Promise<void>;
3327
+ updateConversationSettings(conversationId: string, settings: Partial<AXConversationRoomPreferences>): Promise<void>;
3425
3328
  /**
3426
3329
  * Update conversation title
3427
3330
  * @param conversationId - Conversation ID
@@ -3481,11 +3384,6 @@ declare class AXConversationService {
3481
3384
  * @returns Number of times forwarded
3482
3385
  */
3483
3386
  getForwardCount(messageId: string): Promise<number>;
3484
- /**
3485
- * Disconnect and cleanup
3486
- * Cleanly closes all connections and resources
3487
- */
3488
- disconnect(): Promise<void>;
3489
3387
  /**
3490
3388
  * Archive conversation
3491
3389
  * @param conversationId - Conversation ID
@@ -3564,6 +3462,10 @@ declare class AXConversationService {
3564
3462
  * @param caption - Optional caption
3565
3463
  */
3566
3464
  forwardMessage(messageId: string, conversationIds: string[], caption?: string): Promise<void>;
3465
+ /**
3466
+ * Runs a forward operation while locking all forward actions until it completes.
3467
+ */
3468
+ runWithForwardingLock<T>(task: () => Promise<T>): Promise<T>;
3567
3469
  /**
3568
3470
  * Search messages in conversation
3569
3471
  * @param conversationId - Conversation ID
@@ -3618,7 +3520,7 @@ declare class AXConversationService {
3618
3520
  * @param status - Presence status
3619
3521
  * @param statusText - Optional status text
3620
3522
  */
3621
- updatePresence(status: 'online' | 'offline' | 'away' | 'busy' | 'invisible', statusText?: string): Promise<void>;
3523
+ updatePresence(status: AXConversationPresenceStatus, statusText?: string): Promise<void>;
3622
3524
  /**
3623
3525
  * Validate message content before sending
3624
3526
  * Uses centralized validation utilities for consistency
@@ -3766,6 +3668,7 @@ declare class AXConversationForwardMessageDialogComponent implements OnInit {
3766
3668
  readonly forwardListEmptyTpl: _angular_core.Signal<TemplateRef<unknown>>;
3767
3669
  readonly forwardList: _angular_core.Signal<AXListComponent>;
3768
3670
  readonly forwardListDataSource: AXDataSource<unknown>;
3671
+ readonly isForwarding: _angular_core.Signal<boolean>;
3769
3672
  readonly canForward: _angular_core.Signal<boolean>;
3770
3673
  private readonly _syncPopupTitleEffect;
3771
3674
  ngOnInit(): void;
@@ -3800,12 +3703,15 @@ declare class AXConversationMessageListComponent implements OnDestroy {
3800
3703
  private readonly translation;
3801
3704
  private readonly document;
3802
3705
  private readonly platform;
3706
+ private readonly actionSheetService;
3803
3707
  protected readonly config: Required<_acorex_components_conversation.AXConversationConfig>;
3804
3708
  /**
3805
3709
  * Background for the message list scroll area from config, or the built-in soft wash when unset/empty.
3806
3710
  * Set `messageListBackground` to `transparent` or `none` for a flat look.
3807
3711
  * Supports `{ light, dark }` for theme-specific backgrounds.
3808
3712
  */
3713
+ readonly messageListUsesDefaultWallpaper: _angular_core.Signal<boolean>;
3714
+ readonly messageListWallpaperDark: _angular_core.Signal<boolean>;
3809
3715
  readonly messageListBackgroundStyle: _angular_core.Signal<string>;
3810
3716
  resolvedEmptyStateComponent(): Type<AXConversationMessageListEmptyComponent>;
3811
3717
  /** Fallback when no conversation is active and no `ax-conversation-message-list-no-active` content is projected. */
@@ -3819,8 +3725,11 @@ declare class AXConversationMessageListComponent implements OnDestroy {
3819
3725
  readonly contextMenuMessageId: _angular_core.WritableSignal<string>;
3820
3726
  /** True while files are dragged over the message list drop zone. */
3821
3727
  readonly messageListDragging: _angular_core.WritableSignal<boolean>;
3728
+ /** True when the message list uses single-column adaptive layout (matches CSS container query). */
3729
+ readonly isAdaptiveWideLayout: _angular_core.WritableSignal<boolean>;
3822
3730
  /** While true, older history is being prepended — do not auto-scroll to the latest message. */
3823
3731
  private restoringScrollAfterPrepend;
3732
+ private adaptiveLayoutResizeObserver?;
3824
3733
  readonly availableReactions: _angular_core.WritableSignal<string[]>;
3825
3734
  private reactionsLoading;
3826
3735
  private get registry();
@@ -3838,6 +3747,9 @@ declare class AXConversationMessageListComponent implements OnDestroy {
3838
3747
  readonly showScrollButton: _angular_core.WritableSignal<boolean>;
3839
3748
  /** Active conversation */
3840
3749
  readonly activeConversation: _angular_core.Signal<_acorex_components_conversation.AXConversation>;
3750
+ readonly isGroupConversation: _angular_core.Signal<boolean>;
3751
+ /** Placeholder indices for the initial message list skeleton. */
3752
+ protected readonly loadingSkeletonItems: readonly [0, 1, 2, 3, 4, 5];
3841
3753
  /** Whether the active conversation allows message reactions. */
3842
3754
  readonly reactionsEnabled: _angular_core.Signal<boolean>;
3843
3755
  /** Messages */
@@ -3848,7 +3760,7 @@ declare class AXConversationMessageListComponent implements OnDestroy {
3848
3760
  action: string;
3849
3761
  }>;
3850
3762
  /** Current user from service */
3851
- readonly currentUser: _angular_core.Signal<_acorex_components_conversation.AXConversationParticipant>;
3763
+ readonly currentUser: _angular_core.Signal<_acorex_components_conversation.AXConversationUser>;
3852
3764
  /** Message grouped by date - use service */
3853
3765
  readonly messageGroups: _angular_core.Signal<{
3854
3766
  date: string;
@@ -3857,6 +3769,7 @@ declare class AXConversationMessageListComponent implements OnDestroy {
3857
3769
  }[]>;
3858
3770
  constructor();
3859
3771
  private intersectionObserver?;
3772
+ private readonly readIntersectionObserver;
3860
3773
  private readonly observedReadMessageIds;
3861
3774
  /**
3862
3775
  * Setup intersection observer to mark messages as read when visible
@@ -3872,8 +3785,8 @@ declare class AXConversationMessageListComponent implements OnDestroy {
3872
3785
  getBubbleClasses(message: AXConversationMessage): string;
3873
3786
  /** Check if message is from current user */
3874
3787
  isOwnMessage(message: AXConversationMessage): boolean;
3875
- /** Should show avatar */
3876
- shouldShowAvatar(message: AXConversationMessage): boolean;
3788
+ /** Whether the avatar slot is rendered (visibility is CSS-controlled per layout mode). */
3789
+ shouldRenderAvatar(message: AXConversationMessage): boolean;
3877
3790
  /** Should show sender name */
3878
3791
  shouldShowSenderName(message: AXConversationMessage): boolean;
3879
3792
  /** Get sender name */
@@ -3885,6 +3798,7 @@ declare class AXConversationMessageListComponent implements OnDestroy {
3885
3798
  /** Resolve renderer component for message */
3886
3799
  getRendererComponent(message: AXConversationMessage): Type<_acorex_components_conversation.AXConversationMessageRendererComponent>;
3887
3800
  /** Resolve lazy renderer loader for message */
3801
+ private static readonly fallbackRendererLoader;
3888
3802
  getRendererComponentLoader(message: AXConversationMessage): (() => Promise<Type<_acorex_components_conversation.AXConversationMessageRendererComponent>>) | (() => Promise<typeof _acorex_components_conversation.AXConversationFallbackRendererComponent>);
3889
3803
  /** Provide inputs for the dynamic renderer */
3890
3804
  getRendererInputs(message: AXConversationMessage): {
@@ -3977,19 +3891,6 @@ declare class AXConversationMessageListComponent implements OnDestroy {
3977
3891
  handleMessageContextMenuOpening(event: AXContextMenuOpeningEvent, message: AXConversationMessage): void;
3978
3892
  /** Handle context menu item click for messages */
3979
3893
  handleMessageContextMenuItemClick(event: AXContextMenuItemsClickEvent, message: AXConversationMessage): void;
3980
- /**
3981
- * TrackBy function for message groups.
3982
- * Include the latest message id so new messages in the same date group re-render.
3983
- */
3984
- trackMessageGroup(index: number, group: {
3985
- date: string;
3986
- messages: AXConversationMessage[];
3987
- }): string;
3988
- /**
3989
- * TrackBy function for messages
3990
- * Tracks by ID only to prevent unnecessary re-renders
3991
- */
3992
- trackMessage(index: number, message: AXConversationMessage): string;
3993
3894
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<AXConversationMessageListComponent, never>;
3994
3895
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<AXConversationMessageListComponent, "ax-conversation-message-list", never, {}, { "messageAction": "messageAction"; }, never, ["ax-conversation-message-list-empty, [ax-conversation-message-list-empty]", "ax-conversation-message-list-no-active, [ax-conversation-message-list-no-active]"], true, never>;
3995
3896
  }
@@ -3999,7 +3900,7 @@ declare class AXConversationMessageListService {
3999
3900
  private get registry();
4000
3901
  readonly activeConversation: _angular_core.Signal<_acorex_components_conversation.AXConversation>;
4001
3902
  readonly activeMessages: _angular_core.Signal<AXConversationMessage[]>;
4002
- readonly currentUser: _angular_core.Signal<_acorex_components_conversation.AXConversationParticipant>;
3903
+ readonly currentUser: _angular_core.Signal<_acorex_components_conversation.AXConversationUser>;
4003
3904
  /** Initial message history load (conversation switch) */
4004
3905
  readonly loading: _angular_core.Signal<boolean>;
4005
3906
  /** Loading older messages (scroll-up pagination) */
@@ -4049,6 +3950,103 @@ declare class AXConversationMessageListService {
4049
3950
  static ɵprov: _angular_core.ɵɵInjectableDeclaration<AXConversationMessageListService>;
4050
3951
  }
4051
3952
 
3953
+ declare class AXConversationAvatarPickerComponent {
3954
+ readonly fileInput: _angular_core.Signal<ElementRef<HTMLInputElement>>;
3955
+ readonly showClearButton: _angular_core.InputSignal<boolean>;
3956
+ readonly avatarUrl: _angular_core.ModelSignal<string>;
3957
+ readonly onFileSelected: _angular_core.OutputEmitterRef<string>;
3958
+ triggerFileInput(): void;
3959
+ onFileInputChange(event: Event): Promise<void>;
3960
+ clearAvatar(): void;
3961
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<AXConversationAvatarPickerComponent, never>;
3962
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<AXConversationAvatarPickerComponent, "ax-conversation-avatar-picker", never, { "showClearButton": { "alias": "showClearButton"; "required": false; "isSignal": true; }; "avatarUrl": { "alias": "avatarUrl"; "required": false; "isSignal": true; }; }, { "avatarUrl": "avatarUrlChange"; "onFileSelected": "onFileSelected"; }, never, never, true, never>;
3963
+ }
3964
+
3965
+ /**
3966
+ * Pluggable avatar components for the conversation UI.
3967
+ * Register via `provideConversation({ avatarComponents: { user, conversation } })`.
3968
+ * When only `user` is registered, a built-in conversation avatar host is wired automatically.
3969
+ */
3970
+
3971
+ /** Custom user avatar (e.g. platform `axp-user-avatar`). */
3972
+ interface AXConversationUserAvatarComponent {
3973
+ readonly userId: InputSignal<string>;
3974
+ readonly size: InputSignal<number>;
3975
+ /** Optional resolved display name (e.g. bot/assist peer title). */
3976
+ readonly displayName?: InputSignal<string | undefined>;
3977
+ /** Optional resolved avatar URL when `userId` is not a platform user row. */
3978
+ readonly displayAvatar?: InputSignal<string | undefined>;
3979
+ /** Optional icon class when no avatar image is available. */
3980
+ readonly displayIcon?: InputSignal<string | undefined>;
3981
+ }
3982
+ /** Optional custom group/channel conversation avatar. */
3983
+ interface AXConversationConversationAvatarComponent {
3984
+ readonly conversationId: InputSignal<string>;
3985
+ readonly size: InputSignal<number>;
3986
+ /** Optional resolved display name for the conversation. */
3987
+ readonly displayName?: InputSignal<string | undefined>;
3988
+ /** Optional resolved avatar URL when no platform conversation row exists. */
3989
+ readonly displayAvatar?: InputSignal<string | undefined>;
3990
+ /** Optional icon class when no avatar image is available. */
3991
+ readonly displayIcon?: InputSignal<string | undefined>;
3992
+ }
3993
+ type AXConversationAvatarKind = 'user' | 'conversation' | 'auto';
3994
+ declare const AX_CONVERSATION_USER_AVATAR_COMPONENT: InjectionToken<Type<AXConversationUserAvatarComponent>>;
3995
+ declare const AX_CONVERSATION_CONVERSATION_AVATAR_COMPONENT: InjectionToken<Type<AXConversationConversationAvatarComponent>>;
3996
+ interface AXConversationAvatarComponents {
3997
+ user?: Type<AXConversationUserAvatarComponent>;
3998
+ conversation?: Type<AXConversationConversationAvatarComponent>;
3999
+ }
4000
+
4001
+ declare class AXConversationAvatarComponent {
4002
+ private readonly conversationService;
4003
+ private readonly userAvatarComponent;
4004
+ private readonly conversationAvatarComponent;
4005
+ readonly kind: _angular_core.InputSignal<AXConversationAvatarKind>;
4006
+ readonly userId: _angular_core.InputSignal<string>;
4007
+ readonly conversation: _angular_core.InputSignal<AXConversation>;
4008
+ readonly message: _angular_core.InputSignal<AXConversationMessage>;
4009
+ readonly size: _angular_core.InputSignal<number>;
4010
+ readonly showStatus: _angular_core.InputSignal<boolean>;
4011
+ readonly name: _angular_core.InputSignal<string>;
4012
+ readonly avatar: _angular_core.InputSignal<string>;
4013
+ readonly icon: _angular_core.InputSignal<string>;
4014
+ private readonly currentUserId;
4015
+ readonly resolvedKind: _angular_core.Signal<"user" | "conversation">;
4016
+ readonly resolvedUserId: _angular_core.Signal<string>;
4017
+ readonly customComponent: _angular_core.Signal<Type<unknown>>;
4018
+ readonly customInputs: _angular_core.Signal<Record<string, unknown>>;
4019
+ readonly filteredCustomInputs: _angular_core.Signal<Record<string, unknown>>;
4020
+ readonly fallbackDisplay: _angular_core.Signal<{
4021
+ name: string;
4022
+ avatar: string;
4023
+ icon: string;
4024
+ }>;
4025
+ readonly fallbackInitials: _angular_core.Signal<string>;
4026
+ readonly resolvedStatus: _angular_core.Signal<_acorex_components_conversation.AXConversationPresenceStatus>;
4027
+ readonly statusBadgePresence: _angular_core.Signal<"online" | "offline" | "away" | "busy">;
4028
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<AXConversationAvatarComponent, never>;
4029
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<AXConversationAvatarComponent, "ax-conversation-avatar", never, { "kind": { "alias": "kind"; "required": false; "isSignal": true; }; "userId": { "alias": "userId"; "required": false; "isSignal": true; }; "conversation": { "alias": "conversation"; "required": false; "isSignal": true; }; "message": { "alias": "message"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "showStatus": { "alias": "showStatus"; "required": false; "isSignal": true; }; "name": { "alias": "name"; "required": false; "isSignal": true; }; "avatar": { "alias": "avatar"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
4030
+ }
4031
+
4032
+ interface AXConversationRegistryComponentRef {
4033
+ component?: Type<unknown>;
4034
+ componentLoader?: () => Promise<Type<unknown>>;
4035
+ }
4036
+ declare class AXConversationRegistryComponentOutletComponent {
4037
+ readonly component: _angular_core.InputSignal<Type<unknown>>;
4038
+ readonly componentLoader: _angular_core.InputSignal<() => Promise<Type<unknown>>>;
4039
+ readonly inputs: _angular_core.InputSignal<Record<string, unknown>>;
4040
+ readonly resolvedComponent: _angular_core.WritableSignal<Type<unknown>>;
4041
+ /** Avoid re-loading when the parent re-binds the same lazy loader reference. */
4042
+ private activeLoader;
4043
+ constructor();
4044
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<AXConversationRegistryComponentOutletComponent, never>;
4045
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<AXConversationRegistryComponentOutletComponent, "ax-conversation-registry-component-outlet", never, { "component": { "alias": "component"; "required": false; "isSignal": true; }; "componentLoader": { "alias": "componentLoader"; "required": false; "isSignal": true; }; "inputs": { "alias": "inputs"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
4046
+ }
4047
+ /** Resolve a registry component reference, preferring lazy loaders when provided. */
4048
+ declare function hasRegistryComponent(ref?: AXConversationRegistryComponentRef): boolean;
4049
+
4052
4050
  declare class AXConversationSidebarService {
4053
4051
  private readonly conversationService;
4054
4052
  constructor();
@@ -4103,6 +4101,8 @@ declare class AXConversationSidebarComponent implements OnDestroy {
4103
4101
  readonly loading: _angular_core.Signal<boolean>;
4104
4102
  readonly loadingMore: _angular_core.WritableSignal<boolean>;
4105
4103
  readonly hasMoreConversations: _angular_core.Signal<boolean>;
4104
+ readonly isSidebarTabsHorizontal: _angular_core.Signal<boolean>;
4105
+ readonly sidebarTabLocation: _angular_core.Signal<AXTabLocation>;
4106
4106
  constructor();
4107
4107
  /** Handle search input change with debouncing */
4108
4108
  onSearchChange(value: string): void;
@@ -4219,6 +4219,12 @@ declare function isComposerTabEnabled(tab: AXConversationComposerTabFeature, fea
4219
4219
  * Conversation Configuration Interface
4220
4220
  * Centralized configuration values to avoid magic numbers
4221
4221
  */
4222
+ /**
4223
+ * Sidebar conversation tabs layout.
4224
+ * - `vertical`: horizontal tab strip above the conversation list.
4225
+ * - `horizontal`: vertical tab strip at inline-start beside the list (`ax-tabs` location `start`).
4226
+ */
4227
+ type AXConversationSidebarTabsOrientation = 'vertical' | 'horizontal';
4222
4228
  /**
4223
4229
  * Main configuration interface for the conversation component
4224
4230
  */
@@ -4233,13 +4239,14 @@ interface AXConversationConfig {
4233
4239
  infiniteScrollThreshold?: number;
4234
4240
  /** Typing indicator timeout in milliseconds */
4235
4241
  typingIndicatorTimeout?: number;
4236
- /** Typing indicator throttle in milliseconds (for rate limiting) */
4242
+ /** Typing indicator emit throttle in milliseconds while composing (default: 3000) */
4237
4243
  typingIndicatorThrottle?: number;
4244
+ /** How long to show received typing indicators in the UI (default: 4000) */
4245
+ typingDisplayDuration?: number;
4238
4246
  /** Message highlight duration in milliseconds */
4239
4247
  messageHighlightDuration?: number;
4240
4248
  /** Search debounce delay in milliseconds */
4241
4249
  debounceSearch?: number;
4242
- /** Date separator inactivity fade delay in milliseconds */
4243
4250
  /** Maximum messages per conversation */
4244
4251
  maxMessagesPerConversation?: number;
4245
4252
  /** Maximum total messages in store */
@@ -4252,8 +4259,11 @@ interface AXConversationConfig {
4252
4259
  maxSidebarWidth?: number;
4253
4260
  /** Default sidebar width in pixels */
4254
4261
  defaultSidebarWidth?: number;
4255
- /** Filter cache size */
4256
- filterCacheSize?: number;
4262
+ /**
4263
+ * Sidebar conversation tabs layout.
4264
+ * `vertical` places a horizontal tab strip above the list; `horizontal` places a vertical tab strip at inline-start beside the list.
4265
+ */
4266
+ sidebarTabsOrientation?: AXConversationSidebarTabsOrientation;
4257
4267
  /** Maximum message length in characters */
4258
4268
  maxMessageLength?: number;
4259
4269
  /** Minimum message length in characters */
@@ -4262,7 +4272,7 @@ interface AXConversationConfig {
4262
4272
  maxFilesPerMessage?: number;
4263
4273
  /** Threshold for marking messages as read (0.0 to 1.0, default: 0.3) */
4264
4274
  messageReadThreshold?: number;
4265
- /** Debounce window (ms) before flushing batched read-receipt API calls (default: 400) */
4275
+ /** Debounce window (ms) before flushing batched read-receipt API calls (default: 3000) */
4266
4276
  messageReadDebounce?: number;
4267
4277
  /**
4268
4278
  * When true, marks the whole conversation as read once when it is selected (single API call).
@@ -4273,7 +4283,7 @@ interface AXConversationConfig {
4273
4283
  * CSS `background` for the message list (`ax-conversation-message-list` area, all states: loading, empty, messages).
4274
4284
  * Use full shorthand, or a bare `https://...` / `/path/to.png` (wrapped as `url(...)` with `center/cover`).
4275
4285
  * Pass a string for the same value in both themes, or `{ light, dark }` for theme-specific backgrounds.
4276
- * Empty string = library default. `transparent` or `none` = flat background.
4286
+ * Empty string = Telegram-inspired theme-aware library default (`{ light, dark }`). `transparent` or `none` = flat background.
4277
4287
  */
4278
4288
  messageListBackground?: AXConversationMessageListBackground;
4279
4289
  /** Optional feature flags to reduce bundle size per app. */
@@ -4283,31 +4293,20 @@ interface AXConversationConfig {
4283
4293
  }
4284
4294
 
4285
4295
  /**
4286
-
4287
4296
  * Default Configuration Values
4288
-
4289
4297
  * Centralized defaults to avoid magic numbers throughout the codebase
4290
-
4291
4298
  */
4292
4299
 
4293
4300
  /**
4294
-
4295
4301
  * Default conversation configuration
4296
-
4297
4302
  * All values are explicitly defined here for easy maintenance and documentation
4298
-
4299
4303
  */
4300
4304
  declare const AX_DEFAULT_CONVERSATION_CONFIG: Required<AXConversationConfig>;
4301
4305
  /**
4302
-
4303
4306
  * Helper function to merge user config with defaults
4304
-
4305
4307
  * Properly handles array merging to avoid reference issues
4306
-
4307
4308
  * @param userConfig - User-provided configuration
4308
-
4309
4309
  * @returns Merged configuration with all required fields
4310
-
4311
4310
  */
4312
4311
  declare function mergeWithDefaults(userConfig?: Partial<AXConversationConfig>): Required<AXConversationConfig>;
4313
4312
 
@@ -4326,36 +4325,6 @@ declare const AX_CONVERSATION_CONFIG: InjectionToken<Required<AXConversationConf
4326
4325
  */
4327
4326
  declare const AX_CONVERSATION_ERROR_HANDLER_CONFIG: InjectionToken<Partial<AXConversationErrorHandlerConfig>>;
4328
4327
 
4329
- /**
4330
- * Pluggable avatar components for the conversation UI.
4331
- * Register via `provideConversation({ avatarComponents: { user, conversation } })`.
4332
- * When only `user` is registered, a built-in conversation avatar host is wired automatically.
4333
- */
4334
-
4335
- /** Custom user avatar (e.g. platform `axp-user-avatar`). */
4336
- interface AXConversationUserAvatarComponent {
4337
- readonly userId: InputSignal<string>;
4338
- readonly size: InputSignal<number>;
4339
- /** Optional resolved display name (e.g. bot/assist peer title). */
4340
- readonly displayName?: InputSignal<string | undefined>;
4341
- /** Optional resolved avatar URL when `userId` is not a platform user row. */
4342
- readonly displayAvatar?: InputSignal<string | undefined>;
4343
- /** Optional icon class when no avatar image is available. */
4344
- readonly displayIcon?: InputSignal<string | undefined>;
4345
- }
4346
- /** Optional custom group/channel conversation avatar. */
4347
- interface AXConversationConversationAvatarComponent {
4348
- readonly conversationId: InputSignal<string>;
4349
- readonly size: InputSignal<number>;
4350
- }
4351
- type AXConversationAvatarKind = 'user' | 'conversation' | 'auto';
4352
- declare const AX_CONVERSATION_USER_AVATAR_COMPONENT: InjectionToken<Type<AXConversationUserAvatarComponent>>;
4353
- declare const AX_CONVERSATION_CONVERSATION_AVATAR_COMPONENT: InjectionToken<Type<AXConversationConversationAvatarComponent>>;
4354
- interface AXConversationAvatarComponents {
4355
- user?: Type<AXConversationUserAvatarComponent>;
4356
- conversation?: Type<AXConversationConversationAvatarComponent>;
4357
- }
4358
-
4359
4328
  /**
4360
4329
  * Registry Configuration Tokens
4361
4330
  * Injection tokens for configuring default registry values
@@ -4425,472 +4394,6 @@ interface AXConversationRegistryConfiguration {
4425
4394
  */
4426
4395
  declare const AX_CONVERSATION_REGISTRY_CONFIG: InjectionToken<AXConversationRegistryConfiguration>;
4427
4396
 
4428
- /**
4429
- * IndexedDB Storage Wrapper
4430
- * Provides persistent storage for conversation data
4431
- */
4432
-
4433
- declare const AXConversationIndexedDbStores: {
4434
- readonly PARTICIPANTS: "participants";
4435
- readonly CONVERSATIONS: "conversations";
4436
- readonly MESSAGES: "messages";
4437
- readonly MEDIA: "media";
4438
- readonly SETTINGS: "settings";
4439
- };
4440
- /** Blob stored for demo multimedia uploads */
4441
- interface AXConversationIndexedDbMediaRecord {
4442
- id: string;
4443
- conversationId: string;
4444
- mimeType: string;
4445
- size: number;
4446
- fileName?: string;
4447
- blob: Blob;
4448
- createdAt: string;
4449
- }
4450
- declare class AXConversationIndexedDbStorage {
4451
- private db;
4452
- private initPromise;
4453
- /**
4454
- * Initialize IndexedDB
4455
- */
4456
- init(): Promise<void>;
4457
- /**
4458
- * Get a value from a store
4459
- */
4460
- get<T>(storeName: string, key: string): Promise<T | undefined>;
4461
- /**
4462
- * Get all values from a store
4463
- */
4464
- getAll<T>(storeName: string): Promise<T[]>;
4465
- /**
4466
- * Get values by index
4467
- */
4468
- getAllByIndex<T>(storeName: string, indexName: string, query: IDBValidKey): Promise<T[]>;
4469
- /**
4470
- * Put a value into a store
4471
- */
4472
- put<T>(storeName: string, value: T): Promise<void>;
4473
- /**
4474
- * Delete a value from a store
4475
- */
4476
- delete(storeName: string, key: string): Promise<void>;
4477
- /**
4478
- * Clear all data from a store
4479
- */
4480
- clear(storeName: string): Promise<void>;
4481
- getParticipant(id: string): Promise<AXConversationParticipant | undefined>;
4482
- getAllParticipants(): Promise<AXConversationParticipant[]>;
4483
- putParticipant(participant: AXConversationParticipant): Promise<void>;
4484
- getConversation(id: string): Promise<AXConversation | undefined>;
4485
- getAllConversations(): Promise<AXConversation[]>;
4486
- putConversation(conversation: AXConversation): Promise<void>;
4487
- deleteConversation(id: string): Promise<void>;
4488
- getMessage(id: string): Promise<AXConversationMessage | undefined>;
4489
- getAllMessages(): Promise<AXConversationMessage[]>;
4490
- getMessagesByConversation(conversationId: string): Promise<AXConversationMessage[]>;
4491
- putMessage(message: AXConversationMessage): Promise<void>;
4492
- deleteMessage(id: string): Promise<void>;
4493
- getSetting(key: string): Promise<unknown>;
4494
- putSetting(key: string, value: unknown): Promise<void>;
4495
- getMedia(id: string): Promise<AXConversationIndexedDbMediaRecord | undefined>;
4496
- putMedia(record: AXConversationIndexedDbMediaRecord): Promise<void>;
4497
- deleteMedia(id: string): Promise<void>;
4498
- }
4499
- declare const axConversationIndexedDbStorage: AXConversationIndexedDbStorage;
4500
-
4501
- /**
4502
- * Shared In-Memory Storage
4503
- * Internal storage shared between all IndexedDB API implementations
4504
- * This is NOT a service - just a shared data structure
4505
- */
4506
-
4507
- declare class AXConversationSharedStorage {
4508
- readonly connectionStatus$: BehaviorSubject<AXConversationConnectionStatus>;
4509
- readonly participants: Map<string, AXConversationParticipant>;
4510
- readonly conversations: Map<string, AXConversation>;
4511
- readonly messages: Map<string, AXConversationMessage>;
4512
- readonly messagesByConversation: Map<string, string[]>;
4513
- readonly messageStream$: Subject<AXConversationMessage>;
4514
- readonly messageUpdates$: Subject<AXConversationMessage>;
4515
- readonly messageDeletions$: Subject<string>;
4516
- readonly typingIndicators$: Subject<AXConversationTypingIndicator>;
4517
- readonly presenceUpdates$: Subject<AXConversationPresenceUpdate>;
4518
- readonly conversationUpdates$: Subject<AXConversation>;
4519
- readonly currentUserId = "current-user";
4520
- private isSeeded;
4521
- private presenceInterval?;
4522
- private messageSimulationInterval?;
4523
- private isLoadedFromDB;
4524
- /**
4525
- * Load data from IndexedDB
4526
- */
4527
- loadFromIndexedDB(): Promise<void>;
4528
- /**
4529
- * Seed initial data if not already seeded
4530
- */
4531
- seedIfEmpty(): Promise<void>;
4532
- /** Wipe in-memory and persisted demo data (used when seed version changes). */
4533
- private clearAllData;
4534
- /** @internal Used by demo seed module */
4535
- markSeeded(): void;
4536
- /** @internal Starts demo presence and message simulations */
4537
- startDemoSimulations(): void;
4538
- /**
4539
- * Simulate user presence changes (online/offline/away)
4540
- */
4541
- private startPresenceSimulation;
4542
- /**
4543
- * Simulate random messages from users
4544
- */
4545
- private startMessageSimulation;
4546
- /**
4547
- * Stop presence simulation
4548
- */
4549
- stopPresenceSimulation(): void;
4550
- /**
4551
- * Stop message simulation
4552
- */
4553
- stopMessageSimulation(): void;
4554
- }
4555
- declare const axConversationSharedStorage: AXConversationSharedStorage;
4556
-
4557
- declare const AX_CONVERSATION_DEMO_CONVERSATION_IDS: {
4558
- readonly private: "conv-demo-private";
4559
- readonly group: "conv-demo-group";
4560
- readonly channel: "conv-demo-channel";
4561
- };
4562
- declare function seedSharedStorageInitialData(storage: AXConversationSharedStorage): Promise<void>;
4563
-
4564
- /**
4565
- * Chat-oriented pagination helpers for IndexedDB demo APIs.
4566
- *
4567
- * Convention (matches {@link AXConversationService}):
4568
- * - Page 0: newest items (sidebar: recent chats; messages: latest history window).
4569
- * - Page 1+ or `cursor`: older items before the previous window.
4570
- * - `hasMore`: true when older items remain.
4571
- * - `nextCursor`: id of the oldest item in the current page (use as `pagination.cursor` for the next request).
4572
- */
4573
-
4574
- declare const AX_CONVERSATION_MESSAGE_CURSOR_PREFIX = "msg:";
4575
- declare const AX_CONVERSATION_CURSOR_PREFIX = "conv:";
4576
- type AXConversationChatCursorKind = 'message' | 'conversation';
4577
- interface AXConversationParsedChatCursor {
4578
- kind: AXConversationChatCursorKind;
4579
- id: string;
4580
- }
4581
- declare function encodeMessageCursor(messageId: string): string;
4582
- declare function encodeConversationCursor(conversationId: string): string;
4583
- /** Decode cursor from API pagination (supports prefixed or legacy raw message id). */
4584
- declare function parseChatCursor(cursor?: string): AXConversationParsedChatCursor | null;
4585
- /**
4586
- * Paginate a list sorted newest-first (chats, message history windows).
4587
- */
4588
- declare function paginateChatNewestFirst<T extends {
4589
- id: string;
4590
- }>(sortedNewestFirst: T[], pagination: AXConversationPagination, cursorKind: AXConversationChatCursorKind): AXConversationPaginatedResult<T>;
4591
- /**
4592
- * Paginate a list sorted oldest-first (replies, forward history).
4593
- */
4594
- declare function paginateChatOldestFirst<T extends {
4595
- id: string;
4596
- }>(sortedOldestFirst: T[], pagination: AXConversationPagination): AXConversationPaginatedResult<T>;
4597
-
4598
- /**
4599
- * Pagination demo data — disabled for the minimal 3-chat showcase seed.
4600
- * Kept as a no-op so existing imports remain valid.
4601
- */
4602
- /** @deprecated Pagination demo chat removed from default seed. */
4603
- declare const AX_MESSAGE_PAGINATION_CONVERSATION_ID = "conv-pag-msgs";
4604
- /** No-op: showcase uses a fixed 3-conversation seed (private, group, channel). */
4605
- declare function ensurePaginationDemoData(): Promise<void>;
4606
-
4607
- /**
4608
- * Shared read/write helpers for IndexedDB chat storage (in-memory + persistence).
4609
- */
4610
-
4611
- declare function getConversationLastActivity(conv: AXConversation): number;
4612
- /** Messages for a conversation, newest first (API / pagination order). */
4613
- declare function getConversationMessagesNewestFirst(conversationId: string): AXConversationMessage[];
4614
- /** Keep per-conversation id list sorted ascending by timestamp (store order). */
4615
- declare function sortConversationMessageIds(conversationId: string): void;
4616
- /** Register a message in maps and keep the conversation index sorted. */
4617
- declare function registerChatMessage(message: AXConversationMessage): void;
4618
- /** Remove a message from conversation index and global map. */
4619
- declare function unregisterChatMessage(messageId: string, conversationId: string): void;
4620
- declare function applyConversationFilters(conversations: AXConversation[], filters?: AXConversationFilters): AXConversation[];
4621
- /** Sidebar list order: pinned first, then by last activity (newest first). */
4622
- declare function getSortedConversationsForInbox(filters?: AXConversationFilters): AXConversation[];
4623
- /** Sort all loaded conversation message indexes (after IndexedDB hydration). */
4624
- declare function normalizeAllConversationMessageIndexes(): void;
4625
-
4626
- declare class AXConversationIndexedDbUserApi extends AXConversationUserApi {
4627
- private readonly API_DELAY_MS;
4628
- getCurrentUser(): Promise<AXConversationParticipant>;
4629
- updateProfile(updates: AXConversationUserProfileUpdate): Promise<AXConversationParticipant>;
4630
- uploadAvatar(file: File): Promise<string>;
4631
- getUsers(pagination?: AXConversationPagination, filters?: AXConversationUserSearchFilters): Promise<AXConversationPaginatedResult<AXConversationParticipant>>;
4632
- searchUsers(query: string): Promise<AXConversationParticipant[]>;
4633
- getUserById(userId: string): Promise<AXConversationParticipant>;
4634
- getUsersByIds(userIds: string[]): Promise<AXConversationParticipant[]>;
4635
- getUserPresence(userId: string): Promise<AXConversationPresenceUpdate>;
4636
- updatePresence(_status: AXConversationPresenceStatus, _statusText?: string): Promise<void>;
4637
- blockUser(_userId: string, _reason?: AXConversationBlockReportReason): Promise<void>;
4638
- unblockUser(_userId: string): Promise<void>;
4639
- getBlockedUsers(): Promise<string[]>;
4640
- reportUser(_userId: string, _reason: AXConversationBlockReportReason): Promise<void>;
4641
- getUserSettings(): Promise<Record<string, unknown>>;
4642
- updateUserSettings(_settings: Record<string, unknown>): Promise<void>;
4643
- private getCurrentUserWithoutDelay;
4644
- private fetchUsers;
4645
- private delay;
4646
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<AXConversationIndexedDbUserApi, never>;
4647
- static ɵprov: _angular_core.ɵɵInjectableDeclaration<AXConversationIndexedDbUserApi>;
4648
- }
4649
-
4650
- declare class AXConversationIndexedDbConversationApi extends AXConversationApi {
4651
- createConversation(data: AXConversationCreateData): Promise<AXConversation>;
4652
- getConversation(conversationId: string): Promise<AXConversation>;
4653
- /**
4654
- * Inbox page (pinned + recent activity, newest first).
4655
- * Page 0 / cursor align with {@link AXConversationService.loadConversations} and sidebar infinite scroll.
4656
- */
4657
- getConversations(pagination: AXConversationPagination, filters?: AXConversationFilters): Promise<AXConversationPaginatedResult<AXConversation>>;
4658
- updateConversation(conversationId: string, updates: AXConversationUpdateData): Promise<AXConversation>;
4659
- deleteConversation(conversationId: string): Promise<boolean>;
4660
- archiveConversation(conversationId: string): Promise<void>;
4661
- unarchiveConversation(conversationId: string): Promise<void>;
4662
- pinConversation(conversationId: string): Promise<void>;
4663
- unpinConversation(conversationId: string): Promise<void>;
4664
- markConversationAsRead(conversationId: string): Promise<void>;
4665
- markConversationAsUnread(conversationId: string): Promise<void>;
4666
- searchConversations(query: string): Promise<AXConversation[]>;
4667
- filterConversations(filters: AXConversationFilters, pagination?: AXConversationPagination): Promise<AXConversationPaginatedResult<AXConversation>>;
4668
- getParticipants(conversationId: string): Promise<AXConversationParticipant[]>;
4669
- addParticipants(_conversationId: string, _userIds: string[]): Promise<AXConversation>;
4670
- removeParticipant(conversationId: string, _userId: string): Promise<AXConversation>;
4671
- leaveConversation(_conversationId: string): Promise<void>;
4672
- updateParticipant(conversationId: string, _update: AXConversationParticipantUpdate): Promise<AXConversation>;
4673
- getConversationSettings(conversationId: string): Promise<AXConversationSettingsUpdate>;
4674
- updateConversationSettings(conversationId: string, settings: AXConversationSettingsUpdate): Promise<void>;
4675
- muteConversation(conversationId: string, duration?: number): Promise<void>;
4676
- unmuteConversation(conversationId: string): Promise<void>;
4677
- uploadConversationAvatar(_conversationId: string, file: File): Promise<string>;
4678
- getConversationMedia(conversationId: string, pagination?: AXConversationPagination): Promise<AXConversationPaginatedResult<unknown>>;
4679
- addConversationTags(conversationId: string, tags: string[]): Promise<void>;
4680
- removeConversationTags(conversationId: string, tags: string[]): Promise<void>;
4681
- getConversationTags(conversationId: string): Promise<string[]>;
4682
- saveDraft(conversationId: string, draft: string): Promise<void>;
4683
- getDraft(conversationId: string): Promise<string | null>;
4684
- clearDraft(conversationId: string): Promise<void>;
4685
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<AXConversationIndexedDbConversationApi, never>;
4686
- static ɵprov: _angular_core.ɵɵInjectableDeclaration<AXConversationIndexedDbConversationApi>;
4687
- }
4688
-
4689
- declare class AXConversationIndexedDbMessageApi extends AXConversationMessageApi {
4690
- sendMessage(command: AXConversationSendMessageCommand): Promise<AXConversationMessage>;
4691
- getMessage(messageId: string): Promise<AXConversationMessage>;
4692
- /**
4693
- * Message history for a chat (newest-first pages).
4694
- * - Page 0: latest `pageSize` messages.
4695
- * - Page 1+ or `pagination.cursor`: older messages before the previous window.
4696
- */
4697
- getMessages(conversationId: string, pagination: AXConversationPagination): Promise<AXConversationPaginatedResult<AXConversationMessage>>;
4698
- editMessage(messageId: string, payload: AXConversationMessagePayload): Promise<AXConversationMessage>;
4699
- deleteMessage(messageId: string, _forEveryone?: boolean): Promise<void>;
4700
- deleteMessages(messageIds: string[], forEveryone?: boolean): Promise<void>;
4701
- searchMessages(conversationId: string, filters: AXConversationMessageSearchFilters, pagination?: AXConversationPagination): Promise<AXConversationPaginatedResult<AXConversationMessage>>;
4702
- searchAllMessages(filters: AXConversationMessageSearchFilters, pagination?: AXConversationPagination): Promise<AXConversationPaginatedResult<AXConversationMessage>>;
4703
- addReaction(messageId: string, emoji: string): Promise<void>;
4704
- removeReaction(messageId: string, emoji: string): Promise<void>;
4705
- getAvailableReactions(): Promise<string[]>;
4706
- markAsRead(conversationId: string, messageIds: string[]): Promise<void>;
4707
- markAsUnread(conversationId: string): Promise<void>;
4708
- getReadReceipts(_messageId: string): Promise<AXConversationReadReceipt[]>;
4709
- forwardMessage(_data: AXConversationMessageForwardData): Promise<AXConversationMessage[]>;
4710
- pinMessage(_conversationId: string, _messageId: string): Promise<void>;
4711
- unpinMessage(_conversationId: string, _messageId: string): Promise<void>;
4712
- getPinnedMessages(_conversationId: string): Promise<AXConversationPinnedMessage[]>;
4713
- getMessageReplies(messageId: string, pagination?: AXConversationPagination): Promise<AXConversationPaginatedResult<AXConversationMessage>>;
4714
- getReplyCount(messageId: string): Promise<number>;
4715
- getForwardCount(messageId: string): Promise<number>;
4716
- sendTypingIndicator(conversationId: string): Promise<void>;
4717
- stopTypingIndicator(conversationId: string): Promise<void>;
4718
- updateMessageMetadata(messageId: string, metadata: Record<string, unknown>): Promise<void>;
4719
- getMessageMetadata(messageId: string): Promise<Record<string, unknown>>;
4720
- updateMessageStatus(messageId: string, status: 'sending' | 'sent' | 'delivered' | 'read' | 'failed'): Promise<void>;
4721
- getMessageDeliveryStatus(_messageId: string): Promise<{
4722
- delivered: number;
4723
- read: number;
4724
- total: number;
4725
- }>;
4726
- markMessagesAsRead(messageIds: string[]): Promise<void>;
4727
- bulkDeleteMessages(conversationId: string, messageIds: string[], forEveryone?: boolean): Promise<void>;
4728
- exportMessages(conversationId: string, _format: 'json' | 'csv' | 'txt'): Promise<string | Blob>;
4729
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<AXConversationIndexedDbMessageApi, never>;
4730
- static ɵprov: _angular_core.ɵɵInjectableDeclaration<AXConversationIndexedDbMessageApi>;
4731
- }
4732
-
4733
- declare class AXConversationIndexedDbRealtimeApi extends AXConversationRealtimeApi {
4734
- readonly connectionStatus$: Observable<AXConversationConnectionStatus>;
4735
- connect(_options?: AXConversationConnectionOptions): Promise<void>;
4736
- disconnect(): Promise<void>;
4737
- isConnected(): boolean;
4738
- reconnect(): Promise<void>;
4739
- subscribeToConnectionEvents(): Observable<AXConversationConnectionEvent>;
4740
- subscribeToMessages(conversationId: string): Observable<AXConversationMessage>;
4741
- subscribeToMessageUpdates(_conversationId?: string): Observable<AXConversationMessage>;
4742
- subscribeToMessageDeletions(_conversationId?: string): Observable<string>;
4743
- subscribeToMessageReactions(_conversationId?: string): Observable<AXConversationMessage>;
4744
- subscribeToConversationUpdates(): Observable<AXConversation>;
4745
- subscribeToConversationCreated(): Observable<AXConversation>;
4746
- subscribeToConversationDeleted(): Observable<string>;
4747
- subscribeToTypingIndicators(conversationId: string): Observable<AXConversationTypingIndicator>;
4748
- subscribeToPresenceUpdates(_userIds?: string[]): Observable<AXConversationPresenceUpdate>;
4749
- subscribeToReadReceipts(_conversationId?: string): Observable<{
4750
- messageId: string;
4751
- userId: string;
4752
- readAt: Date;
4753
- }>;
4754
- subscribeToNotifications(): Observable<AXConversationNotificationEvent>;
4755
- subscribeToCallEvents(): Observable<AXConversationCallEvent>;
4756
- subscribeToUserBlockEvents(): Observable<{
4757
- userId: string;
4758
- blocked: boolean;
4759
- }>;
4760
- subscribeToParticipantEvents(_conversationId?: string): Observable<{
4761
- conversationId: string;
4762
- userId: string;
4763
- action: 'added' | 'removed';
4764
- }>;
4765
- subscribeToSystemEvents(): Observable<{
4766
- type: string;
4767
- message: string;
4768
- data?: any;
4769
- }>;
4770
- subscribeToMessageStatusChanges(_conversationId?: string): Observable<{
4771
- messageId: string;
4772
- status: 'sending' | 'sent' | 'delivered' | 'read' | 'failed';
4773
- timestamp: Date;
4774
- }>;
4775
- subscribeToConversationSettingsChanges(_conversationId?: string): Observable<{
4776
- conversationId: string;
4777
- settings: Record<string, unknown>;
4778
- }>;
4779
- subscribeToDraftChanges(_conversationId?: string): Observable<{
4780
- conversationId: string;
4781
- draft: string | null;
4782
- }>;
4783
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<AXConversationIndexedDbRealtimeApi, never>;
4784
- static ɵprov: _angular_core.ɵɵInjectableDeclaration<AXConversationIndexedDbRealtimeApi>;
4785
- }
4786
-
4787
- /**
4788
- * AI Responder Service
4789
- * Provides AI-powered automatic responses using Google Gemini API
4790
- *
4791
- * @security API key should be provided via injection token in production
4792
- * @example
4793
- * ```typescript
4794
- * export const AX_CONVERSATION_AI_API_KEY = new InjectionToken<string>('AX_CONVERSATION_AI_API_KEY');
4795
- *
4796
- * providers: [
4797
- * { provide: AX_CONVERSATION_AI_API_KEY, useValue: environment.geminiApiKey }
4798
- * ]
4799
- * ```
4800
- */
4801
-
4802
- /**
4803
- * Injection token for AI API key
4804
- * Provide this in your app config to avoid hardcoding the API key
4805
- */
4806
- declare const AX_CONVERSATION_AI_API_KEY: InjectionToken<string>;
4807
- /**
4808
- * Configuration for AI Responder
4809
- */
4810
- interface AXConversationAiResponderConfig {
4811
- /** Maximum retry attempts for failed requests */
4812
- maxRetries?: number;
4813
- /** Timeout for API requests in milliseconds */
4814
- timeout?: number;
4815
- /** Enable fallback to random replies on error */
4816
- useFallbackReplies?: boolean;
4817
- }
4818
- declare class AXConversationAiResponderService {
4819
- private readonly injectedApiKey;
4820
- private readonly config;
4821
- /**
4822
- * Get API key from injection token
4823
- * Returns undefined if not configured - service will use fallback responses
4824
- */
4825
- private getApiKey;
4826
- /**
4827
- * Get AI-powered response for a given prompt
4828
- * @param prompt - The user's message to respond to
4829
- * @param retryCount - Current retry attempt (internal use)
4830
- * @returns AI-generated response or fallback message
4831
- */
4832
- getAIResponse(prompt: string, retryCount?: number): Promise<string>;
4833
- /**
4834
- * Fetch with timeout
4835
- */
4836
- private fetchWithTimeout;
4837
- /**
4838
- * Delay helper for retry logic
4839
- */
4840
- private delay;
4841
- /**
4842
- * Get a random fallback reply when AI is unavailable
4843
- */
4844
- private getFallbackReply;
4845
- /**
4846
- * Check if AI service is available
4847
- * @returns true if API key is configured
4848
- */
4849
- isAvailable(): boolean;
4850
- /**
4851
- * Update configuration
4852
- */
4853
- configure(config: Partial<AXConversationAiResponderConfig>): void;
4854
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<AXConversationAiResponderService, never>;
4855
- static ɵprov: _angular_core.ɵɵInjectableDeclaration<AXConversationAiResponderService>;
4856
- }
4857
-
4858
- declare class AXConversationIndexedDbMessageAiApi extends AXConversationIndexedDbMessageApi {
4859
- private readonly aiResponder;
4860
- private readonly AI_TYPING_INDICATOR_DELAY;
4861
- private readonly AI_RESPONSE_DELAY;
4862
- /**
4863
- * Override sendMessage to trigger AI auto-response
4864
- */
4865
- sendMessage(command: AXConversationSendMessageCommand): Promise<AXConversationMessage>;
4866
- /**
4867
- * Extract context from different message types for AI processing
4868
- */
4869
- private extractMessageContext;
4870
- /**
4871
- * Generate AI response to user message
4872
- */
4873
- private generateAIResponse;
4874
- /**
4875
- * Get conversation for AI response
4876
- */
4877
- private getConversationForAI;
4878
- /**
4879
- * Get conversation history (last N messages)
4880
- */
4881
- private getConversationHistory;
4882
- /**
4883
- * Create AI message directly in storage
4884
- */
4885
- private createAIMessage;
4886
- /**
4887
- * Delay helper
4888
- */
4889
- private delay;
4890
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<AXConversationIndexedDbMessageAiApi, never>;
4891
- static ɵprov: _angular_core.ɵɵInjectableDeclaration<AXConversationIndexedDbMessageAiApi>;
4892
- }
4893
-
4894
4397
  declare const AX_CONVERSATION_AUDIO_PRESENTATION: {
4895
4398
  readonly icon: "fa-light fa-music text-amber-500";
4896
4399
  readonly title: "Audio";
@@ -4913,7 +4416,10 @@ declare function applyAudioLocalPreview(payload: AXConversationMessagePayload, l
4913
4416
  * Shared upload state and helpers for composer media pickers.
4914
4417
  */
4915
4418
 
4419
+ /** Stable id for `@for` tracking while upload state is patched immutably. */
4420
+ declare function createPickerUploadItemId(): string;
4916
4421
  interface AXConversationComposerPickerUploadItem {
4422
+ id: string;
4917
4423
  file: File;
4918
4424
  preview?: string;
4919
4425
  duration?: number;
@@ -4963,16 +4469,14 @@ declare function notifyPickerValidationErrors(toast: AXToastService, translation
4963
4469
  file: File;
4964
4470
  errors: AXValidationRuleResult[];
4965
4471
  }[]): void;
4966
- /** Load files dropped onto the message list after the picker is mounted in a popup. */
4967
- declare function seedPickerInitialFiles(initialFiles: InputSignal<File[]>, handleFiles: (files: File[]) => void | Promise<void>): void;
4968
- /** Close inline composer shell or popup host after send/cancel. */
4969
- declare function dismissComposerPickerHost(composerService: AXConversationComposerService, popupRef?: AXPopupRef | null): void;
4472
+ /** Close popup/action-sheet host or inline composer shell after send/cancel. */
4473
+ declare function dismissComposerPickerHost(composerService: AXConversationComposerService, popupRef?: AXPopupRef | null, actionSheetRef?: AXActionSheetRef | null): void;
4970
4474
 
4971
4475
  interface AXConversationAudioFile extends AXConversationComposerPickerUploadItem {
4972
4476
  duration?: number;
4973
4477
  dataUrl?: string;
4974
4478
  }
4975
- declare class AXConversationAudioPickerComponent implements OnDestroy {
4479
+ declare class AXConversationAudioPickerComponent implements OnDestroy, AXConversationComposerActionComponent {
4976
4480
  private uploadsDismissed;
4977
4481
  private retainUploadedOnDismiss;
4978
4482
  readonly service: _angular_core.InputSignal<AXConversationComposerService>;
@@ -4987,16 +4491,20 @@ declare class AXConversationAudioPickerComponent implements OnDestroy {
4987
4491
  readonly conversation: _angular_core.InputSignal<AXConversation>;
4988
4492
  readonly maxFiles: _angular_core.InputSignal<number>;
4989
4493
  readonly initialFiles: _angular_core.InputSignal<File[]>;
4494
+ readonly autoRun: _angular_core.InputSignal<boolean>;
4990
4495
  readonly __popup__: _angular_core.InputSignal<AXPopupRef<any>>;
4496
+ readonly __actionSheet__: _angular_core.InputSignal<AXActionSheetRef<unknown>>;
4991
4497
  readonly catalogFileType: "conversation-audio";
4992
4498
  readonly audioFiles: _angular_core.WritableSignal<AXConversationAudioFile[]>;
4993
4499
  readonly isDragging: _angular_core.WritableSignal<boolean>;
4500
+ private readonly pickerShell;
4994
4501
  readonly typeIconClass: "fa-light fa-music text-amber-500";
4995
4502
  readonly emptyIconClass: _angular_core.Signal<"fa-light fa-music text-amber-500" | "fa-light fa-cloud-arrow-up">;
4996
4503
  private catalogFileTypeDef?;
4997
4504
  caption: string;
4998
4505
  readonly allowMultiple: _angular_core.Signal<boolean>;
4999
4506
  constructor();
4507
+ activate(): Promise<void>;
5000
4508
  private createUtilityContext;
5001
4509
  private getCatalogFileTypeDef;
5002
4510
  private runUtility;
@@ -5008,6 +4516,8 @@ declare class AXConversationAudioPickerComponent implements OnDestroy {
5008
4516
  canSend(): boolean;
5009
4517
  getUploadingLabel(progress: number): string;
5010
4518
  getCancelUploadLabel(): string;
4519
+ getHeaderTitle(): string;
4520
+ onAddMoreFiles(): void;
5011
4521
  cancel(): void;
5012
4522
  ngOnDestroy(): void;
5013
4523
  private dismissPicker;
@@ -5018,7 +4528,7 @@ declare class AXConversationAudioPickerComponent implements OnDestroy {
5018
4528
  getSelectedCountText(): string;
5019
4529
  getSendText(): string;
5020
4530
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<AXConversationAudioPickerComponent, never>;
5021
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<AXConversationAudioPickerComponent, "ax-conversation-audio-picker", never, { "service": { "alias": "service"; "required": false; "isSignal": true; }; "conversation": { "alias": "conversation"; "required": true; "isSignal": true; }; "maxFiles": { "alias": "maxFiles"; "required": false; "isSignal": true; }; "initialFiles": { "alias": "initialFiles"; "required": false; "isSignal": true; }; "__popup__": { "alias": "__popup__"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
4531
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<AXConversationAudioPickerComponent, "ax-conversation-audio-picker", never, { "service": { "alias": "service"; "required": false; "isSignal": true; }; "conversation": { "alias": "conversation"; "required": true; "isSignal": true; }; "maxFiles": { "alias": "maxFiles"; "required": false; "isSignal": true; }; "initialFiles": { "alias": "initialFiles"; "required": false; "isSignal": true; }; "autoRun": { "alias": "autoRun"; "required": false; "isSignal": true; }; "__popup__": { "alias": "__popup__"; "required": false; "isSignal": true; }; "__actionSheet__": { "alias": "__actionSheet__"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
5022
4532
  }
5023
4533
 
5024
4534
  declare const AX_CONVERSATION_COMPOSER_EMOJI_TAB: AXConversationComposerTab;
@@ -5080,20 +4590,16 @@ declare function fileItemFromUpload(file: File, result: AXConversationUploaderRe
5080
4590
  declare function mergeFileUploadResult(payload: AXConversationMessagePayload, result: AXUploadResult): AXConversationMessagePayload;
5081
4591
  declare function applyFileLocalPreview(payload: AXConversationMessagePayload, localUrl: string, mimeType?: string): AXConversationMessagePayload;
5082
4592
 
5083
- interface AXConversationAttachedFile {
5084
- file: File;
5085
- preview?: string;
4593
+ interface AXConversationPickerFileBadge {
4594
+ ext: string;
4595
+ color: string;
4596
+ }
4597
+
4598
+ interface AXConversationAttachedFile extends AXConversationComposerPickerUploadItem {
5086
4599
  icon: string;
5087
4600
  type: 'image' | 'video' | 'audio' | 'file';
5088
- uploadProgress?: number;
5089
- uploading?: boolean;
5090
- uploaded?: boolean;
5091
- uploadedUrl?: string;
5092
- mediaId?: string;
5093
- error?: string;
5094
- abortController?: AbortController;
5095
4601
  }
5096
- declare class AXConversationFilePickerComponent implements OnDestroy {
4602
+ declare class AXConversationFilePickerComponent implements OnDestroy, AXConversationComposerActionComponent {
5097
4603
  private uploadsDismissed;
5098
4604
  private retainUploadedOnDismiss;
5099
4605
  private readonly uploader;
@@ -5108,16 +4614,20 @@ declare class AXConversationFilePickerComponent implements OnDestroy {
5108
4614
  readonly conversation: _angular_core.InputSignal<AXConversation>;
5109
4615
  readonly maxFiles: _angular_core.InputSignal<number>;
5110
4616
  readonly initialFiles: _angular_core.InputSignal<File[]>;
4617
+ readonly autoRun: _angular_core.InputSignal<boolean>;
5111
4618
  readonly __popup__: _angular_core.InputSignal<AXPopupRef<any>>;
4619
+ readonly __actionSheet__: _angular_core.InputSignal<AXActionSheetRef<unknown>>;
5112
4620
  readonly catalogFileType: "conversation-file";
5113
4621
  readonly allowMultiple: _angular_core.Signal<boolean>;
5114
4622
  readonly files: _angular_core.WritableSignal<AXConversationAttachedFile[]>;
5115
4623
  readonly isDragging: _angular_core.WritableSignal<boolean>;
5116
4624
  readonly isUploading: _angular_core.WritableSignal<boolean>;
4625
+ private readonly pickerShell;
5117
4626
  readonly emptyIconClass: _angular_core.Signal<"fa-light fa-file text-neutral-500" | "fa-light fa-cloud-arrow-up">;
5118
4627
  private catalogFileTypeDef?;
5119
4628
  caption: string;
5120
4629
  constructor();
4630
+ activate(): Promise<void>;
5121
4631
  private createUtilityContext;
5122
4632
  private getCatalogFileTypeDef;
5123
4633
  private pickerKind;
@@ -5130,6 +4640,9 @@ declare class AXConversationFilePickerComponent implements OnDestroy {
5130
4640
  cancel(): void;
5131
4641
  ngOnDestroy(): void;
5132
4642
  private dismissPicker;
4643
+ getHeaderTitle(): string;
4644
+ getFileBadge(fileName: string): AXConversationPickerFileBadge;
4645
+ onAddMoreFiles(): void;
5133
4646
  getCancelUploadLabel(): string;
5134
4647
  formatFileSize(bytes: number): string;
5135
4648
  canSend(): boolean;
@@ -5139,7 +4652,7 @@ declare class AXConversationFilePickerComponent implements OnDestroy {
5139
4652
  getSelectedCountText(): string;
5140
4653
  getUploadingLabel(progress: number): string;
5141
4654
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<AXConversationFilePickerComponent, never>;
5142
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<AXConversationFilePickerComponent, "ax-conversation-file-picker", never, { "service": { "alias": "service"; "required": false; "isSignal": true; }; "conversation": { "alias": "conversation"; "required": true; "isSignal": true; }; "maxFiles": { "alias": "maxFiles"; "required": false; "isSignal": true; }; "initialFiles": { "alias": "initialFiles"; "required": false; "isSignal": true; }; "__popup__": { "alias": "__popup__"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
4655
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<AXConversationFilePickerComponent, "ax-conversation-file-picker", never, { "service": { "alias": "service"; "required": false; "isSignal": true; }; "conversation": { "alias": "conversation"; "required": true; "isSignal": true; }; "maxFiles": { "alias": "maxFiles"; "required": false; "isSignal": true; }; "initialFiles": { "alias": "initialFiles"; "required": false; "isSignal": true; }; "autoRun": { "alias": "autoRun"; "required": false; "isSignal": true; }; "__popup__": { "alias": "__popup__"; "required": false; "isSignal": true; }; "__actionSheet__": { "alias": "__actionSheet__"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
5143
4656
  }
5144
4657
 
5145
4658
  declare const AX_CONVERSATION_IMAGE_PRESENTATION: {
@@ -5159,7 +4672,7 @@ declare class AXConversationImageFileTypeProvider extends AXFileTypeInfoProvider
5159
4672
  interface AXConversationImageFile extends AXConversationComposerPickerUploadItem {
5160
4673
  preview: string;
5161
4674
  }
5162
- declare class AXConversationImagePickerComponent implements OnDestroy {
4675
+ declare class AXConversationImagePickerComponent implements OnDestroy, AXConversationComposerActionComponent {
5163
4676
  private uploadsDismissed;
5164
4677
  /** Uploaded blobs are referenced by the sent message — do not delete on dismiss. */
5165
4678
  private retainUploadedOnDismiss;
@@ -5176,14 +4689,18 @@ declare class AXConversationImagePickerComponent implements OnDestroy {
5176
4689
  readonly conversation: _angular_core.InputSignal<AXConversation>;
5177
4690
  readonly maxFiles: _angular_core.InputSignal<number>;
5178
4691
  readonly initialFiles: _angular_core.InputSignal<File[]>;
4692
+ readonly autoRun: _angular_core.InputSignal<boolean>;
5179
4693
  readonly __popup__: _angular_core.InputSignal<AXPopupRef<any>>;
4694
+ readonly __actionSheet__: _angular_core.InputSignal<AXActionSheetRef<unknown>>;
5180
4695
  readonly images: _angular_core.WritableSignal<AXConversationImageFile[]>;
4696
+ private readonly pickerShell;
5181
4697
  readonly isDragging: _angular_core.WritableSignal<boolean>;
5182
4698
  readonly emptyIconClass: _angular_core.Signal<"fa-light fa-image text-purple-500" | "fa-light fa-cloud-arrow-up">;
5183
4699
  caption: string;
5184
4700
  readonly allowMultiple: _angular_core.Signal<boolean>;
5185
4701
  private imageFileType?;
5186
4702
  constructor();
4703
+ activate(): Promise<void>;
5187
4704
  private createUtilityContext;
5188
4705
  private loadImageFileType;
5189
4706
  handleFiles(files: File[]): Promise<void>;
@@ -5194,6 +4711,8 @@ declare class AXConversationImagePickerComponent implements OnDestroy {
5194
4711
  canSend(): boolean;
5195
4712
  getUploadingLabel(progress: number): string;
5196
4713
  getCancelUploadLabel(): string;
4714
+ getHeaderTitle(): string;
4715
+ onAddMoreFiles(): void;
5197
4716
  cancel(): void;
5198
4717
  ngOnDestroy(): void;
5199
4718
  private dismissPicker;
@@ -5202,20 +4721,23 @@ declare class AXConversationImagePickerComponent implements OnDestroy {
5202
4721
  getSelectedCountText(): string;
5203
4722
  getSendText(): string;
5204
4723
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<AXConversationImagePickerComponent, never>;
5205
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<AXConversationImagePickerComponent, "ax-conversation-image-picker", never, { "service": { "alias": "service"; "required": false; "isSignal": true; }; "conversation": { "alias": "conversation"; "required": true; "isSignal": true; }; "maxFiles": { "alias": "maxFiles"; "required": false; "isSignal": true; }; "initialFiles": { "alias": "initialFiles"; "required": false; "isSignal": true; }; "__popup__": { "alias": "__popup__"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
4724
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<AXConversationImagePickerComponent, "ax-conversation-image-picker", never, { "service": { "alias": "service"; "required": false; "isSignal": true; }; "conversation": { "alias": "conversation"; "required": true; "isSignal": true; }; "maxFiles": { "alias": "maxFiles"; "required": false; "isSignal": true; }; "initialFiles": { "alias": "initialFiles"; "required": false; "isSignal": true; }; "autoRun": { "alias": "autoRun"; "required": false; "isSignal": true; }; "__popup__": { "alias": "__popup__"; "required": false; "isSignal": true; }; "__actionSheet__": { "alias": "__actionSheet__"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
5206
4725
  }
5207
4726
 
5208
4727
  declare class AXConversationLocationPickerComponent {
5209
- private readonly composerService;
5210
- private readonly conversationService;
4728
+ readonly service: _angular_core.InputSignal<AXConversationComposerService>;
4729
+ private readonly composerServiceFromInjector;
4730
+ private get composerService();
5211
4731
  readonly translation: AXTranslationService;
5212
4732
  readonly conversation: _angular_core.InputSignal<AXConversation>;
4733
+ readonly __popup__: _angular_core.InputSignal<AXPopupRef<any>>;
4734
+ readonly __actionSheet__: _angular_core.InputSignal<AXActionSheetRef<unknown>>;
5213
4735
  readonly currentLocation: _angular_core.WritableSignal<AXConversationLocationPayload>;
5214
4736
  onMarkerAdded(event: AXMapMarker): void;
5215
4737
  sendLocation(): Promise<void>;
5216
4738
  cancel(): void;
5217
4739
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<AXConversationLocationPickerComponent, never>;
5218
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<AXConversationLocationPickerComponent, "ax-conversation-location-picker", never, { "conversation": { "alias": "conversation"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
4740
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<AXConversationLocationPickerComponent, "ax-conversation-location-picker", never, { "service": { "alias": "service"; "required": false; "isSignal": true; }; "conversation": { "alias": "conversation"; "required": true; "isSignal": true; }; "__popup__": { "alias": "__popup__"; "required": false; "isSignal": true; }; "__actionSheet__": { "alias": "__actionSheet__"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
5219
4741
  }
5220
4742
 
5221
4743
  declare class AXConversationPickerFooterComponent {
@@ -5229,9 +4751,12 @@ declare class AXConversationPickerFooterComponent {
5229
4751
 
5230
4752
  declare class AXConversationPickerHeaderComponent {
5231
4753
  readonly title: _angular_core.InputSignal<string>;
4754
+ readonly showMenu: _angular_core.InputSignal<boolean>;
4755
+ readonly addMoreLabel: _angular_core.InputSignal<string>;
5232
4756
  readonly onClose: _angular_core.OutputEmitterRef<void>;
4757
+ readonly onAddMore: _angular_core.OutputEmitterRef<void>;
5233
4758
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<AXConversationPickerHeaderComponent, never>;
5234
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<AXConversationPickerHeaderComponent, "ax-conversation-picker-header", never, { "title": { "alias": "title"; "required": true; "isSignal": true; }; }, { "onClose": "onClose"; }, never, never, true, never>;
4759
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<AXConversationPickerHeaderComponent, "ax-conversation-picker-header", never, { "title": { "alias": "title"; "required": true; "isSignal": true; }; "showMenu": { "alias": "showMenu"; "required": false; "isSignal": true; }; "addMoreLabel": { "alias": "addMoreLabel"; "required": false; "isSignal": true; }; }, { "onClose": "onClose"; "onAddMore": "onAddMore"; }, never, never, true, never>;
5235
4760
  }
5236
4761
 
5237
4762
  declare function formatFileSize(bytes: number): string;
@@ -5246,12 +4771,14 @@ declare function resolvePersistableMediaUrl(url: string | undefined): string | u
5246
4771
  /** First non-empty URL for img/video/audio at runtime (includes resolved blob: URLs). */
5247
4772
  declare function pickDisplayMediaUrl(...candidates: (string | null | undefined)[]): string;
5248
4773
 
5249
- /** Optional caption field shared by composer media pickers. */
4774
+ /** Telegram-style caption row with emoji affordance and circular send button. */
5250
4775
  declare class AXConversationPickerCaptionComponent {
5251
4776
  readonly translation: AXTranslationService;
5252
4777
  readonly caption: _angular_core.ModelSignal<string>;
4778
+ readonly sendDisabled: _angular_core.InputSignal<boolean>;
4779
+ readonly onSend: _angular_core.OutputEmitterRef<void>;
5253
4780
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<AXConversationPickerCaptionComponent, never>;
5254
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<AXConversationPickerCaptionComponent, "ax-conversation-picker-caption", never, { "caption": { "alias": "caption"; "required": false; "isSignal": true; }; }, { "caption": "captionChange"; }, never, never, true, never>;
4781
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<AXConversationPickerCaptionComponent, "ax-conversation-picker-caption", never, { "caption": { "alias": "caption"; "required": false; "isSignal": true; }; "sendDisabled": { "alias": "sendDisabled"; "required": false; "isSignal": true; }; }, { "caption": "captionChange"; "onSend": "onSend"; }, never, never, true, never>;
5255
4782
  }
5256
4783
 
5257
4784
  /** Shared drag-and-drop handlers for composer pickers. */
@@ -5279,12 +4806,15 @@ declare class AXConversationPickerEmptyComponent {
5279
4806
  declare class AXConversationPickerShellComponent {
5280
4807
  private readonly toast;
5281
4808
  private readonly translation;
4809
+ private readonly zone;
5282
4810
  readonly fileType: _angular_core.InputSignal<string>;
5283
4811
  readonly multiple: _angular_core.InputSignal<boolean>;
5284
4812
  readonly filesSelected: _angular_core.OutputEmitterRef<File[]>;
5285
4813
  readonly dragEnter: _angular_core.OutputEmitterRef<DragEvent>;
5286
4814
  readonly dragLeave: _angular_core.OutputEmitterRef<DragEvent>;
5287
4815
  readonly dragOver: _angular_core.OutputEmitterRef<DragEvent>;
4816
+ /** Open the OS file picker for this shell's catalog. */
4817
+ browse(): Promise<void>;
5288
4818
  protected onZoneFileChange(event: AXUploaderFileChangeEvent): void;
5289
4819
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<AXConversationPickerShellComponent, never>;
5290
4820
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<AXConversationPickerShellComponent, "ax-conversation-picker-shell", never, { "fileType": { "alias": "fileType"; "required": true; "isSignal": true; }; "multiple": { "alias": "multiple"; "required": false; "isSignal": true; }; }, { "filesSelected": "filesSelected"; "dragEnter": "dragEnter"; "dragLeave": "dragLeave"; "dragOver": "dragOver"; }, never, ["*"], true, never>;
@@ -5354,7 +4884,7 @@ interface AXConversationVideoFile extends AXConversationComposerPickerUploadItem
5354
4884
  preview?: string;
5355
4885
  duration?: number;
5356
4886
  }
5357
- declare class AXConversationVideoPickerComponent implements OnDestroy {
4887
+ declare class AXConversationVideoPickerComponent implements OnDestroy, AXConversationComposerActionComponent {
5358
4888
  private uploadsDismissed;
5359
4889
  private retainUploadedOnDismiss;
5360
4890
  readonly service: _angular_core.InputSignal<AXConversationComposerService>;
@@ -5369,16 +4899,20 @@ declare class AXConversationVideoPickerComponent implements OnDestroy {
5369
4899
  readonly conversation: _angular_core.InputSignal<AXConversation>;
5370
4900
  readonly maxFiles: _angular_core.InputSignal<number>;
5371
4901
  readonly initialFiles: _angular_core.InputSignal<File[]>;
4902
+ readonly autoRun: _angular_core.InputSignal<boolean>;
5372
4903
  readonly __popup__: _angular_core.InputSignal<AXPopupRef<any>>;
4904
+ readonly __actionSheet__: _angular_core.InputSignal<AXActionSheetRef<unknown>>;
5373
4905
  readonly catalogFileType: "conversation-video";
5374
4906
  readonly videos: _angular_core.WritableSignal<AXConversationVideoFile[]>;
5375
4907
  readonly isDragging: _angular_core.WritableSignal<boolean>;
4908
+ private readonly pickerShell;
5376
4909
  caption: string;
5377
4910
  readonly allowMultiple: _angular_core.Signal<boolean>;
5378
4911
  readonly typeIconClass: "fa-light fa-video ax-text-blue-500";
5379
4912
  readonly emptyIconClass: _angular_core.Signal<"fa-light fa-video ax-text-blue-500" | "fa-light fa-cloud-arrow-up">;
5380
4913
  private catalogFileTypeDef?;
5381
4914
  constructor();
4915
+ activate(): Promise<void>;
5382
4916
  private createUtilityContext;
5383
4917
  private getCatalogFileTypeDef;
5384
4918
  private runUtility;
@@ -5390,6 +4924,8 @@ declare class AXConversationVideoPickerComponent implements OnDestroy {
5390
4924
  canSend(): boolean;
5391
4925
  getUploadingLabel(progress: number): string;
5392
4926
  getCancelUploadLabel(): string;
4927
+ getHeaderTitle(): string;
4928
+ onAddMoreFiles(): void;
5393
4929
  cancel(): void;
5394
4930
  ngOnDestroy(): void;
5395
4931
  private dismissPicker;
@@ -5400,7 +4936,7 @@ declare class AXConversationVideoPickerComponent implements OnDestroy {
5400
4936
  getSelectedCountText(): string;
5401
4937
  getSendText(): string;
5402
4938
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<AXConversationVideoPickerComponent, never>;
5403
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<AXConversationVideoPickerComponent, "ax-conversation-video-picker", never, { "service": { "alias": "service"; "required": false; "isSignal": true; }; "conversation": { "alias": "conversation"; "required": true; "isSignal": true; }; "maxFiles": { "alias": "maxFiles"; "required": false; "isSignal": true; }; "initialFiles": { "alias": "initialFiles"; "required": false; "isSignal": true; }; "__popup__": { "alias": "__popup__"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
4939
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<AXConversationVideoPickerComponent, "ax-conversation-video-picker", never, { "service": { "alias": "service"; "required": false; "isSignal": true; }; "conversation": { "alias": "conversation"; "required": true; "isSignal": true; }; "maxFiles": { "alias": "maxFiles"; "required": false; "isSignal": true; }; "initialFiles": { "alias": "initialFiles"; "required": false; "isSignal": true; }; "autoRun": { "alias": "autoRun"; "required": false; "isSignal": true; }; "__popup__": { "alias": "__popup__"; "required": false; "isSignal": true; }; "__actionSheet__": { "alias": "__actionSheet__"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
5404
4940
  }
5405
4941
 
5406
4942
  declare const AX_CONVERSATION_VOICE_PRESENTATION: {
@@ -5420,14 +4956,21 @@ declare class AXConversationVoiceFileTypeProvider extends AXFileTypeInfoProvider
5420
4956
  declare function mergeVoiceUploadResult(payload: AXConversationMessagePayload, result: AXUploadResult): AXConversationMessagePayload;
5421
4957
  declare function applyVoiceLocalPreview(payload: AXConversationMessagePayload, localUrl: string): AXConversationMessagePayload;
5422
4958
 
5423
- declare class AXConversationVoiceRecorderComponent {
4959
+ declare class AXConversationVoiceRecorderComponent implements AXConversationComposerActionComponent {
5424
4960
  private readonly platformId;
5425
4961
  private readonly destroyRef;
5426
- private readonly composerService;
4962
+ readonly service: _angular_core.InputSignal<AXConversationComposerService>;
4963
+ private readonly composerServiceFromInjector;
4964
+ private get composerService();
5427
4965
  private readonly uploader;
4966
+ private readonly fileTypeRegistry;
5428
4967
  private readonly toast;
5429
4968
  readonly translation: AXTranslationService;
5430
4969
  readonly conversation: _angular_core.InputSignal<AXConversation>;
4970
+ readonly initialFiles: _angular_core.InputSignal<File[]>;
4971
+ readonly autoRun: _angular_core.InputSignal<boolean>;
4972
+ readonly __popup__: _angular_core.InputSignal<AXPopupRef<any>>;
4973
+ readonly __actionSheet__: _angular_core.InputSignal<AXActionSheetRef<unknown>>;
5431
4974
  readonly recordingComplete: _angular_core.OutputEmitterRef<Blob>;
5432
4975
  readonly recordingCancelled: _angular_core.OutputEmitterRef<void>;
5433
4976
  readonly isRecording: _angular_core.WritableSignal<boolean>;
@@ -5443,7 +4986,9 @@ declare class AXConversationVoiceRecorderComponent {
5443
4986
  private uploadAbortController?;
5444
4987
  readonly formattedTime: _angular_core.Signal<string>;
5445
4988
  constructor();
4989
+ activate(): Promise<void>;
5446
4990
  startRecording(): Promise<void>;
4991
+ private dismissHost;
5447
4992
  /** Stop recording and send */
5448
4993
  stopRecording(): void;
5449
4994
  cancelRecording(): void;
@@ -5457,7 +5002,7 @@ declare class AXConversationVoiceRecorderComponent {
5457
5002
  private sendVoiceMessage;
5458
5003
  private stopAndCleanup;
5459
5004
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<AXConversationVoiceRecorderComponent, never>;
5460
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<AXConversationVoiceRecorderComponent, "ax-conversation-voice-recorder", never, { "conversation": { "alias": "conversation"; "required": false; "isSignal": true; }; }, { "recordingComplete": "recordingComplete"; "recordingCancelled": "recordingCancelled"; }, never, never, true, never>;
5005
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<AXConversationVoiceRecorderComponent, "ax-conversation-voice-recorder", never, { "service": { "alias": "service"; "required": false; "isSignal": true; }; "conversation": { "alias": "conversation"; "required": true; "isSignal": true; }; "initialFiles": { "alias": "initialFiles"; "required": false; "isSignal": true; }; "autoRun": { "alias": "autoRun"; "required": false; "isSignal": true; }; "__popup__": { "alias": "__popup__"; "required": false; "isSignal": true; }; "__actionSheet__": { "alias": "__actionSheet__"; "required": false; "isSignal": true; }; }, { "recordingComplete": "recordingComplete"; "recordingCancelled": "recordingCancelled"; }, never, never, true, never>;
5461
5006
  }
5462
5007
 
5463
5008
  declare const AX_CONVERSATION_COMPOSER_EMOJI_ACTION: AXConversationComposerAction;
@@ -5479,6 +5024,8 @@ declare const AX_CONVERSATION_FILE_TYPES_READY: InjectionToken<boolean>;
5479
5024
  /** Registers validation rules and lazy conversation file-type catalogs for composer actions. */
5480
5025
  declare function provideConversationComposerFileTypes(): Provider[];
5481
5026
 
5027
+ /** Ensure a built-in conversation catalog is registered before pre-overlay file selection. */
5028
+ declare function ensureConversationFileCatalogRegistered(registry: AXFileTypeRegistryService, catalogName: string): Promise<void>;
5482
5029
  /**
5483
5030
  * Lazy-loads conversation file catalogs for the root file-type registry.
5484
5031
  * Must not inject {@link AXConversationComposerActionRegistry} — that registry
@@ -5499,170 +5046,6 @@ declare function createLocalPreviewUrl(fileService: AXFileService, platformId: o
5499
5046
 
5500
5047
  declare function resolveComposerMaxFiles(action: Pick<AXConversationComposerAction, 'maxFiles'> | undefined, config: Pick<Required<AXConversationConfig>, 'maxFilesPerMessage'>): number;
5501
5048
 
5502
- interface AXConversationInfoProfileField {
5503
- id: string;
5504
- labelKey: string;
5505
- value: string;
5506
- icon: string;
5507
- }
5508
- type AXConversationMediaCategoryId = 'image' | 'video' | 'file' | 'audio' | 'voice' | 'sticker' | 'location' | 'link';
5509
- interface AXConversationMediaCategory {
5510
- id: AXConversationMediaCategoryId;
5511
- labelKey: string;
5512
- countLabelKey: string;
5513
- icon: string;
5514
- count: number;
5515
- }
5516
- declare function messageContainsLink(message: AXConversationMessage): boolean;
5517
- declare function getPrivatePeerParticipant(conversation: AXConversation, currentUserId?: string): AXConversationParticipant | undefined;
5518
- declare function getConversationProfileFields(conversation: AXConversation, currentUserId?: string): AXConversationInfoProfileField[];
5519
- declare function getConversationMediaCategories(messages: AXConversationMessage[]): AXConversationMediaCategory[];
5520
- declare function filterMessagesByMediaCategory(messages: AXConversationMessage[], categoryId: AXConversationMediaCategoryId): AXConversationMessage[];
5521
- declare function isGridMediaCategory(categoryId: AXConversationMediaCategoryId): boolean;
5522
- declare function isAttachmentListCategory(categoryId: AXConversationMediaCategoryId): boolean;
5523
- interface AXConversationMediaGalleryTile {
5524
- key: string;
5525
- message: AXConversationMessage;
5526
- kind: 'image' | 'video' | 'sticker';
5527
- image?: AXConversationImageMediaItem;
5528
- video?: AXConversationVideoMediaItem;
5529
- stickerUrl?: string;
5530
- stickerAlt?: string;
5531
- }
5532
- declare function buildMediaGalleryTiles(messages: AXConversationMessage[], categoryId: AXConversationMediaCategoryId): AXConversationMediaGalleryTile[];
5533
- declare function resolveVideoThumbnailUrl(video: AXConversationVideoMediaItem): string | undefined;
5534
- declare function resolveGalleryImageUrl(image: AXConversationImageMediaItem): string | undefined;
5535
- declare function getMessageVideoItems(message: AXConversationMessage): AXConversationVideoMediaItem[];
5536
- declare function getMessageAudioItems(message: AXConversationMessage): AXConversationAudioMediaItem[];
5537
- interface AXConversationMediaPageResult {
5538
- items: AXConversationMessage[];
5539
- hasMore: boolean;
5540
- nextCursor?: string;
5541
- page: number;
5542
- }
5543
- declare function fetchConversationMediaPage(conversationApi: AXConversationApi, conversationId: string, page: number, pageSize?: number, cursor?: string): Promise<AXConversationMediaPageResult>;
5544
- /** @deprecated Use {@link fetchConversationMediaPage} — loads only the first page. */
5545
- declare function fetchConversationMediaMessages(conversationApi: AXConversationApi, conversationId: string, pageSize: number): Promise<AXConversationMessage[]>;
5546
- /** Merge media API results with in-memory messages needed for link/sticker/voice/location tabs. */
5547
- declare function mergeInfoPanelMessages(mediaMessages: AXConversationMessage[], supplemental: AXConversationMessage[]): AXConversationMessage[];
5548
- declare function filterSupplementalInfoPanelMessages(messages: AXConversationMessage[]): AXConversationMessage[];
5549
-
5550
- interface AXInfoPanelQuickAction {
5551
- id: string;
5552
- labelKey: string;
5553
- icon: string;
5554
- danger?: boolean;
5555
- }
5556
- declare class AXConversationInfoPanelComponent extends AXClosableComponent implements OnInit, OnDestroy {
5557
- private readonly toastService;
5558
- readonly translation: AXTranslationService;
5559
- private readonly platform;
5560
- private readonly injectedConversationService;
5561
- readonly onClosed: _angular_core.OutputEmitterRef<AXComponentCloseEvent>;
5562
- conversation: AXConversation;
5563
- conversationService: AXConversationService;
5564
- readonly activeTab: _angular_core.WritableSignal<"profile" | "manage">;
5565
- readonly showMemberSearch: _angular_core.WritableSignal<boolean>;
5566
- readonly panelView: _angular_core.WritableSignal<"main" | "media">;
5567
- readonly selectedMediaCategory: _angular_core.WritableSignal<AXConversationMediaCategory>;
5568
- readonly mediaViewLoader: () => Promise<typeof _acorex_components_conversation.AXConversationInfoMediaViewComponent>;
5569
- readonly conversationMessages: _angular_core.WritableSignal<AXConversationMessage[]>;
5570
- readonly loadingMessages: _angular_core.WritableSignal<boolean>;
5571
- readonly loadingMoreMedia: _angular_core.WritableSignal<boolean>;
5572
- readonly mediaHasMore: _angular_core.WritableSignal<boolean>;
5573
- private mediaNextPage;
5574
- private mediaNextCursor;
5575
- readonly memberSearchQuery: _angular_core.WritableSignal<string>;
5576
- archived: boolean;
5577
- private initialNotifications;
5578
- private initialArchived;
5579
- editTitle: string;
5580
- editAvatar: string;
5581
- private groupTitleSaveTimer;
5582
- private groupDetailsSaveInFlight;
5583
- readonly backgroundPresets: {
5584
- label: string;
5585
- id: string;
5586
- value: AXConversationMessageListThemeBackground;
5587
- }[];
5588
- readonly heroSubtitle: _angular_core.Signal<string>;
5589
- readonly liveConversation: _angular_core.Signal<AXConversation>;
5590
- readonly isConversationMuted: _angular_core.Signal<boolean>;
5591
- readonly profileFields: _angular_core.Signal<_acorex_components_conversation.AXConversationInfoProfileField[]>;
5592
- readonly mediaCategories: _angular_core.Signal<AXConversationMediaCategory[]>;
5593
- readonly quickActions: _angular_core.Signal<AXInfoPanelQuickAction[]>;
5594
- readonly filteredMembers: _angular_core.Signal<AXConversationParticipant[]>;
5595
- ngOnInit(): void;
5596
- private loadConversationMessages;
5597
- loadMoreMedia(): Promise<void>;
5598
- isPrivateConversation(): boolean;
5599
- isGroupConversation(): boolean;
5600
- membersSectionTitle(): string;
5601
- getMemberRoleLabel(participant: AXConversationParticipant): string | null;
5602
- onMemberSearchChange(value: string | null | undefined): void;
5603
- setActiveTab(tab: 'profile' | 'manage'): void;
5604
- toggleMemberSearch(): void;
5605
- openMediaCategory(category: AXConversationMediaCategory): void;
5606
- closeMediaView(): void;
5607
- getMediaViewInputs(category: AXConversationMediaCategory): Record<string, unknown>;
5608
- getMediaRowLabel(category: AXConversationMediaCategory): string;
5609
- getMemberSubtitle(participant: AXConversationParticipant): string;
5610
- onQuickAction(actionId: string): void;
5611
- toggleConversationMute(): Promise<void>;
5612
- onNotificationsChange(value: boolean): Promise<void>;
5613
- onArchivedChange(value: boolean): Promise<void>;
5614
- close(data?: unknown): void;
5615
- closeAll(): void;
5616
- onLeave(): Promise<void>;
5617
- onGroupTitleChange(value: string): void;
5618
- onGroupAvatarChange(value: string): void;
5619
- private persistGroupDetails;
5620
- isBackgroundSelected(preset: {
5621
- id: string;
5622
- value: AXConversationMessageListThemeBackground;
5623
- }): boolean;
5624
- presetBackgroundPreview(preset: AXConversationMessageListThemeBackground): string;
5625
- applyMessageListBackground(value: AXConversationMessageListBackground): Promise<void>;
5626
- getBackgroundAriaLabel(label: string): string;
5627
- private translateBackgroundPresetLabel;
5628
- ngOnDestroy(): void;
5629
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<AXConversationInfoPanelComponent, never>;
5630
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<AXConversationInfoPanelComponent, "ax-conversation-info-panel", never, {}, { "onClosed": "onClosed"; }, never, never, true, never>;
5631
- }
5632
-
5633
- declare class AXConversationInfoMediaViewComponent {
5634
- private readonly translation;
5635
- private readonly parentInjector;
5636
- readonly category: _angular_core.InputSignal<AXConversationMediaCategory>;
5637
- readonly messages: _angular_core.InputSignal<AXConversationMessage[]>;
5638
- readonly conversation: _angular_core.InputSignal<AXConversation>;
5639
- readonly conversationServiceInput: _angular_core.InputSignal<AXConversationService>;
5640
- readonly hasMoreMedia: _angular_core.InputSignal<boolean>;
5641
- readonly loadingMoreMedia: _angular_core.InputSignal<boolean>;
5642
- readonly onLoadMoreMedia: _angular_core.InputSignal<() => void | Promise<void>>;
5643
- /** Callback for lazy outlet wiring (alternative to the `back` output). */
5644
- readonly onBack: _angular_core.InputSignal<() => void>;
5645
- readonly back: _angular_core.OutputEmitterRef<void>;
5646
- readonly items: _angular_core.Signal<AXConversationMessage[]>;
5647
- readonly isGrid: _angular_core.Signal<boolean>;
5648
- readonly isAttachmentList: _angular_core.Signal<boolean>;
5649
- readonly galleryTiles: _angular_core.Signal<_acorex_components_conversation.AXConversationMediaGalleryTile[]>;
5650
- readonly rendererInjector: _angular_core.Signal<_angular_core.DestroyableInjector>;
5651
- readonly titleLabel: _angular_core.Signal<string>;
5652
- readonly getMessageVideoItems: typeof getMessageVideoItems;
5653
- readonly getMessageAudioItems: typeof getMessageAudioItems;
5654
- getRendererComponent(message: AXConversationMessage): _angular_core.Type<_acorex_components_conversation.AXConversationMessageRendererComponent>;
5655
- getRendererComponentLoader(message: AXConversationMessage): (() => Promise<_angular_core.Type<_acorex_components_conversation.AXConversationMessageRendererComponent>>) | (() => Promise<typeof _acorex_components_conversation.AXConversationFallbackRendererComponent>);
5656
- getRendererInputs(message: AXConversationMessage): {
5657
- message: AXConversationMessage;
5658
- };
5659
- formatTimestamp(message: AXConversationMessage): string;
5660
- handleBack(): void;
5661
- onScrollThreshold(edge: 'top' | 'bottom'): void;
5662
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<AXConversationInfoMediaViewComponent, never>;
5663
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<AXConversationInfoMediaViewComponent, "ax-conversation-info-media-view", never, { "category": { "alias": "category"; "required": true; "isSignal": true; }; "messages": { "alias": "messages"; "required": true; "isSignal": true; }; "conversation": { "alias": "conversation"; "required": true; "isSignal": true; }; "conversationServiceInput": { "alias": "conversationService"; "required": true; "isSignal": true; }; "hasMoreMedia": { "alias": "hasMoreMedia"; "required": false; "isSignal": true; }; "loadingMoreMedia": { "alias": "loadingMoreMedia"; "required": false; "isSignal": true; }; "onLoadMoreMedia": { "alias": "onLoadMoreMedia"; "required": false; "isSignal": true; }; "onBack": { "alias": "onBack"; "required": false; "isSignal": true; }; }, { "back": "back"; }, never, never, true, never>;
5664
- }
5665
-
5666
5049
  declare class AXConversationInfoBarSearchComponent {
5667
5050
  private readonly platformId;
5668
5051
  private readonly destroyRef;
@@ -5705,7 +5088,7 @@ declare class AXConversationInfoBarSearchComponent {
5705
5088
  */
5706
5089
 
5707
5090
  /**
5708
- * Search in conversation action (inline)
5091
+ * Search in conversation action (inline on desktop, menu on mobile)
5709
5092
  */
5710
5093
  declare const AX_CONVERSATION_INFO_BAR_SEARCH_ACTION: AXConversationInfoBarAction;
5711
5094
  /**
@@ -6180,14 +5563,6 @@ declare const AX_CONVERSATION_MESSAGE_DELETE_ACTION: AXConversationMessageAction
6180
5563
  */
6181
5564
  declare const AX_CONVERSATION_MESSAGE_FORWARD_ACTION: AXConversationMessageAction;
6182
5565
 
6183
- /** Normalize payload; loads media normalizers on demand. */
6184
- declare function normalizeMessagePayloadAsync(payload: AXConversationMessagePayload): Promise<AXConversationMessagePayload>;
6185
- /**
6186
- * Sync normalize — uses cached normalizers when available.
6187
- * Media payloads pass through until a normalizer chunk has loaded (renderers normalize on display).
6188
- */
6189
- declare function normalizeMessagePayload(payload: AXConversationMessagePayload): AXConversationMessagePayload;
6190
-
6191
5566
  declare const AX_CONVERSATION_TEXT_RENDERER: AXConversationMessageRenderer;
6192
5567
 
6193
5568
  declare const AX_CONVERSATION_IMAGE_RENDERER: AXConversationMessageRenderer;
@@ -6269,6 +5644,7 @@ declare class AXConversationDefaultConversationAvatarComponent {
6269
5644
  displayAvatar: string;
6270
5645
  displayIcon: string;
6271
5646
  }>;
5647
+ readonly filteredUserAvatarInputs: _angular_core.Signal<Record<string, unknown>>;
6272
5648
  readonly fallbackDisplay: _angular_core.Signal<_acorex_components_conversation.AXConversationAvatarDisplay>;
6273
5649
  readonly fallbackInitials: _angular_core.Signal<string>;
6274
5650
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<AXConversationDefaultConversationAvatarComponent, never>;
@@ -6363,19 +5739,21 @@ interface AXConversationMessageListBackgroundPreset {
6363
5739
  id: string;
6364
5740
  value: AXConversationMessageListThemeBackground;
6365
5741
  }
6366
- /** Library default when no per-conversation or global background is set. */
5742
+ /** Library default when no per-conversation or global background is set (pattern-5 tile + gradient wash). */
6367
5743
  declare const AX_CONVERSATION_DEFAULT_MESSAGE_LIST_THEME_BACKGROUND: AXConversationMessageListThemeBackground;
6368
5744
  /** Predefined chat-area backgrounds for the info panel (light + dark variants). */
6369
5745
  declare const AX_CONVERSATION_MESSAGE_LIST_BACKGROUND_PRESETS: AXConversationMessageListBackgroundPreset[];
6370
5746
  declare const AX_CONVERSATION_DEFAULT_MESSAGE_LIST_BACKGROUND_PRESET_ID = "solid-default";
6371
5747
 
6372
- /** Subtle chat-area wash when `messageListBackground` is not set (theme-aware). */
5748
+ /** Subtle Telegram-style chat-area wash when `messageListBackground` is not set (theme-aware). */
6373
5749
  declare const AX_CONVERSATION_DEFAULT_MESSAGE_LIST_BACKGROUND: string;
6374
5750
  declare function isMessageListThemeBackground(value: unknown): value is AXConversationMessageListThemeBackground;
6375
5751
  /** Pick the raw CSS string for the active theme; `undefined` when unset. */
6376
5752
  declare function resolveMessageListBackgroundRaw(value: AXConversationMessageListBackground | undefined, isDark: boolean): string | undefined;
6377
5753
  /** Turn bare `https://...` or `/path` into valid CSS `background` for images. */
6378
5754
  declare function normalizeMessageListBackgroundValue(raw: string): string;
5755
+ /** Whether the built-in pattern-5 wallpaper (gradient + tiled SVG) should be used. */
5756
+ declare function usesDefaultMessageListWallpaper(value: AXConversationMessageListBackground | undefined): boolean;
6379
5757
  /** Resolve config/metadata background for the active theme, with library default fallback. */
6380
5758
  declare function resolveMessageListBackgroundStyle(value: AXConversationMessageListBackground | undefined, isDark: boolean): string;
6381
5759
  /** Whether two stored backgrounds represent the same preset (supports legacy string values). */
@@ -6433,92 +5811,38 @@ declare class AXConversationDateUtilsService {
6433
5811
  static formatTime(date: Date): string;
6434
5812
  }
6435
5813
 
5814
+ /**
5815
+ * Message Utilities Service
5816
+ * Helper functions for message formatting and display
5817
+ */
5818
+
6436
5819
  declare class AXConversationMessageUtilsService {
6437
- /**
6438
- * Normalize optional avatar/icon values so empty or whitespace-only strings
6439
- * are treated as missing data.
6440
- */
6441
- private static normalizeOptionalMediaValue;
6442
- /**
6443
- * Get conversation avatar image URL.
6444
- */
6445
- static getConversationAvatar(conversation: AXConversation): string | undefined;
6446
- /**
6447
- * Font Awesome icon class(es) for a conversation when there is no avatar image.
6448
- */
6449
- static getConversationAvatarIcon(conversation: AXConversation): string | undefined;
6450
- /**
6451
- * Font Awesome icon for a participant when there is no avatar image.
6452
- */
6453
- static getParticipantAvatarIcon(participant?: {
6454
- avatar?: string;
6455
- icon?: string;
6456
- }): string | undefined;
6457
- /**
6458
- * Get sender name from message
6459
- */
6460
- static getSenderName(message: AXConversationMessage, conversation: AXConversation): string;
6461
- /**
6462
- * Get sender avatar image URL (takes precedence over {@link getSenderAvatarIcon}).
6463
- */
6464
- static getSenderAvatar(message: AXConversationMessage, conversation: AXConversation): string | undefined;
6465
- /**
6466
- * Font Awesome icon class(es) for the sender when there is no avatar image:
6467
- * participant `icon` first, then conversation-level `icon`.
6468
- */
6469
- static getSenderAvatarIcon(message: AXConversationMessage, conversation: AXConversation): string | undefined;
6470
- /**
6471
- * Get initials from name
6472
- */
6473
5820
  static getInitials(name: string): string;
6474
- /**
6475
- * Type guard for text payload
6476
- */
6477
- static isTextPayload(payload: AXConversationMessagePayload): payload is AXConversationTextPayload;
6478
- /**
6479
- * Get message text content
6480
- */
6481
5821
  static getMessageText(message: AXConversationMessage): string;
6482
- /**
6483
- * Format message preview text
6484
- */
6485
5822
  static getPreviewText(message: AXConversationMessage, maxLength?: number): {
6486
5823
  value: string;
6487
5824
  type: string;
6488
5825
  icon: string;
6489
5826
  };
6490
- /**
6491
- * Check if message is from current user
6492
- */
6493
5827
  static isOwnMessage(message: AXConversationMessage, currentUserId: string): boolean;
6494
- /**
6495
- * Get message status icon class (Font Awesome)
6496
- */
5828
+ static getSenderName(message: AXConversationMessage, conversation: AXConversation): string;
5829
+ static getSenderAvatar(message: AXConversationMessage, conversation: AXConversation): string | undefined;
5830
+ static getSenderAvatarIcon(message: AXConversationMessage, conversation: AXConversation): string | undefined;
5831
+ static getConversationAvatar(conversation: AXConversation): string | undefined;
5832
+ static getConversationAvatarIcon(conversation: AXConversation): string | undefined;
6497
5833
  static getStatusIcon(message: AXConversationMessage): string;
6498
- /**
6499
- * Check if message should show avatar
6500
- */
6501
- static shouldShowAvatar(message: AXConversationMessage, previousMessage: AXConversationMessage | undefined, conversation: AXConversation): boolean;
6502
- /**
6503
- * Group messages by sender for consecutive messages
6504
- */
6505
- static shouldGroupWithPrevious(message: AXConversationMessage, previousMessage: AXConversationMessage | undefined): boolean;
6506
- /**
6507
- * Get conversation status for avatar (private conversations only)
6508
- */
6509
- static getConversationStatus(conversation: AXConversation): 'online' | 'offline' | 'away' | undefined;
6510
- /**
6511
- * Get typing indicator text for conversation
6512
- */
6513
- static getTypingText(conversation: AXConversation): string;
6514
- /**
6515
- * Format last seen time
6516
- */
5834
+ static getConversationStatus(conversation: AXConversation, presence?: AXConversationUserPresence): AXConversationPresenceStatus | undefined;
5835
+ static getDeliveryStatusIcon(status: AXConversationMessage['status']): string;
5836
+ static shouldGroupMessages(message: AXConversationMessage, previousMessage?: AXConversationMessage): boolean;
5837
+ static getUserPresenceStatus(presence?: AXConversationUserPresence): AXConversationPresenceStatus | undefined;
5838
+ static getTypingText(conversation: AXConversation, typingUserIds: string[]): string;
6517
5839
  static formatLastSeen(date: Date): string;
6518
- /**
6519
- * Get conversation subtitle (status or member count)
6520
- */
6521
- static getConversationSubtitle(conversation: AXConversation): string;
5840
+ static getPrivateChatSubtitle(conversation: AXConversation, presence?: AXConversationUserPresence, currentUserId?: string): string;
5841
+ static getConversationSubtitle(conversation: AXConversation, options?: {
5842
+ typingUserIds?: string[];
5843
+ peerPresence?: AXConversationUserPresence;
5844
+ currentUserId?: string;
5845
+ }): string;
6522
5846
  }
6523
5847
 
6524
5848
  /**
@@ -6616,6 +5940,52 @@ declare function copyWithFileTypeFallback(message: AXConversationMessage, regist
6616
5940
  /** Use file-type `open` on the message when `message.fileType` is set. */
6617
5941
  declare function openWithFileType(message: AXConversationMessage, registry: AXFileTypeRegistryService, ctx: AXFileTypeOpenContext): Promise<boolean>;
6618
5942
 
5943
+ interface AXConversationInfoProfileField {
5944
+ id: string;
5945
+ labelKey: string;
5946
+ value: string;
5947
+ icon: string;
5948
+ }
5949
+ type AXConversationMediaCategoryId = 'image' | 'video' | 'file' | 'audio' | 'voice' | 'sticker' | 'location' | 'link';
5950
+ interface AXConversationMediaCategory {
5951
+ id: AXConversationMediaCategoryId;
5952
+ labelKey: string;
5953
+ countLabelKey: string;
5954
+ icon: string;
5955
+ count: number;
5956
+ }
5957
+ declare function messageContainsLink(message: AXConversationMessage): boolean;
5958
+ declare function getPrivatePeerParticipant(conversation: AXConversation, currentUserId?: string): AXConversationParticipant | undefined;
5959
+ declare function getConversationProfileFields(conversation: AXConversation, currentUserId?: string): AXConversationInfoProfileField[];
5960
+ declare function getConversationMediaCategories(messages: AXConversationMessage[]): AXConversationMediaCategory[];
5961
+ declare function filterMessagesByMediaCategory(messages: AXConversationMessage[], categoryId: AXConversationMediaCategoryId): AXConversationMessage[];
5962
+ declare function isGridMediaCategory(categoryId: AXConversationMediaCategoryId): boolean;
5963
+ declare function isAttachmentListCategory(categoryId: AXConversationMediaCategoryId): boolean;
5964
+ interface AXConversationMediaGalleryTile {
5965
+ key: string;
5966
+ message: AXConversationMessage;
5967
+ kind: 'image' | 'video' | 'sticker';
5968
+ image?: AXConversationImageMediaItem;
5969
+ video?: AXConversationVideoMediaItem;
5970
+ stickerUrl?: string;
5971
+ stickerAlt?: string;
5972
+ }
5973
+ declare function buildMediaGalleryTiles(messages: AXConversationMessage[], categoryId: AXConversationMediaCategoryId): AXConversationMediaGalleryTile[];
5974
+ declare function resolveVideoThumbnailUrl(video: AXConversationVideoMediaItem): string | undefined;
5975
+ declare function resolveGalleryImageUrl(image: AXConversationImageMediaItem): string | undefined;
5976
+ declare function getMessageVideoItems(message: AXConversationMessage): AXConversationVideoMediaItem[];
5977
+ declare function getMessageAudioItems(message: AXConversationMessage): AXConversationAudioMediaItem[];
5978
+ interface AXConversationMediaPageResult {
5979
+ items: AXConversationMessage[];
5980
+ hasMore: boolean;
5981
+ nextCursor?: string;
5982
+ page: number;
5983
+ }
5984
+ declare function fetchConversationMediaPage(conversationApi: AXConversationApi, conversationId: string, page: number, pageSize?: number, cursor?: string): Promise<AXConversationMediaPageResult>;
5985
+ /** Merge media API results with in-memory messages needed for link/sticker/voice/location tabs. */
5986
+ declare function mergeInfoPanelMessages(mediaMessages: AXConversationMessage[], supplemental: AXConversationMessage[]): AXConversationMessage[];
5987
+ declare function filterSupplementalInfoPanelMessages(messages: AXConversationMessage[]): AXConversationMessage[];
5988
+
6619
5989
  /**
6620
5990
  * Error Message Constants
6621
5991
  * Centralized error messages with i18n support structure
@@ -7008,5 +6378,5 @@ declare function getErrorMessage(code: string, params?: Record<string, string |
7008
6378
  */
7009
6379
  type AXConversationErrorCode = typeof AX_CONVERSATION_MESSAGE_ERRORS[keyof typeof AX_CONVERSATION_MESSAGE_ERRORS]['code'] | typeof AX_CONVERSATION_FILE_ERRORS[keyof typeof AX_CONVERSATION_FILE_ERRORS]['code'] | typeof AX_CONVERSATION_USER_ERRORS[keyof typeof AX_CONVERSATION_USER_ERRORS]['code'] | typeof AX_CONVERSATION_ERRORS[keyof typeof AX_CONVERSATION_ERRORS]['code'] | typeof AX_CONVERSATION_CONNECTION_ERRORS[keyof typeof AX_CONVERSATION_CONNECTION_ERRORS]['code'] | typeof AX_CONVERSATION_LOCATION_ERRORS[keyof typeof AX_CONVERSATION_LOCATION_ERRORS]['code'] | typeof AX_CONVERSATION_URL_ERRORS[keyof typeof AX_CONVERSATION_URL_ERRORS]['code'];
7010
6380
 
7011
- export { AXConversationAiResponderService, AXConversationApi, AXConversationApiLoggerService, AXConversationAudioAttachmentComponent, AXConversationAudioFileTypeProvider, AXConversationAudioPickerComponent, AXConversationAudioRendererComponent, AXConversationBaseRegistry, AXConversationComposerActionRegistry, AXConversationComposerComponent, AXConversationComposerFileTypesProvider, AXConversationComposerPopupComponent, AXConversationComposerService, AXConversationComposerTabRegistry, AXConversationContainerComponent, AXConversationContainerDirective, AXConversationDateUtilsService, AXConversationEmojiTabComponent, AXConversationErrorHandlerService, AXConversationFallbackRendererComponent, AXConversationFileAttachmentComponent, AXConversationFileFileTypeProvider, AXConversationFilePickerComponent, AXConversationFileRendererComponent, AXConversationForwardMessageDialogComponent, AXConversationImageAttachmentComponent, AXConversationImageFileTypeProvider, AXConversationImagePickerComponent, AXConversationImageRendererComponent, AXConversationIndexedDbConversationApi, AXConversationIndexedDbMessageAiApi, AXConversationIndexedDbMessageApi, AXConversationIndexedDbRealtimeApi, AXConversationIndexedDbStorage, AXConversationIndexedDbStores, AXConversationIndexedDbUserApi, AXConversationInfiniteScrollDirective, AXConversationInfoBarActionRegistry, AXConversationInfoBarComponent, AXConversationInfoBarSearchComponent, AXConversationInfoBarService, AXConversationInfoMediaViewComponent, AXConversationInfoPanelComponent, AXConversationItemActionRegistry, AXConversationLocationPickerComponent, AXConversationLocationRendererComponent, AXConversationMediaPlaybackInfoBarBannerComponent, AXConversationMessageActionRegistry, AXConversationMessageApi, AXConversationMessageListComponent, AXConversationMessageListNoActiveDefaultComponent, AXConversationMessageListService, AXConversationMessageRendererCopyHostComponent, AXConversationMessageRendererRegistry, AXConversationMessageRendererStateComponent, AXConversationMessageUtilsService, AXConversationModule, AXConversationNewDialogComponent, AXConversationPickerCaptionComponent, AXConversationPickerEmptyComponent, AXConversationPickerFooterComponent, AXConversationPickerHeaderComponent, AXConversationPickerShellComponent, AXConversationPickerToolbarComponent, AXConversationRealtimeApi, AXConversationRegistryService, AXConversationService, AXConversationSharedStorage, AXConversationSidebarComponent, AXConversationSidebarService, AXConversationStickerRendererComponent, AXConversationStickerTabComponent, AXConversationSystemRendererComponent, AXConversationTabRegistry, AXConversationTextRendererComponent, AXConversationUserApi, AXConversationVideoAttachmentComponent, AXConversationVideoFileTypeProvider, AXConversationVideoPickerComponent, AXConversationVideoRendererComponent, AXConversationVoiceFileTypeProvider, AXConversationVoiceRecorderComponent, AXConversationVoiceRendererComponent, AX_CONVERSATION_AI_API_KEY, AX_CONVERSATION_AUDIO_CATALOG, AX_CONVERSATION_AUDIO_PRESENTATION, AX_CONVERSATION_AUDIO_RENDERER, AX_CONVERSATION_BUILTIN_COMPOSER_TABS, AX_CONVERSATION_COMPOSER_AUDIO_ACTION, AX_CONVERSATION_COMPOSER_EMOJI_ACTION, AX_CONVERSATION_COMPOSER_EMOJI_TAB, AX_CONVERSATION_COMPOSER_FILE_ACTION, AX_CONVERSATION_COMPOSER_IMAGE_ACTION, AX_CONVERSATION_COMPOSER_LOCATION_ACTION, AX_CONVERSATION_COMPOSER_STICKER_TAB, AX_CONVERSATION_COMPOSER_VIDEO_ACTION, AX_CONVERSATION_COMPOSER_VOICE_RECORDING_ACTION, AX_CONVERSATION_CONFIG, AX_CONVERSATION_CONNECTION_ERRORS, AX_CONVERSATION_CONVERSATION_AVATAR_COMPONENT, AX_CONVERSATION_CURSOR_PREFIX, AX_CONVERSATION_DEFAULT_COMPOSER_ACTIONS, AX_CONVERSATION_DEFAULT_COMPOSER_TABS, AX_CONVERSATION_DEFAULT_CONVERSATION_ITEM_ACTIONS, AX_CONVERSATION_DEFAULT_CONVERSATION_TABS, AX_CONVERSATION_DEFAULT_GROUP_ICON, AX_CONVERSATION_DEFAULT_INFO_BAR_ACTIONS, AX_CONVERSATION_DEFAULT_MESSAGE_ACTIONS, AX_CONVERSATION_DEFAULT_MESSAGE_LIST_BACKGROUND, AX_CONVERSATION_DEFAULT_MESSAGE_LIST_BACKGROUND_PRESET_ID, AX_CONVERSATION_DEFAULT_MESSAGE_LIST_THEME_BACKGROUND, AX_CONVERSATION_DEFAULT_MESSAGE_RENDERERS, AX_CONVERSATION_DEFAULT_USER_ICON, AX_CONVERSATION_DEMO_CONVERSATION_IDS, AX_CONVERSATION_ERRORS, AX_CONVERSATION_ERROR_HANDLER_CONFIG, AX_CONVERSATION_ERROR_MESSAGES, AX_CONVERSATION_FALLBACK_RENDERER, AX_CONVERSATION_FILE_CATALOG, AX_CONVERSATION_FILE_ERRORS, AX_CONVERSATION_FILE_PRESENTATION, AX_CONVERSATION_FILE_RENDERER, AX_CONVERSATION_FILE_TYPES_READY, AX_CONVERSATION_IMAGE_CATALOG, AX_CONVERSATION_IMAGE_PRESENTATION, AX_CONVERSATION_IMAGE_RENDERER, AX_CONVERSATION_INFO_BAR_ARCHIVE_ACTION, AX_CONVERSATION_INFO_BAR_BLOCK_ACTION, AX_CONVERSATION_INFO_BAR_DELETE_ACTION, AX_CONVERSATION_INFO_BAR_DIVIDER, AX_CONVERSATION_INFO_BAR_MUTE_ACTION, AX_CONVERSATION_INFO_BAR_SEARCH_ACTION, AX_CONVERSATION_ITEM_BLOCK_ACTION, AX_CONVERSATION_ITEM_DELETE_ACTION, AX_CONVERSATION_ITEM_DIVIDER, AX_CONVERSATION_ITEM_MARK_READ_ACTION, AX_CONVERSATION_ITEM_MUTE_ACTION, AX_CONVERSATION_ITEM_PIN_ACTION, AX_CONVERSATION_LOCATION_ERRORS, AX_CONVERSATION_LOCATION_RENDERER, AX_CONVERSATION_MESSAGE_CURSOR_PREFIX, AX_CONVERSATION_MESSAGE_DELETE_ACTION, AX_CONVERSATION_MESSAGE_EDIT_ACTION, AX_CONVERSATION_MESSAGE_ERRORS, AX_CONVERSATION_MESSAGE_FORWARD_ACTION, AX_CONVERSATION_MESSAGE_LIST_BACKGROUND_PRESETS, AX_CONVERSATION_MESSAGE_REPLY_ACTION, AX_CONVERSATION_MESSAGE_TYPE_FILE_TYPE, AX_CONVERSATION_PEER_AVATAR_TYPES, AX_CONVERSATION_REGISTRY_CONFIG, AX_CONVERSATION_STICKER_API_KEY, AX_CONVERSATION_STICKER_RENDERER, AX_CONVERSATION_SYSTEM_RENDERER, AX_CONVERSATION_TAB_ALL, AX_CONVERSATION_TAB_ARCHIVED, AX_CONVERSATION_TAB_BOT, AX_CONVERSATION_TAB_CHANNELS, AX_CONVERSATION_TAB_GROUPS, AX_CONVERSATION_TAB_PRIVATE, AX_CONVERSATION_TAB_UNREAD, AX_CONVERSATION_TEXT_RENDERER, AX_CONVERSATION_URL_ERRORS, AX_CONVERSATION_USER_AVATAR_COMPONENT, AX_CONVERSATION_USER_ERRORS, AX_CONVERSATION_VIDEO_CATALOG, AX_CONVERSATION_VIDEO_PRESENTATION, AX_CONVERSATION_VIDEO_RENDERER, AX_CONVERSATION_VOICE_CATALOG, AX_CONVERSATION_VOICE_PRESENTATION, AX_CONVERSATION_VOICE_RENDERER, AX_DEFAULT_CONVERSATION_CONFIG, AX_MESSAGE_PAGINATION_CONVERSATION_ID, abortPickerUploads, applyAudioLocalPreview, applyConversationFilters, applyFileLocalPreview, applyLocalPreview, applyVideoLocalPreview, applyVoiceLocalPreview, audioItemFromUpload, axConversationIndexedDbStorage, axConversationSharedStorage, bindMediaRendererContentState, buildMediaGalleryTiles, canShowRendererContentError, cleanupPickerUploads, conversationAudioUtilities, conversationFileUtilities, conversationImageUtilities, conversationVideoUtilities, conversationVoiceUtilities, copyWithFileTypeFallback, createConversationAudioFileType, createConversationFileFileType, createConversationImageFileType, createConversationVideoFileType, createConversationVoiceFileType, createLocalPreviewUrl, createObjectUrl, createPickerDragHandlers, createResolvedMediaUrlSignal, deleteUploadedPickerMedia, dismissComposerPickerHost, encodeConversationCursor, encodeMessageCursor, ensurePaginationDemoData, fetchConversationMediaMessages, fetchConversationMediaPage, fileItemFromUpload, filterMessagesByMediaCategory, filterSupplementalInfoPanelMessages, findExistingPrivateConversation, formatDuration, formatErrorMessage, formatFileByteSize, formatFileSize, formatMediaDuration, formatPickerValidationMessage, getConversationLastActivity, getConversationMediaCategories, getConversationMessagesNewestFirst, getConversationProfileFields, getErrorMessage, getMessageAudioItems, getMessageVideoItems, getPickerCancelUploadLabel, getPrivatePeerParticipant, getSortedConversationsForInbox, inferFileExtensionHintFromMessage, isAttachmentListCategory, isComposerTabEnabled, isConversationReactionsEnabled, isGenericPrivateConversationTitle, isGridMediaCategory, isMessageDeliveryPending, isMessageListThemeBackground, isNonPersistableMediaUrl, isPickerItemReadyToSend, isSameMessageListBackground, isUploadAborted, limitFilesToCapacity, mediaCopyText, mergeAudioUploadResult, mergeFileUploadResult, mergeInfoPanelMessages, mergeUploadResult, mergeVideoUploadResult, mergeVoiceUploadResult, mergeWithDefaults, messageContainsLink, normalizeAllConversationMessageIndexes, normalizeAudioPayload, normalizeFilePayload, normalizeImagePayload, normalizeMessageListBackgroundValue, normalizeMessagePayload, normalizeMessagePayloadAsync, normalizeVideoPayload, notifyMaxFilesCapacityExceeded, notifyPickerValidationErrors, openWithFileType, paginateChatNewestFirst, paginateChatOldestFirst, parseChatCursor, pickDisplayMediaUrl, pickerItemToMediaReference, pickerItemToUploadResult, provideConversation, provideConversationComposerFileTypes, provideConversationFileCatalog, registerChatMessage, reportMediaLoadError, resolveComposerMaxFiles, resolveConversationAvatarDisplay, resolveConversationComposerTabs, resolveConversationForViewer, resolveConversationMessageFileType, resolveConversationPeerParticipant, resolveConversationPeerUserId, resolveConversationTitleForViewer, resolveGalleryImageUrl, resolveImageDisplayUrl, resolveMessageListBackgroundRaw, resolveMessageListBackgroundStyle, resolveParticipantProfile, resolvePersistableMediaUrl, resolvePersistedThumbnailUrl, resolvePrivatePeerParticipant, resolvePrivatePeerUserId, resolveUserAvatarDisplay, resolveVideoThumbnailUrl, revokeObjectUrl, revokePickerBlobPreviews, sanitizeInput, seedPickerInitialFiles, seedSharedStorageInitialData, shouldUseUserAvatarForConversation, sortConversationMessageIds, syncPlaybackInfoBarBanner, toUploaderReference as toMediaItemUploaderReference, toUploaderReference$1 as toUploaderReference, unregisterChatMessage, uploadPickerFile, validateConversationId, validateEmail, validateLatitude, validateLongitude, validateMessagePayload, validateMessageText, validateMessageType, validateUrl, validateUserId, validateUserIds, videoItemFromUpload };
7012
- export type { AXConversation, AXConversationAiResponderConfig, AXConversationApiError, AXConversationApiLogEntry, AXConversationApiName, AXConversationAudioMediaItem, AXConversationAudioPayload, AXConversationAvatarComponents, AXConversationAvatarDisplay, AXConversationAvatarKind, AXConversationBlockReportReason, AXConversationCallEvent, AXConversationChatCursorKind, AXConversationCleanupPickerUploadsOptions, AXConversationComposerAction, AXConversationComposerActionComponent, AXConversationComposerActionContext, AXConversationComposerActiveComponent, AXConversationComposerPickerUploadItem, AXConversationComposerTab, AXConversationComposerTabFeature, AXConversationConfig, AXConversationConnectionEvent, AXConversationConnectionOptions, AXConversationConnectionStatus, AXConversationConversationAvatarComponent, AXConversationCreateData, AXConversationDeleteMessageCommand, AXConversationDropdownMenuItem, AXConversationEditMessageCommand, AXConversationError, AXConversationErrorCode, AXConversationErrorHandlerConfig, AXConversationErrorMessage, AXConversationErrorSeverity, AXConversationFeatures, AXConversationFileMediaItem, AXConversationFilePayload, AXConversationFilter, AXConversationFilters, AXConversationGroupedReaction, AXConversationImageMediaItem, AXConversationImagePayload, AXConversationIndexedDbMediaRecord, AXConversationInfoBarAction, AXConversationInfoBarActionComponent, AXConversationInfoBarActionContext, AXConversationInfoBarActiveBanner, AXConversationInfoBarActiveComponent, AXConversationInfoProfileField, AXConversationItemAction, AXConversationItemActionContext, AXConversationLink, AXConversationLinkPreview, AXConversationLoadMessagesResult, AXConversationLocationPayload, AXConversationMediaCategory, AXConversationMediaCategoryId, AXConversationMediaGalleryTile, AXConversationMediaItemFields, AXConversationMediaPageResult, AXConversationMention, AXConversationMessage, AXConversationMessageAction, AXConversationMessageActionContext, AXConversationMessageForwardData, AXConversationMessageInfoBarBannerComponent, AXConversationMessageListBackground, AXConversationMessageListBackgroundPreset, AXConversationMessageListEmptyComponent, AXConversationMessageListThemeBackground, AXConversationMessagePayload, AXConversationMessageRenderer, AXConversationMessageRendererCapabilities, AXConversationMessageRendererComponent, AXConversationMessageRendererContentState, AXConversationMessageRendererState, AXConversationMessageSearchFilters, AXConversationMessageStatus, AXConversationMessageType, AXConversationMetadata, AXConversationNotificationEvent, AXConversationOptions, AXConversationPaginatedResult, AXConversationPagination, AXConversationPaginationState, AXConversationParsedChatCursor, AXConversationParticipant, AXConversationParticipantRole, AXConversationParticipantStatus, AXConversationParticipantUpdate, AXConversationPinnedMessage, AXConversationPlaybackBannerInputs, AXConversationPollOption, AXConversationPollPayload, AXConversationPresenceStatus, AXConversationPresenceUpdate, AXConversationReaction, AXConversationReadReceipt, AXConversationRegistryConfiguration, AXConversationRegistryItem, AXConversationSendMessageCommand, AXConversationSendMessageOptions, AXConversationSendMessageUploadSource, AXConversationSettings, AXConversationSettingsUpdate, AXConversationSort, AXConversationStatus, AXConversationStickerPayload, AXConversationSystemPayload, AXConversationTab, AXConversationTextFormat, AXConversationTextPayload, AXConversationType, AXConversationTypingIndicator, AXConversationUpdateData, AXConversationUploadOptions, AXConversationUploaderFilePreview, AXConversationUploaderReference, AXConversationUploaderResult, AXConversationUserAvatarComponent, AXConversationUserProfile, AXConversationUserProfileUpdate, AXConversationUserRole, AXConversationUserSearchFilters, AXConversationValidationResult, AXConversationVideoMediaItem, AXConversationVideoPayload, AXConversationVoicePayload };
6381
+ export { AXConversationApi, AXConversationApiLoggerService, AXConversationAudioAttachmentComponent, AXConversationAudioFileTypeProvider, AXConversationAudioPickerComponent, AXConversationAudioRendererComponent, AXConversationAvatarComponent, AXConversationAvatarPickerComponent, AXConversationBaseRegistry, AXConversationComposerActionRegistry, AXConversationComposerComponent, AXConversationComposerFileTypesProvider, AXConversationComposerGenerationStateService, AXConversationComposerPopupComponent, AXConversationComposerService, AXConversationComposerTabRegistry, AXConversationContainerComponent, AXConversationContainerDirective, AXConversationDateUtilsService, AXConversationEmojiTabComponent, AXConversationErrorHandlerService, AXConversationFallbackRendererComponent, AXConversationFileAttachmentComponent, AXConversationFileFileTypeProvider, AXConversationFilePickerComponent, AXConversationFileRendererComponent, AXConversationForwardMessageDialogComponent, AXConversationImageAttachmentComponent, AXConversationImageFileTypeProvider, AXConversationImagePickerComponent, AXConversationImageRendererComponent, AXConversationInfiniteScrollDirective, AXConversationInfoBarActionRegistry, AXConversationInfoBarComponent, AXConversationInfoBarSearchComponent, AXConversationInfoBarService, AXConversationItemActionRegistry, AXConversationLocationPickerComponent, AXConversationLocationRendererComponent, AXConversationMediaPlaybackInfoBarBannerComponent, AXConversationMessageActionRegistry, AXConversationMessageApi, AXConversationMessageListComponent, AXConversationMessageListNoActiveDefaultComponent, AXConversationMessageListService, AXConversationMessageRendererCopyHostComponent, AXConversationMessageRendererRegistry, AXConversationMessageRendererStateComponent, AXConversationMessageUtilsService, AXConversationModule, AXConversationNewDialogComponent, AXConversationPickerCaptionComponent, AXConversationPickerEmptyComponent, AXConversationPickerFooterComponent, AXConversationPickerHeaderComponent, AXConversationPickerShellComponent, AXConversationPickerToolbarComponent, AXConversationRealtimeApi, AXConversationRegistryComponentOutletComponent, AXConversationRegistryService, AXConversationService, AXConversationSidebarComponent, AXConversationSidebarService, AXConversationStickerRendererComponent, AXConversationStickerTabComponent, AXConversationSystemRendererComponent, AXConversationTabRegistry, AXConversationTextRendererComponent, AXConversationUserApi, AXConversationVideoAttachmentComponent, AXConversationVideoFileTypeProvider, AXConversationVideoPickerComponent, AXConversationVideoRendererComponent, AXConversationVoiceFileTypeProvider, AXConversationVoiceRecorderComponent, AXConversationVoiceRendererComponent, AX_CONVERSATION_AUDIO_CATALOG, AX_CONVERSATION_AUDIO_PRESENTATION, AX_CONVERSATION_AUDIO_RENDERER, AX_CONVERSATION_BUILTIN_COMPOSER_TABS, AX_CONVERSATION_COMPOSER_AUDIO_ACTION, AX_CONVERSATION_COMPOSER_EMOJI_ACTION, AX_CONVERSATION_COMPOSER_EMOJI_TAB, AX_CONVERSATION_COMPOSER_FILE_ACTION, AX_CONVERSATION_COMPOSER_IMAGE_ACTION, AX_CONVERSATION_COMPOSER_LOCATION_ACTION, AX_CONVERSATION_COMPOSER_STICKER_TAB, AX_CONVERSATION_COMPOSER_VIDEO_ACTION, AX_CONVERSATION_COMPOSER_VOICE_RECORDING_ACTION, AX_CONVERSATION_CONFIG, AX_CONVERSATION_CONNECTION_ERRORS, AX_CONVERSATION_CONVERSATION_AVATAR_COMPONENT, AX_CONVERSATION_DEFAULT_COMPOSER_ACTIONS, AX_CONVERSATION_DEFAULT_COMPOSER_TABS, AX_CONVERSATION_DEFAULT_CONVERSATION_ITEM_ACTIONS, AX_CONVERSATION_DEFAULT_CONVERSATION_TABS, AX_CONVERSATION_DEFAULT_GROUP_ICON, AX_CONVERSATION_DEFAULT_INFO_BAR_ACTIONS, AX_CONVERSATION_DEFAULT_MESSAGE_ACTIONS, AX_CONVERSATION_DEFAULT_MESSAGE_LIST_BACKGROUND, AX_CONVERSATION_DEFAULT_MESSAGE_LIST_BACKGROUND_PRESET_ID, AX_CONVERSATION_DEFAULT_MESSAGE_LIST_THEME_BACKGROUND, AX_CONVERSATION_DEFAULT_MESSAGE_RENDERERS, AX_CONVERSATION_DEFAULT_ROOM_PREFERENCES, AX_CONVERSATION_DEFAULT_USER_ICON, AX_CONVERSATION_ERRORS, AX_CONVERSATION_ERROR_HANDLER_CONFIG, AX_CONVERSATION_ERROR_MESSAGES, AX_CONVERSATION_FALLBACK_RENDERER, AX_CONVERSATION_FILE_CATALOG, AX_CONVERSATION_FILE_ERRORS, AX_CONVERSATION_FILE_PRESENTATION, AX_CONVERSATION_FILE_RENDERER, AX_CONVERSATION_FILE_TYPES_READY, AX_CONVERSATION_IMAGE_CATALOG, AX_CONVERSATION_IMAGE_PRESENTATION, AX_CONVERSATION_IMAGE_RENDERER, AX_CONVERSATION_INFO_BAR_ARCHIVE_ACTION, AX_CONVERSATION_INFO_BAR_BLOCK_ACTION, AX_CONVERSATION_INFO_BAR_DELETE_ACTION, AX_CONVERSATION_INFO_BAR_DIVIDER, AX_CONVERSATION_INFO_BAR_MUTE_ACTION, AX_CONVERSATION_INFO_BAR_SEARCH_ACTION, AX_CONVERSATION_ITEM_BLOCK_ACTION, AX_CONVERSATION_ITEM_DELETE_ACTION, AX_CONVERSATION_ITEM_DIVIDER, AX_CONVERSATION_ITEM_MARK_READ_ACTION, AX_CONVERSATION_ITEM_MUTE_ACTION, AX_CONVERSATION_ITEM_PIN_ACTION, AX_CONVERSATION_LOCATION_ERRORS, AX_CONVERSATION_LOCATION_RENDERER, AX_CONVERSATION_MESSAGE_DELETE_ACTION, AX_CONVERSATION_MESSAGE_EDIT_ACTION, AX_CONVERSATION_MESSAGE_ERRORS, AX_CONVERSATION_MESSAGE_FORWARD_ACTION, AX_CONVERSATION_MESSAGE_LIST_BACKGROUND_PRESETS, AX_CONVERSATION_MESSAGE_REPLY_ACTION, AX_CONVERSATION_MESSAGE_TYPE_FILE_TYPE, AX_CONVERSATION_PEER_AVATAR_TYPES, AX_CONVERSATION_REGISTRY_CONFIG, AX_CONVERSATION_STICKER_API_KEY, AX_CONVERSATION_STICKER_RENDERER, AX_CONVERSATION_SYSTEM_RENDERER, AX_CONVERSATION_TAB_ALL, AX_CONVERSATION_TAB_ARCHIVED, AX_CONVERSATION_TAB_BOT, AX_CONVERSATION_TAB_CHANNELS, AX_CONVERSATION_TAB_GROUPS, AX_CONVERSATION_TAB_PRIVATE, AX_CONVERSATION_TAB_UNREAD, AX_CONVERSATION_TEXT_RENDERER, AX_CONVERSATION_URL_ERRORS, AX_CONVERSATION_USER_AVATAR_COMPONENT, AX_CONVERSATION_USER_ERRORS, AX_CONVERSATION_VIDEO_CATALOG, AX_CONVERSATION_VIDEO_PRESENTATION, AX_CONVERSATION_VIDEO_RENDERER, AX_CONVERSATION_VOICE_CATALOG, AX_CONVERSATION_VOICE_PRESENTATION, AX_CONVERSATION_VOICE_RENDERER, AX_DEFAULT_CONVERSATION_CONFIG, abortPickerUploads, applyAudioLocalPreview, applyFileLocalPreview, applyLocalPreview, applyVideoLocalPreview, applyVoiceLocalPreview, audioItemFromUpload, bindMediaRendererContentState, buildMediaGalleryTiles, canShowRendererContentError, cleanupPickerUploads, conversationAudioUtilities, conversationFileUtilities, conversationImageUtilities, conversationVideoUtilities, conversationVoiceUtilities, copyWithFileTypeFallback, createConversationAudioFileType, createConversationFileFileType, createConversationImageFileType, createConversationVideoFileType, createConversationVoiceFileType, createLocalPreviewUrl, createObjectUrl, createPickerDragHandlers, createPickerUploadItemId, createResolvedMediaUrlSignal, deleteUploadedPickerMedia, dismissComposerPickerHost, ensureConversationFileCatalogRegistered, fetchConversationMediaPage, fileItemFromUpload, filterMessagesByMediaCategory, filterSupplementalInfoPanelMessages, findExistingPrivateConversation, formatDuration, formatErrorMessage, formatFileByteSize, formatFileSize, formatMediaDuration, formatPickerValidationMessage, getConversationMediaCategories, getConversationProfileFields, getErrorMessage, getMessageAudioItems, getMessageVideoItems, getPickerCancelUploadLabel, getPrivatePeerParticipant, hasRegistryComponent, inferFileExtensionHintFromMessage, isAttachmentListCategory, isComposerTabEnabled, isConversationReactionsEnabled, isGenericPrivateConversationTitle, isGridMediaCategory, isMessageDeliveryPending, isMessageListThemeBackground, isNonPersistableMediaUrl, isPickerItemReadyToSend, isSameMessageListBackground, isUploadAborted, limitFilesToCapacity, mediaCopyText, mergeAudioUploadResult, mergeFileUploadResult, mergeInfoPanelMessages, mergeUploadResult, mergeVideoUploadResult, mergeVoiceUploadResult, mergeWithDefaults, messageContainsLink, normalizeAudioPayload, normalizeFilePayload, normalizeImagePayload, normalizeMessageListBackgroundValue, normalizeVideoPayload, notifyMaxFilesCapacityExceeded, notifyPickerValidationErrors, openWithFileType, pickDisplayMediaUrl, pickerItemToMediaReference, pickerItemToUploadResult, provideConversation, provideConversationComposerFileTypes, provideConversationFileCatalog, reportMediaLoadError, resolveComposerMaxFiles, resolveConversationAvatarDisplay, resolveConversationComposerTabs, resolveConversationForViewer, resolveConversationMessageFileType, resolveConversationPeerParticipant, resolveConversationPeerUserId, resolveConversationTitleForViewer, resolveGalleryImageUrl, resolveImageDisplayUrl, resolveMessageListBackgroundRaw, resolveMessageListBackgroundStyle, resolveParticipantProfile, resolvePersistableMediaUrl, resolvePersistedThumbnailUrl, resolvePrivatePeerParticipant, resolvePrivatePeerUserId, resolveUserAvatarDisplay, resolveVideoThumbnailUrl, revokeObjectUrl, revokePickerBlobPreviews, sanitizeInput, shouldUseUserAvatarForConversation, syncPlaybackInfoBarBanner, toUploaderReference as toMediaItemUploaderReference, toUploaderReference$1 as toUploaderReference, uploadPickerFile, usesDefaultMessageListWallpaper, validateConversationId, validateEmail, validateLatitude, validateLongitude, validateMessagePayload, validateMessageText, validateMessageType, validateUrl, validateUserId, validateUserIds, videoItemFromUpload };
6382
+ export type { AXConversation, AXConversationApiError, AXConversationApiLogEntry, AXConversationApiName, AXConversationAudioMediaItem, AXConversationAudioPayload, AXConversationAvatarComponents, AXConversationAvatarDisplay, AXConversationAvatarKind, AXConversationBlockReportReason, AXConversationCleanupPickerUploadsOptions, AXConversationComposerAction, AXConversationComposerActionComponent, AXConversationComposerActionContext, AXConversationComposerGenerationPhase, AXConversationComposerPickerUploadItem, AXConversationComposerPrimaryButtonMode, AXConversationComposerTab, AXConversationComposerTabFeature, AXConversationConfig, AXConversationConnectionStatus, AXConversationConversationAvatarComponent, AXConversationCreateData, AXConversationDeleteMessageCommand, AXConversationDropdownMenuItem, AXConversationEditMessageCommand, AXConversationError, AXConversationErrorCode, AXConversationErrorHandlerConfig, AXConversationErrorMessage, AXConversationErrorSeverity, AXConversationFeatures, AXConversationFileMediaItem, AXConversationFilePayload, AXConversationFilter, AXConversationFilters, AXConversationGroupedReaction, AXConversationImageMediaItem, AXConversationImagePayload, AXConversationInfoBarAction, AXConversationInfoBarActionComponent, AXConversationInfoBarActionContext, AXConversationInfoBarActiveBanner, AXConversationInfoBarActiveComponent, AXConversationInfoProfileField, AXConversationItemAction, AXConversationItemActionContext, AXConversationLink, AXConversationLinkPreview, AXConversationLoadMessagesResult, AXConversationLocationPayload, AXConversationMediaCategory, AXConversationMediaCategoryId, AXConversationMediaGalleryTile, AXConversationMediaItemFields, AXConversationMediaPageResult, AXConversationMention, AXConversationMessage, AXConversationMessageAction, AXConversationMessageActionContext, AXConversationMessageForwardData, AXConversationMessageInfoBarBannerComponent, AXConversationMessageListBackground, AXConversationMessageListBackgroundPreset, AXConversationMessageListEmptyComponent, AXConversationMessageListThemeBackground, AXConversationMessagePayload, AXConversationMessageRenderer, AXConversationMessageRendererCapabilities, AXConversationMessageRendererComponent, AXConversationMessageRendererContentState, AXConversationMessageRendererState, AXConversationMessageSearchFilters, AXConversationMessageStatus, AXConversationMessageType, AXConversationMetadata, AXConversationOptions, AXConversationPaginatedResult, AXConversationPagination, AXConversationPaginationState, AXConversationParticipant, AXConversationParticipantRole, AXConversationParticipantUpdate, AXConversationPinnedMessage, AXConversationPlaybackBannerInputs, AXConversationPollOption, AXConversationPollPayload, AXConversationPresenceStatus, AXConversationPresenceUpdate, AXConversationReaction, AXConversationReadReceipt, AXConversationRegistryComponentRef, AXConversationRegistryConfiguration, AXConversationRegistryItem, AXConversationRoomPreferences, AXConversationRoomPreferencesMap, AXConversationSendMessageCommand, AXConversationSendMessageOptions, AXConversationSendMessageUploadSource, AXConversationSettingsUpdate, AXConversationSidebarTabsOrientation, AXConversationSort, AXConversationStickerPayload, AXConversationSystemPayload, AXConversationTab, AXConversationTextFormat, AXConversationTextPayload, AXConversationType, AXConversationTypingIndicator, AXConversationUpdateData, AXConversationUploadOptions, AXConversationUploaderFilePreview, AXConversationUploaderReference, AXConversationUploaderResult, AXConversationUser, AXConversationUserAvatarComponent, AXConversationUserPresence, AXConversationUserProfile, AXConversationUserProfileUpdate, AXConversationUserSearchFilters, AXConversationValidationResult, AXConversationVideoMediaItem, AXConversationVideoPayload, AXConversationVoicePayload };