From 39f5f8b8857f679dbb29a0ed2e22e57ceccac906 Mon Sep 17 00:00:00 2001 From: rajdubey Date: Wed, 1 Jul 2026 15:48:51 +0530 Subject: [PATCH 1/2] Updated v5 docs to remove broken/unwanted code --- ui-kit/angular/api-reference/introduction.mdx | 5 +- .../components/cometchat-audio-bubble.mdx | 12 +- .../components/cometchat-call-buttons.mdx | 8 +- ...ometchat-collaborative-document-bubble.mdx | 14 +- ...etchat-collaborative-whiteboard-bubble.mdx | 14 +- .../cometchat-conversation-item.mdx | 2 +- .../components/cometchat-conversations.mdx | 2 +- .../components/cometchat-file-bubble.mdx | 8 +- .../components/cometchat-group-item.mdx | 12 +- .../cometchat-group-member-item.mdx | 12 +- .../components/cometchat-group-members.mdx | 118 ++++--------- .../angular/components/cometchat-groups.mdx | 26 ++- .../components/cometchat-image-bubble.mdx | 12 +- .../components/cometchat-message-bubble.mdx | 55 ++++-- .../components/cometchat-message-composer.mdx | 156 ++++++++++-------- .../components/cometchat-outgoing-call.mdx | 17 +- .../components/cometchat-text-bubble.mdx | 12 +- ui-kit/angular/components/cometchat-users.mdx | 2 +- .../components/cometchat-video-bubble.mdx | 8 +- .../components/components-overview.mdx | 4 +- ui-kit/angular/events.mdx | 12 +- .../angular/guides/custom-message-types.mdx | 11 +- .../angular/guides/custom-text-formatter.mdx | 2 +- ui-kit/angular/guides/group-chat.mdx | 78 +++++---- ui-kit/angular/guides/mentions-formatter.mdx | 2 +- ui-kit/angular/guides/message-privately.mdx | 49 ++++-- 26 files changed, 363 insertions(+), 290 deletions(-) diff --git a/ui-kit/angular/api-reference/introduction.mdx b/ui-kit/angular/api-reference/introduction.mdx index 4c1b21f41..bc365ee1a 100644 --- a/ui-kit/angular/api-reference/introduction.mdx +++ b/ui-kit/angular/api-reference/introduction.mdx @@ -109,8 +109,9 @@ See the [State Management Guide — Scoping Customization Services](/ui-kit/angu Subscribe to message-related events. ```typescript -CometChatMessageEvents.ccMessageSent.subscribe((message) => { - console.log('Message sent:', message); +CometChatMessageEvents.ccMessageSent.subscribe(({ message, status }) => { + // `status` reflects the send lifecycle: inprogress, success, or error. + console.log('Message sent:', message, status); }); CometChatMessageEvents.onTextMessageReceived.subscribe((message) => { diff --git a/ui-kit/angular/components/cometchat-audio-bubble.mdx b/ui-kit/angular/components/cometchat-audio-bubble.mdx index 54346bdd9..74da4982e 100644 --- a/ui-kit/angular/components/cometchat-audio-bubble.mdx +++ b/ui-kit/angular/components/cometchat-audio-bubble.mdx @@ -49,7 +49,7 @@ import { CometChatAudioBubbleComponent, MessageBubbleAlignment } from '@cometcha template: ` ` }) @@ -75,13 +75,13 @@ import { CometChatAudioBubbleComponent, MessageBubbleAlignment } from '@cometcha ` }) @@ -139,7 +139,7 @@ export class InteractiveMessageComponent { | Property | Type | Default | Description | |----------|------|---------|-------------| | `message` | `CometChat.MediaMessage` | **required** | The CometChat.MediaMessage object to render. Contains audio attachments, metadata, and sender information | -| `alignment` | `MessageBubbleAlignment` | `MessageBubbleAlignment.LEFT` | The alignment of the message bubble. `LEFT` for incoming/receiver messages, `RIGHT` for outgoing/sender messages | +| `alignment` | `MessageBubbleAlignment` | `MessageBubbleAlignment.left` | The alignment of the message bubble. `left` for incoming/receiver messages, `right` for outgoing/sender messages | ## Events @@ -235,13 +235,13 @@ import { CometChatAudioBubbleComponent, MessageBubbleAlignment } from '@cometcha ` }) diff --git a/ui-kit/angular/components/cometchat-call-buttons.mdx b/ui-kit/angular/components/cometchat-call-buttons.mdx index a7d0f41fc..a4c70c387 100644 --- a/ui-kit/angular/components/cometchat-call-buttons.mdx +++ b/ui-kit/angular/components/cometchat-call-buttons.mdx @@ -73,7 +73,7 @@ export class CallButtonsDemoComponent { | `onError` | `((error: CometChat.CometChatException) => void) \| null` | `null` | Error callback invoked for any error during call operations. | | `outgoingCallDisableSoundForCalls` | `boolean` | `false` | Disables sound for the outgoing call overlay. Supports global config override. | | `outgoingCallCustomSoundForCalls` | `string` | `''` | Custom sound URL for the outgoing call overlay. Supports global config override. | -| `callSettingsBuilder` | `CallSettingsBuilder` | `undefined` | Custom `CallSettingsBuilder` to override the default call settings used in the ongoing call screen. Follows the three-tier priority: @Input > [GlobalConfig](/ui-kit/angular/customization/global-config) > default. | +| `callSettingsBuilder` | `SessionSettings` | `undefined` | A plain v5 `SessionSettings` object used to override the default call settings in the ongoing call screen. Pass a built `SessionSettings` object — the kit does **not** call `.build()` internally. Follows the three-tier priority: @Input > [GlobalConfig](/ui-kit/angular/customization/global-config) > default. | | `voiceCallButtonView` | `TemplateRef \| null` | `null` | Replaces the default voice call button with a custom template. | | `videoCallButtonView` | `TemplateRef \| null` | `null` | Replaces the default video call button with a custom template. | @@ -115,7 +115,7 @@ cometchat-call-buttons { ### Custom Call Settings -Override the default `CallSettingsBuilder` to customize the call UI: +Pass a plain v5 `SessionSettings` object to customize the call UI. Build the object yourself with `.build()` — the kit does **not** call `.build()` internally: ```typescript expandable import { Component, OnInit } from '@angular/core'; @@ -139,9 +139,11 @@ export class CustomCallSettingsComponent implements OnInit { customCallSettings: any; ngOnInit(): void { + // Build the SessionSettings object yourself — the kit does not call .build(). this.customCallSettings = new CometChatCalls.CallSettingsBuilder() .enableDefaultLayout(true) - .setIsAudioOnlyCall(false); + .setIsAudioOnlyCall(false) + .build(); } } ``` diff --git a/ui-kit/angular/components/cometchat-collaborative-document-bubble.mdx b/ui-kit/angular/components/cometchat-collaborative-document-bubble.mdx index 5156c302e..939418a0e 100644 --- a/ui-kit/angular/components/cometchat-collaborative-document-bubble.mdx +++ b/ui-kit/angular/components/cometchat-collaborative-document-bubble.mdx @@ -49,7 +49,7 @@ import { template: ` ` }) @@ -77,13 +77,13 @@ import { ` }) @@ -127,7 +127,7 @@ export class InteractiveDocumentComponent { | Property | Type | Default | Description | |----------|------|---------|-------------| | `message` | `CometChat.CustomMessage` | **required** | The CometChat.CustomMessage object containing collaborative document metadata | -| `alignment` | `MessageBubbleAlignment` | `MessageBubbleAlignment.LEFT` | The alignment of the message bubble. `LEFT` for incoming/receiver messages, `RIGHT` for outgoing/sender messages | +| `alignment` | `MessageBubbleAlignment` | `MessageBubbleAlignment.left` | The alignment of the message bubble. `left` for incoming/receiver messages, `right` for outgoing/sender messages | | `disableInteraction` | `boolean` | `false` | When true, disables the action button and other interactive elements within the bubble | ## Events @@ -219,7 +219,7 @@ export class DocumentChatMessageComponent { } get alignment(): MessageBubbleAlignment { - return this.isOutgoing ? MessageBubbleAlignment.RIGHT : MessageBubbleAlignment.LEFT; + return this.isOutgoing ? MessageBubbleAlignment.right : MessageBubbleAlignment.left; } handleDocumentOpen(url: string): void { @@ -289,8 +289,8 @@ export class DocumentMessageListComponent implements OnInit { getAlignment(message: CometChat.CustomMessage): MessageBubbleAlignment { return this.isOutgoing(message) - ? MessageBubbleAlignment.RIGHT - : MessageBubbleAlignment.LEFT; + ? MessageBubbleAlignment.right + : MessageBubbleAlignment.left; } onDocumentOpen(url: string): void { diff --git a/ui-kit/angular/components/cometchat-collaborative-whiteboard-bubble.mdx b/ui-kit/angular/components/cometchat-collaborative-whiteboard-bubble.mdx index b472ed46f..34ba29a95 100644 --- a/ui-kit/angular/components/cometchat-collaborative-whiteboard-bubble.mdx +++ b/ui-kit/angular/components/cometchat-collaborative-whiteboard-bubble.mdx @@ -49,7 +49,7 @@ import { template: ` ` }) @@ -77,13 +77,13 @@ import { ` }) @@ -127,7 +127,7 @@ export class InteractiveWhiteboardComponent { | Property | Type | Default | Description | |----------|------|---------|-------------| | `message` | `CometChat.CustomMessage` | **required** | The CometChat.CustomMessage object containing collaborative whiteboard metadata | -| `alignment` | `MessageBubbleAlignment` | `MessageBubbleAlignment.LEFT` | The alignment of the message bubble. `LEFT` for incoming/receiver messages, `RIGHT` for outgoing/sender messages | +| `alignment` | `MessageBubbleAlignment` | `MessageBubbleAlignment.left` | The alignment of the message bubble. `left` for incoming/receiver messages, `right` for outgoing/sender messages | | `disableInteraction` | `boolean` | `false` | When true, disables the action button and other interactive elements within the bubble | ## Events @@ -219,7 +219,7 @@ export class WhiteboardChatMessageComponent { } get alignment(): MessageBubbleAlignment { - return this.isOutgoing ? MessageBubbleAlignment.RIGHT : MessageBubbleAlignment.LEFT; + return this.isOutgoing ? MessageBubbleAlignment.right : MessageBubbleAlignment.left; } handleWhiteboardOpen(url: string): void { @@ -289,8 +289,8 @@ export class WhiteboardMessageListComponent implements OnInit { getAlignment(message: CometChat.CustomMessage): MessageBubbleAlignment { return this.isOutgoing(message) - ? MessageBubbleAlignment.RIGHT - : MessageBubbleAlignment.LEFT; + ? MessageBubbleAlignment.right + : MessageBubbleAlignment.left; } onWhiteboardOpen(url: string): void { diff --git a/ui-kit/angular/components/cometchat-conversation-item.mdx b/ui-kit/angular/components/cometchat-conversation-item.mdx index e22cdea37..2cc5f2946 100644 --- a/ui-kit/angular/components/cometchat-conversation-item.mdx +++ b/ui-kit/angular/components/cometchat-conversation-item.mdx @@ -123,7 +123,7 @@ export class ConversationItemDemoComponent { | `hideReceipts` | `boolean` | `false` | Hide message read receipts (sent, delivered, read indicators) | | `hideUserStatus` | `boolean` | `false` | Hide the user online/offline status indicator | | `hideGroupType` | `boolean` | `false` | Hide the group type icon (public, private, password) | -| `disableDefaultContextMenu` | `boolean` | `true` | When true, prevents the browser's native context menu and shows the custom context menu instead | +| `disableDefaultContextMenu` | `boolean` | `true` | When true, prevents the browser's native context menu. Custom CometChat menu visibility depends on the component's context-menu options and interaction state. | | `dateFormat` | `CalendarObject` | `undefined` | Custom date format configuration for the timestamp display | | `textFormatters` | `CometChatTextFormatter[]` | `[]` | Array of text formatters applied to the last message subtitle text | diff --git a/ui-kit/angular/components/cometchat-conversations.mdx b/ui-kit/angular/components/cometchat-conversations.mdx index b37a2775a..695589a0f 100644 --- a/ui-kit/angular/components/cometchat-conversations.mdx +++ b/ui-kit/angular/components/cometchat-conversations.mdx @@ -177,7 +177,7 @@ export class ChatComponent { | Property | Type | Default | Description | |----------|------|---------|-------------| | `options` | `(conversation: Conversation) => CometChatOption[]` | `undefined` | Function to provide custom context menu options | -| `disableDefaultContextMenu` | `boolean` | `true` | When true, prevents the browser's native context menu and shows the custom context menu instead | +| `disableDefaultContextMenu` | `boolean` | `true` | When true, prevents the browser's native context menu. Custom CometChat menu visibility depends on the component's context-menu options and interaction state. | | `slots` | `Partial` | `undefined` | Slot-based customization for fine-grained UI control of conversation items | ### Sound Configuration Properties diff --git a/ui-kit/angular/components/cometchat-file-bubble.mdx b/ui-kit/angular/components/cometchat-file-bubble.mdx index ea6881cee..8fcabf9d0 100644 --- a/ui-kit/angular/components/cometchat-file-bubble.mdx +++ b/ui-kit/angular/components/cometchat-file-bubble.mdx @@ -44,7 +44,7 @@ import { CometChatFileBubbleComponent, MessageBubbleAlignment } from '@cometchat template: ` ` }) @@ -70,13 +70,13 @@ import { CometChatFileBubbleComponent, MessageBubbleAlignment } from '@cometchat ` }) @@ -92,7 +92,7 @@ export class MessageListComponent { | Property | Type | Default | Description | |----------|------|---------|-------------| | `message` | `CometChat.MediaMessage` | **required** | The CometChat.MediaMessage object to render. Contains file attachments, metadata, and sender information | -| `alignment` | `MessageBubbleAlignment` | `MessageBubbleAlignment.LEFT` | The alignment of the message bubble. `LEFT` for incoming/receiver messages, `RIGHT` for outgoing/sender messages | +| `alignment` | `MessageBubbleAlignment` | `MessageBubbleAlignment.left` | The alignment of the message bubble. `left` for incoming/receiver messages, `right` for outgoing/sender messages | ## Advanced Usage diff --git a/ui-kit/angular/components/cometchat-group-item.mdx b/ui-kit/angular/components/cometchat-group-item.mdx index 567bc8c1d..52f9c8209 100644 --- a/ui-kit/angular/components/cometchat-group-item.mdx +++ b/ui-kit/angular/components/cometchat-group-item.mdx @@ -13,7 +13,7 @@ The CometChatGroupItem component renders a single group entry within a list. It - **Group Avatar**: Displays the group icon with a group type indicator badge - **Member Count**: Shows the localized member count below the group name - **Custom Templates**: Template projection for leading, title, subtitle, and trailing sections -- **Context Menu**: Configurable context menu options on hover or right-click +- **Context Menu**: Configurable context menu options that appear on hover or focus - **Keyboard Accessibility**: Full keyboard support with Enter, Space, and Shift+F10 shortcuts - **Global Config Priority**: Supports a three-tier priority system (Input > GlobalConfig > Default) @@ -70,8 +70,8 @@ export class GroupItemDemoComponent { | `isFocused` | `boolean` | `false` | Whether this group item currently has keyboard focus. Applies focus styling. | | `tabIndex` | `number` | `-1` | The tabindex for roving tabindex pattern. Only the focused item should have `0`. | | `hideGroupType` | `boolean` | `false` | Whether to hide the group type indicator (public, private, password). Supports global config override. | -| `disableDefaultContextMenu` | `boolean` | `true` | Whether to disable the browser's default context menu on right-click/long-press. | -| `contextMenuOptions` | `CometChatOption[]` | `undefined` | Options for the context menu displayed on hover/right-click. | +| `disableDefaultContextMenu` | `boolean` | `true` | When true, prevents the browser's native context menu. Custom CometChat menu visibility depends on the component's context-menu options and interaction state. | +| `contextMenuOptions` | `CometChatOption[]` | `undefined` | Options for the context menu displayed on hover/focus. | | `leadingView` | `TemplateRef<{ $implicit: CometChat.Group }>` | `undefined` | Custom template for the leading section (icon/avatar area). | | `titleView` | `TemplateRef<{ $implicit: CometChat.Group }>` | `undefined` | Custom template for the title section. | | `subtitleView` | `TemplateRef<{ $implicit: CometChat.Group }>` | `undefined` | Custom template for the subtitle section. | @@ -83,7 +83,7 @@ export class GroupItemDemoComponent { |-------|-------------|-------------| | `itemClick` | `CometChat.Group` | Emitted when the group item is clicked or activated via keyboard. | | `itemSelect` | `{ group: CometChat.Group; selected: boolean }` | Emitted when the group is selected/deselected in selection mode. | -| `contextMenuOpen` | `CometChat.Group` | Emitted when the context menu is opened. | +| `contextMenuOpen` | `CometChat.Group` | Emitted for keyboard shortcuts (Shift+F10 / ContextMenu) to request the context menu. Menu option visibility itself is driven by hover/focus state. | | `contextMenuOptionClick` | `{ option: CometChatOption; group: CometChat.Group }` | Emitted when a context menu option is clicked. | | `itemFocus` | `void` | Emitted when the item's inner container receives native focus. Used by the parent list for roving tabindex management. | @@ -136,8 +136,8 @@ Provide custom templates via inputs to override any visual section: |-----|--------| | `Enter` | Activate the group item (emits `itemClick`) | | `Space` | Activate the group item (emits `itemClick`) | -| `Shift + F10` | Open the context menu | -| `ContextMenu` | Open the context menu | +| `Shift + F10` | Emit `contextMenuOpen` to request the context menu (options appear on hover/focus) | +| `ContextMenu` | Emit `contextMenuOpen` to request the context menu (options appear on hover/focus) | ### ARIA Attributes diff --git a/ui-kit/angular/components/cometchat-group-member-item.mdx b/ui-kit/angular/components/cometchat-group-member-item.mdx index 31494049c..963344c5c 100644 --- a/ui-kit/angular/components/cometchat-group-member-item.mdx +++ b/ui-kit/angular/components/cometchat-group-member-item.mdx @@ -13,8 +13,8 @@ The CometChatGroupMemberItem component renders a single group member entry withi - **Member Avatar**: Displays the member's avatar image with an online/offline status indicator - **Role Badge**: Shows the member's scope/role (owner, admin, moderator) as a visual badge - **Custom Templates**: Template projection for leading, title, subtitle, and trailing sections -- **Context Menu**: Configurable context menu options for member management (kick, ban, change scope) -- **Keyboard Accessibility**: Full keyboard support with Enter, Space, and Shift+F10 shortcuts +- **Context Menu**: Configurable context menu options for member management (kick, ban, change scope) shown on hover or focus +- **Keyboard Accessibility**: Full keyboard support with Enter and Space shortcuts - **Global Config Priority**: Supports a three-tier priority system (Input > GlobalConfig > Default) @@ -70,8 +70,8 @@ export class GroupMemberItemDemoComponent { | `isFocused` | `boolean` | `false` | Whether this member item currently has keyboard focus. Applies focus styling. | | `tabIndex` | `number` | `-1` | The tabindex for roving tabindex pattern. Only the focused item should have `0`. | | `hideUserStatus` | `boolean` | `false` | Whether to hide the member online/offline status indicator. Supports global config override. | -| `disableDefaultContextMenu` | `boolean` | `true` | Whether to disable the browser's default context menu on right-click/long-press. | -| `contextMenuOptions` | `CometChatOption[]` | `undefined` | Options for the context menu (kick, ban, change scope). | +| `disableDefaultContextMenu` | `boolean` | `true` | When true, prevents the browser's native context menu. Custom CometChat menu visibility depends on the component's context-menu options and interaction state. | +| `contextMenuOptions` | `CometChatOption[]` | `undefined` | Options for the context menu (kick, ban, change scope), shown on hover/focus. | | `leadingView` | `TemplateRef<{ $implicit: CometChat.GroupMember }>` | `undefined` | Custom template for the leading section (avatar area). | | `titleView` | `TemplateRef<{ $implicit: CometChat.GroupMember }>` | `undefined` | Custom template for the title section. | | `subtitleView` | `TemplateRef<{ $implicit: CometChat.GroupMember }>` | `undefined` | Custom template for the subtitle section. | @@ -164,8 +164,8 @@ getContextMenuOptions(member: CometChat.GroupMember): CometChatOption[] { |-----|--------| | `Enter` | Activate the member item (emits `itemClick`) | | `Space` | Activate the member item (emits `itemClick`) | -| `Shift + F10` | Open the context menu | -| `ContextMenu` | Open the context menu | + +Context menu options are shown on hover or focus; there is no keyboard shortcut that opens the menu. ### ARIA Attributes diff --git a/ui-kit/angular/components/cometchat-group-members.mdx b/ui-kit/angular/components/cometchat-group-members.mdx index cecaf4b80..68fbdf5de 100644 --- a/ui-kit/angular/components/cometchat-group-members.mdx +++ b/ui-kit/angular/components/cometchat-group-members.mdx @@ -133,59 +133,11 @@ export class GroupMembersComponent implements OnInit { } ``` -## Usage Patterns +## Usage Pattern -CometChatGroupMembers supports two usage patterns. The default service-based approach uses -`ChatStateService` to automatically wire the group context. Alternatively, you can -pass data explicitly via `@Input()` bindings. - - - - -When a group is selected via `ChatStateService`, `cometchat-group-members` automatically subscribes to `ChatStateService.activeGroup` — no explicit `[group]` binding required. This is ideal when your app already uses `ChatStateService` to manage the active conversation. - -```typescript expandable -import { Component } from '@angular/core'; -import { - CometChatGroupMembersComponent, - CometChatGroupsComponent, -} from '@cometchat/chat-uikit-angular'; - -@Component({ - selector: 'app-group-members-service', - standalone: true, - imports: [CometChatGroupsComponent, CometChatGroupMembersComponent], - template: ` -
- - - - - -
- `, -}) -export class GroupMembersServiceComponent { - onGroupClick(group: any): void { - // ChatStateService is updated automatically — - // cometchat-group-members reacts to the active group change - } -} -``` - -See the [ChatStateService API reference](/ui-kit/angular/api-reference/chat-state-service) for the full list of signals, observables, and setter methods. - - - This is the recommended approach for most applications. It reduces boilerplate - and keeps components in sync automatically. - - -
- - -Pass `[group]` directly to override `ChatStateService` state for this component instance. This is useful when you manage group selection yourself or render multiple group member panels. +`cometchat-group-members` requires an explicit `[group]` input. Pass a +`CometChat.Group` object via the `@Input()` binding — the component does not +subscribe to any global active-group state, so `[group]` must always be provided. ```typescript expandable import { Component, OnInit, signal } from '@angular/core'; @@ -198,18 +150,17 @@ import { CometChatGroupMembersComponent } from '@cometchat/chat-uikit-angular'; imports: [CometChatGroupMembersComponent], template: ` @if (group()) { - + } `, }) export class GroupMembersPropsComponent implements OnInit { group = signal(null); + activeGroup!: CometChat.Group; ngOnInit(): void { CometChat.getGroup('your-group-guid').then((group: CometChat.Group) => { + this.activeGroup = group; this.group.set(group); }); } @@ -221,13 +172,10 @@ export class GroupMembersPropsComponent implements OnInit { ``` - When the `[group]` `@Input()` binding is provided, it takes priority over - `ChatStateService` state for that component instance. + The `[group]` input (a `CometChat.Group`) is required. Fetch the group from the + SDK before rendering the component. - -
- ## Properties ### Display Control Properties @@ -242,7 +190,7 @@ export class GroupMembersPropsComponent implements OnInit { | `hideScopeChangeOption` | `boolean` | `false` | Hide the scope change option from context menus | | `disableLoadingState` | `boolean` | `false` | Disable the shimmer loading state | | `showScrollbar` | `boolean` | `false` | Show/hide scrollbar in member list | -| `disableDefaultContextMenu` | `boolean` | `true` | When true, prevents the browser's native context menu and shows the custom context menu instead | +| `disableDefaultContextMenu` | `boolean` | `true` | When true, suppresses the browser's native context menu only. Visibility of the custom CometChat menu depends on the component's context-menu options and interaction (hover/focus) state | ### Data Configuration Properties @@ -275,7 +223,7 @@ export class GroupMembersPropsComponent implements OnInit { | Event | Payload Type | Description | |-------|-------------|-------------| | `itemClick` | `CometChat.GroupMember` | Emitted when a member item is clicked | -| `selectionChange` | `{member: CometChat.GroupMember, selected: boolean}` | Emitted when a member is selected/deselected | +| `selectionChange` | `SelectionState` | Emitted when the selection changes. Payload: `{ mode: SelectionMode; selectedIds: Set; lastSelectedId: string \| null }` | | `error` | `CometChat.CometChatException` | Emitted when an error occurs | | `empty` | `void` | Emitted when the member list is empty after initial fetch | @@ -337,12 +285,17 @@ export class FilteredMembersComponent implements OnInit { Enable single or multiple member selection: +The `selectionChange` event emits a `SelectionState` object. Read the currently +selected member IDs from `state.selectedIds`. If you need the full member objects, +map these IDs back to the currently loaded members. + ```typescript expandable import { Component, OnInit, signal } from '@angular/core'; import { CometChat } from '@cometchat/chat-sdk-javascript'; import { CometChatGroupMembersComponent, - SelectionMode + SelectionMode, + SelectionState } from '@cometchat/chat-uikit-angular'; @Component({ @@ -350,9 +303,9 @@ import { standalone: true, imports: [CometChatGroupMembersComponent], template: ` - @if (selectedMembers.length > 0) { + @if (selectedMemberIds.length > 0) {
- {{ selectedMembers.length }} members selected + {{ selectedMemberIds.length }} members selected
} @@ -370,7 +323,7 @@ import { export class SelectableMembersComponent implements OnInit { group = signal(null); selectionMode = SelectionMode.multiple; - selectedMembers: CometChat.GroupMember[] = []; + selectedMemberIds: string[] = []; ngOnInit(): void { CometChat.getGroup('your-group-guid').then((group) => { @@ -378,14 +331,8 @@ export class SelectableMembersComponent implements OnInit { }); } - onSelectionChange(event: { member: CometChat.GroupMember; selected: boolean }): void { - if (event.selected) { - this.selectedMembers.push(event.member); - } else { - this.selectedMembers = this.selectedMembers.filter( - m => m.getUid() !== event.member.getUid() - ); - } + onSelectionChange(state: SelectionState): void { + this.selectedMemberIds = Array.from(state.selectedIds); } onMemberClick(member: CometChat.GroupMember): void { @@ -393,7 +340,7 @@ export class SelectableMembersComponent implements OnInit { } performAction(): void { - console.log('Performing action on members:', this.selectedMembers); + console.log('Performing action on members:', this.selectedMemberIds); } } ``` @@ -808,6 +755,7 @@ import { CometChat } from '@cometchat/chat-sdk-javascript'; import { CometChatGroupMembersComponent, SelectionMode, + SelectionState, CometChatOption } from '@cometchat/chat-uikit-angular'; @@ -817,9 +765,9 @@ import { imports: [CommonModule, CometChatGroupMembersComponent], template: `
- @if (selectedMembers.length > 0) { + @if (selectedMemberIds.length > 0) {
- {{ selectedMembers.length }} selected + {{ selectedMemberIds.length }} selected
} @@ -875,7 +823,7 @@ export class GroupMembersDemoComponent implements OnInit { group = signal(null); membersBuilder!: CometChat.GroupMembersRequestBuilder; selectionMode = SelectionMode.multiple; - selectedMembers: CometChat.GroupMember[] = []; + selectedMemberIds: string[] = []; ngOnInit(): void { CometChat.getGroup('your-group-guid').then((group) => { @@ -907,14 +855,8 @@ export class GroupMembersDemoComponent implements OnInit { console.log('Member clicked:', member.getName()); } - onSelectionChange(event: { member: CometChat.GroupMember; selected: boolean }): void { - if (event.selected) { - this.selectedMembers.push(event.member); - } else { - this.selectedMembers = this.selectedMembers.filter( - m => m.getUid() !== event.member.getUid() - ); - } + onSelectionChange(state: SelectionState): void { + this.selectedMemberIds = Array.from(state.selectedIds); } messageMember(member: CometChat.GroupMember): void { @@ -926,7 +868,7 @@ export class GroupMembersDemoComponent implements OnInit { } clearSelection(): void { - this.selectedMembers = []; + this.selectedMemberIds = []; } handleError(error: CometChat.CometChatException): void { diff --git a/ui-kit/angular/components/cometchat-groups.mdx b/ui-kit/angular/components/cometchat-groups.mdx index f4877830d..fc43b0c46 100644 --- a/ui-kit/angular/components/cometchat-groups.mdx +++ b/ui-kit/angular/components/cometchat-groups.mdx @@ -130,7 +130,7 @@ export class GroupsComponent { | `hideError` | `boolean` | `false` | Hide error views when errors occur | | `hideGroupType` | `boolean` | `false` | Hide group type icon (public/private/password) | | `showScrollbar` | `boolean` | `false` | Show/hide scrollbar in group list | -| `disableDefaultContextMenu` | `boolean` | `true` | When true, prevents the browser's native context menu and shows the custom context menu instead | +| `disableDefaultContextMenu` | `boolean` | `true` | When true, prevents the browser's native context menu. Custom CometChat menu visibility depends on the component's context-menu options and interaction state. | ### Data Configuration Properties @@ -181,6 +181,8 @@ CometChatGroups supports two usage patterns for communicating the selected group When a group is selected, `ChatStateService` stores the active group. Downstream components like `cometchat-message-header`, `cometchat-message-list`, and `cometchat-message-composer` automatically subscribe to the change. +The component auto-updates `ChatStateService` (via `setActiveGroup`) only when `(itemClick)` is **not** observed. For this service-driven mode, leave `(itemClick)` unbound so the automatic selection stays enabled. + ```typescript expandable import { Component } from '@angular/core'; import { @@ -201,9 +203,8 @@ import { ], template: `
- + +
@@ -214,22 +215,24 @@ import {
`, }) -export class GroupsChatComponent { - onGroupClick(group: any): void { - // ChatStateService is updated automatically - } -} +export class GroupsChatComponent {} ``` This is the recommended approach. Selecting a group automatically updates all downstream message components. + + Binding `(itemClick)` suppresses the automatic `ChatStateService` selection. If you observe `(itemClick)`, you must drive selection yourself — either call `this.chatState.setActiveGroup(group)` inside your handler, or pass `[group]="activeGroup"` into the downstream components (see the "Using Props" tab). + + Pass `[group]` directly to downstream components to override `ChatStateService` state. This is useful when you manage group selection yourself. +Because this example binds `(itemClick)`, the automatic `ChatStateService` selection is suppressed, so you must drive selection manually. Here the `onGroupClick` handler stores the group in `activeGroup` and passes `[group]="activeGroup"` into each downstream component. + ```typescript expandable import { Component } from '@angular/core'; import { CometChat } from '@cometchat/chat-sdk-javascript'; @@ -753,7 +756,6 @@ import { Subject, takeUntil } from 'rxjs'; (itemClick)="onGroupClick($event)" (select)="onGroupSelect($event)" (error)="handleError($event)" - (empty)="handleEmpty()" >
@@ -863,9 +865,5 @@ export class GroupsDemoComponent implements OnInit, OnDestroy { handleError(error: CometChat.CometChatException): void { console.error('Error:', error); } - - handleEmpty(): void { - console.log('No groups found'); - } } ``` diff --git a/ui-kit/angular/components/cometchat-image-bubble.mdx b/ui-kit/angular/components/cometchat-image-bubble.mdx index cfdef4cb4..2d4601ec9 100644 --- a/ui-kit/angular/components/cometchat-image-bubble.mdx +++ b/ui-kit/angular/components/cometchat-image-bubble.mdx @@ -47,7 +47,7 @@ import { CometChatImageBubbleComponent, MessageBubbleAlignment } from '@cometcha template: ` ` }) @@ -73,13 +73,13 @@ import { CometChatImageBubbleComponent, MessageBubbleAlignment } from '@cometcha ` }) @@ -136,7 +136,8 @@ export class InteractiveMessageComponent { | Property | Type | Default | Description | |----------|------|---------|-------------| | `message` | `CometChat.MediaMessage` | **required** | The CometChat.MediaMessage object to render. Contains image attachments, metadata, and sender information | -| `alignment` | `MessageBubbleAlignment` | `MessageBubbleAlignment.LEFT` | The alignment of the message bubble. `LEFT` for incoming/receiver messages, `RIGHT` for outgoing/sender messages | +| `alignment` | `MessageBubbleAlignment` | `MessageBubbleAlignment.left` | The alignment of the message bubble. `left` for incoming/receiver messages, `right` for outgoing/sender messages | +| `disableInteraction` | `boolean` | `false` | When `true`, disables image click/viewer interaction so the bubble renders non-interactive. The image will not open the fullscreen gallery viewer on click | ## Events @@ -312,6 +313,9 @@ cometchat-image-bubble { | `--cometchat-text-color-white` | Overflow text color | `#FFFFFF` | | `--cometchat-font-heading2-bold` | Overflow text font | `600 20px Roboto` | + + In addition to the global theme tokens listed above, the Image Bubble exposes component-specific CSS custom properties prefixed with `--cometchat-image-bubble-`. These are scoped to the component and can be overridden on the `cometchat-image-bubble` selector to fine-tune the bubble's appearance independently of the global theme. + ### Custom Color Schemes diff --git a/ui-kit/angular/components/cometchat-message-bubble.mdx b/ui-kit/angular/components/cometchat-message-bubble.mdx index 34f662d9d..6d917ab1c 100644 --- a/ui-kit/angular/components/cometchat-message-bubble.mdx +++ b/ui-kit/angular/components/cometchat-message-bubble.mdx @@ -185,9 +185,24 @@ export class InteractiveMessageComponent { MessageBubbleAlignment = MessageBubbleAlignment; messageOptions: CometChatActionsIcon[] = [ - new CometChatActionsIcon({ id: 'reply', title: 'Reply', iconURL: 'assets/reply.svg' }), - new CometChatActionsIcon({ id: 'copy', title: 'Copy', iconURL: 'assets/copy.svg' }), - new CometChatActionsIcon({ id: 'delete', title: 'Delete', iconURL: 'assets/delete.svg' }), + new CometChatActionsIcon({ + id: 'reply', + title: 'Reply', + iconURL: 'assets/reply.svg', + onClick: (messageId) => { console.log('Reply on message:', messageId); } + }), + new CometChatActionsIcon({ + id: 'copy', + title: 'Copy', + iconURL: 'assets/copy.svg', + onClick: (messageId) => { console.log('Copy message:', messageId); } + }), + new CometChatActionsIcon({ + id: 'delete', + title: 'Delete', + iconURL: 'assets/delete.svg', + onClick: (messageId) => { console.log('Delete message:', messageId); } + }), ]; onOptionClick(option: any): void { @@ -239,7 +254,9 @@ export class InteractiveMessageComponent { | `hideTimestamp` | `boolean` | `false` | Whether to hide the timestamp | | `showError` | `boolean` | `false` | Whether to show error state indicator | | `hideModerationView` | `boolean` | `false` | Whether to hide moderation status indicators | -| `disableInteraction` | `boolean` | `false` | When true, disables all interactive elements within the bubble (context menu, reactions, etc.) | +| `hideThreadView` | `boolean` | `false` | Whether to hide the thread-replies view | +| `hideStatusInfoView` | `boolean` | `false` | Whether to hide the status-info view (timestamp, receipts) | +| `disableInteraction` | `boolean` | `false` | When true, disables most interactive elements within the bubble (context menu, reactions, etc.). Note: this is not a fully-inert guarantee — some interaction paths remain, such as thread clicks (which still emit `threadRepliesClick`) and the keyboard Space media toggle on media messages (which can still emit `mediaToggle`) | ### Events @@ -1244,17 +1261,21 @@ export class GlobalCustomizationComponent implements AfterViewInit { ngAfterViewInit(): void { // Set global status info view for all message types - this.bubbleConfigService.setGlobalStatusInfoView(this.globalStatusInfo); + this.bubbleConfigService.setGlobalView('statusInfoView', this.globalStatusInfo); + + // Set multiple global view parts at once + this.bubbleConfigService.setGlobalViews({ + statusInfoView: this.globalStatusInfo + }); // Set custom content view for text messages only this.bubbleConfigService.setBubbleView('text_message', { contentView: this.customTextContent }); - // Set multiple message type customizations at once - this.bubbleConfigService.setMessageTemplates({ - 'text_message': { contentView: this.customTextContent }, - 'image_message': { statusInfoView: this.globalStatusInfo } + // Set customizations for additional message types + this.bubbleConfigService.setBubbleView('image_message', { + statusInfoView: this.globalStatusInfo }); } } @@ -1265,11 +1286,11 @@ export class GlobalCustomizationComponent implements AfterViewInit { | Method | Parameters | Description | |--------|------------|-------------| | `setBubbleView` | `messageType: string, map: BubblePartMap` | Set custom views for a specific message type | -| `setGlobalStatusInfoView` | `view: TemplateRef` | Set status info view for all message types | -| `setGlobalLeadingView` | `view: TemplateRef` | Set leading view for all message types | -| `setGlobalHeaderView` | `view: TemplateRef` | Set header view for all message types | -| `setMessageTemplates` | `maps: Record` | Set multiple message type customizations | +| `setGlobalView` | `part: BubblePart, view: TemplateRef` | Set a single view part (e.g. `'statusInfoView'`) for all message types | +| `setGlobalViews` | `views: Partial>>` | Set multiple view parts for all message types at once | | `getView` | `messageType: string, part: BubblePart` | Get the configured view for a message type and part | +| `clearType` | `messageType: string` | Clear configured views for a specific message type | +| `clearGlobalViews` | none | Clear all globally configured views | | `clearAll` | none | Clear all configured views | ### Scoping for Multiple Instances @@ -1348,6 +1369,14 @@ The Message Bubble component uses CSS variables for consistent theming. Override } ``` +### Component-Specific CSS Variables + +In addition to the global theme tokens above, the Message Bubble component exposes its own overridable CSS custom properties, prefixed with `--cometchat-message-bubble-`. Override these to customize appearance for this component specifically, independently of the global theme tokens. + + + The component exposes `--cometchat-message-bubble-` prefixed CSS custom properties that can be overridden. Inspect the rendered `.cometchat-message-bubble` element in your browser's developer tools to discover the exact variable names exposed by your installed version of the UI Kit. + + ### Dark Theme ```css expandable diff --git a/ui-kit/angular/components/cometchat-message-composer.mdx b/ui-kit/angular/components/cometchat-message-composer.mdx index bd2c4197b..a25946884 100644 --- a/ui-kit/angular/components/cometchat-message-composer.mdx +++ b/ui-kit/angular/components/cometchat-message-composer.mdx @@ -16,7 +16,7 @@ The component follows a **Service-Based Architecture** where: ### Key Features - **Auto-Expanding Text Input**: Textarea that grows with content up to a configurable maximum height -- **Multiple Attachments**: Support for images, videos, audio, and files with drag-and-drop +- **Attachments**: Support for images, videos, audio, and files (selected files are sent directly) - **Rich Text Editing**: Optional rich text formatting using custom RichTextEditorService (bold, italic, lists, code blocks, etc.) - **Emoji Picker**: Built-in emoji keyboard with category navigation - **Voice Recording**: Record and send audio messages with waveform visualization @@ -115,17 +115,14 @@ export class GroupChatComponent { > ``` -### With Attachments and Drag-Drop +### With Attachments + +Attachments are enabled by default through the attachment button. Selected files +are sent directly in the current build — there is no queued preview before sending. ```typescript ``` @@ -304,11 +301,6 @@ Both layouts work seamlessly with rich text editing: | Property | Type | Default | Description | |----------|------|---------|-------------| | `attachmentOptions` | `CometChatMessageComposerAction[]` | `undefined` | Custom attachment options for the attachment menu | -| `maxAttachments` | `number` | `10` | Maximum number of attachments allowed | -| `allowedFileTypes` | `string[]` | `undefined` | Allowed MIME types for attachments (e.g., `['image/*', 'application/pdf']`) | -| `maxFileSize` | `number` | `undefined` | Maximum file size in bytes | -| `showAttachmentPreview` | `boolean` | `true` | Show attachment preview thumbnails before sending | -| `enableDragDrop` | `boolean` | `true` | Enable drag-and-drop file uploads | ### Hide Option Properties @@ -343,10 +335,9 @@ Both layouts work seamlessly with rich text editing: | Property | Type | Default | Description | |----------|------|---------|-------------| -| `enableRichText` | `boolean` | `true` | Enable rich text editing. When disabled, toolbar toggle button is hidden and pasting/adding content won't apply rich text formatting. Mentions and other formatters still work independently. | -| `hideRichTextToolbar` | `boolean` | `false` | Hide the rich text formatting toolbar. When showToolbarToggle is enabled, the toggle overrides this setting. | -| `showBubbleMenuOnSelection` | `boolean` | `true` | Show floating bubble menu when text is selected (Web/Desktop only) | -| `showToolbarToggle` | `boolean` | `true` | Show a toggle button to show/hide the fixed toolbar. Emits toolbarToggleClick with 'active' or 'inactive' state. | +| `enableRichText` | `boolean` | `true` | Enable rich text editing. When disabled, pasting/adding content won't apply rich text formatting. Mentions and other formatters still work independently. | +| `hideRichTextToolbar` | `boolean` | `true` | Hide the rich text formatting toolbar. | +| `showBubbleMenuOnSelection` | `boolean` | `false` | Show floating bubble menu when text is selected (Web/Desktop only) | ### Other Configuration Properties @@ -354,12 +345,12 @@ Both layouts work seamlessly with rich text editing: |----------|------|---------|-------------| | `disableTypingEvents` | `boolean` | `false` | Disable sending typing indicator events | | `disableSoundForMessage` | `boolean` | `false` | Disable sound when sending messages | -| `customSoundForMessage` | `string` | `undefined` | Custom sound URL for message sent notification | +| `customSoundForMessage` | `string` | `''` | Custom sound URL for message sent notification. Empty string falls back to the global/default sound. | | `liveReactionIcon` | `string` | `undefined` | Custom icon for live reaction button | | `messageToEdit` | `CometChat.BaseMessage` | `undefined` | Message to edit (enables edit mode) | | `messageToReply` | `CometChat.BaseMessage` | `undefined` | Message to reply to (enables reply preview) | | `textFormatters` | `CometChatTextFormatter[]` | `undefined` | Array of text formatters to apply | -| `showToolbarToggle` | `boolean` | `true` | Whether to show the toolbar toggle button for expanding/collapsing the action toolbar | +| `hideError` | `boolean` | `false` | Hides the built-in composer error UI (useful when using `(error)` or a custom `errorView`). | ### Template Properties @@ -383,8 +374,6 @@ Both layouts work seamlessly with rich text editing: | `sendButtonClick` | `CometChat.BaseMessage` | Emitted when a message is sent successfully | | `error` | `CometChat.CometChatException` | Emitted when an error occurs | | `closePreview` | `void` | Emitted when the reply/edit preview is closed | -| `attachmentAdded` | `File` | Emitted when an attachment is added | -| `attachmentRemoved` | `File` | Emitted when an attachment is removed | | `mentionSelected` | `CometChat.User \| CometChat.GroupMember` | Emitted when a mention is selected | ## Usage Patterns @@ -416,9 +405,9 @@ import { ], template: `
- + +
@@ -429,11 +418,24 @@ import {
`, }) -export class ChatComponent { - onConversationClick(conversation: any): void {} -} +export class ChatComponent {} ``` + + If you need to observe `(itemClick)` yourself, you must set the active + conversation manually so the message components stay in sync: + + ```typescript + import { ChatStateService } from '@cometchat/chat-uikit-angular'; + + constructor(private chatState: ChatStateService) {} + + onConversationClick(conversation: any): void { + this.chatState.setActiveConversation(conversation); + } + ``` + + This is the recommended approach. The composer stays in sync with the conversation list without manual wiring. @@ -483,9 +485,49 @@ For group conversations: ## Advanced Usage -### Reply Mode (Threaded Messages) +### Threaded Replies + +Set `parentMessageId` to make outgoing messages part of a thread. This controls +the threaded **send** behavior (the thread parent for outgoing messages) — it does +**not** render a quoted reply preview on its own. + +```typescript expandable +import { Component } from '@angular/core'; +import { CometChat } from '@cometchat/chat-sdk-javascript'; +import { CometChatMessageComposerComponent } from '@cometchat/chat-uikit-angular'; + +@Component({ + selector: 'app-thread-composer', + standalone: true, + imports: [CometChatMessageComposerComponent], + template: ` + + ` +}) +export class ThreadComposerComponent { + selectedUser!: CometChat.User; + parentMessageId?: number; + + openThread(message: CometChat.BaseMessage): void { + this.parentMessageId = message.getId(); + } + + onReplySent(message: CometChat.BaseMessage): void { + console.log('Threaded reply sent:', message); + } +} +``` + +### Quoted Reply Preview -Enable reply mode by setting the `parentMessageId` to reply to a specific message: +To show the visible quoted reply preview UI, set `messageToReply`. This drives +the preview and works with `(closePreview)`. Note that `parentMessageId` alone +does not render the quoted preview — `messageToReply` is what drives the preview +plus the `closePreview` event. ```typescript expandable import { Component } from '@angular/core'; @@ -499,27 +541,27 @@ import { CometChatMessageComposerComponent } from '@cometchat/chat-uikit-angular template: ` ` }) export class ReplyComposerComponent { selectedUser!: CometChat.User; - replyToMessageId?: number; + message?: CometChat.BaseMessage; replyToMessage(message: CometChat.BaseMessage): void { - this.replyToMessageId = message.getId(); + this.message = message; } onReplySent(message: CometChat.BaseMessage): void { console.log('Reply sent:', message); - this.replyToMessageId = undefined; + this.clearReply(); } - cancelReply(): void { - this.replyToMessageId = undefined; + clearReply(): void { + this.message = undefined; } } ``` @@ -593,7 +635,9 @@ export class RichTextComposerComponent { onMessageSent(message: CometChat.BaseMessage): void { console.log('Rich text message sent:', message); - // Message metadata will contain rich text formatting info + // Rich text formatting is serialized into the message text (as markdown-style + // content). Note: rich-text formatting is NOT attached as message metadata + // (there is no `message.getMetadata().richText`) in the current send path. } } ``` @@ -665,12 +709,15 @@ export class BubbleMenuComposerComponent { #### Always-Visible Toolbar -Keep the formatting toolbar visible at all times for improved discoverability: +Keep the formatting toolbar visible at all times for improved discoverability. +Because the toolbar is hidden by default (`hideRichTextToolbar` defaults to +`true`), set `[hideRichTextToolbar]="false"` to keep it visible: ```typescript ``` @@ -696,7 +743,6 @@ Use all rich text enhancements together: This configuration provides: - Floating bubble menu for quick text selection formatting -- Toolbar toggle button for showing/hiding the fixed toolbar - Full keyboard shortcut support ### @Mentions with Custom Request Builder @@ -746,9 +792,11 @@ export class MentionsComposerComponent implements OnInit { } ``` -### File Attachments with Validation +### File Attachments -Configure attachment handling with file type and size validation: +Attachments are handled through the attachment button. Selected files are sent +directly (there is no queued preview in the current build). Use the `(error)` +output to surface any send failures: ```typescript expandable import { Component } from '@angular/core'; @@ -762,40 +810,14 @@ import { CometChatMessageComposerComponent } from '@cometchat/chat-uikit-angular template: ` ` }) export class AttachmentsComposerComponent { selectedUser!: CometChat.User; - - // Allow images, PDFs, and common document types - allowedTypes = [ - 'image/jpeg', - 'image/png', - 'image/gif', - 'application/pdf', - 'application/msword', - 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' - ]; - - onAttachmentAdded(file: File): void { - console.log('Attachment added:', file.name, file.size); - } - - onAttachmentRemoved(file: File): void { - console.log('Attachment removed:', file.name); - } onError(error: CometChat.CometChatException): void { - // Handle file validation errors console.error('Error:', error.message); } } diff --git a/ui-kit/angular/components/cometchat-outgoing-call.mdx b/ui-kit/angular/components/cometchat-outgoing-call.mdx index 73510c3b6..1921e8286 100644 --- a/ui-kit/angular/components/cometchat-outgoing-call.mdx +++ b/ui-kit/angular/components/cometchat-outgoing-call.mdx @@ -33,6 +33,12 @@ The CometChatOutgoingCall component renders a full-screen outgoing call overlay ## Basic Usage + + When `` is used **standalone**, it is purely presentational. Its default cancel action only stops the local ringtone and emits `(callCanceled)` — it does **not** call the Chat SDK cancellation API. Your `(callCanceled)` handler must cancel the outgoing call itself via the Chat SDK (see the example below). + + When the component is rendered inside ``, the buttons component performs the SDK cancellation for you, so you should **not** cancel the call again in your own handler. + + ```typescript expandable import { Component } from '@angular/core'; import { CometChat } from '@cometchat/chat-sdk-javascript'; @@ -52,8 +58,13 @@ import { CometChatOutgoingCallComponent } from '@cometchat/chat-uikit-angular'; export class OutgoingCallDemoComponent { outgoingCall!: CometChat.Call; - onCallCanceled(): void { - console.log('Outgoing call canceled'); + // Standalone usage: the component does not cancel the call for you. + // Your handler must reject/cancel the call through the Chat SDK. + async onCallCanceled(): Promise { + const sessionId = this.outgoingCall?.getSessionId(); + if (sessionId) { + await CometChat.rejectCall(sessionId, CometChat.CALL_STATUS.CANCELLED); + } } } ``` @@ -125,7 +136,7 @@ cometchat-outgoing-call { ### ARIA Attributes -- `role="alertdialog"` on the overlay container +- `role="dialog"` on the overlay container - `aria-labelledby` references the receiver name heading - Focus is trapped within the dialog while visible - Initial focus is set to the cancel button diff --git a/ui-kit/angular/components/cometchat-text-bubble.mdx b/ui-kit/angular/components/cometchat-text-bubble.mdx index d2def7876..2554b9abf 100644 --- a/ui-kit/angular/components/cometchat-text-bubble.mdx +++ b/ui-kit/angular/components/cometchat-text-bubble.mdx @@ -51,7 +51,7 @@ import { CometChatTextBubbleComponent, MessageBubbleAlignment } from '@cometchat template: ` ` }) @@ -77,13 +77,13 @@ import { CometChatTextBubbleComponent, MessageBubbleAlignment } from '@cometchat ` }) @@ -134,7 +134,7 @@ export class InteractiveMessageComponent { | Property | Type | Default | Description | |----------|------|---------|-------------| | `message` | `CometChat.TextMessage` | **required** | The CometChat.TextMessage object to render. Contains text content, metadata, and sender information | -| `alignment` | `MessageBubbleAlignment` | `MessageBubbleAlignment.LEFT` | The alignment of the message bubble. `LEFT` for incoming/receiver messages, `RIGHT` for outgoing/sender messages | +| `alignment` | `MessageBubbleAlignment` | `MessageBubbleAlignment.left` | The alignment of the message bubble. `left` for incoming/receiver messages, `right` for outgoing/sender messages | | `textFormatters` | `CometChatTextFormatter[]` | `[]` | Array of text formatters to apply to the message text. If empty, default formatters (mentions, URLs) will be used | | `translatedTextOverride` | `string` | `undefined` | Override for the translated text display. When provided, this text is shown as the translation instead of the message's built-in translated text | @@ -563,6 +563,10 @@ cometchat-text-bubble { | `--cometchat-radius-2` | Border radius | `8px` | | `--cometchat-border-color-light` | Border color | `#E0E0E0` | + + In addition to the global theme tokens listed above, the Text Bubble exposes component-specific CSS custom properties prefixed with `--cometchat-text-bubble-`. These are scoped to the component and can be overridden on the `cometchat-text-bubble` selector to fine-tune the bubble's appearance independently of the global theme. + + ### Custom Color Schemes ```css expandable diff --git a/ui-kit/angular/components/cometchat-users.mdx b/ui-kit/angular/components/cometchat-users.mdx index fe8bb6265..671e47d29 100644 --- a/ui-kit/angular/components/cometchat-users.mdx +++ b/ui-kit/angular/components/cometchat-users.mdx @@ -131,7 +131,7 @@ export class UsersComponent { | `disableLoadingState` | `boolean` | `false` | Disable loading state (maintains list during search) | | `hideUserStatus` | `boolean` | `false` | Hide online/offline status indicators | | `showScrollbar` | `boolean` | `false` | Show/hide scrollbar in user list | -| `disableDefaultContextMenu` | `boolean` | `true` | When true, prevents the browser's native context menu and shows the custom context menu instead | +| `disableDefaultContextMenu` | `boolean` | `true` | When true, prevents the browser's native context menu. Custom CometChat menu visibility depends on the component's context-menu options and interaction state. | | `showSelectedUsersPreview` | `boolean` | `false` | Show selected users preview chips (multiple mode only) | ### Data Configuration Properties diff --git a/ui-kit/angular/components/cometchat-video-bubble.mdx b/ui-kit/angular/components/cometchat-video-bubble.mdx index 195d3e7ba..230b3cec4 100644 --- a/ui-kit/angular/components/cometchat-video-bubble.mdx +++ b/ui-kit/angular/components/cometchat-video-bubble.mdx @@ -48,7 +48,7 @@ import { CometChatVideoBubbleComponent, MessageBubbleAlignment } from '@cometcha template: ` ` }) @@ -74,13 +74,13 @@ import { CometChatVideoBubbleComponent, MessageBubbleAlignment } from '@cometcha ` }) @@ -136,7 +136,7 @@ export class InteractiveMessageComponent { | Property | Type | Default | Description | |----------|------|---------|-------------| | `message` | `CometChat.MediaMessage` | **required** | The CometChat.MediaMessage object to render. Contains video attachments, metadata, and sender information | -| `alignment` | `MessageBubbleAlignment` | `MessageBubbleAlignment.LEFT` | The alignment of the message bubble. `LEFT` for incoming/receiver messages, `RIGHT` for outgoing/sender messages | +| `alignment` | `MessageBubbleAlignment` | `MessageBubbleAlignment.left` | The alignment of the message bubble. `left` for incoming/receiver messages, `right` for outgoing/sender messages | ## Events diff --git a/ui-kit/angular/components/components-overview.mdx b/ui-kit/angular/components/components-overview.mdx index 2b10e53b8..47d44849e 100644 --- a/ui-kit/angular/components/components-overview.mdx +++ b/ui-kit/angular/components/components-overview.mdx @@ -76,8 +76,8 @@ import { CometChatMessageEvents } from '@cometchat/chat-uikit-angular'; import { Subscription } from 'rxjs'; // Subscribe in ngOnInit -this.subscription = CometChatMessageEvents.ccMessageSent.subscribe((message) => { - // react to sent message +this.subscription = CometChatMessageEvents.ccMessageSent.subscribe(({ message, status }) => { + // react to sent message; `status` is inprogress, success, or error }); // Cleanup in ngOnDestroy diff --git a/ui-kit/angular/events.mdx b/ui-kit/angular/events.mdx index 6475955f7..921d4ccc9 100644 --- a/ui-kit/angular/events.mdx +++ b/ui-kit/angular/events.mdx @@ -53,7 +53,6 @@ Events provide decoupled communication between UIKit components using a publish/ | **ccReplyToMessage** | Triggered when the user successfully replies to a message. | | **ccMessageDeleted** | Triggered when the user successfully deletes a message. | | **ccMessageRead** | Triggered when the sent message is read by the receiver. | -| **ccLiveReaction** | Triggered when the user sends a live reaction. | ### SDK Listener Events @@ -108,8 +107,9 @@ export class ChatComponent implements OnInit, OnDestroy { ngOnInit(): void { this.messageSubscription = CometChatMessageEvents.ccMessageSent.subscribe( - (message) => { - console.log('Message sent:', message); + ({ message, status }) => { + // `status` reflects the send lifecycle: inprogress, success, or error. + console.log('Message sent:', message, status); } ); } @@ -143,8 +143,10 @@ export class ChatListenerComponent implements OnInit, OnDestroy { ngOnInit(): void { this.subscriptions.add( - CometChatMessageEvents.ccMessageSent.subscribe((message) => { - console.log('Message sent:', message); + CometChatMessageEvents.ccMessageSent.subscribe(({ message, status, parentMessageId }) => { + // `status` reflects the send lifecycle: inprogress, success, or error. + // `parentMessageId` is present for thread-scoped messages. + console.log('Message sent:', message, status, parentMessageId); }) ); diff --git a/ui-kit/angular/guides/custom-message-types.mdx b/ui-kit/angular/guides/custom-message-types.mdx index e776e1980..f30b62779 100644 --- a/ui-kit/angular/guides/custom-message-types.mdx +++ b/ui-kit/angular/guides/custom-message-types.mdx @@ -290,6 +290,9 @@ export class LocationDemoComponent implements OnInit, AfterViewInit { ```typescript expandable +import { CometChat } from '@cometchat/chat-sdk-javascript'; +import { CometChatUIKit } from '@cometchat/chat-uikit-angular'; + // Send a custom location message const receiverID = 'uid'; const customData = { @@ -305,11 +308,17 @@ const customMessage = new CometChat.CustomMessage( customData ); -CometChat.sendCustomMessage(customMessage).then( +// Prefer the UI Kit wrapper so the message participates in UI Kit +// message events and optimistic/send-status behavior. +CometChatUIKit.sendCustomMessage(customMessage).then( (message) => console.log('Location sent:', message), (error) => console.error('Error:', error) ); ``` + + +`CometChatUIKit.sendCustomMessage` emits the `ccMessageSent` event through its lifecycle (in-progress, success, and error) and keeps UI Kit message state in sync, so the sent message appears optimistically and updates its send status in the UI. Use the raw SDK `CometChat.sendCustomMessage` only when you deliberately want to bypass UI Kit event/state synchronization. + diff --git a/ui-kit/angular/guides/custom-text-formatter.mdx b/ui-kit/angular/guides/custom-text-formatter.mdx index d7b31d5bb..deae6001a 100644 --- a/ui-kit/angular/guides/custom-text-formatter.mdx +++ b/ui-kit/angular/guides/custom-text-formatter.mdx @@ -27,7 +27,7 @@ description: "Extend the CometChatTextFormatter base class to implement custom i | Key event callbacks | Hooks for `keyUp` and `keyDown` events | -Always wrap formatted output in a `` with a unique CSS class (e.g. `"custom-hashtag"`). This tells the UI Kit to render it as-is instead of sanitizing it. +Formatter output is always sanitized (via DOMPurify in the text bubble) before it is rendered — there is no way to bypass sanitization. Make sure your custom HTML is sanitizer-compatible (DOMPurify-safe). Wrapping formatted output in a `` with a CSS class (e.g. `"custom-hashtag"`) is only a styling and identification hook; it does NOT render the output as-is or bypass sanitization. --- diff --git a/ui-kit/angular/guides/group-chat.mdx b/ui-kit/angular/guides/group-chat.mdx index 8b302c2f5..b721ce409 100644 --- a/ui-kit/angular/guides/group-chat.mdx +++ b/ui-kit/angular/guides/group-chat.mdx @@ -83,7 +83,10 @@ export class CreateGroupComponent { async handleSubmit(): Promise { const guid = `group_${Date.now()}`; - const group = new CometChat.Group(guid, this.groupName, this.groupType, this.groupPassword); + const group = new CometChat.Group(guid, this.groupName, this.groupType as CometChat.GroupType); + if (this.groupType === CometChat.GROUP_TYPE.PASSWORD && this.groupPassword) { + group.setPassword(this.groupPassword); + } try { const created = await CometChat.createGroup(group); @@ -134,13 +137,17 @@ export class JoinGroupComponent { async joinGroup(): Promise { try { const joinedGroup = await CometChat.joinGroup( - this.group.getGuid(), this.group.getType(), this.password + this.group.getGuid(), + this.group.getType() as CometChat.GroupType, + this.password ?? '' ); const loggedInUser = await CometChat.getLoggedinUser(); - CometChatGroupEvents.ccGroupMemberJoined.next({ - joinedGroup, - joinedUser: loggedInUser - }); + if (loggedInUser) { + CometChatGroupEvents.ccGroupMemberJoined.next({ + joinedGroup, + joinedUser: loggedInUser, + }); + } this.groupJoined.emit(joinedGroup); } catch { this.error = true; @@ -149,6 +156,10 @@ export class JoinGroupComponent { } ``` + +Private groups cannot be joined with `joinGroup`. They require an invitation or an admin to add the member. + + --- ### 3. View Group Members @@ -173,21 +184,31 @@ onMemberClick(member: CometChat.GroupMember): void { ### 4. Add Members -`cometchat-add-members` is a sample-app component. Use `CometChat.addMembersToGroup()` to build your own add-members UI. +`cometchat-add-members` is a sample-app reference component driven by `ChatStateService.activeGroup`. It has no `[group]` input and no `(addMembersClick)` output — it reads the active group from the state service. Use `CometChat.addMembersToGroup()` to build your own add-members UI. Let admins select users and add them to the group. ```html - - + ``` +When you add members with a raw SDK call, emit the `ccGroupMemberAdded` UI Kit event so the rest of the UI stays in sync. Raw SDK calls alone will not produce UI Kit action-message synchronization. + ```typescript -onMembersAdded(members: CometChat.User[]): void { - console.log('Added members:', members.length); +onMembersAdded( + members: CometChat.User[], + addedGroupMembers: CometChat.GroupMember[], + group: CometChat.Group +): void { + const loggedInUser = CometChatUIKit.getLoggedInUser(); + if (!loggedInUser) return; + CometChatGroupEvents.ccGroupMemberAdded.next({ + messages: [], + usersAdded: members, + userAddedIn: group, + userAddedBy: loggedInUser, + }); } ``` @@ -225,19 +246,19 @@ async changeMemberScope( group: CometChat.Group ): Promise { try { + const oldScope = member.getScope(); await CometChat.updateGroupMemberScope( + group.getGuid(), member.getUid(), - newScope, - group.getGuid() + newScope ); - const loggedInUser = await CometChat.getLoggedinUser(); CometChatGroupEvents.ccGroupMemberScopeChanged.next({ - changedBy: loggedInUser!, - changedUser: member, - changedIn: group, - newScope, - oldScope: member.getScope() + message, + updatedUser: member, + scopeChangedTo: newScope, + scopeChangedFrom: oldScope, + group }); } catch (error) { console.error('Failed to update member scope:', error); @@ -245,26 +266,27 @@ async changeMemberScope( } ``` + +The `ccGroupMemberScopeChanged` payload uses the Angular UI Kit event shape `{ message, updatedUser, scopeChangedTo, scopeChangedFrom, group }`. The `message` is the group action message for the scope change, and the actor is read from the message via `message.getActionBy()` — there is no top-level `changedBy` field. + + --- ### 7. Transfer Ownership -`cometchat-transfer-ownership` is a sample-app component. Use `CometChat.transferGroupOwnership()` to build your own transfer-ownership UI. +`cometchat-transfer-ownership` is a sample-app reference component driven by `ChatStateService.activeGroup`. It exposes only a `(closeClick)` output — there is no `[group]` input or `(transferOwnershipClick)` output. Use `CometChat.transferGroupOwnership()` to build your own transfer-ownership UI. Let the current owner select a member and transfer ownership. ```html - - + ``` ```typescript -onOwnershipTransferred(newOwner: CometChat.GroupMember): void { - console.log('Ownership transferred to:', newOwner.getName()); +onClose(): void { + console.log('Transfer ownership dialog closed'); } ``` diff --git a/ui-kit/angular/guides/mentions-formatter.mdx b/ui-kit/angular/guides/mentions-formatter.mdx index b9682ba01..a24fdc496 100644 --- a/ui-kit/angular/guides/mentions-formatter.mdx +++ b/ui-kit/angular/guides/mentions-formatter.mdx @@ -143,7 +143,7 @@ mentionsFormatter.setAllMentionConfig(true, 'everyone'); Browse all feature and formatter guides. - + Auto-detect and style URLs as clickable links. diff --git a/ui-kit/angular/guides/message-privately.mdx b/ui-kit/angular/guides/message-privately.mdx index 94adc9a36..76f25f151 100644 --- a/ui-kit/angular/guides/message-privately.mdx +++ b/ui-kit/angular/guides/message-privately.mdx @@ -17,7 +17,9 @@ description: "Launch a direct 1:1 chat from a group member profile in CometChat -Message Privately lets users start a direct 1:1 conversation with a group member without leaving the group context. The user can return to the group after the private chat. +Message Privately lets users start a direct 1:1 conversation with another group member without leaving the group context. Selecting it opens a normal 1:1 user chat — the resulting conversation is not group-scoped. The user can return to the group after the private chat. + +`cometchat-message-list` provides this as a built-in action. The "Message Privately" option appears only in group chats, and only for messages sent by other users. It is controlled by the `hideMessagePrivatelyOption` property, which defaults to `false`, so the action is shown by default. When a user selects it, the `(messagePrivatelyClick)` output emits the target message and user. Before starting, complete the [Integration Guide](/ui-kit/angular/integration). @@ -27,18 +29,42 @@ Before starting, complete the [Integration Guide](/ui-kit/angular/integration). | Component / Selector | Role | |:---|:---| -| `cometchat-group-members` | Displays group members with click handlers for private messaging | +| `cometchat-message-list` | Emits the built-in "Message Privately" action via `(messagePrivatelyClick)` and displays private conversation messages | | `cometchat-message-header` | Header showing private chat information | -| `cometchat-message-list` | Displays private conversation messages | | `cometchat-message-composer` | Input component for composing private messages | +| `cometchat-group-members` | Optional alternative entry point: start a private chat from the member list | --- ## Implementation Steps -### 1. Group Member Click Handler +### 1. Handle the Built-in "Message Privately" Action (Canonical) + +The canonical way to launch a private chat is the built-in action on `cometchat-message-list`. Bind the `(messagePrivatelyClick)` output to open a 1:1 chat with the emitted user. + +```html + + +``` + +```ts +openPrivateChat(event: { message: CometChat.BaseMessage; user: CometChat.User }) { + this.privateChatUser = event.user; +} +``` + +Notes: + +- `hideMessagePrivatelyOption` defaults to `false`, so the action is shown by default. Set it to `true` to hide the option. +- The action appears only in group chats, and only for messages sent by other users. +- Selecting it opens a normal 1:1 user chat — it is not group-scoped. + +--- + +### 2. Alternative: Group Member Click Handler -When a group member is clicked, cast them to a `User` object and initiate a private chat. Save the current group so the user can return to it later. +As a secondary route, you can also start a private chat from the group member list. When a group member is clicked, cast them to a `User` object and initiate a private chat. Save the current group so the user can return to it later. ```typescript expandable import { Component, OnDestroy } from '@angular/core'; @@ -77,9 +103,9 @@ export class PrivateChatComponent implements OnDestroy { --- -### 2. Group Members with Private Messaging Option +### 3. Alternative: Group Members with Private Messaging Option -Render `cometchat-group-members` and handle the `(itemClick)` output to trigger the private chat flow. +For the group-members route, render `cometchat-group-members` and handle the `(itemClick)` output to trigger the private chat flow. ```html Date: Thu, 2 Jul 2026 19:39:49 +0530 Subject: [PATCH 2/2] changes --- .../components/cometchat-message-composer.mdx | 4 +--- ui-kit/angular/guides/custom-message-types.mdx | 8 ++++---- ui-kit/angular/guides/group-chat.mdx | 2 +- ui-kit/angular/troubleshooting.mdx | 14 ++++++++------ 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/ui-kit/angular/components/cometchat-message-composer.mdx b/ui-kit/angular/components/cometchat-message-composer.mdx index a25946884..fb9f76c29 100644 --- a/ui-kit/angular/components/cometchat-message-composer.mdx +++ b/ui-kit/angular/components/cometchat-message-composer.mdx @@ -336,7 +336,7 @@ Both layouts work seamlessly with rich text editing: | Property | Type | Default | Description | |----------|------|---------|-------------| | `enableRichText` | `boolean` | `true` | Enable rich text editing. When disabled, pasting/adding content won't apply rich text formatting. Mentions and other formatters still work independently. | -| `hideRichTextToolbar` | `boolean` | `true` | Hide the rich text formatting toolbar. | +| `hideRichTextToolbar` | `boolean` | `false` | Hide the rich text formatting toolbar. | | `showBubbleMenuOnSelection` | `boolean` | `false` | Show floating bubble menu when text is selected (Web/Desktop only) | ### Other Configuration Properties @@ -710,8 +710,6 @@ export class BubbleMenuComposerComponent { #### Always-Visible Toolbar Keep the formatting toolbar visible at all times for improved discoverability. -Because the toolbar is hidden by default (`hideRichTextToolbar` defaults to -`true`), set `[hideRichTextToolbar]="false"` to keep it visible: ```typescript - + Customize the message bubble component. - + Customize the conversations list. - + Override text and translations. - + Customize date and time display. diff --git a/ui-kit/angular/guides/group-chat.mdx b/ui-kit/angular/guides/group-chat.mdx index b721ce409..e2891ee7d 100644 --- a/ui-kit/angular/guides/group-chat.mdx +++ b/ui-kit/angular/guides/group-chat.mdx @@ -247,7 +247,7 @@ async changeMemberScope( ): Promise { try { const oldScope = member.getScope(); - await CometChat.updateGroupMemberScope( + const message = await CometChat.updateGroupMemberScope( group.getGuid(), member.getUid(), newScope diff --git a/ui-kit/angular/troubleshooting.mdx b/ui-kit/angular/troubleshooting.mdx index 656c1abdd..df0fa8f5a 100644 --- a/ui-kit/angular/troubleshooting.mdx +++ b/ui-kit/angular/troubleshooting.mdx @@ -2172,14 +2172,16 @@ Make sure the CometChat SDK is properly initialized and typing events are not di **3. Attachments not uploading** -Verify file validation settings: +The composer does not expose client-side `maxFileSize` / `allowedFileTypes` / +`maxAttachments` inputs — selected files are sent directly. If attachments are not +working, check that the relevant attachment options are not hidden and that file +handling is enabled in your dashboard: ```typescript -// Check file size limit (in bytes) -[maxFileSize]="10485760" // 10MB - -// Check allowed file types -[allowedFileTypes]="['image/*', 'application/pdf']" +// Ensure the attachment button and the file/media options are visible +[hideAttachmentButton]="false" +[hideFileAttachmentOption]="false" +[hideImageAttachmentOption]="false" ``` **4. Rich text toolbar not showing**