@progress/kendo-angular-conversational-ui 20.0.0-develop.4 → 20.0.0-develop.5
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.
- package/chat/api/action.interface.d.ts +1 -1
- package/chat/api/attachment.interface.d.ts +1 -1
- package/chat/api/chat-file-interface.d.ts +41 -0
- package/chat/api/chat-suggestion.interface.d.ts +25 -0
- package/chat/api/file-action.d.ts +42 -0
- package/chat/api/file-download-event.interface.d.ts +21 -0
- package/chat/api/index.d.ts +8 -0
- package/chat/api/message-action.d.ts +42 -0
- package/{esm2022/chat/chat.directives.mjs → chat/api/message-toolbar-visibility.d.ts} +4 -4
- package/chat/api/message-width-mode.d.ts +10 -0
- package/chat/api/message.interface.d.ts +30 -12
- package/chat/api/send-button-settings.d.ts +15 -0
- package/chat/api/user.interface.d.ts +4 -0
- package/chat/attachment.component.d.ts +1 -1
- package/chat/cards/hero-card.component.d.ts +1 -1
- package/chat/chat-file.component.d.ts +34 -0
- package/chat/chat-item.d.ts +1 -0
- package/chat/chat-view.d.ts +1 -1
- package/chat/chat.component.d.ts +218 -19
- package/chat/chat.module.d.ts +8 -4
- package/chat/common/chat.service.d.ts +51 -0
- package/chat/{chat.directives.d.ts → common/models/default-model-fields.d.ts} +5 -4
- package/chat/common/models/message-box-options.d.ts +1 -1
- package/chat/common/models/model-fields.d.ts +111 -0
- package/chat/common/utils.d.ts +50 -0
- package/chat/l10n/messages.d.ts +40 -3
- package/chat/message-attachments.component.d.ts +1 -4
- package/chat/message-box.component.d.ts +54 -25
- package/chat/message-list.component.d.ts +18 -11
- package/chat/message-reference-content.component.d.ts +24 -0
- package/chat/message.component.d.ts +54 -6
- package/chat/suggested-actions.component.d.ts +17 -4
- package/chat/templates/header-template.directive.d.ts +24 -0
- package/chat/{message-box.directive.d.ts → templates/message-box.directive.d.ts} +1 -1
- package/chat/templates/status-template.directive.d.ts +24 -0
- package/chat/templates/suggestion-template.directive.d.ts +24 -0
- package/chat/templates/timestamp-template.directive.d.ts +28 -0
- package/codemods/template-transformer/index.js +94 -0
- package/codemods/utils.js +609 -0
- package/codemods/v20/chat-user.js +50 -0
- package/conversational-ui.module.d.ts +11 -7
- package/directives.d.ts +9 -5
- package/esm2022/chat/api/chat-file-interface.mjs +5 -0
- package/esm2022/chat/api/chat-suggestion.interface.mjs +5 -0
- package/esm2022/chat/api/file-action.mjs +5 -0
- package/esm2022/chat/api/file-download-event.interface.mjs +5 -0
- package/esm2022/chat/api/index.mjs +8 -0
- package/esm2022/chat/api/message-action.mjs +5 -0
- package/esm2022/chat/api/message-toolbar-visibility.mjs +5 -0
- package/esm2022/chat/api/message-width-mode.mjs +5 -0
- package/esm2022/chat/api/send-button-settings.mjs +5 -0
- package/esm2022/chat/attachment.component.mjs +1 -1
- package/esm2022/chat/builtin-actions.mjs +1 -1
- package/esm2022/chat/cards/hero-card.component.mjs +1 -1
- package/esm2022/chat/chat-file.component.mjs +141 -0
- package/esm2022/chat/chat-item.mjs +1 -0
- package/esm2022/chat/chat-view.mjs +2 -2
- package/esm2022/chat/chat.component.mjs +518 -57
- package/esm2022/chat/chat.module.mjs +8 -4
- package/esm2022/chat/common/chat.service.mjs +97 -0
- package/esm2022/chat/common/models/default-model-fields.mjs +26 -0
- package/esm2022/chat/common/models/model-fields.mjs +5 -0
- package/esm2022/chat/common/utils.mjs +127 -0
- package/esm2022/chat/l10n/messages.mjs +60 -5
- package/esm2022/chat/message-attachments.component.mjs +1 -4
- package/esm2022/chat/message-box.component.mjs +360 -111
- package/esm2022/chat/message-list.component.mjs +166 -96
- package/esm2022/chat/message-reference-content.component.mjs +75 -0
- package/esm2022/chat/message.component.mjs +448 -35
- package/esm2022/chat/suggested-actions.component.mjs +151 -41
- package/esm2022/chat/templates/header-template.directive.mjs +33 -0
- package/esm2022/chat/{message-box.directive.mjs → templates/message-box.directive.mjs} +1 -1
- package/esm2022/chat/templates/status-template.directive.mjs +33 -0
- package/esm2022/chat/templates/suggestion-template.directive.mjs +33 -0
- package/esm2022/chat/templates/timestamp-template.directive.mjs +39 -0
- package/esm2022/conversational-ui.module.mjs +12 -8
- package/esm2022/directives.mjs +12 -4
- package/esm2022/index.mjs +9 -3
- package/esm2022/package-metadata.mjs +2 -2
- package/fesm2022/progress-kendo-angular-conversational-ui.mjs +4986 -3125
- package/index.d.ts +10 -3
- package/package.json +29 -12
- /package/chat/{attachment-template.directive.d.ts → templates/attachment-template.directive.d.ts} +0 -0
- /package/chat/{message-template.directive.d.ts → templates/message-template.directive.d.ts} +0 -0
- /package/esm2022/chat/{attachment-template.directive.mjs → templates/attachment-template.directive.mjs} +0 -0
- /package/esm2022/chat/{message-template.directive.mjs → templates/message-template.directive.mjs} +0 -0
@@ -4,24 +4,28 @@
|
|
4
4
|
*-------------------------------------------------------------------------------------------*/
|
5
5
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
6
6
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
7
|
-
import { Component, ElementRef, EventEmitter, HostBinding, Input, Output, QueryList, Renderer2, ViewChildren } from '@angular/core';
|
8
|
-
import { NgFor, NgSwitch, NgSwitchCase, NgIf } from '@angular/common';
|
7
|
+
import { ChangeDetectorRef, Component, ElementRef, EventEmitter, HostBinding, Input, Output, QueryList, Renderer2, ViewChildren } from '@angular/core';
|
8
|
+
import { NgFor, NgSwitch, NgSwitchCase, NgIf, NgTemplateOutlet } from '@angular/common';
|
9
9
|
import { ExecuteActionEvent } from './api';
|
10
10
|
import { 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
|
-
import { closest } from './common/utils';
|
13
|
+
import { closest, DOWNLOAD_ALL_SELECTOR, FILE_ACTION_BTN_SELECTOR } from './common/utils';
|
14
14
|
import { ChatItem } from './chat-item';
|
15
15
|
import { chatView, isAuthor } from './chat-view';
|
16
|
-
import { AttachmentTemplateDirective } from './attachment-template.directive';
|
17
|
-
import { MessageTemplateDirective } from './message-template.directive';
|
16
|
+
import { AttachmentTemplateDirective } from './templates/attachment-template.directive';
|
17
|
+
import { MessageTemplateDirective } from './templates/message-template.directive';
|
18
|
+
import { ChatTimestampTemplateDirective } from './templates/timestamp-template.directive';
|
18
19
|
import { Subscription } from 'rxjs';
|
19
20
|
import { SuggestedActionsComponent } from './suggested-actions.component';
|
20
21
|
import { MessageComponent } from './message.component';
|
21
22
|
import { MessageAttachmentsComponent } from './message-attachments.component';
|
22
23
|
import { AttachmentComponent } from './attachment.component';
|
24
|
+
import { ChatService } from './common/chat.service';
|
25
|
+
import { ChatStatusTemplateDirective } from './templates/status-template.directive';
|
23
26
|
import * as i0 from "@angular/core";
|
24
27
|
import * as i1 from "@progress/kendo-angular-intl";
|
28
|
+
import * as i2 from "./common/chat.service";
|
25
29
|
/**
|
26
30
|
* @hidden
|
27
31
|
*/
|
@@ -29,6 +33,8 @@ export class MessageListComponent {
|
|
29
33
|
element;
|
30
34
|
intl;
|
31
35
|
renderer;
|
36
|
+
chatService;
|
37
|
+
cdr;
|
32
38
|
set messages(value) {
|
33
39
|
const data = value || [];
|
34
40
|
this.view = chatView(data);
|
@@ -39,8 +45,10 @@ export class MessageListComponent {
|
|
39
45
|
}
|
40
46
|
attachmentTemplate;
|
41
47
|
messageTemplate;
|
48
|
+
timestampTemplate;
|
49
|
+
statusTemplate;
|
42
50
|
localization;
|
43
|
-
|
51
|
+
authorId;
|
44
52
|
executeAction = new EventEmitter();
|
45
53
|
navigate = new EventEmitter();
|
46
54
|
resize = new EventEmitter();
|
@@ -57,15 +65,20 @@ export class MessageListComponent {
|
|
57
65
|
[Keys.ArrowDown]: (e) => this.navigateTo(e, 1),
|
58
66
|
[Keys.Tab]: (e) => this.onTabKeyDown(e),
|
59
67
|
};
|
60
|
-
constructor(element, intl, renderer) {
|
68
|
+
constructor(element, intl, renderer, chatService, cdr) {
|
61
69
|
this.element = element;
|
62
70
|
this.intl = intl;
|
63
71
|
this.renderer = renderer;
|
72
|
+
this.chatService = chatService;
|
73
|
+
this.cdr = cdr;
|
64
74
|
}
|
65
75
|
ngOnInit() {
|
66
76
|
const elRef = this.element.nativeElement;
|
67
77
|
this.subs.add(this.renderer.listen(elRef, 'keydown', event => this.onKeydown(event)));
|
68
78
|
this.subs.add(this.renderer.listen(elRef, 'focusout', event => this.onBlur(event)));
|
79
|
+
this.subs.add(this.chatService.replyReferenceClick$.subscribe((messageId) => {
|
80
|
+
this.scrollToAndSelectMessage(messageId);
|
81
|
+
}));
|
69
82
|
}
|
70
83
|
ngAfterViewInit() {
|
71
84
|
this.selectedItem = this.items.last;
|
@@ -76,6 +89,9 @@ export class MessageListComponent {
|
|
76
89
|
onResize() {
|
77
90
|
this.resize.emit();
|
78
91
|
}
|
92
|
+
onClick(message, event) {
|
93
|
+
this.select(message, event);
|
94
|
+
}
|
79
95
|
formatTimeStamp(date) {
|
80
96
|
return this.intl.formatDate(date, { date: 'full' });
|
81
97
|
}
|
@@ -90,12 +106,13 @@ export class MessageListComponent {
|
|
90
106
|
onBlur(args) {
|
91
107
|
const next = args.relatedTarget || document.activeElement;
|
92
108
|
const outside = !closest(next, (node) => node === this.element.nativeElement);
|
93
|
-
|
109
|
+
const isActionClick = closest(next, (node) => node?.classList?.contains('k-context-menu-popup')) || closest(next, (node) => node?.classList?.contains('k-menu-popup'));
|
110
|
+
if (outside && !isActionClick) {
|
94
111
|
this.select(null);
|
95
112
|
}
|
96
113
|
}
|
97
114
|
isOwnMessage(msg) {
|
98
|
-
return isAuthor(this.
|
115
|
+
return isAuthor(this.authorId, msg);
|
99
116
|
}
|
100
117
|
dispatchAction(action, message) {
|
101
118
|
const args = new ExecuteActionEvent(action, message);
|
@@ -104,21 +121,38 @@ export class MessageListComponent {
|
|
104
121
|
trackGroup(_index, item) {
|
105
122
|
return item.trackBy;
|
106
123
|
}
|
107
|
-
select(item) {
|
108
|
-
|
109
|
-
|
110
|
-
|
124
|
+
select(item, event) {
|
125
|
+
if (event) {
|
126
|
+
const target = event.target;
|
127
|
+
if (target.classList.contains('k-suggestion') || target.closest(DOWNLOAD_ALL_SELECTOR) || target.closest(FILE_ACTION_BTN_SELECTOR)) {
|
128
|
+
return;
|
129
|
+
}
|
111
130
|
}
|
112
|
-
if (
|
113
|
-
|
114
|
-
|
131
|
+
if (!this.chatService.toggleMessageState) {
|
132
|
+
const prevItem = this.selectedItem;
|
133
|
+
if (prevItem) {
|
134
|
+
prevItem.selected = false;
|
135
|
+
}
|
136
|
+
if (item) {
|
137
|
+
item.selected = true;
|
138
|
+
this.selectedItem = item;
|
139
|
+
}
|
140
|
+
this.cdr.detectChanges();
|
115
141
|
}
|
142
|
+
this.chatService.toggleMessageState = false;
|
116
143
|
}
|
117
144
|
last(items) {
|
118
145
|
if (!items || items.length === 0) {
|
119
146
|
return;
|
120
147
|
}
|
121
|
-
|
148
|
+
const messageGroups = items.filter((item) => item.type === 'message-group');
|
149
|
+
const lastMessageGroup = messageGroups[messageGroups.length - 1].messages;
|
150
|
+
return lastMessageGroup[lastMessageGroup.length - 1];
|
151
|
+
}
|
152
|
+
handleMenuClose(state) {
|
153
|
+
if (!state) {
|
154
|
+
this.select(null);
|
155
|
+
}
|
122
156
|
}
|
123
157
|
onHomeOrEndKeyDown(key) {
|
124
158
|
const items = this.items.toArray();
|
@@ -157,29 +191,42 @@ export class MessageListComponent {
|
|
157
191
|
e.preventDefault();
|
158
192
|
}
|
159
193
|
}
|
160
|
-
|
161
|
-
|
162
|
-
|
194
|
+
scrollToAndSelectMessage(messageId) {
|
195
|
+
this.chatService.scrollToMessage(messageId);
|
196
|
+
const message = this.chatService.getMessageById(messageId);
|
197
|
+
const chatItem = this.items.find(item => item instanceof MessageComponent &&
|
198
|
+
item.message === message);
|
199
|
+
if (chatItem) {
|
200
|
+
this.select(chatItem);
|
201
|
+
}
|
202
|
+
}
|
163
203
|
textFor(key) {
|
164
204
|
return this.localization.get(key);
|
165
205
|
}
|
166
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: MessageListComponent, deps: [{ token: i0.ElementRef }, { token: i1.IntlService }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
|
167
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: MessageListComponent, isStandalone: true, selector: "kendo-chat-message-list", inputs: { messages: "messages", attachmentTemplate: "attachmentTemplate", messageTemplate: "messageTemplate", localization: "localization",
|
206
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: MessageListComponent, deps: [{ token: i0.ElementRef }, { token: i1.IntlService }, { token: i0.Renderer2 }, { token: i2.ChatService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
207
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: MessageListComponent, isStandalone: true, selector: "kendo-chat-message-list", inputs: { messages: "messages", attachmentTemplate: "attachmentTemplate", messageTemplate: "messageTemplate", timestampTemplate: "timestampTemplate", statusTemplate: "statusTemplate", localization: "localization", authorId: "authorId" }, outputs: { executeAction: "executeAction", navigate: "navigate", resize: "resize" }, host: { properties: { "class.k-message-list-content": "this.cssClass" } }, viewQueries: [{ propertyName: "items", predicate: ChatItem, descendants: true }], ngImport: i0, template: `
|
168
208
|
<ng-container *ngFor="let group of view; last as lastGroup; trackBy: trackGroup">
|
169
209
|
<ng-container [ngSwitch]="group.type">
|
170
210
|
<div
|
171
211
|
*ngSwitchCase="'date-marker'"
|
172
212
|
class="k-timestamp"
|
173
213
|
>
|
174
|
-
|
214
|
+
<ng-container
|
215
|
+
*ngIf="timestampTemplate?.templateRef"
|
216
|
+
[ngTemplateOutlet]="timestampTemplate.templateRef"
|
217
|
+
[ngTemplateOutletContext]="{ $implicit: group.timestamp }"
|
218
|
+
>
|
219
|
+
</ng-container>
|
220
|
+
<ng-container *ngIf="!timestampTemplate?.templateRef">{{ formatTimeStamp(group.timestamp) }}</ng-container>
|
175
221
|
</div>
|
176
222
|
<div
|
177
223
|
*ngSwitchCase="'message-group'"
|
178
224
|
class="k-message-group"
|
179
|
-
[class.k-
|
225
|
+
[class.k-message-group-sender]="isOwnMessage(group.messages[0])"
|
226
|
+
[class.k-message-group-receiver]="!isOwnMessage(group.messages[0])"
|
180
227
|
[class.k-no-avatar]="!group.author.avatarUrl"
|
228
|
+
[class.k-message-group-full-width]="chatService.messageWidthMode === 'full'"
|
181
229
|
>
|
182
|
-
<p *ngIf="group.author.name" class="k-author">{{ group.author.name }}</p>
|
183
230
|
<div
|
184
231
|
*ngIf="group.author.avatarUrl"
|
185
232
|
class="k-avatar k-avatar-md k-avatar-solid k-avatar-solid-primary k-rounded-full"
|
@@ -187,40 +234,46 @@ export class MessageListComponent {
|
|
187
234
|
<span class="k-avatar-image">
|
188
235
|
<img
|
189
236
|
[attr.src]="group.author.avatarUrl"
|
190
|
-
[alt]="
|
237
|
+
[alt]="group.author.avatarAltText"
|
191
238
|
/>
|
192
239
|
</span>
|
193
240
|
</div>
|
194
|
-
<
|
195
|
-
*
|
196
|
-
|
197
|
-
|
198
|
-
*ngIf="msg.user?.avatarUrl"
|
199
|
-
class="k-avatar k-avatar-md k-avatar-solid k-avatar-solid-primary k-rounded-full"
|
241
|
+
<div class="k-message-group-content">
|
242
|
+
<p *ngIf="group.author.name" class="k-message-author">{{ group.author.name }}</p>
|
243
|
+
<ng-container
|
244
|
+
*ngFor="let msg of group.messages; first as firstMessage; last as lastMessage"
|
200
245
|
>
|
201
|
-
<
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
246
|
+
<div
|
247
|
+
*ngIf="msg.user?.avatarUrl"
|
248
|
+
class="k-avatar k-avatar-md k-avatar-solid k-avatar-solid-primary k-rounded-full"
|
249
|
+
>
|
250
|
+
<span class="k-avatar-image">
|
251
|
+
<img [src]="msg.user?.avatarUrl">
|
252
|
+
</span>
|
253
|
+
</div>
|
254
|
+
<kendo-chat-message #message
|
255
|
+
[message]="msg"
|
256
|
+
[tabbable]="lastGroup && lastMessage"
|
257
|
+
[template]="messageTemplate"
|
258
|
+
[statusTemplate]="statusTemplate"
|
259
|
+
[authorId]="authorId"
|
260
|
+
(click)="onClick(message, $event)"
|
261
|
+
(mouseenter)="message.hovered = true"
|
262
|
+
(mouseleave)="message.hovered = false"
|
263
|
+
(contextMenuVisibilityChange)="handleMenuClose($event)"
|
264
|
+
[class.k-first]="group.messages.length > 1 && firstMessage"
|
265
|
+
[class.k-last]="group.messages.length > 1 && lastMessage"
|
266
|
+
>
|
267
|
+
</kendo-chat-message>
|
216
268
|
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
269
|
+
<kendo-chat-attachment
|
270
|
+
*ngIf="msg.attachments && msg.attachments.length === 1"
|
271
|
+
[attachment]="msg.attachments[0]"
|
272
|
+
[template]="attachmentTemplate"
|
273
|
+
>
|
274
|
+
</kendo-chat-attachment>
|
275
|
+
</ng-container>
|
276
|
+
</div>
|
224
277
|
</div>
|
225
278
|
|
226
279
|
<kendo-chat-message-attachments #attachments
|
@@ -239,16 +292,16 @@ export class MessageListComponent {
|
|
239
292
|
*ngSwitchCase="'action-group'"
|
240
293
|
[actions]="group.actions"
|
241
294
|
[tabbable]="lastGroup"
|
242
|
-
(
|
243
|
-
(click)="select(actions)"
|
244
|
-
(focus)="select(actions)"
|
295
|
+
(dispatchAction)="dispatchAction($event, last(view))"
|
296
|
+
(click)="select(actions, $event)"
|
297
|
+
(focus)="select(actions, $event)"
|
245
298
|
>
|
246
299
|
</kendo-chat-suggested-actions>
|
247
300
|
</ng-container>
|
248
301
|
</ng-container>
|
249
302
|
<kendo-resize-sensor (resize)="onResize()">
|
250
303
|
</kendo-resize-sensor>
|
251
|
-
`, isInline: true, dependencies: [{ kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: MessageComponent, selector: "kendo-chat-message", inputs: ["message", "tabbable", "template"] }, { kind: "component", type: AttachmentComponent, selector: "kendo-chat-attachment", inputs: ["attachment", "template"] }, { kind: "component", type: MessageAttachmentsComponent, selector: "kendo-chat-message-attachments", inputs: ["attachments", "layout", "tabbable", "template", "localization"] }, { kind: "component", type: SuggestedActionsComponent, selector: "kendo-chat-suggested-actions", inputs: ["actions", "tabbable"], outputs: ["
|
304
|
+
`, isInline: true, dependencies: [{ kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: MessageComponent, selector: "kendo-chat-message", inputs: ["message", "tabbable", "template", "statusTemplate", "showMessageTime", "authorId"], outputs: ["contextMenuVisibilityChange"] }, { kind: "component", type: AttachmentComponent, selector: "kendo-chat-attachment", inputs: ["attachment", "template"] }, { kind: "component", type: MessageAttachmentsComponent, selector: "kendo-chat-message-attachments", inputs: ["attachments", "layout", "tabbable", "template", "localization"] }, { kind: "component", type: SuggestedActionsComponent, selector: "kendo-chat-suggested-actions", inputs: ["actions", "suggestions", "tabbable", "suggestionTemplate"], outputs: ["dispatchAction", "dispatchSuggestion"] }, { kind: "component", type: ResizeSensorComponent, selector: "kendo-resize-sensor", inputs: ["rateLimit"], outputs: ["resize"] }] });
|
252
305
|
}
|
253
306
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: MessageListComponent, decorators: [{
|
254
307
|
type: Component,
|
@@ -261,15 +314,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
261
314
|
*ngSwitchCase="'date-marker'"
|
262
315
|
class="k-timestamp"
|
263
316
|
>
|
264
|
-
|
317
|
+
<ng-container
|
318
|
+
*ngIf="timestampTemplate?.templateRef"
|
319
|
+
[ngTemplateOutlet]="timestampTemplate.templateRef"
|
320
|
+
[ngTemplateOutletContext]="{ $implicit: group.timestamp }"
|
321
|
+
>
|
322
|
+
</ng-container>
|
323
|
+
<ng-container *ngIf="!timestampTemplate?.templateRef">{{ formatTimeStamp(group.timestamp) }}</ng-container>
|
265
324
|
</div>
|
266
325
|
<div
|
267
326
|
*ngSwitchCase="'message-group'"
|
268
327
|
class="k-message-group"
|
269
|
-
[class.k-
|
328
|
+
[class.k-message-group-sender]="isOwnMessage(group.messages[0])"
|
329
|
+
[class.k-message-group-receiver]="!isOwnMessage(group.messages[0])"
|
270
330
|
[class.k-no-avatar]="!group.author.avatarUrl"
|
331
|
+
[class.k-message-group-full-width]="chatService.messageWidthMode === 'full'"
|
271
332
|
>
|
272
|
-
<p *ngIf="group.author.name" class="k-author">{{ group.author.name }}</p>
|
273
333
|
<div
|
274
334
|
*ngIf="group.author.avatarUrl"
|
275
335
|
class="k-avatar k-avatar-md k-avatar-solid k-avatar-solid-primary k-rounded-full"
|
@@ -277,40 +337,46 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
277
337
|
<span class="k-avatar-image">
|
278
338
|
<img
|
279
339
|
[attr.src]="group.author.avatarUrl"
|
280
|
-
[alt]="
|
340
|
+
[alt]="group.author.avatarAltText"
|
281
341
|
/>
|
282
342
|
</span>
|
283
343
|
</div>
|
284
|
-
<
|
285
|
-
*
|
286
|
-
|
287
|
-
|
288
|
-
*ngIf="msg.user?.avatarUrl"
|
289
|
-
class="k-avatar k-avatar-md k-avatar-solid k-avatar-solid-primary k-rounded-full"
|
290
|
-
>
|
291
|
-
<span class="k-avatar-image">
|
292
|
-
<img [src]="msg.user?.avatarUrl">
|
293
|
-
</span>
|
294
|
-
</div>
|
295
|
-
<kendo-chat-message #message
|
296
|
-
[message]="msg"
|
297
|
-
[tabbable]="lastGroup && lastMessage"
|
298
|
-
[template]="messageTemplate"
|
299
|
-
(click)="select(message)"
|
300
|
-
(focus)="select(message)"
|
301
|
-
[class.k-only]="group.messages.length === 1"
|
302
|
-
[class.k-first]="group.messages.length > 1 && firstMessage"
|
303
|
-
[class.k-last]="group.messages.length > 1 && lastMessage"
|
344
|
+
<div class="k-message-group-content">
|
345
|
+
<p *ngIf="group.author.name" class="k-message-author">{{ group.author.name }}</p>
|
346
|
+
<ng-container
|
347
|
+
*ngFor="let msg of group.messages; first as firstMessage; last as lastMessage"
|
304
348
|
>
|
305
|
-
|
349
|
+
<div
|
350
|
+
*ngIf="msg.user?.avatarUrl"
|
351
|
+
class="k-avatar k-avatar-md k-avatar-solid k-avatar-solid-primary k-rounded-full"
|
352
|
+
>
|
353
|
+
<span class="k-avatar-image">
|
354
|
+
<img [src]="msg.user?.avatarUrl">
|
355
|
+
</span>
|
356
|
+
</div>
|
357
|
+
<kendo-chat-message #message
|
358
|
+
[message]="msg"
|
359
|
+
[tabbable]="lastGroup && lastMessage"
|
360
|
+
[template]="messageTemplate"
|
361
|
+
[statusTemplate]="statusTemplate"
|
362
|
+
[authorId]="authorId"
|
363
|
+
(click)="onClick(message, $event)"
|
364
|
+
(mouseenter)="message.hovered = true"
|
365
|
+
(mouseleave)="message.hovered = false"
|
366
|
+
(contextMenuVisibilityChange)="handleMenuClose($event)"
|
367
|
+
[class.k-first]="group.messages.length > 1 && firstMessage"
|
368
|
+
[class.k-last]="group.messages.length > 1 && lastMessage"
|
369
|
+
>
|
370
|
+
</kendo-chat-message>
|
306
371
|
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
372
|
+
<kendo-chat-attachment
|
373
|
+
*ngIf="msg.attachments && msg.attachments.length === 1"
|
374
|
+
[attachment]="msg.attachments[0]"
|
375
|
+
[template]="attachmentTemplate"
|
376
|
+
>
|
377
|
+
</kendo-chat-attachment>
|
378
|
+
</ng-container>
|
379
|
+
</div>
|
314
380
|
</div>
|
315
381
|
|
316
382
|
<kendo-chat-message-attachments #attachments
|
@@ -329,9 +395,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
329
395
|
*ngSwitchCase="'action-group'"
|
330
396
|
[actions]="group.actions"
|
331
397
|
[tabbable]="lastGroup"
|
332
|
-
(
|
333
|
-
(click)="select(actions)"
|
334
|
-
(focus)="select(actions)"
|
398
|
+
(dispatchAction)="dispatchAction($event, last(view))"
|
399
|
+
(click)="select(actions, $event)"
|
400
|
+
(focus)="select(actions, $event)"
|
335
401
|
>
|
336
402
|
</kendo-chat-suggested-actions>
|
337
403
|
</ng-container>
|
@@ -340,17 +406,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
340
406
|
</kendo-resize-sensor>
|
341
407
|
`,
|
342
408
|
standalone: true,
|
343
|
-
imports: [NgFor, NgSwitch, NgSwitchCase, NgIf, MessageComponent, AttachmentComponent, MessageAttachmentsComponent, SuggestedActionsComponent, ResizeSensorComponent]
|
409
|
+
imports: [NgFor, NgSwitch, NgSwitchCase, NgIf, NgTemplateOutlet, MessageComponent, AttachmentComponent, MessageAttachmentsComponent, SuggestedActionsComponent, ResizeSensorComponent]
|
344
410
|
}]
|
345
|
-
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i1.IntlService }, { type: i0.Renderer2 }]; }, propDecorators: { messages: [{
|
411
|
+
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i1.IntlService }, { type: i0.Renderer2 }, { type: i2.ChatService }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { messages: [{
|
346
412
|
type: Input
|
347
413
|
}], attachmentTemplate: [{
|
348
414
|
type: Input
|
349
415
|
}], messageTemplate: [{
|
350
416
|
type: Input
|
417
|
+
}], timestampTemplate: [{
|
418
|
+
type: Input
|
419
|
+
}], statusTemplate: [{
|
420
|
+
type: Input
|
351
421
|
}], localization: [{
|
352
422
|
type: Input
|
353
|
-
}],
|
423
|
+
}], authorId: [{
|
354
424
|
type: Input
|
355
425
|
}], executeAction: [{
|
356
426
|
type: Output
|
@@ -0,0 +1,75 @@
|
|
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
|
+
/* eslint-disable @typescript-eslint/no-empty-function */
|
6
|
+
import { Component, forwardRef, Input, HostBinding } from '@angular/core';
|
7
|
+
import { ChatItem } from './chat-item';
|
8
|
+
import { NgIf } from '@angular/common';
|
9
|
+
import { ChatFileComponent } from './chat-file.component';
|
10
|
+
import { ChatService } from './common/chat.service';
|
11
|
+
import { LocalizationService } from '@progress/kendo-angular-l10n';
|
12
|
+
import { isAuthor } from './chat-view';
|
13
|
+
import * as i0 from "@angular/core";
|
14
|
+
import * as i1 from "@progress/kendo-angular-l10n";
|
15
|
+
import * as i2 from "./common/chat.service";
|
16
|
+
/**
|
17
|
+
* @hidden
|
18
|
+
*/
|
19
|
+
export class MessageReferenceComponent extends ChatItem {
|
20
|
+
localization;
|
21
|
+
chatService;
|
22
|
+
hostClass = true;
|
23
|
+
message;
|
24
|
+
constructor(localization, chatService) {
|
25
|
+
super();
|
26
|
+
this.localization = localization;
|
27
|
+
this.chatService = chatService;
|
28
|
+
}
|
29
|
+
isOwnMessage(msg) {
|
30
|
+
return isAuthor(this.chatService.authorId, msg);
|
31
|
+
}
|
32
|
+
textFor(key) {
|
33
|
+
return this.localization.get(key);
|
34
|
+
}
|
35
|
+
focus() { }
|
36
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: MessageReferenceComponent, deps: [{ token: i1.LocalizationService }, { token: i2.ChatService }], target: i0.ɵɵFactoryTarget.Component });
|
37
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: MessageReferenceComponent, isStandalone: true, selector: "chat-message-reference-content", inputs: { message: "message" }, host: { properties: { "class.k-message-reference-content": "this.hostClass" } }, providers: [{
|
38
|
+
provide: ChatItem,
|
39
|
+
useExisting: forwardRef(() => MessageReferenceComponent)
|
40
|
+
}], usesInheritance: true, ngImport: i0, template: `
|
41
|
+
<ng-container *ngIf="message.text && !message.isDeleted">{{message.text}}</ng-container>
|
42
|
+
<ng-container *ngIf="!message.text && !message.isDeleted && message.files && message.files.length > 0">
|
43
|
+
<li class="k-chat-file" [chatFile]="message.files[0]">
|
44
|
+
</li>
|
45
|
+
</ng-container>
|
46
|
+
<ng-container *ngIf="message.isDeleted && isOwnMessage(message)">{{ textFor('deletedMessageSenderText') }}</ng-container>
|
47
|
+
<ng-container *ngIf="message.isDeleted && !isOwnMessage(message)">{{ textFor('deletedMessageReceiverText') }}</ng-container>
|
48
|
+
`, isInline: true, dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ChatFileComponent, selector: "li[chatFile]", inputs: ["chatFile", "removable", "fileActions"], outputs: ["remove", "actionClick", "actionsToggle", "actionButtonClick"] }] });
|
49
|
+
}
|
50
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: MessageReferenceComponent, decorators: [{
|
51
|
+
type: Component,
|
52
|
+
args: [{
|
53
|
+
selector: 'chat-message-reference-content',
|
54
|
+
providers: [{
|
55
|
+
provide: ChatItem,
|
56
|
+
useExisting: forwardRef(() => MessageReferenceComponent)
|
57
|
+
}],
|
58
|
+
template: `
|
59
|
+
<ng-container *ngIf="message.text && !message.isDeleted">{{message.text}}</ng-container>
|
60
|
+
<ng-container *ngIf="!message.text && !message.isDeleted && message.files && message.files.length > 0">
|
61
|
+
<li class="k-chat-file" [chatFile]="message.files[0]">
|
62
|
+
</li>
|
63
|
+
</ng-container>
|
64
|
+
<ng-container *ngIf="message.isDeleted && isOwnMessage(message)">{{ textFor('deletedMessageSenderText') }}</ng-container>
|
65
|
+
<ng-container *ngIf="message.isDeleted && !isOwnMessage(message)">{{ textFor('deletedMessageReceiverText') }}</ng-container>
|
66
|
+
`,
|
67
|
+
standalone: true,
|
68
|
+
imports: [NgIf, ChatFileComponent]
|
69
|
+
}]
|
70
|
+
}], ctorParameters: function () { return [{ type: i1.LocalizationService }, { type: i2.ChatService }]; }, propDecorators: { hostClass: [{
|
71
|
+
type: HostBinding,
|
72
|
+
args: ['class.k-message-reference-content']
|
73
|
+
}], message: [{
|
74
|
+
type: Input
|
75
|
+
}] } });
|