@progress/kendo-angular-conversational-ui 21.0.0-develop.9 → 21.0.1-develop.1

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.
@@ -34,10 +34,12 @@ const utils_1 = require("../utils");
34
34
  function default_1(fileInfo, api) {
35
35
  const filePath = fileInfo.path;
36
36
  if (filePath.endsWith('.html')) {
37
- let updatedContent = fileInfo.source;
38
- updatedContent = (0, utils_1.htmlBoundAttributeTransformer)({ ...fileInfo, source: updatedContent }, 'kendo-chat', 'user', 'authorId', 'id');
39
- // Only write to file once after all transformations
40
- fs.writeFileSync(filePath, updatedContent, 'utf-8');
37
+ if ((0, utils_1.hasKendoInTemplate)(fileInfo.source)) {
38
+ let updatedContent = fileInfo.source;
39
+ updatedContent = (0, utils_1.htmlBoundAttributeTransformer)({ ...fileInfo, source: updatedContent }, 'kendo-chat', 'user', 'authorId', 'id');
40
+ // Only write to file once after all transformations
41
+ fs.writeFileSync(filePath, updatedContent, 'utf-8');
42
+ }
41
43
  return;
42
44
  }
43
45
  const j = api.jscodeshift;
@@ -45,6 +47,6 @@ function default_1(fileInfo, api) {
45
47
  (0, index_1.templateTransformer)(rootSource, j, (root) => {
46
48
  (0, utils_1.templateBoundAttributeTransformer)(root, 'kendo-chat', 'user', 'authorId', 'id');
47
49
  });
48
- (0, utils_1.tsPropertyTransformer)(rootSource, j, 'ChatComponent', 'user', 'authorId', 'id');
50
+ (0, utils_1.tsPropertyTransformer)(fileInfo.source, rootSource, j, 'ChatComponent', 'user', 'authorId', 'id');
49
51
  return rootSource.toSource();
50
52
  }
@@ -0,0 +1,53 @@
1
+ /**-----------------------------------------------------------------------------------------
2
+ * Copyright © 2025 Progress Software Corporation. All rights reserved.
3
+ * Licensed under commercial license. See LICENSE.md in the project root for more information
4
+ *-------------------------------------------------------------------------------------------*/
5
+ "use strict";
6
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
+ if (k2 === undefined) k2 = k;
8
+ var desc = Object.getOwnPropertyDescriptor(m, k);
9
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
10
+ desc = { enumerable: true, get: function() { return m[k]; } };
11
+ }
12
+ Object.defineProperty(o, k2, desc);
13
+ }) : (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ o[k2] = m[k];
16
+ }));
17
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
18
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
19
+ }) : function(o, v) {
20
+ o["default"] = v;
21
+ });
22
+ var __importStar = (this && this.__importStar) || function (mod) {
23
+ if (mod && mod.__esModule) return mod;
24
+ var result = {};
25
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
26
+ __setModuleDefault(result, mod);
27
+ return result;
28
+ };
29
+ Object.defineProperty(exports, "__esModule", { value: true });
30
+ exports.default = default_1;
31
+ const fs = __importStar(require("fs"));
32
+ const index_1 = require("../template-transformer/index");
33
+ const utils_1 = require("../utils");
34
+ function default_1(fileInfo, api) {
35
+ const filePath = fileInfo.path;
36
+ if (filePath.endsWith('.html')) {
37
+ if ((0, utils_1.hasKendoInTemplate)(fileInfo.source)) {
38
+ let updatedContent = fileInfo.source;
39
+ updatedContent = (0, utils_1.htmlAttributeRemoval)({ ...fileInfo, source: updatedContent }, 'kendo-chat', 'messageToolbarVisibility');
40
+ // Only write to file once after all transformations
41
+ fs.writeFileSync(filePath, updatedContent, 'utf-8');
42
+ }
43
+ return;
44
+ }
45
+ const j = api.jscodeshift;
46
+ const rootSource = j(fileInfo.source);
47
+ (0, index_1.templateTransformer)(rootSource, j, (root) => {
48
+ (0, utils_1.templateAttributeRemoval)(root, 'kendo-chat', 'messageToolbarVisibility');
49
+ });
50
+ (0, utils_1.tsPropertyRemoval)(fileInfo.source, rootSource, j, 'ChatComponent', 'messageToolbarVisibility');
51
+ (0, utils_1.tsComponentPropertyRemoval)(fileInfo.source, rootSource, j, 'ChatComponent', 'messageToolbarVisibility');
52
+ return rootSource.toSource();
53
+ }
@@ -0,0 +1,19 @@
1
+ /**-----------------------------------------------------------------------------------------
2
+ * Copyright © 2025 Progress Software Corporation. All rights reserved.
3
+ * Licensed under commercial license. See LICENSE.md in the project root for more information
4
+ *-------------------------------------------------------------------------------------------*/
5
+ "use strict";
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.default = default_1;
8
+ const utils_1 = require("../utils");
9
+ function default_1(fileInfo, api) {
10
+ const filePath = fileInfo.path;
11
+ if (filePath.endsWith('.html')) {
12
+ return;
13
+ }
14
+ const j = api.jscodeshift;
15
+ const rootSource = j(fileInfo.source);
16
+ (0, utils_1.tsPropertyRemoval)(fileInfo.source, rootSource, j, 'ConversationalUIModelFields', 'pinnedByField');
17
+ (0, utils_1.tsComponentPropertyRemoval)(fileInfo.source, rootSource, j, 'ConversationalUIModelFields', 'pinnedByField');
18
+ return rootSource.toSource();
19
+ }
@@ -18,3 +18,4 @@ export * from './file-download-event.interface';
18
18
  export * from './send-button-settings';
19
19
  export * from './files-layout';
20
20
  export * from './suggestions-layout';
21
+ export * from './timestamp-visibility';
@@ -0,0 +1,5 @@
1
+ /**-----------------------------------------------------------------------------------------
2
+ * Copyright © 2025 Progress Software Corporation. All rights reserved.
3
+ * Licensed under commercial license. See LICENSE.md in the project root for more information
4
+ *-------------------------------------------------------------------------------------------*/
5
+ export {};
@@ -63,7 +63,7 @@ export class ChatComponent {
63
63
  chatService;
64
64
  /**
65
65
  * Sets the Chat messages.
66
- * Accepts an array of `Message` objects, but can also accept custom data structures.
66
+ * Accepts an array of `Message` objects, but can also accept custom data types.
67
67
  * For more information, check [Data Binding](slug:databinding_chat) section in the documentation.
68
68
  */
69
69
  messages;
@@ -101,6 +101,26 @@ export class ChatComponent {
101
101
  * @default 'standard'
102
102
  */
103
103
  messageWidthMode = 'standard';
104
+ /**
105
+ * Controls the visibility of timestamps in messages.
106
+ *
107
+ * @default 'focus'
108
+ */
109
+ timestampVisibility = 'focus';
110
+ /**
111
+ * Controls the visibility of usernames in messages.
112
+ * When set to `true`, the username displays above each message bubble.
113
+ *
114
+ * @default true
115
+ */
116
+ showUsername = true;
117
+ /**
118
+ * Controls the avatar visibility for the messages.
119
+ * When set to `true`, the user avatar displays next to each message bubble.
120
+ *
121
+ * @default true
122
+ */
123
+ showAvatar = true;
104
124
  /**
105
125
  * Enables the expand or collapse functionality for messages.
106
126
  *
@@ -220,7 +240,7 @@ export class ChatComponent {
220
240
  sendButtonSettings = SEND_BTN_DEFAULT_SETTINGS;
221
241
  /**
222
242
  * Sets the names of the model fields from which the Chat reads its data.
223
- * Lets you map custom data structures to the expected `Message` format.
243
+ * Lets you map custom data types to the expected `Message` format.
224
244
  */
225
245
  set modelFields(value) {
226
246
  this._modelFields = { ...defaultModelFields, ...value };
@@ -379,6 +399,9 @@ export class ChatComponent {
379
399
  */
380
400
  ngOnInit() {
381
401
  this.chatService.messageWidthMode = this.messageWidthMode;
402
+ this.chatService.timestampVisibility = this.timestampVisibility;
403
+ this.chatService.showUsername = this.showUsername;
404
+ this.chatService.showAvatar = this.showAvatar;
382
405
  this.chatService.allowMessageCollapse = this.allowMessageCollapse;
383
406
  this.chatService.enableSpeechToText = this.enableSpeechToText;
384
407
  this.chatService.sendButtonSettings = this.sendButtonSettings;
@@ -428,6 +451,9 @@ export class ChatComponent {
428
451
  this.updateChatServiceProperties([
429
452
  'authorId',
430
453
  'messageWidthMode',
454
+ 'timestampVisibility',
455
+ 'showUsername',
456
+ 'showAvatar',
431
457
  'allowMessageCollapse',
432
458
  'enableSpeechToText',
433
459
  'sendButtonSettings',
@@ -545,7 +571,7 @@ export class ChatComponent {
545
571
  });
546
572
  }
547
573
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ChatComponent, deps: [{ token: i1.LocalizationService }, { token: i0.NgZone }, { token: i0.Renderer2 }, { token: i0.ElementRef }, { token: i2.ChatService }], target: i0.ɵɵFactoryTarget.Component });
548
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: ChatComponent, isStandalone: true, selector: "kendo-chat", inputs: { messages: "messages", authorId: "authorId", messageBoxType: "messageBoxType", height: "height", width: "width", placeholder: "placeholder", messageWidthMode: "messageWidthMode", allowMessageCollapse: "allowMessageCollapse", enableSpeechToText: "enableSpeechToText", enableFileSelect: "enableFileSelect", messageToolbarActions: "messageToolbarActions", inputValue: "inputValue", authorMessageSettings: "authorMessageSettings", receiverMessageSettings: "receiverMessageSettings", messageContextMenuActions: "messageContextMenuActions", fileActions: "fileActions", messageFilesLayout: "messageFilesLayout", suggestionsLayout: "suggestionsLayout", quickActionsLayout: "quickActionsLayout", suggestions: "suggestions", sendButtonSettings: "sendButtonSettings", modelFields: "modelFields" }, outputs: { sendMessage: "sendMessage", toolbarActionClick: "toolbarActionClick", contextMenuActionClick: "contextMenuActionClick", fileActionClick: "fileActionClick", download: "download", executeAction: "executeAction", suggestionExecute: "suggestionExecute", fileSelect: "fileSelect", fileRemove: "fileRemove", unpin: "unpin", inputValueChange: "inputValueChange" }, host: { properties: { "class": "this.className", "attr.dir": "this.dirAttr" } }, providers: [
574
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: ChatComponent, isStandalone: true, selector: "kendo-chat", inputs: { messages: "messages", authorId: "authorId", messageBoxType: "messageBoxType", height: "height", width: "width", placeholder: "placeholder", messageWidthMode: "messageWidthMode", timestampVisibility: "timestampVisibility", showUsername: "showUsername", showAvatar: "showAvatar", allowMessageCollapse: "allowMessageCollapse", enableSpeechToText: "enableSpeechToText", enableFileSelect: "enableFileSelect", messageToolbarActions: "messageToolbarActions", inputValue: "inputValue", authorMessageSettings: "authorMessageSettings", receiverMessageSettings: "receiverMessageSettings", messageContextMenuActions: "messageContextMenuActions", fileActions: "fileActions", messageFilesLayout: "messageFilesLayout", suggestionsLayout: "suggestionsLayout", quickActionsLayout: "quickActionsLayout", suggestions: "suggestions", sendButtonSettings: "sendButtonSettings", modelFields: "modelFields" }, outputs: { sendMessage: "sendMessage", toolbarActionClick: "toolbarActionClick", contextMenuActionClick: "contextMenuActionClick", fileActionClick: "fileActionClick", download: "download", executeAction: "executeAction", suggestionExecute: "suggestionExecute", fileSelect: "fileSelect", fileRemove: "fileRemove", unpin: "unpin", inputValueChange: "inputValueChange" }, host: { properties: { "class": "this.className", "attr.dir": "this.dirAttr" } }, providers: [
549
575
  LocalizationService,
550
576
  ChatService,
551
577
  SuggestionsScrollService,
@@ -854,6 +880,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
854
880
  type: Input
855
881
  }], messageWidthMode: [{
856
882
  type: Input
883
+ }], timestampVisibility: [{
884
+ type: Input
885
+ }], showUsername: [{
886
+ type: Input
887
+ }], showAvatar: [{
888
+ type: Input
857
889
  }], allowMessageCollapse: [{
858
890
  type: Input
859
891
  }], enableSpeechToText: [{
@@ -27,6 +27,9 @@ export class ChatService {
27
27
  selectOnMenuClose = false;
28
28
  active = false;
29
29
  messageFilesLayout = 'vertical';
30
+ timestampVisibility = 'focus';
31
+ showUsername = true;
32
+ showAvatar = true;
30
33
  _enableSpeechToText = STB_DEFAULT_SETTINGS;
31
34
  _enableFileSelect = FILESELECT_DEFAULT_SETTINGS;
32
35
  _sendButtonSettings = SEND_BTN_DEFAULT_SETTINGS;
@@ -7,7 +7,7 @@
7
7
  import { ChangeDetectorRef, Component, ElementRef, EventEmitter, HostBinding, Input, Output, QueryList, Renderer2, ViewChildren } from '@angular/core';
8
8
  import { NgFor, NgSwitch, NgSwitchCase, NgIf, NgTemplateOutlet } from '@angular/common';
9
9
  import { ExecuteActionEvent } from './api';
10
- import { Keys, normalizeNumpadKeys, ResizeSensorComponent } from '@progress/kendo-angular-common';
10
+ import { isPresent, Keys, normalizeNumpadKeys, ResizeSensorComponent } from '@progress/kendo-angular-common';
11
11
  import { IntlService } from '@progress/kendo-angular-intl';
12
12
  import { LocalizationService } from '@progress/kendo-angular-l10n';
13
13
  import { closest, DOWNLOAD_ALL_SELECTOR, FILE_ACTION_BTN_SELECTOR } from './common/utils';
@@ -121,6 +121,20 @@ export class MessageListComponent {
121
121
  onClick(message, event) {
122
122
  this.select(message, event);
123
123
  }
124
+ showGroupAuthor(group) {
125
+ const messageSettings = this.isOwnMessage(group.messages[0]) ? this.chatService.authorMessageSettings : this.chatService.receiverMessageSettings;
126
+ if (isPresent(messageSettings?.showUsername)) {
127
+ return messageSettings.showUsername && group.author.name;
128
+ }
129
+ return this.chatService.showUsername && group.author.name;
130
+ }
131
+ showGroupAvatar(group) {
132
+ const messageSettings = this.isOwnMessage(group.messages[0]) ? this.chatService.authorMessageSettings : this.chatService.receiverMessageSettings;
133
+ if (isPresent(messageSettings?.showAvatar)) {
134
+ return messageSettings.showAvatar && group.author.avatarUrl;
135
+ }
136
+ return this.chatService.showAvatar && group.author.avatarUrl;
137
+ }
124
138
  onContextMenuClick(message, event, messageElement) {
125
139
  this.chatService.calculateContextMenuActions(this.isOwnMessage(message));
126
140
  if (this.chatService.calculatedContextMenuActions.length > 0) {
@@ -316,11 +330,11 @@ export class MessageListComponent {
316
330
  class="k-message-group"
317
331
  [class.k-message-group-sender]="isOwnMessage(group.messages[0])"
318
332
  [class.k-message-group-receiver]="!isOwnMessage(group.messages[0])"
319
- [class.k-no-avatar]="!group.author.avatarUrl"
333
+ [class.k-no-avatar]="!showGroupAvatar(group)"
320
334
  [class.k-message-group-full-width]="calculateMessageWidthMode(group.messages[0])"
321
335
  >
322
336
  <div
323
- *ngIf="!userStatusTemplate?.templateRef && group.author.avatarUrl"
337
+ *ngIf="!userStatusTemplate?.templateRef && showGroupAvatar(group)"
324
338
  class="k-avatar k-avatar-md k-avatar-solid k-avatar-solid-primary k-rounded-full"
325
339
  >
326
340
  <span class="k-avatar-image">
@@ -330,7 +344,7 @@ export class MessageListComponent {
330
344
  />
331
345
  </span>
332
346
  </div>
333
- <div class="k-chat-user-status-wrapper" *ngIf="group.author.avatarUrl && userStatusTemplate?.templateRef">
347
+ <div class="k-chat-user-status-wrapper" *ngIf="userStatusTemplate?.templateRef && showGroupAvatar(group)">
334
348
  <div
335
349
  class="k-avatar k-avatar-md k-avatar-solid k-avatar-solid-primary k-rounded-full"
336
350
  >
@@ -350,18 +364,10 @@ export class MessageListComponent {
350
364
  </div>
351
365
  </div>
352
366
  <div class="k-message-group-content">
353
- <p *ngIf="group.author.name" class="k-message-author">{{ group.author.name }}</p>
367
+ <p *ngIf="showGroupAuthor(group)" class="k-message-author">{{ group.author.name }}</p>
354
368
  <ng-container
355
369
  *ngFor="let msg of group.messages; first as firstMessage; last as lastMessage"
356
370
  >
357
- <div
358
- *ngIf="msg.user?.avatarUrl"
359
- class="k-avatar k-avatar-md k-avatar-solid k-avatar-solid-primary k-rounded-full"
360
- >
361
- <span class="k-avatar-image">
362
- <img [src]="msg.user?.avatarUrl">
363
- </span>
364
- </div>
365
371
  <kendo-chat-message #message
366
372
  [message]="msg"
367
373
  [tabbable]="lastGroup && lastMessage"
@@ -438,11 +444,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
438
444
  class="k-message-group"
439
445
  [class.k-message-group-sender]="isOwnMessage(group.messages[0])"
440
446
  [class.k-message-group-receiver]="!isOwnMessage(group.messages[0])"
441
- [class.k-no-avatar]="!group.author.avatarUrl"
447
+ [class.k-no-avatar]="!showGroupAvatar(group)"
442
448
  [class.k-message-group-full-width]="calculateMessageWidthMode(group.messages[0])"
443
449
  >
444
450
  <div
445
- *ngIf="!userStatusTemplate?.templateRef && group.author.avatarUrl"
451
+ *ngIf="!userStatusTemplate?.templateRef && showGroupAvatar(group)"
446
452
  class="k-avatar k-avatar-md k-avatar-solid k-avatar-solid-primary k-rounded-full"
447
453
  >
448
454
  <span class="k-avatar-image">
@@ -452,7 +458,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
452
458
  />
453
459
  </span>
454
460
  </div>
455
- <div class="k-chat-user-status-wrapper" *ngIf="group.author.avatarUrl && userStatusTemplate?.templateRef">
461
+ <div class="k-chat-user-status-wrapper" *ngIf="userStatusTemplate?.templateRef && showGroupAvatar(group)">
456
462
  <div
457
463
  class="k-avatar k-avatar-md k-avatar-solid k-avatar-solid-primary k-rounded-full"
458
464
  >
@@ -472,18 +478,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
472
478
  </div>
473
479
  </div>
474
480
  <div class="k-message-group-content">
475
- <p *ngIf="group.author.name" class="k-message-author">{{ group.author.name }}</p>
481
+ <p *ngIf="showGroupAuthor(group)" class="k-message-author">{{ group.author.name }}</p>
476
482
  <ng-container
477
483
  *ngFor="let msg of group.messages; first as firstMessage; last as lastMessage"
478
484
  >
479
- <div
480
- *ngIf="msg.user?.avatarUrl"
481
- class="k-avatar k-avatar-md k-avatar-solid k-avatar-solid-primary k-rounded-full"
482
- >
483
- <span class="k-avatar-image">
484
- <img [src]="msg.user?.avatarUrl">
485
- </span>
486
- </div>
487
485
  <kendo-chat-message #message
488
486
  [message]="msg"
489
487
  [tabbable]="lastGroup && lastMessage"
@@ -344,7 +344,7 @@ export class MessageComponent extends ChatItem {
344
344
  <time
345
345
  [attr.aria-hidden]="!selected"
346
346
  class="k-message-time"
347
- *ngIf="message.timestamp"
347
+ *ngIf="chatService.timestampVisibility === 'focus' && message.timestamp"
348
348
  >
349
349
  {{ formatTimeStamp(message.timestamp) }}
350
350
  </time>
@@ -522,7 +522,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
522
522
  <time
523
523
  [attr.aria-hidden]="!selected"
524
524
  class="k-message-time"
525
- *ngIf="message.timestamp"
525
+ *ngIf="chatService.timestampVisibility === 'focus' && message.timestamp"
526
526
  >
527
527
  {{ formatTimeStamp(message.timestamp) }}
528
528
  </time>
@@ -10,7 +10,7 @@ export const packageMetadata = {
10
10
  productName: 'Kendo UI for Angular',
11
11
  productCode: 'KENDOUIANGULAR',
12
12
  productCodes: ['KENDOUIANGULAR'],
13
- publishDate: 1761910356,
14
- version: '21.0.0-develop.9',
13
+ publishDate: 1762953404,
14
+ version: '21.0.1-develop.1',
15
15
  licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/'
16
16
  };
@@ -216,8 +216,8 @@ const packageMetadata = {
216
216
  productName: 'Kendo UI for Angular',
217
217
  productCode: 'KENDOUIANGULAR',
218
218
  productCodes: ['KENDOUIANGULAR'],
219
- publishDate: 1761910356,
220
- version: '21.0.0-develop.9',
219
+ publishDate: 1762953404,
220
+ version: '21.0.1-develop.1',
221
221
  licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/'
222
222
  };
223
223
 
@@ -2131,6 +2131,9 @@ class ChatService {
2131
2131
  selectOnMenuClose = false;
2132
2132
  active = false;
2133
2133
  messageFilesLayout = 'vertical';
2134
+ timestampVisibility = 'focus';
2135
+ showUsername = true;
2136
+ showAvatar = true;
2134
2137
  _enableSpeechToText = STB_DEFAULT_SETTINGS;
2135
2138
  _enableFileSelect = FILESELECT_DEFAULT_SETTINGS;
2136
2139
  _sendButtonSettings = SEND_BTN_DEFAULT_SETTINGS;
@@ -4214,7 +4217,7 @@ class MessageComponent extends ChatItem {
4214
4217
  <time
4215
4218
  [attr.aria-hidden]="!selected"
4216
4219
  class="k-message-time"
4217
- *ngIf="message.timestamp"
4220
+ *ngIf="chatService.timestampVisibility === 'focus' && message.timestamp"
4218
4221
  >
4219
4222
  {{ formatTimeStamp(message.timestamp) }}
4220
4223
  </time>
@@ -4392,7 +4395,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
4392
4395
  <time
4393
4396
  [attr.aria-hidden]="!selected"
4394
4397
  class="k-message-time"
4395
- *ngIf="message.timestamp"
4398
+ *ngIf="chatService.timestampVisibility === 'focus' && message.timestamp"
4396
4399
  >
4397
4400
  {{ formatTimeStamp(message.timestamp) }}
4398
4401
  </time>
@@ -5032,6 +5035,20 @@ class MessageListComponent {
5032
5035
  onClick(message, event) {
5033
5036
  this.select(message, event);
5034
5037
  }
5038
+ showGroupAuthor(group) {
5039
+ const messageSettings = this.isOwnMessage(group.messages[0]) ? this.chatService.authorMessageSettings : this.chatService.receiverMessageSettings;
5040
+ if (isPresent(messageSettings?.showUsername)) {
5041
+ return messageSettings.showUsername && group.author.name;
5042
+ }
5043
+ return this.chatService.showUsername && group.author.name;
5044
+ }
5045
+ showGroupAvatar(group) {
5046
+ const messageSettings = this.isOwnMessage(group.messages[0]) ? this.chatService.authorMessageSettings : this.chatService.receiverMessageSettings;
5047
+ if (isPresent(messageSettings?.showAvatar)) {
5048
+ return messageSettings.showAvatar && group.author.avatarUrl;
5049
+ }
5050
+ return this.chatService.showAvatar && group.author.avatarUrl;
5051
+ }
5035
5052
  onContextMenuClick(message, event, messageElement) {
5036
5053
  this.chatService.calculateContextMenuActions(this.isOwnMessage(message));
5037
5054
  if (this.chatService.calculatedContextMenuActions.length > 0) {
@@ -5227,11 +5244,11 @@ class MessageListComponent {
5227
5244
  class="k-message-group"
5228
5245
  [class.k-message-group-sender]="isOwnMessage(group.messages[0])"
5229
5246
  [class.k-message-group-receiver]="!isOwnMessage(group.messages[0])"
5230
- [class.k-no-avatar]="!group.author.avatarUrl"
5247
+ [class.k-no-avatar]="!showGroupAvatar(group)"
5231
5248
  [class.k-message-group-full-width]="calculateMessageWidthMode(group.messages[0])"
5232
5249
  >
5233
5250
  <div
5234
- *ngIf="!userStatusTemplate?.templateRef && group.author.avatarUrl"
5251
+ *ngIf="!userStatusTemplate?.templateRef && showGroupAvatar(group)"
5235
5252
  class="k-avatar k-avatar-md k-avatar-solid k-avatar-solid-primary k-rounded-full"
5236
5253
  >
5237
5254
  <span class="k-avatar-image">
@@ -5241,7 +5258,7 @@ class MessageListComponent {
5241
5258
  />
5242
5259
  </span>
5243
5260
  </div>
5244
- <div class="k-chat-user-status-wrapper" *ngIf="group.author.avatarUrl && userStatusTemplate?.templateRef">
5261
+ <div class="k-chat-user-status-wrapper" *ngIf="userStatusTemplate?.templateRef && showGroupAvatar(group)">
5245
5262
  <div
5246
5263
  class="k-avatar k-avatar-md k-avatar-solid k-avatar-solid-primary k-rounded-full"
5247
5264
  >
@@ -5261,18 +5278,10 @@ class MessageListComponent {
5261
5278
  </div>
5262
5279
  </div>
5263
5280
  <div class="k-message-group-content">
5264
- <p *ngIf="group.author.name" class="k-message-author">{{ group.author.name }}</p>
5281
+ <p *ngIf="showGroupAuthor(group)" class="k-message-author">{{ group.author.name }}</p>
5265
5282
  <ng-container
5266
5283
  *ngFor="let msg of group.messages; first as firstMessage; last as lastMessage"
5267
5284
  >
5268
- <div
5269
- *ngIf="msg.user?.avatarUrl"
5270
- class="k-avatar k-avatar-md k-avatar-solid k-avatar-solid-primary k-rounded-full"
5271
- >
5272
- <span class="k-avatar-image">
5273
- <img [src]="msg.user?.avatarUrl">
5274
- </span>
5275
- </div>
5276
5285
  <kendo-chat-message #message
5277
5286
  [message]="msg"
5278
5287
  [tabbable]="lastGroup && lastMessage"
@@ -5349,11 +5358,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
5349
5358
  class="k-message-group"
5350
5359
  [class.k-message-group-sender]="isOwnMessage(group.messages[0])"
5351
5360
  [class.k-message-group-receiver]="!isOwnMessage(group.messages[0])"
5352
- [class.k-no-avatar]="!group.author.avatarUrl"
5361
+ [class.k-no-avatar]="!showGroupAvatar(group)"
5353
5362
  [class.k-message-group-full-width]="calculateMessageWidthMode(group.messages[0])"
5354
5363
  >
5355
5364
  <div
5356
- *ngIf="!userStatusTemplate?.templateRef && group.author.avatarUrl"
5365
+ *ngIf="!userStatusTemplate?.templateRef && showGroupAvatar(group)"
5357
5366
  class="k-avatar k-avatar-md k-avatar-solid k-avatar-solid-primary k-rounded-full"
5358
5367
  >
5359
5368
  <span class="k-avatar-image">
@@ -5363,7 +5372,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
5363
5372
  />
5364
5373
  </span>
5365
5374
  </div>
5366
- <div class="k-chat-user-status-wrapper" *ngIf="group.author.avatarUrl && userStatusTemplate?.templateRef">
5375
+ <div class="k-chat-user-status-wrapper" *ngIf="userStatusTemplate?.templateRef && showGroupAvatar(group)">
5367
5376
  <div
5368
5377
  class="k-avatar k-avatar-md k-avatar-solid k-avatar-solid-primary k-rounded-full"
5369
5378
  >
@@ -5383,18 +5392,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
5383
5392
  </div>
5384
5393
  </div>
5385
5394
  <div class="k-message-group-content">
5386
- <p *ngIf="group.author.name" class="k-message-author">{{ group.author.name }}</p>
5395
+ <p *ngIf="showGroupAuthor(group)" class="k-message-author">{{ group.author.name }}</p>
5387
5396
  <ng-container
5388
5397
  *ngFor="let msg of group.messages; first as firstMessage; last as lastMessage"
5389
5398
  >
5390
- <div
5391
- *ngIf="msg.user?.avatarUrl"
5392
- class="k-avatar k-avatar-md k-avatar-solid k-avatar-solid-primary k-rounded-full"
5393
- >
5394
- <span class="k-avatar-image">
5395
- <img [src]="msg.user?.avatarUrl">
5396
- </span>
5397
- </div>
5398
5399
  <kendo-chat-message #message
5399
5400
  [message]="msg"
5400
5401
  [tabbable]="lastGroup && lastMessage"
@@ -5808,7 +5809,7 @@ class ChatComponent {
5808
5809
  chatService;
5809
5810
  /**
5810
5811
  * Sets the Chat messages.
5811
- * Accepts an array of `Message` objects, but can also accept custom data structures.
5812
+ * Accepts an array of `Message` objects, but can also accept custom data types.
5812
5813
  * For more information, check [Data Binding](slug:databinding_chat) section in the documentation.
5813
5814
  */
5814
5815
  messages;
@@ -5846,6 +5847,26 @@ class ChatComponent {
5846
5847
  * @default 'standard'
5847
5848
  */
5848
5849
  messageWidthMode = 'standard';
5850
+ /**
5851
+ * Controls the visibility of timestamps in messages.
5852
+ *
5853
+ * @default 'focus'
5854
+ */
5855
+ timestampVisibility = 'focus';
5856
+ /**
5857
+ * Controls the visibility of usernames in messages.
5858
+ * When set to `true`, the username displays above each message bubble.
5859
+ *
5860
+ * @default true
5861
+ */
5862
+ showUsername = true;
5863
+ /**
5864
+ * Controls the avatar visibility for the messages.
5865
+ * When set to `true`, the user avatar displays next to each message bubble.
5866
+ *
5867
+ * @default true
5868
+ */
5869
+ showAvatar = true;
5849
5870
  /**
5850
5871
  * Enables the expand or collapse functionality for messages.
5851
5872
  *
@@ -5965,7 +5986,7 @@ class ChatComponent {
5965
5986
  sendButtonSettings = SEND_BTN_DEFAULT_SETTINGS;
5966
5987
  /**
5967
5988
  * Sets the names of the model fields from which the Chat reads its data.
5968
- * Lets you map custom data structures to the expected `Message` format.
5989
+ * Lets you map custom data types to the expected `Message` format.
5969
5990
  */
5970
5991
  set modelFields(value) {
5971
5992
  this._modelFields = { ...defaultModelFields, ...value };
@@ -6124,6 +6145,9 @@ class ChatComponent {
6124
6145
  */
6125
6146
  ngOnInit() {
6126
6147
  this.chatService.messageWidthMode = this.messageWidthMode;
6148
+ this.chatService.timestampVisibility = this.timestampVisibility;
6149
+ this.chatService.showUsername = this.showUsername;
6150
+ this.chatService.showAvatar = this.showAvatar;
6127
6151
  this.chatService.allowMessageCollapse = this.allowMessageCollapse;
6128
6152
  this.chatService.enableSpeechToText = this.enableSpeechToText;
6129
6153
  this.chatService.sendButtonSettings = this.sendButtonSettings;
@@ -6173,6 +6197,9 @@ class ChatComponent {
6173
6197
  this.updateChatServiceProperties([
6174
6198
  'authorId',
6175
6199
  'messageWidthMode',
6200
+ 'timestampVisibility',
6201
+ 'showUsername',
6202
+ 'showAvatar',
6176
6203
  'allowMessageCollapse',
6177
6204
  'enableSpeechToText',
6178
6205
  'sendButtonSettings',
@@ -6290,7 +6317,7 @@ class ChatComponent {
6290
6317
  });
6291
6318
  }
6292
6319
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ChatComponent, deps: [{ token: i1.LocalizationService }, { token: i0.NgZone }, { token: i0.Renderer2 }, { token: i0.ElementRef }, { token: ChatService }], target: i0.ɵɵFactoryTarget.Component });
6293
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: ChatComponent, isStandalone: true, selector: "kendo-chat", inputs: { messages: "messages", authorId: "authorId", messageBoxType: "messageBoxType", height: "height", width: "width", placeholder: "placeholder", messageWidthMode: "messageWidthMode", allowMessageCollapse: "allowMessageCollapse", enableSpeechToText: "enableSpeechToText", enableFileSelect: "enableFileSelect", messageToolbarActions: "messageToolbarActions", inputValue: "inputValue", authorMessageSettings: "authorMessageSettings", receiverMessageSettings: "receiverMessageSettings", messageContextMenuActions: "messageContextMenuActions", fileActions: "fileActions", messageFilesLayout: "messageFilesLayout", suggestionsLayout: "suggestionsLayout", quickActionsLayout: "quickActionsLayout", suggestions: "suggestions", sendButtonSettings: "sendButtonSettings", modelFields: "modelFields" }, outputs: { sendMessage: "sendMessage", toolbarActionClick: "toolbarActionClick", contextMenuActionClick: "contextMenuActionClick", fileActionClick: "fileActionClick", download: "download", executeAction: "executeAction", suggestionExecute: "suggestionExecute", fileSelect: "fileSelect", fileRemove: "fileRemove", unpin: "unpin", inputValueChange: "inputValueChange" }, host: { properties: { "class": "this.className", "attr.dir": "this.dirAttr" } }, providers: [
6320
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: ChatComponent, isStandalone: true, selector: "kendo-chat", inputs: { messages: "messages", authorId: "authorId", messageBoxType: "messageBoxType", height: "height", width: "width", placeholder: "placeholder", messageWidthMode: "messageWidthMode", timestampVisibility: "timestampVisibility", showUsername: "showUsername", showAvatar: "showAvatar", allowMessageCollapse: "allowMessageCollapse", enableSpeechToText: "enableSpeechToText", enableFileSelect: "enableFileSelect", messageToolbarActions: "messageToolbarActions", inputValue: "inputValue", authorMessageSettings: "authorMessageSettings", receiverMessageSettings: "receiverMessageSettings", messageContextMenuActions: "messageContextMenuActions", fileActions: "fileActions", messageFilesLayout: "messageFilesLayout", suggestionsLayout: "suggestionsLayout", quickActionsLayout: "quickActionsLayout", suggestions: "suggestions", sendButtonSettings: "sendButtonSettings", modelFields: "modelFields" }, outputs: { sendMessage: "sendMessage", toolbarActionClick: "toolbarActionClick", contextMenuActionClick: "contextMenuActionClick", fileActionClick: "fileActionClick", download: "download", executeAction: "executeAction", suggestionExecute: "suggestionExecute", fileSelect: "fileSelect", fileRemove: "fileRemove", unpin: "unpin", inputValueChange: "inputValueChange" }, host: { properties: { "class": "this.className", "attr.dir": "this.dirAttr" } }, providers: [
6294
6321
  LocalizationService,
6295
6322
  ChatService,
6296
6323
  SuggestionsScrollService,
@@ -6599,6 +6626,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
6599
6626
  type: Input
6600
6627
  }], messageWidthMode: [{
6601
6628
  type: Input
6629
+ }], timestampVisibility: [{
6630
+ type: Input
6631
+ }], showUsername: [{
6632
+ type: Input
6633
+ }], showAvatar: [{
6634
+ type: Input
6602
6635
  }], allowMessageCollapse: [{
6603
6636
  type: Input
6604
6637
  }], enableSpeechToText: [{