@progress/kendo-angular-conversational-ui 21.0.0-develop.8 → 21.0.0-develop.9
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/files-layout.d.ts +12 -0
- package/chat/api/index.d.ts +3 -1
- package/chat/api/message-settings.interface.d.ts +33 -0
- package/chat/api/message.interface.d.ts +5 -1
- package/chat/api/suggestions-layout.d.ts +20 -0
- package/chat/chat.component.d.ts +92 -34
- package/chat/chat.directives.d.ts +18 -0
- package/chat/chat.module.d.ts +15 -8
- package/chat/common/chat.service.d.ts +32 -3
- package/chat/common/models/model-fields.d.ts +0 -6
- package/chat/common/scroll-button.component.d.ts +32 -0
- package/chat/common/scroll.service.d.ts +39 -0
- package/chat/common/utils.d.ts +13 -1
- package/chat/l10n/messages.d.ts +9 -1
- package/chat/message-list.component.d.ts +20 -3
- package/chat/message.component.d.ts +40 -16
- package/chat/suggested-actions.component.d.ts +30 -5
- package/chat/templates/author-message-content-template.directive.d.ts +28 -0
- package/chat/templates/author-message-template.directive.d.ts +28 -0
- package/chat/templates/message-content-template.directive.d.ts +28 -0
- package/chat/templates/message-template.directive.d.ts +1 -1
- package/chat/templates/no-data-template.directive.d.ts +27 -0
- package/chat/templates/receiver-message-content-template.directive.d.ts +28 -0
- package/chat/templates/receiver-message-template.directive.d.ts +28 -0
- package/chat/templates/user-status-template.directive.d.ts +27 -0
- package/conversational-ui.module.d.ts +18 -11
- package/directives.d.ts +9 -2
- package/esm2022/chat/api/index.mjs +3 -1
- package/{chat/api/message-toolbar-visibility.d.ts → esm2022/chat/api/message-settings.interface.mjs} +1 -4
- package/esm2022/chat/api/suggestions-layout.mjs +5 -0
- package/esm2022/chat/builtin-actions.mjs +2 -0
- package/esm2022/chat/chat-file.component.mjs +2 -2
- package/esm2022/chat/chat.component.mjs +265 -71
- package/esm2022/chat/chat.directives.mjs +18 -0
- package/esm2022/chat/chat.module.mjs +16 -9
- package/esm2022/chat/common/chat.service.mjs +83 -4
- package/esm2022/chat/common/models/default-model-fields.mjs +0 -1
- package/esm2022/chat/common/scroll-button.component.mjs +81 -0
- package/esm2022/chat/common/scroll.service.mjs +110 -0
- package/esm2022/chat/common/utils.mjs +22 -3
- package/esm2022/chat/l10n/messages.mjs +13 -1
- package/esm2022/chat/message-attachments.component.mjs +2 -2
- package/esm2022/chat/message-box.component.mjs +5 -2
- package/esm2022/chat/message-list.component.mjs +165 -19
- package/esm2022/chat/message.component.mjs +487 -326
- package/esm2022/chat/suggested-actions.component.mjs +298 -80
- package/esm2022/chat/templates/author-message-content-template.directive.mjs +39 -0
- package/esm2022/chat/templates/author-message-template.directive.mjs +39 -0
- package/esm2022/chat/templates/message-content-template.directive.mjs +39 -0
- package/esm2022/chat/templates/message-template.directive.mjs +1 -1
- package/esm2022/chat/templates/no-data-template.directive.mjs +38 -0
- package/esm2022/chat/templates/receiver-message-content-template.directive.mjs +39 -0
- package/esm2022/chat/templates/receiver-message-template.directive.mjs +39 -0
- package/esm2022/chat/templates/user-status-template.directive.mjs +38 -0
- package/esm2022/conversational-ui.module.mjs +19 -12
- package/esm2022/directives.mjs +15 -1
- package/esm2022/index.mjs +7 -0
- package/esm2022/package-metadata.mjs +2 -2
- package/fesm2022/progress-kendo-angular-conversational-ui.mjs +1771 -547
- package/index.d.ts +7 -0
- package/package.json +14 -14
- /package/esm2022/chat/api/{message-toolbar-visibility.mjs → files-layout.mjs} +0 -0
|
@@ -3,15 +3,15 @@
|
|
|
3
3
|
* Licensed under commercial license. See LICENSE.md in the project root for more information
|
|
4
4
|
*-------------------------------------------------------------------------------------------*/
|
|
5
5
|
import * as i0 from '@angular/core';
|
|
6
|
-
import { InjectionToken, Directive, Inject, HostBinding, ViewChild, Input, Injectable, Optional, forwardRef, EventEmitter, Component, ContentChildren, ContentChild, Output, isDevMode, ViewChildren, HostListener,
|
|
6
|
+
import { InjectionToken, Directive, Inject, HostBinding, ViewChild, Input, Injectable, Optional, forwardRef, EventEmitter, Component, ContentChildren, ContentChild, Output, isDevMode, ElementRef, ViewChildren, HostListener, ViewContainerRef, inject, SkipSelf, NgModule } from '@angular/core';
|
|
7
7
|
import { IconWrapperComponent, IconsService } from '@progress/kendo-angular-icons';
|
|
8
8
|
import * as i1$2 from '@progress/kendo-angular-popup';
|
|
9
9
|
import { PopupComponent, KENDO_POPUP, PopupService } from '@progress/kendo-angular-popup';
|
|
10
|
-
import { isPresent, normalizeNumpadKeys, Keys, focusableSelector, guid, getter, closest as closest$1, ResizeSensorComponent, isChanged, processCssValue,
|
|
10
|
+
import { isPresent, normalizeNumpadKeys, Keys, focusableSelector, guid, getter, isDocumentAvailable, closest as closest$1, ResizeSensorComponent, isChanged, processCssValue, ResizeBatchService } from '@progress/kendo-angular-common';
|
|
11
11
|
import { DialogContainerService, DialogService, WindowService, WindowContainerService } from '@progress/kendo-angular-dialog';
|
|
12
12
|
import { NgFor, NgIf, NgTemplateOutlet, NgClass, NgSwitch, NgSwitchCase } from '@angular/common';
|
|
13
13
|
import { Subject, Subscription, fromEvent } from 'rxjs';
|
|
14
|
-
import { sparklesIcon, commentIcon, moreHorizontalIcon, stopSmIcon, thumbUpIcon, thumbDownOutlineIcon, thumbDownIcon, thumbUpOutlineIcon, copyIcon, arrowRotateCwIcon, chevronUpIcon, chevronDownIcon, paperPlaneIcon, undoIcon, downloadIcon, xIcon, moreVerticalIcon, paperclipIcon, fileIcon,
|
|
14
|
+
import { sparklesIcon, commentIcon, moreHorizontalIcon, stopSmIcon, thumbUpIcon, thumbDownOutlineIcon, thumbDownIcon, thumbUpOutlineIcon, copyIcon, arrowRotateCwIcon, chevronUpIcon, chevronDownIcon, paperPlaneIcon, undoIcon, downloadIcon, chevronLeftIcon, chevronRightIcon, xIcon, moreVerticalIcon, paperclipIcon, fileIcon, pinIcon, cancelOutlineIcon, menuIcon } from '@progress/kendo-svg-icons';
|
|
15
15
|
import * as i1 from '@progress/kendo-angular-l10n';
|
|
16
16
|
import { ComponentMessages, LocalizationService, L10N_PREFIX } from '@progress/kendo-angular-l10n';
|
|
17
17
|
import { validatePackage } from '@progress/kendo-licensing';
|
|
@@ -25,10 +25,10 @@ import { TextAreaComponent, TextAreaSuffixComponent, TextAreaPrefixComponent, In
|
|
|
25
25
|
import { fileSVGGroupIcon, fileGroupClass, getTotalFilesSizeMessage, FileSelectComponent } from '@progress/kendo-angular-upload';
|
|
26
26
|
import { FormsModule } from '@angular/forms';
|
|
27
27
|
import * as i1$1 from '@progress/kendo-angular-intl';
|
|
28
|
-
import * as i4 from '@progress/kendo-angular-menu';
|
|
29
|
-
import { ContextMenuComponent, KENDO_CONTEXTMENU } from '@progress/kendo-angular-menu';
|
|
30
28
|
import { ToolBarComponent, ToolBarButtonComponent } from '@progress/kendo-angular-toolbar';
|
|
31
29
|
import { AppBarComponent } from '@progress/kendo-angular-navigation';
|
|
30
|
+
import * as i4 from '@progress/kendo-angular-menu';
|
|
31
|
+
import { ContextMenuComponent, KENDO_CONTEXTMENU } from '@progress/kendo-angular-menu';
|
|
32
32
|
|
|
33
33
|
/**
|
|
34
34
|
* @hidden
|
|
@@ -216,8 +216,8 @@ const packageMetadata = {
|
|
|
216
216
|
productName: 'Kendo UI for Angular',
|
|
217
217
|
productCode: 'KENDOUIANGULAR',
|
|
218
218
|
productCodes: ['KENDOUIANGULAR'],
|
|
219
|
-
publishDate:
|
|
220
|
-
version: '21.0.0-develop.
|
|
219
|
+
publishDate: 1761910356,
|
|
220
|
+
version: '21.0.0-develop.9',
|
|
221
221
|
licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/'
|
|
222
222
|
};
|
|
223
223
|
|
|
@@ -1887,6 +1887,7 @@ const noop = () => { };
|
|
|
1887
1887
|
const handlers = {
|
|
1888
1888
|
'reply': (action, sender) => {
|
|
1889
1889
|
sender.sendMessage.emit(new SendMessageEvent({
|
|
1890
|
+
id: guid(),
|
|
1890
1891
|
author: { id: sender.authorId },
|
|
1891
1892
|
text: action.value,
|
|
1892
1893
|
timestamp: new Date()
|
|
@@ -1904,40 +1905,6 @@ const handlers = {
|
|
|
1904
1905
|
*/
|
|
1905
1906
|
const makeHandler = (action) => handlers[action.type] || noop;
|
|
1906
1907
|
|
|
1907
|
-
/**
|
|
1908
|
-
* Defines a template for displaying Chat messages.
|
|
1909
|
-
*
|
|
1910
|
-
* To define a message template, nest an `<ng-template>` tag with the `kendoChatMessageTemplate` directive inside the `<kendo-chat>` component.
|
|
1911
|
-
* The template context is set to the `message` instance.
|
|
1912
|
-
* For more information, refer to the article on [message templates](slug:message_templates_chat).
|
|
1913
|
-
*
|
|
1914
|
-
* @example
|
|
1915
|
-
* ```html
|
|
1916
|
-
* <kendo-chat>
|
|
1917
|
-
* <ng-template kendoChatMessageTemplate let-message>
|
|
1918
|
-
* <div>Message: {{ message.text }}</div>
|
|
1919
|
-
* </ng-template>
|
|
1920
|
-
* </kendo-chat>
|
|
1921
|
-
* ```
|
|
1922
|
-
*/
|
|
1923
|
-
class MessageTemplateDirective {
|
|
1924
|
-
templateRef;
|
|
1925
|
-
constructor(templateRef) {
|
|
1926
|
-
this.templateRef = templateRef;
|
|
1927
|
-
}
|
|
1928
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MessageTemplateDirective, deps: [{ token: i0.TemplateRef, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
|
|
1929
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.14", type: MessageTemplateDirective, isStandalone: true, selector: "[kendoChatMessageTemplate]", ngImport: i0 });
|
|
1930
|
-
}
|
|
1931
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MessageTemplateDirective, decorators: [{
|
|
1932
|
-
type: Directive,
|
|
1933
|
-
args: [{
|
|
1934
|
-
selector: '[kendoChatMessageTemplate]',
|
|
1935
|
-
standalone: true
|
|
1936
|
-
}]
|
|
1937
|
-
}], ctorParameters: () => [{ type: i0.TemplateRef, decorators: [{
|
|
1938
|
-
type: Optional
|
|
1939
|
-
}] }] });
|
|
1940
|
-
|
|
1941
1908
|
/**
|
|
1942
1909
|
* Creates a message box area that overrides the default message box of the Chat component.
|
|
1943
1910
|
*
|
|
@@ -1986,7 +1953,6 @@ const defaultModelFields = {
|
|
|
1986
1953
|
attachmentLayoutField: 'attachmentLayout',
|
|
1987
1954
|
suggestedActionsField: 'suggestedActions',
|
|
1988
1955
|
isPinnedField: 'isPinned',
|
|
1989
|
-
pinnedByField: 'pinnedBy',
|
|
1990
1956
|
replyToIdField: 'replyToId',
|
|
1991
1957
|
isDeletedField: 'isDeleted',
|
|
1992
1958
|
typingField: 'typing'
|
|
@@ -2053,6 +2019,10 @@ const FILESELECT_DEFAULT_SETTINGS = {
|
|
|
2053
2019
|
multiple: true,
|
|
2054
2020
|
disabled: false
|
|
2055
2021
|
};
|
|
2022
|
+
/**
|
|
2023
|
+
* @hidden
|
|
2024
|
+
*/
|
|
2025
|
+
const SUGGESTIONS_LAYOUT_DEFAULT_SETTINGS = 'scroll';
|
|
2056
2026
|
/**
|
|
2057
2027
|
* @hidden
|
|
2058
2028
|
*/
|
|
@@ -2105,14 +2075,16 @@ const parseMessage = (message, fields) => {
|
|
|
2105
2075
|
id: authorId,
|
|
2106
2076
|
...(authorName && { name: authorName }),
|
|
2107
2077
|
...(authorImageUrl && { avatarUrl: authorImageUrl }),
|
|
2108
|
-
...(authorImageAltText && { avatarAltText: authorImageAltText })
|
|
2078
|
+
...(authorImageAltText && { avatarAltText: authorImageAltText }),
|
|
2109
2079
|
};
|
|
2110
2080
|
}
|
|
2081
|
+
const timestampValue = getter(modelFields.timestampField)(message);
|
|
2082
|
+
const timestamp = timestampValue instanceof Date ? timestampValue : new Date(timestampValue);
|
|
2111
2083
|
return {
|
|
2112
2084
|
id: getter(modelFields.idField)(message),
|
|
2113
2085
|
text: getter(modelFields.textField)(message),
|
|
2114
2086
|
author: author,
|
|
2115
|
-
timestamp:
|
|
2087
|
+
timestamp: timestamp,
|
|
2116
2088
|
status: getter(modelFields.statusField)(message),
|
|
2117
2089
|
files: getter(modelFields.filesField)(message),
|
|
2118
2090
|
attachments: getter(modelFields.attachmentsField)(message),
|
|
@@ -2121,9 +2093,22 @@ const parseMessage = (message, fields) => {
|
|
|
2121
2093
|
isPinned: getter(modelFields.isPinnedField)(message),
|
|
2122
2094
|
replyToId: getter(modelFields.replyToIdField)(message),
|
|
2123
2095
|
isDeleted: getter(modelFields.isDeletedField)(message),
|
|
2124
|
-
typing: getter(modelFields.typingField)(message)
|
|
2096
|
+
typing: getter(modelFields.typingField)(message),
|
|
2097
|
+
dataItem: message
|
|
2125
2098
|
};
|
|
2126
2099
|
};
|
|
2100
|
+
/**
|
|
2101
|
+
* @hidden
|
|
2102
|
+
*/
|
|
2103
|
+
const transformActions = (actions) => {
|
|
2104
|
+
return actions.map(action => ({
|
|
2105
|
+
text: action.label,
|
|
2106
|
+
icon: action.icon,
|
|
2107
|
+
svgIcon: action.svgIcon,
|
|
2108
|
+
disabled: action.disabled,
|
|
2109
|
+
originalAction: action
|
|
2110
|
+
}));
|
|
2111
|
+
};
|
|
2127
2112
|
|
|
2128
2113
|
/**
|
|
2129
2114
|
* @hidden
|
|
@@ -2131,26 +2116,42 @@ const parseMessage = (message, fields) => {
|
|
|
2131
2116
|
class ChatService {
|
|
2132
2117
|
authorId;
|
|
2133
2118
|
messageWidthMode;
|
|
2134
|
-
allowMessageCollapse;
|
|
2135
2119
|
messageToolbarActions = [];
|
|
2136
2120
|
messageContextMenuActions = [];
|
|
2121
|
+
calculatedContextMenuActions = [];
|
|
2137
2122
|
fileActions = [];
|
|
2138
|
-
messageToolbarVisibility = 'hidden';
|
|
2139
2123
|
toggleMessageState = false;
|
|
2140
2124
|
reply;
|
|
2141
2125
|
messages = [];
|
|
2142
2126
|
chatElement;
|
|
2143
2127
|
messageElementsMap = new Map();
|
|
2128
|
+
messagesContextMenu;
|
|
2129
|
+
activeMessage;
|
|
2130
|
+
activeMessageElement;
|
|
2131
|
+
selectOnMenuClose = false;
|
|
2132
|
+
active = false;
|
|
2133
|
+
messageFilesLayout = 'vertical';
|
|
2144
2134
|
_enableSpeechToText = STB_DEFAULT_SETTINGS;
|
|
2145
2135
|
_enableFileSelect = FILESELECT_DEFAULT_SETTINGS;
|
|
2146
2136
|
_sendButtonSettings = SEND_BTN_DEFAULT_SETTINGS;
|
|
2137
|
+
_suggestionsLayout = SUGGESTIONS_LAYOUT_DEFAULT_SETTINGS;
|
|
2138
|
+
_quickActionsLayout = SUGGESTIONS_LAYOUT_DEFAULT_SETTINGS;
|
|
2139
|
+
_authorMessageSettings;
|
|
2140
|
+
_receiverMessageSettings;
|
|
2141
|
+
_allowMessageCollapse;
|
|
2147
2142
|
subjects = {
|
|
2148
2143
|
toolbarAction: new Subject(),
|
|
2149
2144
|
contextMenuAction: new Subject(),
|
|
2150
2145
|
fileAction: new Subject(),
|
|
2151
2146
|
fileDownload: new Subject(),
|
|
2152
2147
|
replyReferenceClick: new Subject(),
|
|
2153
|
-
inputValueChange: new Subject()
|
|
2148
|
+
inputValueChange: new Subject(),
|
|
2149
|
+
contextMenuVisibilityChange: new Subject(),
|
|
2150
|
+
suggestionsLayoutChange: new Subject(),
|
|
2151
|
+
quickActionsLayoutChange: new Subject(),
|
|
2152
|
+
authorMessageSettingsChange: new Subject(),
|
|
2153
|
+
receiverMessageSettingsChange: new Subject(),
|
|
2154
|
+
allowMessageCollapseChange: new Subject(),
|
|
2154
2155
|
};
|
|
2155
2156
|
toolbarAction$ = this.subjects.toolbarAction.asObservable();
|
|
2156
2157
|
contextMenuAction$ = this.subjects.contextMenuAction.asObservable();
|
|
@@ -2158,6 +2159,32 @@ class ChatService {
|
|
|
2158
2159
|
fileDownload$ = this.subjects.fileDownload.asObservable();
|
|
2159
2160
|
replyReferenceClick$ = this.subjects.replyReferenceClick.asObservable();
|
|
2160
2161
|
inputValueChange$ = this.subjects.inputValueChange.asObservable();
|
|
2162
|
+
contextMenuVisibilityChange$ = this.subjects.contextMenuVisibilityChange.asObservable();
|
|
2163
|
+
suggestionsLayoutChange$ = this.subjects.suggestionsLayoutChange.asObservable();
|
|
2164
|
+
quickActionsLayoutChange$ = this.subjects.quickActionsLayoutChange.asObservable();
|
|
2165
|
+
authorMessageSettingsChange$ = this.subjects.authorMessageSettingsChange.asObservable();
|
|
2166
|
+
receiverMessageSettingsChange$ = this.subjects.receiverMessageSettingsChange.asObservable();
|
|
2167
|
+
allowMessageCollapseChange$ = this.subjects.allowMessageCollapseChange.asObservable();
|
|
2168
|
+
set authorMessageSettings(settings) {
|
|
2169
|
+
const previousSettings = this._authorMessageSettings;
|
|
2170
|
+
if (JSON.stringify(previousSettings) !== JSON.stringify(settings)) {
|
|
2171
|
+
this.updateComponentSettings('_authorMessageSettings', settings, null);
|
|
2172
|
+
this.emit('authorMessageSettingsChange', this._authorMessageSettings);
|
|
2173
|
+
}
|
|
2174
|
+
}
|
|
2175
|
+
get authorMessageSettings() {
|
|
2176
|
+
return this._authorMessageSettings;
|
|
2177
|
+
}
|
|
2178
|
+
set receiverMessageSettings(settings) {
|
|
2179
|
+
const previousSettings = this._receiverMessageSettings;
|
|
2180
|
+
if (JSON.stringify(previousSettings) !== JSON.stringify(settings)) {
|
|
2181
|
+
this.updateComponentSettings('_receiverMessageSettings', settings, null);
|
|
2182
|
+
this.emit('receiverMessageSettingsChange', this._receiverMessageSettings);
|
|
2183
|
+
}
|
|
2184
|
+
}
|
|
2185
|
+
get receiverMessageSettings() {
|
|
2186
|
+
return this._receiverMessageSettings;
|
|
2187
|
+
}
|
|
2161
2188
|
set enableSpeechToText(settings) {
|
|
2162
2189
|
this.updateComponentSettings('_enableSpeechToText', settings, STB_DEFAULT_SETTINGS);
|
|
2163
2190
|
}
|
|
@@ -2176,6 +2203,38 @@ class ChatService {
|
|
|
2176
2203
|
get sendButtonSettings() {
|
|
2177
2204
|
return this._sendButtonSettings;
|
|
2178
2205
|
}
|
|
2206
|
+
set suggestionsLayout(layoutMode) {
|
|
2207
|
+
this._suggestionsLayout = layoutMode;
|
|
2208
|
+
this.emit('suggestionsLayoutChange', this._suggestionsLayout);
|
|
2209
|
+
}
|
|
2210
|
+
get suggestionsLayout() {
|
|
2211
|
+
return this._suggestionsLayout;
|
|
2212
|
+
}
|
|
2213
|
+
set quickActionsLayout(layoutMode) {
|
|
2214
|
+
this._quickActionsLayout = layoutMode;
|
|
2215
|
+
this.emit('quickActionsLayoutChange', this._quickActionsLayout);
|
|
2216
|
+
}
|
|
2217
|
+
get quickActionsLayout() {
|
|
2218
|
+
return this._quickActionsLayout;
|
|
2219
|
+
}
|
|
2220
|
+
set allowMessageCollapse(value) {
|
|
2221
|
+
const previousValue = this._allowMessageCollapse;
|
|
2222
|
+
if (previousValue !== value) {
|
|
2223
|
+
this._allowMessageCollapse = value;
|
|
2224
|
+
this.emit('allowMessageCollapseChange', this._allowMessageCollapse);
|
|
2225
|
+
}
|
|
2226
|
+
}
|
|
2227
|
+
get allowMessageCollapse() {
|
|
2228
|
+
return this._allowMessageCollapse;
|
|
2229
|
+
}
|
|
2230
|
+
calculateContextMenuActions(isOwn) {
|
|
2231
|
+
const settings = isOwn ? this.authorMessageSettings : this.receiverMessageSettings;
|
|
2232
|
+
if (settings?.messageContextMenuActions) {
|
|
2233
|
+
this.calculatedContextMenuActions = settings.messageContextMenuActions;
|
|
2234
|
+
return;
|
|
2235
|
+
}
|
|
2236
|
+
this.calculatedContextMenuActions = this.messageContextMenuActions || [];
|
|
2237
|
+
}
|
|
2179
2238
|
emit(subjectKey, value) {
|
|
2180
2239
|
(this.subjects[subjectKey]).next(value);
|
|
2181
2240
|
}
|
|
@@ -2197,6 +2256,11 @@ class ChatService {
|
|
|
2197
2256
|
elementRef.nativeElement.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
|
|
2198
2257
|
}
|
|
2199
2258
|
}
|
|
2259
|
+
focusActiveMessageElement() {
|
|
2260
|
+
if (this.activeMessageElement) {
|
|
2261
|
+
this.activeMessageElement.element?.nativeElement?.focus();
|
|
2262
|
+
}
|
|
2263
|
+
}
|
|
2200
2264
|
updateComponentSettings(property, settings, defaultSettings) {
|
|
2201
2265
|
if (settings === true) {
|
|
2202
2266
|
this[property] = defaultSettings;
|
|
@@ -2253,24 +2317,238 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
2253
2317
|
}]
|
|
2254
2318
|
}], ctorParameters: () => [{ type: i0.TemplateRef }] });
|
|
2255
2319
|
|
|
2320
|
+
const DIRECTION_CLASSES = {
|
|
2321
|
+
left: 'chevron-left',
|
|
2322
|
+
right: 'chevron-right',
|
|
2323
|
+
};
|
|
2324
|
+
/**
|
|
2325
|
+
* @hidden
|
|
2326
|
+
*/
|
|
2327
|
+
class ChatScrollableButtonComponent {
|
|
2328
|
+
host;
|
|
2329
|
+
renderer;
|
|
2330
|
+
ngZone;
|
|
2331
|
+
localization;
|
|
2332
|
+
role = 'button';
|
|
2333
|
+
prev = false;
|
|
2334
|
+
onClick = new EventEmitter();
|
|
2335
|
+
get scrollButtonIconClass() {
|
|
2336
|
+
const defaultPrevIcon = !this.localization.rtl ? DIRECTION_CLASSES.left : DIRECTION_CLASSES.right;
|
|
2337
|
+
const defaultNextIcon = !this.localization.rtl ? DIRECTION_CLASSES.right : DIRECTION_CLASSES.left;
|
|
2338
|
+
return this.prev ? defaultPrevIcon : defaultNextIcon;
|
|
2339
|
+
}
|
|
2340
|
+
get scrollButtonSVGIcon() {
|
|
2341
|
+
const defaultPrevSVGIcon = !this.localization.rtl ? this.chevronLeftIcon : this.chevronRightIcon;
|
|
2342
|
+
const defaultNextSVGIcon = !this.localization.rtl ? this.chevronRightIcon : this.chevronLeftIcon;
|
|
2343
|
+
return this.prev ? defaultPrevSVGIcon : defaultNextSVGIcon;
|
|
2344
|
+
}
|
|
2345
|
+
chevronLeftIcon = chevronLeftIcon;
|
|
2346
|
+
chevronRightIcon = chevronRightIcon;
|
|
2347
|
+
subs = new Subscription();
|
|
2348
|
+
constructor(host, renderer, ngZone, localization) {
|
|
2349
|
+
this.host = host;
|
|
2350
|
+
this.renderer = renderer;
|
|
2351
|
+
this.ngZone = ngZone;
|
|
2352
|
+
this.localization = localization;
|
|
2353
|
+
}
|
|
2354
|
+
ngAfterViewInit() {
|
|
2355
|
+
this.ngZone.runOutsideAngular(() => {
|
|
2356
|
+
this.subs.add(this.renderer.listen(this.host.nativeElement, 'click', () => this.clickHandler()));
|
|
2357
|
+
});
|
|
2358
|
+
}
|
|
2359
|
+
ngOnDestroy() {
|
|
2360
|
+
this.subs.unsubscribe();
|
|
2361
|
+
}
|
|
2362
|
+
clickHandler() {
|
|
2363
|
+
const buttonType = this.prev ? 'prev' : 'next';
|
|
2364
|
+
this.onClick.emit(buttonType);
|
|
2365
|
+
}
|
|
2366
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ChatScrollableButtonComponent, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.NgZone }, { token: i1.LocalizationService }], target: i0.ɵɵFactoryTarget.Component });
|
|
2367
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: ChatScrollableButtonComponent, isStandalone: true, selector: "[kendoChatScrollableButton]", inputs: { prev: "prev" }, outputs: { onClick: "onClick" }, host: { properties: { "attr.role": "this.role" } }, ngImport: i0, template: `
|
|
2368
|
+
<kendo-icon-wrapper [name]="scrollButtonIconClass" [svgIcon]="scrollButtonSVGIcon" innerCssClass="k-button-icon"> </kendo-icon-wrapper>
|
|
2369
|
+
`, isInline: true, dependencies: [{ kind: "component", type: IconWrapperComponent, selector: "kendo-icon-wrapper", inputs: ["name", "svgIcon", "innerCssClass", "customFontClass", "size"], exportAs: ["kendoIconWrapper"] }] });
|
|
2370
|
+
}
|
|
2371
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ChatScrollableButtonComponent, decorators: [{
|
|
2372
|
+
type: Component,
|
|
2373
|
+
args: [{
|
|
2374
|
+
template: `
|
|
2375
|
+
<kendo-icon-wrapper [name]="scrollButtonIconClass" [svgIcon]="scrollButtonSVGIcon" innerCssClass="k-button-icon"> </kendo-icon-wrapper>
|
|
2376
|
+
`,
|
|
2377
|
+
// eslint-disable-next-line @angular-eslint/component-selector
|
|
2378
|
+
selector: '[kendoChatScrollableButton]',
|
|
2379
|
+
standalone: true,
|
|
2380
|
+
imports: [IconWrapperComponent],
|
|
2381
|
+
}]
|
|
2382
|
+
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i0.NgZone }, { type: i1.LocalizationService }], propDecorators: { role: [{
|
|
2383
|
+
type: HostBinding,
|
|
2384
|
+
args: ['attr.role']
|
|
2385
|
+
}], prev: [{
|
|
2386
|
+
type: Input
|
|
2387
|
+
}], onClick: [{
|
|
2388
|
+
type: Output
|
|
2389
|
+
}] } });
|
|
2390
|
+
|
|
2391
|
+
const DEFAULT_SCROLL_BEHAVIOR = 'smooth';
|
|
2392
|
+
const DEFAULT_SCROLL_SPEED = 100;
|
|
2393
|
+
/**
|
|
2394
|
+
* @hidden
|
|
2395
|
+
*/
|
|
2396
|
+
class SuggestionsScrollService {
|
|
2397
|
+
ngZone;
|
|
2398
|
+
localization;
|
|
2399
|
+
owner;
|
|
2400
|
+
position = 0;
|
|
2401
|
+
scrollButtonActiveStateChange = new Subject();
|
|
2402
|
+
get scrollElement() {
|
|
2403
|
+
return this.owner.suggestionsContainer?.nativeElement;
|
|
2404
|
+
}
|
|
2405
|
+
get scrollContainerOverflowSize() {
|
|
2406
|
+
if (!isDocumentAvailable()) {
|
|
2407
|
+
return 0;
|
|
2408
|
+
}
|
|
2409
|
+
if (!this.scrollElement) {
|
|
2410
|
+
return 0;
|
|
2411
|
+
}
|
|
2412
|
+
const overflowSize = Math.floor(this.scrollElement.scrollWidth - this.scrollElement.offsetWidth);
|
|
2413
|
+
return overflowSize < 0 ? 0 : overflowSize;
|
|
2414
|
+
}
|
|
2415
|
+
get suggestionsOverflow() {
|
|
2416
|
+
return this.scrollContainerOverflowSize > 0;
|
|
2417
|
+
}
|
|
2418
|
+
constructor(ngZone, localization) {
|
|
2419
|
+
this.ngZone = ngZone;
|
|
2420
|
+
this.localization = localization;
|
|
2421
|
+
}
|
|
2422
|
+
toggleScrollButtonsState() {
|
|
2423
|
+
const suggestedActions = this.owner;
|
|
2424
|
+
if (!suggestedActions?.hasScrollButtons) {
|
|
2425
|
+
return;
|
|
2426
|
+
}
|
|
2427
|
+
const currentPrevButtonActive = !this.isDisabled('prev');
|
|
2428
|
+
const currentNextButtonActive = !this.isDisabled('next');
|
|
2429
|
+
const defaultOffset = 1;
|
|
2430
|
+
const rtlDelta = this.localization.rtl ? -1 : 1;
|
|
2431
|
+
const calculatedPrevButtonActive = (this.position * rtlDelta) > 0 && this.scrollContainerOverflowSize > 0;
|
|
2432
|
+
const calculatedNextButtonActive = (this.position * rtlDelta) < this.scrollContainerOverflowSize - defaultOffset && this.scrollContainerOverflowSize > 0;
|
|
2433
|
+
if (calculatedPrevButtonActive !== currentPrevButtonActive) {
|
|
2434
|
+
this.ngZone.run(() => this.toggleButtonActiveState('prev', calculatedPrevButtonActive));
|
|
2435
|
+
}
|
|
2436
|
+
if (calculatedNextButtonActive !== currentNextButtonActive) {
|
|
2437
|
+
this.ngZone.run(() => this.toggleButtonActiveState('next', calculatedNextButtonActive));
|
|
2438
|
+
}
|
|
2439
|
+
}
|
|
2440
|
+
onScroll(e) {
|
|
2441
|
+
this.position = e.target.scrollLeft;
|
|
2442
|
+
this.toggleScrollButtonsState();
|
|
2443
|
+
}
|
|
2444
|
+
scrollSuggestions(direction) {
|
|
2445
|
+
this.calculateListPosition(direction, DEFAULT_SCROLL_SPEED);
|
|
2446
|
+
if (this.scrollElement) {
|
|
2447
|
+
this.scrollElement.scrollTo({ left: this.position, behavior: DEFAULT_SCROLL_BEHAVIOR });
|
|
2448
|
+
}
|
|
2449
|
+
this.toggleScrollButtonsState();
|
|
2450
|
+
}
|
|
2451
|
+
updateScrollPosition(element) {
|
|
2452
|
+
this.position = element.scrollLeft;
|
|
2453
|
+
}
|
|
2454
|
+
calculateListPosition(direction, scrollSpeed) {
|
|
2455
|
+
if (direction === 'prev') {
|
|
2456
|
+
if (!this.localization.rtl) {
|
|
2457
|
+
this.position = this.position - scrollSpeed <= 0 ? 0 : this.position - scrollSpeed;
|
|
2458
|
+
}
|
|
2459
|
+
else {
|
|
2460
|
+
this.position = this.position + scrollSpeed >= 0 ? 0 : this.position + scrollSpeed;
|
|
2461
|
+
}
|
|
2462
|
+
}
|
|
2463
|
+
else if (direction === 'next' && this.position < this.scrollContainerOverflowSize) {
|
|
2464
|
+
if (this.position + scrollSpeed > this.scrollContainerOverflowSize) {
|
|
2465
|
+
if (this.localization.rtl) {
|
|
2466
|
+
this.position = -this.scrollContainerOverflowSize;
|
|
2467
|
+
}
|
|
2468
|
+
else {
|
|
2469
|
+
this.position = this.scrollContainerOverflowSize;
|
|
2470
|
+
}
|
|
2471
|
+
return;
|
|
2472
|
+
}
|
|
2473
|
+
if (this.localization.rtl) {
|
|
2474
|
+
this.position -= scrollSpeed;
|
|
2475
|
+
}
|
|
2476
|
+
else {
|
|
2477
|
+
this.position += scrollSpeed;
|
|
2478
|
+
}
|
|
2479
|
+
}
|
|
2480
|
+
}
|
|
2481
|
+
toggleButtonActiveState(buttonType, active) {
|
|
2482
|
+
this.scrollButtonActiveStateChange.next({ buttonType, active });
|
|
2483
|
+
}
|
|
2484
|
+
isDisabled = (buttonType) => this.owner[`${buttonType}ScrollButton`]?.nativeElement.classList.contains('k-disabled');
|
|
2485
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SuggestionsScrollService, deps: [{ token: i0.NgZone }, { token: i1.LocalizationService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2486
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SuggestionsScrollService });
|
|
2487
|
+
}
|
|
2488
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SuggestionsScrollService, decorators: [{
|
|
2489
|
+
type: Injectable
|
|
2490
|
+
}], ctorParameters: () => [{ type: i0.NgZone }, { type: i1.LocalizationService }] });
|
|
2491
|
+
|
|
2256
2492
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2257
2493
|
/* eslint-disable @typescript-eslint/no-empty-function */
|
|
2258
2494
|
/**
|
|
2259
2495
|
* @hidden
|
|
2260
2496
|
*/
|
|
2261
2497
|
class SuggestedActionsComponent extends ChatItem {
|
|
2498
|
+
chatService;
|
|
2499
|
+
localization;
|
|
2500
|
+
scrollService;
|
|
2501
|
+
ngZone;
|
|
2502
|
+
renderer;
|
|
2503
|
+
get defaultClass() {
|
|
2504
|
+
if (this.type === 'suggestion') {
|
|
2505
|
+
return this.chatService.suggestionsLayout === 'wrap' || this.chatService.suggestionsLayout === 'scroll';
|
|
2506
|
+
}
|
|
2507
|
+
else if (this.type === 'action') {
|
|
2508
|
+
return this.chatService.quickActionsLayout === 'wrap' || this.chatService.quickActionsLayout === 'scroll';
|
|
2509
|
+
}
|
|
2510
|
+
}
|
|
2511
|
+
get scrollableClass() {
|
|
2512
|
+
if (this.type === 'suggestion') {
|
|
2513
|
+
return this.chatService.suggestionsLayout === 'scroll';
|
|
2514
|
+
}
|
|
2515
|
+
else if (this.type === 'action') {
|
|
2516
|
+
return this.chatService.quickActionsLayout === 'scroll';
|
|
2517
|
+
}
|
|
2518
|
+
}
|
|
2519
|
+
get scrollButtonsClass() {
|
|
2520
|
+
if (this.type === 'suggestion') {
|
|
2521
|
+
return this.chatService.suggestionsLayout === 'scrollbuttons';
|
|
2522
|
+
}
|
|
2523
|
+
else if (this.type === 'action') {
|
|
2524
|
+
return this.chatService.quickActionsLayout === 'scrollbuttons';
|
|
2525
|
+
}
|
|
2526
|
+
}
|
|
2527
|
+
get role() {
|
|
2528
|
+
if (!this.hasScrollButtons) {
|
|
2529
|
+
return 'group';
|
|
2530
|
+
}
|
|
2531
|
+
return null;
|
|
2532
|
+
}
|
|
2262
2533
|
actions;
|
|
2263
2534
|
suggestions;
|
|
2264
2535
|
tabbable;
|
|
2536
|
+
type;
|
|
2265
2537
|
suggestionTemplate;
|
|
2266
2538
|
dispatchAction = new EventEmitter();
|
|
2267
2539
|
dispatchSuggestion = new EventEmitter();
|
|
2268
|
-
defaultClass = true;
|
|
2269
|
-
role = 'group';
|
|
2270
2540
|
items;
|
|
2541
|
+
suggestionsContainer;
|
|
2542
|
+
prevScrollButton;
|
|
2543
|
+
nextScrollButton;
|
|
2271
2544
|
selectedIndex = 0;
|
|
2272
2545
|
activeIndex = -1;
|
|
2273
2546
|
active = false;
|
|
2547
|
+
get hasScrollButtons() {
|
|
2548
|
+
return this.type === 'suggestion' ? this.chatService.suggestionsLayout === 'scrollbuttons' : this.chatService.quickActionsLayout === 'scrollbuttons';
|
|
2549
|
+
}
|
|
2550
|
+
subscriptions = new Subscription();
|
|
2551
|
+
resizeObserver = null;
|
|
2274
2552
|
actionKeyHandlers = {
|
|
2275
2553
|
[Keys.Tab]: (e) => this.changeSelectedIndex(e),
|
|
2276
2554
|
[Keys.Enter]: (_, action) => this.actionClick(action),
|
|
@@ -2281,6 +2559,58 @@ class SuggestedActionsComponent extends ChatItem {
|
|
|
2281
2559
|
[Keys.Enter]: (_, suggestion) => this.suggestionClick(suggestion),
|
|
2282
2560
|
[Keys.Space]: (_, suggestion) => this.suggestionClick(suggestion),
|
|
2283
2561
|
};
|
|
2562
|
+
constructor(chatService, localization, scrollService, ngZone, renderer) {
|
|
2563
|
+
super();
|
|
2564
|
+
this.chatService = chatService;
|
|
2565
|
+
this.localization = localization;
|
|
2566
|
+
this.scrollService = scrollService;
|
|
2567
|
+
this.ngZone = ngZone;
|
|
2568
|
+
this.renderer = renderer;
|
|
2569
|
+
this.scrollService.owner = this;
|
|
2570
|
+
}
|
|
2571
|
+
ngAfterViewInit() {
|
|
2572
|
+
const layoutChangeObservable = this.type === 'suggestion'
|
|
2573
|
+
? this.chatService.suggestionsLayoutChange$
|
|
2574
|
+
: this.chatService.quickActionsLayoutChange$;
|
|
2575
|
+
this.subscriptions.add(layoutChangeObservable.subscribe((layoutMode) => {
|
|
2576
|
+
if (layoutMode === 'scrollbuttons') {
|
|
2577
|
+
this.ngZone.onStable.pipe(take(1)).subscribe(() => {
|
|
2578
|
+
if (this.suggestionsContainer) {
|
|
2579
|
+
this.scrollService.updateScrollPosition(this.suggestionsContainer.nativeElement);
|
|
2580
|
+
}
|
|
2581
|
+
this.scrollService.toggleScrollButtonsState();
|
|
2582
|
+
});
|
|
2583
|
+
}
|
|
2584
|
+
}));
|
|
2585
|
+
this.subscriptions.add(this.scrollService.scrollButtonActiveStateChange.subscribe((change) => {
|
|
2586
|
+
this.toggleScrollButtonState(change.buttonType, change.active);
|
|
2587
|
+
}));
|
|
2588
|
+
if (this.hasScrollButtons && this.suggestionsContainer) {
|
|
2589
|
+
this.ngZone.runOutsideAngular(() => {
|
|
2590
|
+
this.resizeObserver = new ResizeObserver(() => {
|
|
2591
|
+
this.ngZone.run(() => {
|
|
2592
|
+
this.scrollService.toggleScrollButtonsState();
|
|
2593
|
+
});
|
|
2594
|
+
});
|
|
2595
|
+
this.resizeObserver.observe(this.suggestionsContainer.nativeElement);
|
|
2596
|
+
});
|
|
2597
|
+
}
|
|
2598
|
+
if (this.hasScrollButtons) {
|
|
2599
|
+
this.ngZone.onStable.pipe(take(1)).subscribe(() => {
|
|
2600
|
+
this.scrollService.toggleScrollButtonsState();
|
|
2601
|
+
});
|
|
2602
|
+
if (this.suggestionsContainer) {
|
|
2603
|
+
this.scrollService.updateScrollPosition(this.suggestionsContainer.nativeElement);
|
|
2604
|
+
}
|
|
2605
|
+
}
|
|
2606
|
+
}
|
|
2607
|
+
ngOnDestroy() {
|
|
2608
|
+
this.subscriptions.unsubscribe();
|
|
2609
|
+
if (this.resizeObserver) {
|
|
2610
|
+
this.resizeObserver.disconnect();
|
|
2611
|
+
this.resizeObserver = null;
|
|
2612
|
+
}
|
|
2613
|
+
}
|
|
2284
2614
|
isSelected(index) {
|
|
2285
2615
|
return this.selected && this.selectedIndex === index;
|
|
2286
2616
|
}
|
|
@@ -2314,67 +2644,130 @@ class SuggestedActionsComponent extends ChatItem {
|
|
|
2314
2644
|
handler(e, suggestion);
|
|
2315
2645
|
}
|
|
2316
2646
|
}
|
|
2647
|
+
getScrollButtonTitle(direction) {
|
|
2648
|
+
let currentButton;
|
|
2649
|
+
if (this.localization.rtl) {
|
|
2650
|
+
currentButton = direction === 'prev' ? 'nextSuggestionsButtonTitle' : 'previousSuggestionsButtonTitle';
|
|
2651
|
+
}
|
|
2652
|
+
else {
|
|
2653
|
+
currentButton = direction === 'prev' ? 'previousSuggestionsButtonTitle' : 'nextSuggestionsButtonTitle';
|
|
2654
|
+
}
|
|
2655
|
+
return this.localization.get(currentButton);
|
|
2656
|
+
}
|
|
2657
|
+
onScroll(event) {
|
|
2658
|
+
this.scrollService.onScroll(event);
|
|
2659
|
+
}
|
|
2660
|
+
scrollSuggestions(direction) {
|
|
2661
|
+
this.scrollService.scrollSuggestions(direction);
|
|
2662
|
+
}
|
|
2317
2663
|
focus() { }
|
|
2664
|
+
toggleScrollButtonState(buttonType, active) {
|
|
2665
|
+
const button = this[`${buttonType}ScrollButton`];
|
|
2666
|
+
if (button?.nativeElement) {
|
|
2667
|
+
if (active) {
|
|
2668
|
+
this.renderer.removeClass(button.nativeElement, 'k-disabled');
|
|
2669
|
+
}
|
|
2670
|
+
else {
|
|
2671
|
+
this.renderer.addClass(button.nativeElement, 'k-disabled');
|
|
2672
|
+
}
|
|
2673
|
+
}
|
|
2674
|
+
}
|
|
2318
2675
|
changeSelectedIndex(e) {
|
|
2319
2676
|
const offset = e.shiftKey ? -1 : 1;
|
|
2320
2677
|
const prevIndex = this.selectedIndex;
|
|
2321
2678
|
this.selectedIndex = Math.max(0, Math.min(prevIndex + offset, this.items.length - 1));
|
|
2322
2679
|
}
|
|
2323
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SuggestedActionsComponent, deps:
|
|
2324
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: SuggestedActionsComponent, isStandalone: true, selector: "kendo-chat-suggested-actions", inputs: { actions: "actions", suggestions: "suggestions", tabbable: "tabbable", suggestionTemplate: "suggestionTemplate" }, outputs: { dispatchAction: "dispatchAction", dispatchSuggestion: "dispatchSuggestion" }, host: { properties: { "class.k-suggestion-group": "this.defaultClass", "attr.role": "this.role" } }, providers: [{
|
|
2680
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SuggestedActionsComponent, deps: [{ token: ChatService }, { token: i1.LocalizationService }, { token: SuggestionsScrollService }, { token: i0.NgZone }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
|
|
2681
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: SuggestedActionsComponent, isStandalone: true, selector: "kendo-chat-suggested-actions", inputs: { actions: "actions", suggestions: "suggestions", tabbable: "tabbable", type: "type", suggestionTemplate: "suggestionTemplate" }, outputs: { dispatchAction: "dispatchAction", dispatchSuggestion: "dispatchSuggestion" }, host: { properties: { "class.k-suggestion-group": "this.defaultClass", "class.k-suggestion-group-scrollable": "this.scrollableClass", "class.k-suggestion-scrollwrap": "this.scrollButtonsClass", "attr.role": "this.role" } }, providers: [{
|
|
2325
2682
|
provide: ChatItem,
|
|
2326
2683
|
useExisting: forwardRef(() => SuggestedActionsComponent)
|
|
2327
|
-
}
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
</
|
|
2684
|
+
},
|
|
2685
|
+
SuggestionsScrollService
|
|
2686
|
+
], viewQueries: [{ propertyName: "suggestionsContainer", first: true, predicate: ["suggestionsContainer"], descendants: true, read: ElementRef }, { propertyName: "prevScrollButton", first: true, predicate: ["prevScrollButton"], descendants: true, read: ElementRef }, { propertyName: "nextScrollButton", first: true, predicate: ["nextScrollButton"], descendants: true, read: ElementRef }, { propertyName: "items", predicate: ["item"], descendants: true }], usesInheritance: true, ngImport: i0, template: `
|
|
2687
|
+
<span
|
|
2688
|
+
*ngIf="hasScrollButtons"
|
|
2689
|
+
#prevScrollButton
|
|
2690
|
+
kendoChatScrollableButton
|
|
2691
|
+
[prev]="true"
|
|
2692
|
+
[title]="getScrollButtonTitle('prev')"
|
|
2693
|
+
class="k-button k-button-md k-button-solid k-button-solid-base k-rounded-md k-icon-button"
|
|
2694
|
+
(onClick)="scrollSuggestions($event)"
|
|
2695
|
+
>
|
|
2696
|
+
</span>
|
|
2697
|
+
<div class="k-suggestion-group" *ngIf="hasScrollButtons; else noScrollButtons"
|
|
2698
|
+
#suggestionsContainer
|
|
2699
|
+
role="group"
|
|
2700
|
+
(scroll)="onScroll($event)">
|
|
2701
|
+
<ng-container *ngTemplateOutlet="suggestionsContent"></ng-container>
|
|
2702
|
+
</div>
|
|
2703
|
+
|
|
2704
|
+
<ng-template #noScrollButtons>
|
|
2705
|
+
<ng-container *ngTemplateOutlet="suggestionsContent"></ng-container>
|
|
2706
|
+
</ng-template>
|
|
2346
2707
|
|
|
2347
|
-
<ng-
|
|
2348
|
-
<ng-container *ngIf="
|
|
2708
|
+
<ng-template #suggestionsContent>
|
|
2709
|
+
<ng-container *ngIf="actions">
|
|
2349
2710
|
<span
|
|
2350
2711
|
#item
|
|
2351
|
-
*ngFor="let
|
|
2352
|
-
class="k-suggestion"
|
|
2712
|
+
*ngFor="let action of actions; index as index; first as first; last as last"
|
|
2713
|
+
class="k-suggestion k-suggestion-primary"
|
|
2353
2714
|
role="button"
|
|
2354
2715
|
[class.k-selected]="isSelected(index)"
|
|
2355
2716
|
[class.k-focus]="isSelected(index)"
|
|
2356
2717
|
[class.k-active]="isActive(index)"
|
|
2357
2718
|
[attr.tabindex]="0"
|
|
2358
|
-
(click)="
|
|
2359
|
-
(keydown)="
|
|
2719
|
+
(click)="actionClick(action, index)"
|
|
2720
|
+
(keydown)="actionKeydown($event, action)"
|
|
2360
2721
|
(mousedown)="toggleActiveState(true, index)"
|
|
2361
2722
|
(mouseup)="toggleActiveState(false, index)"
|
|
2362
2723
|
>
|
|
2363
|
-
{{
|
|
2724
|
+
{{ action.title || action.value }}
|
|
2364
2725
|
</span>
|
|
2365
2726
|
</ng-container>
|
|
2366
2727
|
|
|
2367
|
-
<ng-container *ngIf="
|
|
2368
|
-
<ng-container *
|
|
2369
|
-
<
|
|
2370
|
-
|
|
2371
|
-
|
|
2728
|
+
<ng-container *ngIf="suggestions">
|
|
2729
|
+
<ng-container *ngIf="!suggestionTemplate?.templateRef">
|
|
2730
|
+
<span
|
|
2731
|
+
#item
|
|
2732
|
+
*ngFor="let suggestion of suggestions; index as index; first as first; last as last"
|
|
2733
|
+
class="k-suggestion"
|
|
2734
|
+
role="button"
|
|
2735
|
+
[class.k-selected]="isSelected(index)"
|
|
2736
|
+
[class.k-focus]="isSelected(index)"
|
|
2737
|
+
[class.k-active]="isActive(index)"
|
|
2738
|
+
[attr.tabindex]="0"
|
|
2739
|
+
(click)="suggestionClick(suggestion, index)"
|
|
2740
|
+
(keydown)="suggestionKeydown($event, suggestion)"
|
|
2741
|
+
(mousedown)="toggleActiveState(true, index)"
|
|
2742
|
+
(mouseup)="toggleActiveState(false, index)"
|
|
2372
2743
|
>
|
|
2373
|
-
|
|
2744
|
+
{{ suggestion.text }}
|
|
2745
|
+
</span>
|
|
2746
|
+
</ng-container>
|
|
2747
|
+
|
|
2748
|
+
<ng-container *ngIf="suggestionTemplate?.templateRef">
|
|
2749
|
+
<ng-container *ngFor="let suggestion of suggestions">
|
|
2750
|
+
<ng-template
|
|
2751
|
+
[ngTemplateOutlet]="suggestionTemplate.templateRef"
|
|
2752
|
+
[ngTemplateOutletContext]="{ $implicit: suggestion }"
|
|
2753
|
+
>
|
|
2754
|
+
</ng-template>
|
|
2755
|
+
</ng-container>
|
|
2374
2756
|
</ng-container>
|
|
2375
2757
|
</ng-container>
|
|
2376
|
-
</ng-
|
|
2377
|
-
|
|
2758
|
+
</ng-template>
|
|
2759
|
+
|
|
2760
|
+
<span
|
|
2761
|
+
*ngIf="hasScrollButtons"
|
|
2762
|
+
#nextScrollButton
|
|
2763
|
+
kendoChatScrollableButton
|
|
2764
|
+
[prev]="false"
|
|
2765
|
+
[title]="getScrollButtonTitle('next')"
|
|
2766
|
+
class="k-button k-button-md k-button-solid k-button-solid-base k-rounded-md k-icon-button"
|
|
2767
|
+
(onClick)="scrollSuggestions($event)"
|
|
2768
|
+
>
|
|
2769
|
+
</span>
|
|
2770
|
+
`, isInline: true, dependencies: [{ kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ChatScrollableButtonComponent, selector: "[kendoChatScrollableButton]", inputs: ["prev"], outputs: ["onClick"] }] });
|
|
2378
2771
|
}
|
|
2379
2772
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SuggestedActionsComponent, decorators: [{
|
|
2380
2773
|
type: Component,
|
|
@@ -2383,82 +2776,134 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
2383
2776
|
providers: [{
|
|
2384
2777
|
provide: ChatItem,
|
|
2385
2778
|
useExisting: forwardRef(() => SuggestedActionsComponent)
|
|
2386
|
-
}
|
|
2779
|
+
},
|
|
2780
|
+
SuggestionsScrollService],
|
|
2387
2781
|
template: `
|
|
2388
|
-
<
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
>
|
|
2403
|
-
|
|
2404
|
-
</span>
|
|
2405
|
-
</ng-container>
|
|
2782
|
+
<span
|
|
2783
|
+
*ngIf="hasScrollButtons"
|
|
2784
|
+
#prevScrollButton
|
|
2785
|
+
kendoChatScrollableButton
|
|
2786
|
+
[prev]="true"
|
|
2787
|
+
[title]="getScrollButtonTitle('prev')"
|
|
2788
|
+
class="k-button k-button-md k-button-solid k-button-solid-base k-rounded-md k-icon-button"
|
|
2789
|
+
(onClick)="scrollSuggestions($event)"
|
|
2790
|
+
>
|
|
2791
|
+
</span>
|
|
2792
|
+
<div class="k-suggestion-group" *ngIf="hasScrollButtons; else noScrollButtons"
|
|
2793
|
+
#suggestionsContainer
|
|
2794
|
+
role="group"
|
|
2795
|
+
(scroll)="onScroll($event)">
|
|
2796
|
+
<ng-container *ngTemplateOutlet="suggestionsContent"></ng-container>
|
|
2797
|
+
</div>
|
|
2406
2798
|
|
|
2407
|
-
<ng-
|
|
2408
|
-
<ng-container *
|
|
2799
|
+
<ng-template #noScrollButtons>
|
|
2800
|
+
<ng-container *ngTemplateOutlet="suggestionsContent"></ng-container>
|
|
2801
|
+
</ng-template>
|
|
2802
|
+
|
|
2803
|
+
<ng-template #suggestionsContent>
|
|
2804
|
+
<ng-container *ngIf="actions">
|
|
2409
2805
|
<span
|
|
2410
2806
|
#item
|
|
2411
|
-
*ngFor="let
|
|
2412
|
-
class="k-suggestion"
|
|
2807
|
+
*ngFor="let action of actions; index as index; first as first; last as last"
|
|
2808
|
+
class="k-suggestion k-suggestion-primary"
|
|
2413
2809
|
role="button"
|
|
2414
2810
|
[class.k-selected]="isSelected(index)"
|
|
2415
2811
|
[class.k-focus]="isSelected(index)"
|
|
2416
2812
|
[class.k-active]="isActive(index)"
|
|
2417
2813
|
[attr.tabindex]="0"
|
|
2418
|
-
(click)="
|
|
2419
|
-
(keydown)="
|
|
2814
|
+
(click)="actionClick(action, index)"
|
|
2815
|
+
(keydown)="actionKeydown($event, action)"
|
|
2420
2816
|
(mousedown)="toggleActiveState(true, index)"
|
|
2421
2817
|
(mouseup)="toggleActiveState(false, index)"
|
|
2422
2818
|
>
|
|
2423
|
-
{{
|
|
2819
|
+
{{ action.title || action.value }}
|
|
2424
2820
|
</span>
|
|
2425
2821
|
</ng-container>
|
|
2426
2822
|
|
|
2427
|
-
<ng-container *ngIf="
|
|
2428
|
-
<ng-container *
|
|
2429
|
-
<
|
|
2430
|
-
|
|
2431
|
-
|
|
2823
|
+
<ng-container *ngIf="suggestions">
|
|
2824
|
+
<ng-container *ngIf="!suggestionTemplate?.templateRef">
|
|
2825
|
+
<span
|
|
2826
|
+
#item
|
|
2827
|
+
*ngFor="let suggestion of suggestions; index as index; first as first; last as last"
|
|
2828
|
+
class="k-suggestion"
|
|
2829
|
+
role="button"
|
|
2830
|
+
[class.k-selected]="isSelected(index)"
|
|
2831
|
+
[class.k-focus]="isSelected(index)"
|
|
2832
|
+
[class.k-active]="isActive(index)"
|
|
2833
|
+
[attr.tabindex]="0"
|
|
2834
|
+
(click)="suggestionClick(suggestion, index)"
|
|
2835
|
+
(keydown)="suggestionKeydown($event, suggestion)"
|
|
2836
|
+
(mousedown)="toggleActiveState(true, index)"
|
|
2837
|
+
(mouseup)="toggleActiveState(false, index)"
|
|
2432
2838
|
>
|
|
2433
|
-
|
|
2839
|
+
{{ suggestion.text }}
|
|
2840
|
+
</span>
|
|
2841
|
+
</ng-container>
|
|
2842
|
+
|
|
2843
|
+
<ng-container *ngIf="suggestionTemplate?.templateRef">
|
|
2844
|
+
<ng-container *ngFor="let suggestion of suggestions">
|
|
2845
|
+
<ng-template
|
|
2846
|
+
[ngTemplateOutlet]="suggestionTemplate.templateRef"
|
|
2847
|
+
[ngTemplateOutletContext]="{ $implicit: suggestion }"
|
|
2848
|
+
>
|
|
2849
|
+
</ng-template>
|
|
2850
|
+
</ng-container>
|
|
2434
2851
|
</ng-container>
|
|
2435
2852
|
</ng-container>
|
|
2436
|
-
</ng-
|
|
2853
|
+
</ng-template>
|
|
2854
|
+
|
|
2855
|
+
<span
|
|
2856
|
+
*ngIf="hasScrollButtons"
|
|
2857
|
+
#nextScrollButton
|
|
2858
|
+
kendoChatScrollableButton
|
|
2859
|
+
[prev]="false"
|
|
2860
|
+
[title]="getScrollButtonTitle('next')"
|
|
2861
|
+
class="k-button k-button-md k-button-solid k-button-solid-base k-rounded-md k-icon-button"
|
|
2862
|
+
(onClick)="scrollSuggestions($event)"
|
|
2863
|
+
>
|
|
2864
|
+
</span>
|
|
2437
2865
|
`,
|
|
2438
2866
|
standalone: true,
|
|
2439
|
-
imports: [NgFor, NgIf, NgTemplateOutlet]
|
|
2867
|
+
imports: [NgFor, NgIf, NgTemplateOutlet, ChatScrollableButtonComponent]
|
|
2440
2868
|
}]
|
|
2441
|
-
}], propDecorators: {
|
|
2869
|
+
}], ctorParameters: () => [{ type: ChatService }, { type: i1.LocalizationService }, { type: SuggestionsScrollService }, { type: i0.NgZone }, { type: i0.Renderer2 }], propDecorators: { defaultClass: [{
|
|
2870
|
+
type: HostBinding,
|
|
2871
|
+
args: ['class.k-suggestion-group']
|
|
2872
|
+
}], scrollableClass: [{
|
|
2873
|
+
type: HostBinding,
|
|
2874
|
+
args: ['class.k-suggestion-group-scrollable']
|
|
2875
|
+
}], scrollButtonsClass: [{
|
|
2876
|
+
type: HostBinding,
|
|
2877
|
+
args: ['class.k-suggestion-scrollwrap']
|
|
2878
|
+
}], role: [{
|
|
2879
|
+
type: HostBinding,
|
|
2880
|
+
args: ['attr.role']
|
|
2881
|
+
}], actions: [{
|
|
2442
2882
|
type: Input
|
|
2443
2883
|
}], suggestions: [{
|
|
2444
2884
|
type: Input
|
|
2445
2885
|
}], tabbable: [{
|
|
2446
2886
|
type: Input
|
|
2887
|
+
}], type: [{
|
|
2888
|
+
type: Input
|
|
2447
2889
|
}], suggestionTemplate: [{
|
|
2448
2890
|
type: Input
|
|
2449
2891
|
}], dispatchAction: [{
|
|
2450
2892
|
type: Output
|
|
2451
2893
|
}], dispatchSuggestion: [{
|
|
2452
2894
|
type: Output
|
|
2453
|
-
}], defaultClass: [{
|
|
2454
|
-
type: HostBinding,
|
|
2455
|
-
args: ['class.k-suggestion-group']
|
|
2456
|
-
}], role: [{
|
|
2457
|
-
type: HostBinding,
|
|
2458
|
-
args: ['attr.role']
|
|
2459
2895
|
}], items: [{
|
|
2460
2896
|
type: ViewChildren,
|
|
2461
2897
|
args: ['item']
|
|
2898
|
+
}], suggestionsContainer: [{
|
|
2899
|
+
type: ViewChild,
|
|
2900
|
+
args: ['suggestionsContainer', { read: ElementRef, static: false }]
|
|
2901
|
+
}], prevScrollButton: [{
|
|
2902
|
+
type: ViewChild,
|
|
2903
|
+
args: ['prevScrollButton', { read: ElementRef }]
|
|
2904
|
+
}], nextScrollButton: [{
|
|
2905
|
+
type: ViewChild,
|
|
2906
|
+
args: ['nextScrollButton', { read: ElementRef }]
|
|
2462
2907
|
}] } });
|
|
2463
2908
|
|
|
2464
2909
|
/* eslint-disable @typescript-eslint/no-empty-function */
|
|
@@ -2499,7 +2944,7 @@ class ChatFileComponent extends ChatItem {
|
|
|
2499
2944
|
useExisting: forwardRef(() => ChatFileComponent)
|
|
2500
2945
|
}], usesInheritance: true, ngImport: i0, template: `
|
|
2501
2946
|
<kendo-icon-wrapper
|
|
2502
|
-
size="
|
|
2947
|
+
size="xlarge"
|
|
2503
2948
|
[name]="fileGroupClass(chatFile.extension)"
|
|
2504
2949
|
[svgIcon]="fileThumbnail(chatFile.extension)"
|
|
2505
2950
|
>
|
|
@@ -2540,7 +2985,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
2540
2985
|
}],
|
|
2541
2986
|
template: `
|
|
2542
2987
|
<kendo-icon-wrapper
|
|
2543
|
-
size="
|
|
2988
|
+
size="xlarge"
|
|
2544
2989
|
[name]="fileGroupClass(chatFile.extension)"
|
|
2545
2990
|
[svgIcon]="fileThumbnail(chatFile.extension)"
|
|
2546
2991
|
>
|
|
@@ -2790,6 +3235,7 @@ class MessageBoxComponent {
|
|
|
2790
3235
|
return;
|
|
2791
3236
|
}
|
|
2792
3237
|
const message = {
|
|
3238
|
+
id: guid(),
|
|
2793
3239
|
text: this.inputValue,
|
|
2794
3240
|
timestamp: new Date(),
|
|
2795
3241
|
author: { id: this.authorId },
|
|
@@ -2927,6 +3373,7 @@ class MessageBoxComponent {
|
|
|
2927
3373
|
*ngIf="suggestions?.length > 0"
|
|
2928
3374
|
#suggestedActions
|
|
2929
3375
|
[suggestions]="suggestions"
|
|
3376
|
+
type="suggestion"
|
|
2930
3377
|
[suggestionTemplate]="suggestionTemplate"
|
|
2931
3378
|
[tabbable]="true"
|
|
2932
3379
|
(dispatchSuggestion)="dispatchSuggestion($event)"
|
|
@@ -3027,7 +3474,7 @@ class MessageBoxComponent {
|
|
|
3027
3474
|
[showFileList]="false"
|
|
3028
3475
|
(select)="handleFileSelect($event)"
|
|
3029
3476
|
></kendo-fileselect>
|
|
3030
|
-
`, isInline: true, dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: TextAreaComponent, selector: "kendo-textarea", inputs: ["focusableId", "flow", "inputAttributes", "adornmentsOrientation", "rows", "cols", "maxlength", "maxResizableRows", "tabindex", "tabIndex", "resizable", "size", "rounded", "fillMode", "showPrefixSeparator", "showSuffixSeparator"], outputs: ["focus", "blur", "valueChange"], exportAs: ["kendoTextArea"] }, { kind: "component", type: MessageReferenceComponent, selector: "chat-message-reference-content", inputs: ["message"] }, { kind: "component", type: TextAreaSuffixComponent, selector: "kendo-textarea-suffix", inputs: ["flow", "orientation"], exportAs: ["kendoTextAreaSuffix"] }, { kind: "component", type: TextAreaPrefixComponent, selector: "kendo-textarea-prefix", inputs: ["flow", "orientation"], exportAs: ["kendoTextAreaPrefix"] }, { kind: "component", type: SpeechToTextButtonComponent, selector: "button[kendoSpeechToTextButton]", inputs: ["disabled", "size", "rounded", "fillMode", "themeColor", "integrationMode", "lang", "continuous", "interimResults", "maxAlternatives"], outputs: ["start", "end", "result", "error", "click"], exportAs: ["kendoSpeechToTextButton"] }, { kind: "component", type: InputSpacerComponent, selector: "kendo-input-spacer, kendo-textbox-spacer", inputs: ["width"] }, { kind: "component", type: FileSelectComponent, selector: "kendo-fileselect", inputs: ["name"], outputs: ["valueChange"], exportAs: ["kendoFileSelect"] }, { kind: "component", type: SuggestedActionsComponent, selector: "kendo-chat-suggested-actions", inputs: ["actions", "suggestions", "tabbable", "suggestionTemplate"], outputs: ["dispatchAction", "dispatchSuggestion"] }, { kind: "component", type: ChatFileComponent, selector: "li[chatFile]", inputs: ["chatFile", "removable", "fileActions"], outputs: ["remove", "actionClick", "actionsToggle", "actionButtonClick"] }] });
|
|
3477
|
+
`, isInline: true, dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: TextAreaComponent, selector: "kendo-textarea", inputs: ["focusableId", "flow", "inputAttributes", "adornmentsOrientation", "rows", "cols", "maxlength", "maxResizableRows", "tabindex", "tabIndex", "resizable", "size", "rounded", "fillMode", "showPrefixSeparator", "showSuffixSeparator"], outputs: ["focus", "blur", "valueChange"], exportAs: ["kendoTextArea"] }, { kind: "component", type: MessageReferenceComponent, selector: "chat-message-reference-content", inputs: ["message"] }, { kind: "component", type: TextAreaSuffixComponent, selector: "kendo-textarea-suffix", inputs: ["flow", "orientation"], exportAs: ["kendoTextAreaSuffix"] }, { kind: "component", type: TextAreaPrefixComponent, selector: "kendo-textarea-prefix", inputs: ["flow", "orientation"], exportAs: ["kendoTextAreaPrefix"] }, { kind: "component", type: SpeechToTextButtonComponent, selector: "button[kendoSpeechToTextButton]", inputs: ["disabled", "size", "rounded", "fillMode", "themeColor", "integrationMode", "lang", "continuous", "interimResults", "maxAlternatives"], outputs: ["start", "end", "result", "error", "click"], exportAs: ["kendoSpeechToTextButton"] }, { kind: "component", type: InputSpacerComponent, selector: "kendo-input-spacer, kendo-textbox-spacer", inputs: ["width"] }, { kind: "component", type: FileSelectComponent, selector: "kendo-fileselect", inputs: ["name"], outputs: ["valueChange"], exportAs: ["kendoFileSelect"] }, { kind: "component", type: SuggestedActionsComponent, selector: "kendo-chat-suggested-actions", inputs: ["actions", "suggestions", "tabbable", "type", "suggestionTemplate"], outputs: ["dispatchAction", "dispatchSuggestion"] }, { kind: "component", type: ChatFileComponent, selector: "li[chatFile]", inputs: ["chatFile", "removable", "fileActions"], outputs: ["remove", "actionClick", "actionsToggle", "actionButtonClick"] }] });
|
|
3031
3478
|
}
|
|
3032
3479
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MessageBoxComponent, decorators: [{
|
|
3033
3480
|
type: Component,
|
|
@@ -3038,6 +3485,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
3038
3485
|
*ngIf="suggestions?.length > 0"
|
|
3039
3486
|
#suggestedActions
|
|
3040
3487
|
[suggestions]="suggestions"
|
|
3488
|
+
type="suggestion"
|
|
3041
3489
|
[suggestionTemplate]="suggestionTemplate"
|
|
3042
3490
|
[tabbable]="true"
|
|
3043
3491
|
(dispatchSuggestion)="dispatchSuggestion($event)"
|
|
@@ -3183,6 +3631,40 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
3183
3631
|
type: Output
|
|
3184
3632
|
}] } });
|
|
3185
3633
|
|
|
3634
|
+
/**
|
|
3635
|
+
* Defines a template for displaying custom content inside the Chat messages.
|
|
3636
|
+
*
|
|
3637
|
+
* To define a message template, nest an `<ng-template>` tag with the `kendoChatMessageContentTemplate` directive inside the `<kendo-chat>` component.
|
|
3638
|
+
* The template context is set to the `message` instance.
|
|
3639
|
+
* For more information, refer to the article on [message templates](slug:message_templates_chat).
|
|
3640
|
+
*
|
|
3641
|
+
* @example
|
|
3642
|
+
* ```html
|
|
3643
|
+
* <kendo-chat>
|
|
3644
|
+
* <ng-template kendoChatMessageContentTemplate let-message>
|
|
3645
|
+
* <div>Message: {{ message.text }}</div>
|
|
3646
|
+
* </ng-template>
|
|
3647
|
+
* </kendo-chat>
|
|
3648
|
+
* ```
|
|
3649
|
+
*/
|
|
3650
|
+
class MessageContentTemplateDirective {
|
|
3651
|
+
templateRef;
|
|
3652
|
+
constructor(templateRef) {
|
|
3653
|
+
this.templateRef = templateRef;
|
|
3654
|
+
}
|
|
3655
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MessageContentTemplateDirective, deps: [{ token: i0.TemplateRef, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
|
|
3656
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.14", type: MessageContentTemplateDirective, isStandalone: true, selector: "[kendoChatMessageContentTemplate]", ngImport: i0 });
|
|
3657
|
+
}
|
|
3658
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MessageContentTemplateDirective, decorators: [{
|
|
3659
|
+
type: Directive,
|
|
3660
|
+
args: [{
|
|
3661
|
+
selector: '[kendoChatMessageContentTemplate]',
|
|
3662
|
+
standalone: true
|
|
3663
|
+
}]
|
|
3664
|
+
}], ctorParameters: () => [{ type: i0.TemplateRef, decorators: [{
|
|
3665
|
+
type: Optional
|
|
3666
|
+
}] }] });
|
|
3667
|
+
|
|
3186
3668
|
/**
|
|
3187
3669
|
* Defines a template for displaying the chat timestamp.
|
|
3188
3670
|
*
|
|
@@ -3248,6 +3730,176 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
3248
3730
|
}]
|
|
3249
3731
|
}], ctorParameters: () => [{ type: i0.TemplateRef }] });
|
|
3250
3732
|
|
|
3733
|
+
/**
|
|
3734
|
+
* Defines a template for displaying fully custom Chat message bubbles.
|
|
3735
|
+
*
|
|
3736
|
+
* To define a message template, nest an `<ng-template>` tag with the `kendoChatMessageTemplate` directive inside the `<kendo-chat>` component.
|
|
3737
|
+
* The template context is set to the `message` instance.
|
|
3738
|
+
* For more information, refer to the article on [message templates](slug:message_templates_chat).
|
|
3739
|
+
*
|
|
3740
|
+
* @example
|
|
3741
|
+
* ```html
|
|
3742
|
+
* <kendo-chat>
|
|
3743
|
+
* <ng-template kendoChatMessageTemplate let-message>
|
|
3744
|
+
* <div>Message: {{ message.text }}</div>
|
|
3745
|
+
* </ng-template>
|
|
3746
|
+
* </kendo-chat>
|
|
3747
|
+
* ```
|
|
3748
|
+
*/
|
|
3749
|
+
class MessageTemplateDirective {
|
|
3750
|
+
templateRef;
|
|
3751
|
+
constructor(templateRef) {
|
|
3752
|
+
this.templateRef = templateRef;
|
|
3753
|
+
}
|
|
3754
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MessageTemplateDirective, deps: [{ token: i0.TemplateRef, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
|
|
3755
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.14", type: MessageTemplateDirective, isStandalone: true, selector: "[kendoChatMessageTemplate]", ngImport: i0 });
|
|
3756
|
+
}
|
|
3757
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MessageTemplateDirective, decorators: [{
|
|
3758
|
+
type: Directive,
|
|
3759
|
+
args: [{
|
|
3760
|
+
selector: '[kendoChatMessageTemplate]',
|
|
3761
|
+
standalone: true
|
|
3762
|
+
}]
|
|
3763
|
+
}], ctorParameters: () => [{ type: i0.TemplateRef, decorators: [{
|
|
3764
|
+
type: Optional
|
|
3765
|
+
}] }] });
|
|
3766
|
+
|
|
3767
|
+
/**
|
|
3768
|
+
* Defines a template for displaying custom content inside the current user's messages in the Chat.
|
|
3769
|
+
*
|
|
3770
|
+
* To define a message template, nest an `<ng-template>` tag with the `kendoChatAuthorMessageContentTemplate` directive inside the `<kendo-chat>` component.
|
|
3771
|
+
* The template context is set to the `message` instance.
|
|
3772
|
+
* For more information, refer to the article on [message templates](slug:message_templates_chat).
|
|
3773
|
+
*
|
|
3774
|
+
* @example
|
|
3775
|
+
* ```html
|
|
3776
|
+
* <kendo-chat>
|
|
3777
|
+
* <ng-template kendoChatAuthorMessageContentTemplate let-message>
|
|
3778
|
+
* <div>Message: {{ message.text }}</div>
|
|
3779
|
+
* </ng-template>
|
|
3780
|
+
* </kendo-chat>
|
|
3781
|
+
* ```
|
|
3782
|
+
*/
|
|
3783
|
+
class AuthorMessageContentTemplateDirective {
|
|
3784
|
+
templateRef;
|
|
3785
|
+
constructor(templateRef) {
|
|
3786
|
+
this.templateRef = templateRef;
|
|
3787
|
+
}
|
|
3788
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AuthorMessageContentTemplateDirective, deps: [{ token: i0.TemplateRef, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
|
|
3789
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.14", type: AuthorMessageContentTemplateDirective, isStandalone: true, selector: "[kendoChatAuthorMessageContentTemplate]", ngImport: i0 });
|
|
3790
|
+
}
|
|
3791
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AuthorMessageContentTemplateDirective, decorators: [{
|
|
3792
|
+
type: Directive,
|
|
3793
|
+
args: [{
|
|
3794
|
+
selector: '[kendoChatAuthorMessageContentTemplate]',
|
|
3795
|
+
standalone: true
|
|
3796
|
+
}]
|
|
3797
|
+
}], ctorParameters: () => [{ type: i0.TemplateRef, decorators: [{
|
|
3798
|
+
type: Optional
|
|
3799
|
+
}] }] });
|
|
3800
|
+
|
|
3801
|
+
/**
|
|
3802
|
+
* Defines a template for displaying custom content inside the other users' messages in the Chat.
|
|
3803
|
+
*
|
|
3804
|
+
* To define a message template, nest an `<ng-template>` tag with the `kendoChatReceiverMessageContentTemplate` directive inside the `<kendo-chat>` component.
|
|
3805
|
+
* The template context is set to the `message` instance.
|
|
3806
|
+
* For more information, refer to the article on [message templates](slug:message_templates_chat).
|
|
3807
|
+
*
|
|
3808
|
+
* @example
|
|
3809
|
+
* ```html
|
|
3810
|
+
* <kendo-chat>
|
|
3811
|
+
* <ng-template kendoChatReceiverMessageContentTemplate let-message>
|
|
3812
|
+
* <div>Message: {{ message.text }}</div>
|
|
3813
|
+
* </ng-template>
|
|
3814
|
+
* </kendo-chat>
|
|
3815
|
+
* ```
|
|
3816
|
+
*/
|
|
3817
|
+
class ReceiverMessageContentTemplateDirective {
|
|
3818
|
+
templateRef;
|
|
3819
|
+
constructor(templateRef) {
|
|
3820
|
+
this.templateRef = templateRef;
|
|
3821
|
+
}
|
|
3822
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReceiverMessageContentTemplateDirective, deps: [{ token: i0.TemplateRef, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
|
|
3823
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.14", type: ReceiverMessageContentTemplateDirective, isStandalone: true, selector: "[kendoChatReceiverMessageContentTemplate]", ngImport: i0 });
|
|
3824
|
+
}
|
|
3825
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReceiverMessageContentTemplateDirective, decorators: [{
|
|
3826
|
+
type: Directive,
|
|
3827
|
+
args: [{
|
|
3828
|
+
selector: '[kendoChatReceiverMessageContentTemplate]',
|
|
3829
|
+
standalone: true
|
|
3830
|
+
}]
|
|
3831
|
+
}], ctorParameters: () => [{ type: i0.TemplateRef, decorators: [{
|
|
3832
|
+
type: Optional
|
|
3833
|
+
}] }] });
|
|
3834
|
+
|
|
3835
|
+
/**
|
|
3836
|
+
* Defines a template for displaying fully custom Chat message bubbles for the other users.
|
|
3837
|
+
*
|
|
3838
|
+
* To define a message template, nest an `<ng-template>` tag with the `kendoChatReceiverMessageTemplate` directive inside the `<kendo-chat>` component.
|
|
3839
|
+
* The template context is set to the `message` instance.
|
|
3840
|
+
* For more information, refer to the article on [message templates](slug:message_templates_chat).
|
|
3841
|
+
*
|
|
3842
|
+
* @example
|
|
3843
|
+
* ```html
|
|
3844
|
+
* <kendo-chat>
|
|
3845
|
+
* <ng-template kendoChatReceiverMessageTemplate let-message>
|
|
3846
|
+
* <div>Message: {{ message.text }}</div>
|
|
3847
|
+
* </ng-template>
|
|
3848
|
+
* </kendo-chat>
|
|
3849
|
+
* ```
|
|
3850
|
+
*/
|
|
3851
|
+
class ReceiverMessageTemplateDirective {
|
|
3852
|
+
templateRef;
|
|
3853
|
+
constructor(templateRef) {
|
|
3854
|
+
this.templateRef = templateRef;
|
|
3855
|
+
}
|
|
3856
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReceiverMessageTemplateDirective, deps: [{ token: i0.TemplateRef, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
|
|
3857
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.14", type: ReceiverMessageTemplateDirective, isStandalone: true, selector: "[kendoChatReceiverMessageTemplate]", ngImport: i0 });
|
|
3858
|
+
}
|
|
3859
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReceiverMessageTemplateDirective, decorators: [{
|
|
3860
|
+
type: Directive,
|
|
3861
|
+
args: [{
|
|
3862
|
+
selector: '[kendoChatReceiverMessageTemplate]',
|
|
3863
|
+
standalone: true
|
|
3864
|
+
}]
|
|
3865
|
+
}], ctorParameters: () => [{ type: i0.TemplateRef, decorators: [{
|
|
3866
|
+
type: Optional
|
|
3867
|
+
}] }] });
|
|
3868
|
+
|
|
3869
|
+
/**
|
|
3870
|
+
* Defines a template for displaying fully custom Chat message bubbles for the current user.
|
|
3871
|
+
*
|
|
3872
|
+
* To define a message template, nest an `<ng-template>` tag with the `kendoChatAuthorMessageTemplate` directive inside the `<kendo-chat>` component.
|
|
3873
|
+
* The template context is set to the `message` instance.
|
|
3874
|
+
* For more information, refer to the article on [message templates](slug:message_templates_chat).
|
|
3875
|
+
*
|
|
3876
|
+
* @example
|
|
3877
|
+
* ```html
|
|
3878
|
+
* <kendo-chat>
|
|
3879
|
+
* <ng-template kendoChatAuthorMessageTemplate let-message>
|
|
3880
|
+
* <div>Message: {{ message.text }}</div>
|
|
3881
|
+
* </ng-template>
|
|
3882
|
+
* </kendo-chat>
|
|
3883
|
+
* ```
|
|
3884
|
+
*/
|
|
3885
|
+
class AuthorMessageTemplateDirective {
|
|
3886
|
+
templateRef;
|
|
3887
|
+
constructor(templateRef) {
|
|
3888
|
+
this.templateRef = templateRef;
|
|
3889
|
+
}
|
|
3890
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AuthorMessageTemplateDirective, deps: [{ token: i0.TemplateRef, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
|
|
3891
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.14", type: AuthorMessageTemplateDirective, isStandalone: true, selector: "[kendoChatAuthorMessageTemplate]", ngImport: i0 });
|
|
3892
|
+
}
|
|
3893
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AuthorMessageTemplateDirective, decorators: [{
|
|
3894
|
+
type: Directive,
|
|
3895
|
+
args: [{
|
|
3896
|
+
selector: '[kendoChatAuthorMessageTemplate]',
|
|
3897
|
+
standalone: true
|
|
3898
|
+
}]
|
|
3899
|
+
}], ctorParameters: () => [{ type: i0.TemplateRef, decorators: [{
|
|
3900
|
+
type: Optional
|
|
3901
|
+
}] }] });
|
|
3902
|
+
|
|
3251
3903
|
// eslint-disable no-forward-ref
|
|
3252
3904
|
/**
|
|
3253
3905
|
* @hidden
|
|
@@ -3257,13 +3909,23 @@ class MessageComponent extends ChatItem {
|
|
|
3257
3909
|
intl;
|
|
3258
3910
|
chatService;
|
|
3259
3911
|
localization;
|
|
3260
|
-
|
|
3912
|
+
cdr;
|
|
3913
|
+
set message(value) {
|
|
3914
|
+
this._message = value;
|
|
3915
|
+
}
|
|
3916
|
+
get message() {
|
|
3917
|
+
return this._message;
|
|
3918
|
+
}
|
|
3261
3919
|
tabbable;
|
|
3262
|
-
|
|
3920
|
+
authorMessageContentTemplate;
|
|
3921
|
+
receiverMessageContentTemplate;
|
|
3922
|
+
messageContentTemplate;
|
|
3923
|
+
authorMessageTemplate;
|
|
3924
|
+
receiverMessageTemplate;
|
|
3925
|
+
messageTemplate;
|
|
3263
3926
|
statusTemplate;
|
|
3264
3927
|
showMessageTime = true;
|
|
3265
3928
|
authorId;
|
|
3266
|
-
contextMenuVisibilityChange = new EventEmitter();
|
|
3267
3929
|
cssClass = true;
|
|
3268
3930
|
get removedClass() {
|
|
3269
3931
|
return this.message.isDeleted;
|
|
@@ -3278,44 +3940,142 @@ class MessageComponent extends ChatItem {
|
|
|
3278
3940
|
this.onExpandableKeydown(event);
|
|
3279
3941
|
}
|
|
3280
3942
|
selected;
|
|
3281
|
-
active = false;
|
|
3282
|
-
selectOnMenuClose = false;
|
|
3283
3943
|
get tabIndex() {
|
|
3284
3944
|
return this.tabbable ? '0' : '-1';
|
|
3285
3945
|
}
|
|
3286
|
-
onContextMenu(event) {
|
|
3287
|
-
if (this.message.isDeleted) {
|
|
3288
|
-
return;
|
|
3289
|
-
}
|
|
3290
|
-
this.active = true;
|
|
3291
|
-
event.stopPropagation();
|
|
3292
|
-
}
|
|
3293
3946
|
expandIcon = chevronDownIcon;
|
|
3294
3947
|
collapseIcon = chevronUpIcon;
|
|
3295
3948
|
downloadIcon = downloadIcon;
|
|
3296
3949
|
isMessageExpanded = false;
|
|
3297
|
-
|
|
3950
|
+
showExpandCollapseIcon = false;
|
|
3298
3951
|
fileActions = [];
|
|
3952
|
+
toolbarActions = [];
|
|
3299
3953
|
parts = [];
|
|
3300
|
-
|
|
3954
|
+
get useCustomBubbleTemplate() {
|
|
3955
|
+
return !!(this.getActiveBubbleTemplate());
|
|
3956
|
+
}
|
|
3957
|
+
get useCustomContentTemplate() {
|
|
3958
|
+
return !!(this.getActiveContentTemplate());
|
|
3959
|
+
}
|
|
3960
|
+
get hasMessageContent() {
|
|
3961
|
+
return !!(this.message?.text || this.message?.files?.length > 0);
|
|
3962
|
+
}
|
|
3963
|
+
get hasFiles() {
|
|
3964
|
+
return this.message?.files?.length > 0;
|
|
3965
|
+
}
|
|
3966
|
+
get hasMultipleFiles() {
|
|
3967
|
+
return this.message?.files?.length > 1;
|
|
3968
|
+
}
|
|
3969
|
+
get isActiveMessage() {
|
|
3970
|
+
return this.chatService.active && this.message?.id === this.chatService.activeMessage?.id;
|
|
3971
|
+
}
|
|
3972
|
+
get isMessageExpandable() {
|
|
3973
|
+
const isOwn = this.isOwnMessage(this.message);
|
|
3974
|
+
const messageSettings = isOwn
|
|
3975
|
+
? this.chatService.authorMessageSettings
|
|
3976
|
+
: this.chatService.receiverMessageSettings;
|
|
3977
|
+
if (isPresent(messageSettings?.allowMessageCollapse)) {
|
|
3978
|
+
return messageSettings.allowMessageCollapse;
|
|
3979
|
+
}
|
|
3980
|
+
return this.chatService.allowMessageCollapse || false;
|
|
3981
|
+
}
|
|
3982
|
+
get showToolbar() {
|
|
3983
|
+
if (this.message?.isDeleted) {
|
|
3984
|
+
return false;
|
|
3985
|
+
}
|
|
3986
|
+
const hasComponentActions = this.chatService.messageToolbarActions?.length > 0;
|
|
3987
|
+
const hasMessageActions = this.toolbarActions?.length > 0;
|
|
3988
|
+
return hasComponentActions || hasMessageActions;
|
|
3989
|
+
}
|
|
3990
|
+
subs = new Subscription();
|
|
3991
|
+
_message;
|
|
3992
|
+
constructor(element, intl, chatService, localization, cdr) {
|
|
3301
3993
|
super();
|
|
3302
3994
|
this.element = element;
|
|
3303
3995
|
this.intl = intl;
|
|
3304
3996
|
this.chatService = chatService;
|
|
3305
3997
|
this.localization = localization;
|
|
3998
|
+
this.cdr = cdr;
|
|
3306
3999
|
}
|
|
3307
4000
|
ngOnInit() {
|
|
3308
|
-
this.
|
|
3309
|
-
this.
|
|
4001
|
+
this.fileActions = this.getFileActions();
|
|
4002
|
+
this.toolbarActions = this.getToolbarActions();
|
|
4003
|
+
const settingsChange$ = this.isOwnMessage(this.message)
|
|
4004
|
+
? this.chatService.authorMessageSettingsChange$
|
|
4005
|
+
: this.chatService.receiverMessageSettingsChange$;
|
|
4006
|
+
this.subs.add(settingsChange$.subscribe(() => {
|
|
4007
|
+
this.fileActions = this.getFileActions();
|
|
4008
|
+
this.toolbarActions = this.getToolbarActions();
|
|
4009
|
+
setTimeout(() => {
|
|
4010
|
+
this.showExpandCollapseIcon = this.calculateExpandCollapseIconVisibility();
|
|
4011
|
+
});
|
|
4012
|
+
}));
|
|
4013
|
+
this.subs.add(this.chatService.allowMessageCollapseChange$.subscribe(() => {
|
|
4014
|
+
setTimeout(() => {
|
|
4015
|
+
this.showExpandCollapseIcon = this.calculateExpandCollapseIconVisibility();
|
|
4016
|
+
});
|
|
4017
|
+
}));
|
|
3310
4018
|
if (this.message.id) {
|
|
3311
4019
|
this.chatService.registerMessageElement(this.message.id, this.element);
|
|
3312
4020
|
}
|
|
3313
4021
|
this.parts = this.getFormattedTextParts(this.message.text);
|
|
3314
4022
|
}
|
|
4023
|
+
ngAfterViewInit() {
|
|
4024
|
+
this.showExpandCollapseIcon = this.calculateExpandCollapseIconVisibility();
|
|
4025
|
+
this.cdr.detectChanges();
|
|
4026
|
+
}
|
|
3315
4027
|
ngOnDestroy() {
|
|
3316
4028
|
if (this.message.id) {
|
|
3317
4029
|
this.chatService.unregisterMessageElement(this.message.id);
|
|
3318
4030
|
}
|
|
4031
|
+
this.subs.unsubscribe();
|
|
4032
|
+
}
|
|
4033
|
+
calculateExpandCollapseIconVisibility() {
|
|
4034
|
+
if (this.isMessageExpanded) {
|
|
4035
|
+
return true;
|
|
4036
|
+
}
|
|
4037
|
+
const bubbleContent = this.element.nativeElement.querySelector('.k-bubble-content');
|
|
4038
|
+
if (!bubbleContent) {
|
|
4039
|
+
return false;
|
|
4040
|
+
}
|
|
4041
|
+
const hasVerticalOverflow = bubbleContent.scrollHeight > bubbleContent.clientHeight;
|
|
4042
|
+
const hasHorizontalOverflow = bubbleContent.scrollWidth > bubbleContent.clientWidth;
|
|
4043
|
+
if (this.useCustomContentTemplate) {
|
|
4044
|
+
return hasVerticalOverflow || hasHorizontalOverflow;
|
|
4045
|
+
}
|
|
4046
|
+
const messageText = this.element.nativeElement.querySelector('.k-chat-bubble-text');
|
|
4047
|
+
const hasTextOverflow = messageText?.scrollWidth > messageText?.clientWidth;
|
|
4048
|
+
return hasTextOverflow || hasVerticalOverflow || hasHorizontalOverflow;
|
|
4049
|
+
}
|
|
4050
|
+
getActiveBubbleTemplate() {
|
|
4051
|
+
const isOwn = this.isOwnMessage(this.message);
|
|
4052
|
+
if (isOwn && this.authorMessageTemplate) {
|
|
4053
|
+
return this.authorMessageTemplate;
|
|
4054
|
+
}
|
|
4055
|
+
if (!isOwn && this.receiverMessageTemplate) {
|
|
4056
|
+
return this.receiverMessageTemplate;
|
|
4057
|
+
}
|
|
4058
|
+
if (this.messageTemplate) {
|
|
4059
|
+
return this.messageTemplate;
|
|
4060
|
+
}
|
|
4061
|
+
return null;
|
|
4062
|
+
}
|
|
4063
|
+
getActiveContentTemplate() {
|
|
4064
|
+
const isOwn = this.isOwnMessage(this.message);
|
|
4065
|
+
if (isOwn && this.authorMessageContentTemplate) {
|
|
4066
|
+
return this.authorMessageContentTemplate;
|
|
4067
|
+
}
|
|
4068
|
+
if (!isOwn && this.receiverMessageContentTemplate) {
|
|
4069
|
+
return this.receiverMessageContentTemplate;
|
|
4070
|
+
}
|
|
4071
|
+
if (this.messageContentTemplate) {
|
|
4072
|
+
return this.messageContentTemplate;
|
|
4073
|
+
}
|
|
4074
|
+
return null;
|
|
4075
|
+
}
|
|
4076
|
+
getDeletedMessageText() {
|
|
4077
|
+
const isOwn = this.isOwnMessage(this.message);
|
|
4078
|
+
return isOwn ? this.textFor('deletedMessageSenderText') : this.textFor('deletedMessageReceiverText');
|
|
3319
4079
|
}
|
|
3320
4080
|
textFor(key) {
|
|
3321
4081
|
return this.localization.get(key);
|
|
@@ -3343,66 +4103,19 @@ class MessageComponent extends ChatItem {
|
|
|
3343
4103
|
this.toggleMessageState(event);
|
|
3344
4104
|
}
|
|
3345
4105
|
}
|
|
3346
|
-
isToolbarVisible() {
|
|
3347
|
-
if (!this.chatService.messageToolbarActions || this.chatService.messageToolbarActions.length === 0 || this.message.isDeleted) {
|
|
3348
|
-
return false;
|
|
3349
|
-
}
|
|
3350
|
-
return this.chatService.messageToolbarVisibility === 'always';
|
|
3351
|
-
}
|
|
3352
4106
|
onToolbarAction(event, action, message) {
|
|
3353
4107
|
event.stopImmediatePropagation();
|
|
3354
4108
|
this.chatService.emit('toolbarAction', { action, message });
|
|
3355
4109
|
}
|
|
3356
|
-
onContextMenuAction(action) {
|
|
3357
|
-
if (action.id === 'reply') {
|
|
3358
|
-
this.chatService.reply = this.message;
|
|
3359
|
-
}
|
|
3360
|
-
if (action.id === 'copy') {
|
|
3361
|
-
navigator.clipboard.writeText(this.message.text);
|
|
3362
|
-
}
|
|
3363
|
-
this.chatService.emit('contextMenuAction', { action, message: this.message });
|
|
3364
|
-
}
|
|
3365
4110
|
onFileAction(action, file) {
|
|
3366
4111
|
if (action.originalAction.id === 'download') {
|
|
3367
4112
|
this.chatService.emit('fileDownload', { files: [file], message: this.message });
|
|
3368
4113
|
}
|
|
3369
4114
|
this.chatService.emit('fileAction', { action: action.originalAction, file });
|
|
3370
4115
|
}
|
|
3371
|
-
transformActions(actions) {
|
|
3372
|
-
return actions.map(action => ({
|
|
3373
|
-
text: action.label,
|
|
3374
|
-
icon: action.icon,
|
|
3375
|
-
svgIcon: action.svgIcon,
|
|
3376
|
-
disabled: action.disabled,
|
|
3377
|
-
originalAction: action
|
|
3378
|
-
}));
|
|
3379
|
-
}
|
|
3380
4116
|
getMessageById(id) {
|
|
3381
4117
|
return this.chatService.getMessageById(id);
|
|
3382
4118
|
}
|
|
3383
|
-
// processes the message text to extract parts that are either plain text or links
|
|
3384
|
-
// this allows us not to render an additional wrapper element for the text
|
|
3385
|
-
getFormattedTextParts(text) {
|
|
3386
|
-
if (!text) {
|
|
3387
|
-
return [];
|
|
3388
|
-
}
|
|
3389
|
-
const parts = [];
|
|
3390
|
-
const urlMatches = Array.from(text.matchAll(URL_REGEX));
|
|
3391
|
-
let lastIndex = 0;
|
|
3392
|
-
for (const match of urlMatches) {
|
|
3393
|
-
const url = match[1];
|
|
3394
|
-
const matchStart = match.index;
|
|
3395
|
-
if (matchStart > lastIndex) {
|
|
3396
|
-
parts.push({ type: 'text', content: text.substring(lastIndex, matchStart) });
|
|
3397
|
-
}
|
|
3398
|
-
parts.push({ type: 'link', content: url, href: url });
|
|
3399
|
-
lastIndex = matchStart + match[0].length;
|
|
3400
|
-
}
|
|
3401
|
-
if (lastIndex < text.length) {
|
|
3402
|
-
parts.push({ type: 'text', content: text.substring(lastIndex) });
|
|
3403
|
-
}
|
|
3404
|
-
return parts;
|
|
3405
|
-
}
|
|
3406
4119
|
onReplyReferenceClick(event, replyToId) {
|
|
3407
4120
|
event.stopPropagation();
|
|
3408
4121
|
this.chatService.emit('replyReferenceClick', replyToId);
|
|
@@ -3414,9 +4127,9 @@ class MessageComponent extends ChatItem {
|
|
|
3414
4127
|
this.onActionButtonClick(originalEvent);
|
|
3415
4128
|
}
|
|
3416
4129
|
}
|
|
3417
|
-
this.active = false;
|
|
3418
|
-
this.
|
|
3419
|
-
if (this.selectOnMenuClose) {
|
|
4130
|
+
this.chatService.active = false;
|
|
4131
|
+
this.chatService.emit('contextMenuVisibilityChange', false);
|
|
4132
|
+
if (this.chatService.selectOnMenuClose) {
|
|
3420
4133
|
this.selected = true;
|
|
3421
4134
|
this.focus();
|
|
3422
4135
|
}
|
|
@@ -3425,16 +4138,16 @@ class MessageComponent extends ChatItem {
|
|
|
3425
4138
|
const clickOutsideMessage = event instanceof MouseEvent && !event.target?.closest('.k-chat-bubble');
|
|
3426
4139
|
const menuItemClick = event instanceof MouseEvent && event.target?.closest(MENU_ITEM_SELECTOR);
|
|
3427
4140
|
if (clickOutsideMessage && !menuItemClick) {
|
|
3428
|
-
this.selectOnMenuClose = false;
|
|
4141
|
+
this.chatService.selectOnMenuClose = false;
|
|
3429
4142
|
}
|
|
3430
4143
|
}
|
|
3431
4144
|
handleMenuOpen() {
|
|
3432
|
-
this.selectOnMenuClose = this.selected;
|
|
3433
|
-
this.
|
|
4145
|
+
this.chatService.selectOnMenuClose = this.selected;
|
|
4146
|
+
this.chatService.emit('contextMenuVisibilityChange', true);
|
|
3434
4147
|
}
|
|
3435
4148
|
onActionPopupChange(expanded) {
|
|
3436
4149
|
if (expanded) {
|
|
3437
|
-
this.active = true;
|
|
4150
|
+
this.chatService.active = true;
|
|
3438
4151
|
this.handleMenuOpen();
|
|
3439
4152
|
}
|
|
3440
4153
|
else {
|
|
@@ -3444,124 +4157,211 @@ class MessageComponent extends ChatItem {
|
|
|
3444
4157
|
isOwnMessage(msg) {
|
|
3445
4158
|
return isAuthor(this.authorId, msg);
|
|
3446
4159
|
}
|
|
3447
|
-
|
|
3448
|
-
|
|
4160
|
+
getFormattedTextParts(text) {
|
|
4161
|
+
if (!text) {
|
|
4162
|
+
return [];
|
|
4163
|
+
}
|
|
4164
|
+
const parts = [];
|
|
4165
|
+
const urlMatches = Array.from(text.matchAll(URL_REGEX));
|
|
4166
|
+
let lastIndex = 0;
|
|
4167
|
+
for (const match of urlMatches) {
|
|
4168
|
+
const url = match[1];
|
|
4169
|
+
const matchStart = match.index;
|
|
4170
|
+
if (!isPresent(matchStart)) {
|
|
4171
|
+
continue;
|
|
4172
|
+
}
|
|
4173
|
+
if (matchStart > lastIndex) {
|
|
4174
|
+
parts.push({ type: 'text', content: text.substring(lastIndex, matchStart) });
|
|
4175
|
+
}
|
|
4176
|
+
parts.push({ type: 'link', content: url, href: url });
|
|
4177
|
+
lastIndex = matchStart + match[0].length;
|
|
4178
|
+
}
|
|
4179
|
+
if (lastIndex < text.length) {
|
|
4180
|
+
parts.push({ type: 'text', content: text.substring(lastIndex) });
|
|
4181
|
+
}
|
|
4182
|
+
return parts;
|
|
4183
|
+
}
|
|
4184
|
+
getMessageSettings() {
|
|
4185
|
+
return this.isOwnMessage(this.message)
|
|
4186
|
+
? this.chatService.authorMessageSettings
|
|
4187
|
+
: this.chatService.receiverMessageSettings;
|
|
4188
|
+
}
|
|
4189
|
+
getToolbarActions() {
|
|
4190
|
+
const messageSettings = this.getMessageSettings();
|
|
4191
|
+
return messageSettings?.messageToolbarActions?.length
|
|
4192
|
+
? messageSettings.messageToolbarActions
|
|
4193
|
+
: this.chatService.messageToolbarActions || [];
|
|
4194
|
+
}
|
|
4195
|
+
getFileActions() {
|
|
4196
|
+
const messageSettings = this.getMessageSettings();
|
|
4197
|
+
const actions = messageSettings?.fileActions?.length
|
|
4198
|
+
? messageSettings.fileActions
|
|
4199
|
+
: this.chatService.fileActions || [];
|
|
4200
|
+
return transformActions(actions);
|
|
4201
|
+
}
|
|
4202
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MessageComponent, deps: [{ token: i0.ElementRef }, { token: i1$1.IntlService }, { token: ChatService }, { token: i1.LocalizationService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
4203
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: MessageComponent, isStandalone: true, selector: "kendo-chat-message", inputs: { message: "message", tabbable: "tabbable", authorMessageContentTemplate: "authorMessageContentTemplate", receiverMessageContentTemplate: "receiverMessageContentTemplate", messageContentTemplate: "messageContentTemplate", authorMessageTemplate: "authorMessageTemplate", receiverMessageTemplate: "receiverMessageTemplate", messageTemplate: "messageTemplate", statusTemplate: "statusTemplate", showMessageTime: "showMessageTime", authorId: "authorId" }, host: { listeners: { "keydown": "onKeyDown($event)" }, properties: { "class.k-message": "this.cssClass", "class.k-message-removed": "this.removedClass", "attr.tabIndex": "this.tabIndex" } }, providers: [
|
|
3449
4204
|
{
|
|
3450
4205
|
provide: ChatItem,
|
|
3451
4206
|
useExisting: forwardRef(() => MessageComponent)
|
|
3452
4207
|
}
|
|
3453
4208
|
], usesInheritance: true, ngImport: i0, template: `
|
|
3454
|
-
<
|
|
3455
|
-
|
|
3456
|
-
|
|
3457
|
-
*ngIf="message.timestamp"
|
|
3458
|
-
>
|
|
3459
|
-
{{ formatTimeStamp(message.timestamp) }}
|
|
3460
|
-
</time>
|
|
3461
|
-
|
|
3462
|
-
<ng-container *ngIf="!message.typing; else typing">
|
|
3463
|
-
<div
|
|
3464
|
-
class="k-chat-bubble k-bubble"
|
|
3465
|
-
*ngIf="template"
|
|
3466
|
-
[attr.tabindex]="0"
|
|
3467
|
-
[ngClass]="{
|
|
3468
|
-
'k-selected': selected,
|
|
3469
|
-
'k-focus': selected,
|
|
3470
|
-
'k-active': active
|
|
3471
|
-
}"
|
|
3472
|
-
>
|
|
3473
|
-
<div class="k-bubble-content">
|
|
3474
|
-
<ng-container
|
|
3475
|
-
*ngTemplateOutlet="template.templateRef; context: { $implicit: message };"
|
|
3476
|
-
>
|
|
3477
|
-
</ng-container>
|
|
3478
|
-
</div>
|
|
3479
|
-
</div>
|
|
4209
|
+
<ng-container *ngIf="useCustomBubbleTemplate">
|
|
4210
|
+
<ng-container *ngTemplateOutlet="getActiveBubbleTemplate()?.templateRef; context: { $implicit: message };"></ng-container>
|
|
4211
|
+
</ng-container>
|
|
3480
4212
|
|
|
3481
|
-
|
|
3482
|
-
|
|
3483
|
-
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
'k-bubble-expandable': chatService.allowMessageCollapse,
|
|
3487
|
-
'k-expanded': isMessageExpanded,
|
|
3488
|
-
'k-selected': selected,
|
|
3489
|
-
'k-focus': selected,
|
|
3490
|
-
'k-active': active
|
|
3491
|
-
}"
|
|
4213
|
+
<ng-container *ngIf="!useCustomBubbleTemplate">
|
|
4214
|
+
<time
|
|
4215
|
+
[attr.aria-hidden]="!selected"
|
|
4216
|
+
class="k-message-time"
|
|
4217
|
+
*ngIf="message.timestamp"
|
|
3492
4218
|
>
|
|
3493
|
-
|
|
3494
|
-
|
|
3495
|
-
|
|
3496
|
-
|
|
3497
|
-
|
|
3498
|
-
|
|
3499
|
-
<
|
|
3500
|
-
<
|
|
3501
|
-
|
|
3502
|
-
<ng-container *ngIf="part.type === 'text'">{{part.content}}</ng-container>
|
|
3503
|
-
<a *ngIf="part.type === 'link'" [href]="part.href" target="_blank">{{part.content}}</a>
|
|
3504
|
-
</ng-container>
|
|
3505
|
-
</ng-container>
|
|
3506
|
-
</span>
|
|
3507
|
-
<ul class="k-chat-file-wrapper" *ngIf="message.files && message.files.length > 0">
|
|
3508
|
-
<li
|
|
3509
|
-
*ngFor="let file of message.files"
|
|
3510
|
-
class="k-chat-file"
|
|
3511
|
-
[chatFile]="file"
|
|
3512
|
-
[fileActions]="fileActions"
|
|
3513
|
-
(actionClick)="onFileAction($event, file)"
|
|
3514
|
-
(actionsToggle)="onActionPopupChange($event)"
|
|
3515
|
-
(actionButtonClick)="onActionButtonClick($event)"
|
|
3516
|
-
></li>
|
|
3517
|
-
</ul>
|
|
3518
|
-
<div class="k-chat-download-button-wrapper" *ngIf="message.files?.length > 1">
|
|
3519
|
-
<button
|
|
3520
|
-
kendoButton
|
|
3521
|
-
class="k-chat-download-button"
|
|
3522
|
-
fillMode="flat"
|
|
3523
|
-
icon="download"
|
|
3524
|
-
[svgIcon]="downloadIcon"
|
|
3525
|
-
(click)="onDownloadAll()"
|
|
3526
|
-
>{{ textFor('downloadAllFilesText') }}</button>
|
|
4219
|
+
{{ formatTimeStamp(message.timestamp) }}
|
|
4220
|
+
</time>
|
|
4221
|
+
|
|
4222
|
+
<ng-container *ngIf="message.typing">
|
|
4223
|
+
<div class="k-chat-bubble k-bubble">
|
|
4224
|
+
<div class="k-typing-indicator" [attr.tabindex]="'-1'">
|
|
4225
|
+
<span></span>
|
|
4226
|
+
<span></span>
|
|
4227
|
+
<span></span>
|
|
3527
4228
|
</div>
|
|
3528
4229
|
</div>
|
|
3529
|
-
|
|
3530
|
-
|
|
3531
|
-
|
|
3532
|
-
|
|
3533
|
-
|
|
3534
|
-
|
|
3535
|
-
|
|
4230
|
+
</ng-container>
|
|
4231
|
+
|
|
4232
|
+
<ng-container *ngIf="!message.typing">
|
|
4233
|
+
<div
|
|
4234
|
+
class="k-chat-bubble k-bubble"
|
|
4235
|
+
*ngIf="useCustomContentTemplate"
|
|
4236
|
+
[attr.tabindex]="0"
|
|
4237
|
+
[ngClass]="{
|
|
4238
|
+
'k-bubble-expandable': isMessageExpandable,
|
|
4239
|
+
'k-expanded': isMessageExpanded,
|
|
4240
|
+
'k-selected': selected,
|
|
4241
|
+
'k-focus': selected,
|
|
4242
|
+
'k-active': isActiveMessage
|
|
4243
|
+
}"
|
|
3536
4244
|
>
|
|
3537
|
-
<
|
|
3538
|
-
|
|
3539
|
-
|
|
4245
|
+
<div class="k-bubble-content">
|
|
4246
|
+
<ng-container *ngTemplateOutlet="getActiveContentTemplate()?.templateRef; context: { $implicit: message };"></ng-container>
|
|
4247
|
+
</div>
|
|
4248
|
+
<span
|
|
4249
|
+
class="k-bubble-expandable-indicator"
|
|
4250
|
+
*ngIf="isMessageExpandable && showExpandCollapseIcon"
|
|
4251
|
+
[attr.tabindex]="'0'"
|
|
4252
|
+
[attr.role]="'button'"
|
|
4253
|
+
[attr.title]="isMessageExpanded ? textFor('collapseTitle') : textFor('expandTitle')"
|
|
4254
|
+
(mousedown)="chatService.toggleMessageState = true"
|
|
4255
|
+
(click)="toggleMessageState($event)"
|
|
3540
4256
|
>
|
|
3541
|
-
|
|
3542
|
-
|
|
3543
|
-
|
|
3544
|
-
|
|
4257
|
+
<kendo-icon-wrapper
|
|
4258
|
+
[name]="isMessageExpanded ? 'chevron-up' : 'chevron-down'"
|
|
4259
|
+
[svgIcon]="isMessageExpanded ? collapseIcon : expandIcon"
|
|
4260
|
+
>
|
|
4261
|
+
</kendo-icon-wrapper>
|
|
4262
|
+
</span>
|
|
4263
|
+
</div>
|
|
3545
4264
|
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
|
|
3553
|
-
|
|
4265
|
+
<div
|
|
4266
|
+
class="k-chat-bubble k-bubble"
|
|
4267
|
+
*ngIf="!useCustomContentTemplate && hasMessageContent"
|
|
4268
|
+
[attr.tabindex]="0"
|
|
4269
|
+
[ngClass]="{
|
|
4270
|
+
'k-bubble-expandable': isMessageExpandable,
|
|
4271
|
+
'k-expanded': isMessageExpanded,
|
|
4272
|
+
'k-selected': selected,
|
|
4273
|
+
'k-focus': selected,
|
|
4274
|
+
'k-active': isActiveMessage
|
|
4275
|
+
}"
|
|
3554
4276
|
>
|
|
3555
|
-
|
|
3556
|
-
|
|
3557
|
-
|
|
3558
|
-
|
|
4277
|
+
<div class="k-bubble-content">
|
|
4278
|
+
<ng-container *ngIf="message.text || message.isDeleted">
|
|
4279
|
+
<div
|
|
4280
|
+
class="k-message-reference k-message-reference-receiver"
|
|
4281
|
+
*ngIf="message.replyToId && !message.isDeleted"
|
|
4282
|
+
(click)="onReplyReferenceClick($event, message.replyToId)"
|
|
4283
|
+
>
|
|
4284
|
+
<chat-message-reference-content [message]="getMessageById(message.replyToId)"></chat-message-reference-content>
|
|
4285
|
+
</div>
|
|
4286
|
+
|
|
4287
|
+
<span class="k-chat-bubble-text" *ngIf="message.isDeleted">
|
|
4288
|
+
{{ getDeletedMessageText() }}
|
|
4289
|
+
</span>
|
|
4290
|
+
|
|
4291
|
+
<span class="k-chat-bubble-text" *ngIf="!message.isDeleted && parts.length > 0">
|
|
4292
|
+
<ng-container *ngFor="let part of parts">
|
|
4293
|
+
<ng-container *ngIf="part.type === 'text'">{{part.content}}</ng-container>
|
|
4294
|
+
<a *ngIf="part.type === 'link'" [href]="part.href" target="_blank">{{part.content}}</a>
|
|
4295
|
+
</ng-container>
|
|
4296
|
+
</span>
|
|
4297
|
+
</ng-container>
|
|
4298
|
+
|
|
4299
|
+
<ul
|
|
4300
|
+
class="k-chat-file-wrapper"
|
|
4301
|
+
*ngIf="hasFiles && !message.isDeleted"
|
|
4302
|
+
[ngClass]="{
|
|
4303
|
+
'k-chat-files-wrap': chatService.messageFilesLayout === 'wrap',
|
|
4304
|
+
'k-chat-files-horizontal': chatService.messageFilesLayout === 'horizontal'
|
|
4305
|
+
}"
|
|
4306
|
+
>
|
|
4307
|
+
<li
|
|
4308
|
+
*ngFor="let file of message.files"
|
|
4309
|
+
class="k-chat-file"
|
|
4310
|
+
[chatFile]="file"
|
|
4311
|
+
[fileActions]="fileActions"
|
|
4312
|
+
(actionClick)="onFileAction($event, file)"
|
|
4313
|
+
(actionsToggle)="onActionPopupChange($event)"
|
|
4314
|
+
(actionButtonClick)="onActionButtonClick($event)"
|
|
4315
|
+
></li>
|
|
4316
|
+
</ul>
|
|
4317
|
+
|
|
4318
|
+
<div class="k-chat-download-button-wrapper" *ngIf="hasMultipleFiles && !message.isDeleted">
|
|
4319
|
+
<button
|
|
4320
|
+
kendoButton
|
|
4321
|
+
class="k-chat-download-button"
|
|
4322
|
+
fillMode="flat"
|
|
4323
|
+
icon="download"
|
|
4324
|
+
[svgIcon]="downloadIcon"
|
|
4325
|
+
[attr.title]="textFor('downloadAllFilesText')"
|
|
4326
|
+
(click)="onDownloadAll()"
|
|
4327
|
+
>{{ textFor('downloadAllFilesText') }}</button>
|
|
4328
|
+
</div>
|
|
4329
|
+
</div>
|
|
4330
|
+
|
|
4331
|
+
<span
|
|
4332
|
+
class="k-bubble-expandable-indicator"
|
|
4333
|
+
*ngIf="isMessageExpandable && showExpandCollapseIcon"
|
|
4334
|
+
[attr.tabindex]="'0'"
|
|
4335
|
+
[attr.role]="'button'"
|
|
4336
|
+
[attr.title]="isMessageExpanded ? textFor('collapseTitle') : textFor('expandTitle')"
|
|
4337
|
+
(mousedown)="chatService.toggleMessageState = true"
|
|
4338
|
+
(click)="toggleMessageState($event)"
|
|
4339
|
+
>
|
|
4340
|
+
<kendo-icon-wrapper
|
|
4341
|
+
[name]="isMessageExpanded ? 'chevron-up' : 'chevron-down'"
|
|
4342
|
+
[svgIcon]="isMessageExpanded ? collapseIcon : expandIcon"
|
|
4343
|
+
>
|
|
4344
|
+
</kendo-icon-wrapper>
|
|
4345
|
+
</span>
|
|
4346
|
+
</div>
|
|
3559
4347
|
</ng-container>
|
|
3560
|
-
</span>
|
|
3561
4348
|
|
|
3562
|
-
|
|
4349
|
+
<span class="k-message-status" *ngIf="message.status">
|
|
4350
|
+
<ng-container *ngIf="statusTemplate?.templateRef">
|
|
4351
|
+
<ng-template
|
|
4352
|
+
[ngTemplateOutlet]="statusTemplate.templateRef"
|
|
4353
|
+
[ngTemplateOutletContext]="{ $implicit: message.status, message }"
|
|
4354
|
+
>
|
|
4355
|
+
</ng-template>
|
|
4356
|
+
</ng-container>
|
|
4357
|
+
<ng-container *ngIf="!statusTemplate?.templateRef">
|
|
4358
|
+
{{ message.status }}
|
|
4359
|
+
</ng-container>
|
|
4360
|
+
</span>
|
|
4361
|
+
</ng-container>
|
|
4362
|
+
<kendo-toolbar *ngIf="showToolbar" class="k-chat-message-toolbar" fillMode="flat">
|
|
3563
4363
|
<kendo-toolbar-button
|
|
3564
|
-
*ngFor="let action of
|
|
4364
|
+
*ngFor="let action of toolbarActions"
|
|
3565
4365
|
fillMode="flat"
|
|
3566
4366
|
[icon]="action.icon"
|
|
3567
4367
|
[svgIcon]="action.svgIcon"
|
|
@@ -3571,28 +4371,7 @@ class MessageComponent extends ChatItem {
|
|
|
3571
4371
|
>
|
|
3572
4372
|
</kendo-toolbar-button>
|
|
3573
4373
|
</kendo-toolbar>
|
|
3574
|
-
|
|
3575
|
-
<ng-template #typing>
|
|
3576
|
-
<div class="k-chat-bubble k-bubble">
|
|
3577
|
-
<div class="k-typing-indicator">
|
|
3578
|
-
<span></span>
|
|
3579
|
-
<span></span>
|
|
3580
|
-
<span></span>
|
|
3581
|
-
</div>
|
|
3582
|
-
</div>
|
|
3583
|
-
</ng-template>
|
|
3584
|
-
|
|
3585
|
-
<kendo-contextmenu
|
|
3586
|
-
*ngIf="!message.isDeleted"
|
|
3587
|
-
[target]="element"
|
|
3588
|
-
[items]="contextMenuActions"
|
|
3589
|
-
(popupOpen)="handleMenuOpen()"
|
|
3590
|
-
(popupClose)="handleMenuClose($event)"
|
|
3591
|
-
(select)="onContextMenuAction($event.item.originalAction)"
|
|
3592
|
-
[popupAlign]="{ horizontal: 'right', vertical: 'top' }"
|
|
3593
|
-
[collision]="{ horizontal: 'flip', vertical: 'flip'}"
|
|
3594
|
-
></kendo-contextmenu>
|
|
3595
|
-
`, isInline: true, dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: IconWrapperComponent, selector: "kendo-icon-wrapper", inputs: ["name", "svgIcon", "innerCssClass", "customFontClass", "size"], exportAs: ["kendoIconWrapper"] }, { kind: "component", type: i2.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "component", type: ChatFileComponent, selector: "li[chatFile]", inputs: ["chatFile", "removable", "fileActions"], outputs: ["remove", "actionClick", "actionsToggle", "actionButtonClick"] }, { kind: "component", type: ContextMenuComponent, selector: "kendo-contextmenu", inputs: ["showOn", "target", "filter", "alignToAnchor", "vertical", "popupAnimate", "popupAlign", "anchorAlign", "collision", "appendTo", "ariaLabel"], outputs: ["popupOpen", "popupClose", "select", "open", "close"], exportAs: ["kendoContextMenu"] }, { kind: "component", type: ToolBarComponent, selector: "kendo-toolbar", inputs: ["overflow", "resizable", "popupSettings", "fillMode", "tabindex", "size", "tabIndex", "showIcon", "showText"], outputs: ["open", "close"], exportAs: ["kendoToolBar"] }, { kind: "component", type: ToolBarButtonComponent, selector: "kendo-toolbar-button", inputs: ["showText", "showIcon", "text", "style", "className", "title", "disabled", "toggleable", "look", "togglable", "selected", "fillMode", "rounded", "themeColor", "icon", "iconClass", "svgIcon", "imageUrl"], outputs: ["click", "pointerdown", "selectedChange"], exportAs: ["kendoToolBarButton"] }, { kind: "component", type: MessageReferenceComponent, selector: "chat-message-reference-content", inputs: ["message"] }] });
|
|
4374
|
+
`, isInline: true, dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: IconWrapperComponent, selector: "kendo-icon-wrapper", inputs: ["name", "svgIcon", "innerCssClass", "customFontClass", "size"], exportAs: ["kendoIconWrapper"] }, { kind: "component", type: i2.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "component", type: ChatFileComponent, selector: "li[chatFile]", inputs: ["chatFile", "removable", "fileActions"], outputs: ["remove", "actionClick", "actionsToggle", "actionButtonClick"] }, { kind: "component", type: ToolBarComponent, selector: "kendo-toolbar", inputs: ["overflow", "resizable", "popupSettings", "fillMode", "tabindex", "size", "tabIndex", "showIcon", "showText"], outputs: ["open", "close"], exportAs: ["kendoToolBar"] }, { kind: "component", type: ToolBarButtonComponent, selector: "kendo-toolbar-button", inputs: ["showText", "showIcon", "text", "style", "className", "title", "disabled", "toggleable", "look", "togglable", "selected", "fillMode", "rounded", "themeColor", "icon", "iconClass", "svgIcon", "imageUrl"], outputs: ["click", "pointerdown", "selectedChange"], exportAs: ["kendoToolBarButton"] }, { kind: "component", type: MessageReferenceComponent, selector: "chat-message-reference-content", inputs: ["message"] }] });
|
|
3596
4375
|
}
|
|
3597
4376
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MessageComponent, decorators: [{
|
|
3598
4377
|
type: Component,
|
|
@@ -3605,117 +4384,162 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
3605
4384
|
}
|
|
3606
4385
|
],
|
|
3607
4386
|
template: `
|
|
3608
|
-
<
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
*ngIf="message.timestamp"
|
|
3612
|
-
>
|
|
3613
|
-
{{ formatTimeStamp(message.timestamp) }}
|
|
3614
|
-
</time>
|
|
4387
|
+
<ng-container *ngIf="useCustomBubbleTemplate">
|
|
4388
|
+
<ng-container *ngTemplateOutlet="getActiveBubbleTemplate()?.templateRef; context: { $implicit: message };"></ng-container>
|
|
4389
|
+
</ng-container>
|
|
3615
4390
|
|
|
3616
|
-
<ng-container *ngIf="!
|
|
3617
|
-
<
|
|
3618
|
-
|
|
3619
|
-
|
|
3620
|
-
|
|
3621
|
-
[ngClass]="{
|
|
3622
|
-
'k-selected': selected,
|
|
3623
|
-
'k-focus': selected,
|
|
3624
|
-
'k-active': active
|
|
3625
|
-
}"
|
|
4391
|
+
<ng-container *ngIf="!useCustomBubbleTemplate">
|
|
4392
|
+
<time
|
|
4393
|
+
[attr.aria-hidden]="!selected"
|
|
4394
|
+
class="k-message-time"
|
|
4395
|
+
*ngIf="message.timestamp"
|
|
3626
4396
|
>
|
|
3627
|
-
|
|
3628
|
-
|
|
3629
|
-
|
|
4397
|
+
{{ formatTimeStamp(message.timestamp) }}
|
|
4398
|
+
</time>
|
|
4399
|
+
|
|
4400
|
+
<ng-container *ngIf="message.typing">
|
|
4401
|
+
<div class="k-chat-bubble k-bubble">
|
|
4402
|
+
<div class="k-typing-indicator" [attr.tabindex]="'-1'">
|
|
4403
|
+
<span></span>
|
|
4404
|
+
<span></span>
|
|
4405
|
+
<span></span>
|
|
4406
|
+
</div>
|
|
4407
|
+
</div>
|
|
4408
|
+
</ng-container>
|
|
4409
|
+
|
|
4410
|
+
<ng-container *ngIf="!message.typing">
|
|
4411
|
+
<div
|
|
4412
|
+
class="k-chat-bubble k-bubble"
|
|
4413
|
+
*ngIf="useCustomContentTemplate"
|
|
4414
|
+
[attr.tabindex]="0"
|
|
4415
|
+
[ngClass]="{
|
|
4416
|
+
'k-bubble-expandable': isMessageExpandable,
|
|
4417
|
+
'k-expanded': isMessageExpanded,
|
|
4418
|
+
'k-selected': selected,
|
|
4419
|
+
'k-focus': selected,
|
|
4420
|
+
'k-active': isActiveMessage
|
|
4421
|
+
}"
|
|
4422
|
+
>
|
|
4423
|
+
<div class="k-bubble-content">
|
|
4424
|
+
<ng-container *ngTemplateOutlet="getActiveContentTemplate()?.templateRef; context: { $implicit: message };"></ng-container>
|
|
4425
|
+
</div>
|
|
4426
|
+
<span
|
|
4427
|
+
class="k-bubble-expandable-indicator"
|
|
4428
|
+
*ngIf="isMessageExpandable && showExpandCollapseIcon"
|
|
4429
|
+
[attr.tabindex]="'0'"
|
|
4430
|
+
[attr.role]="'button'"
|
|
4431
|
+
[attr.title]="isMessageExpanded ? textFor('collapseTitle') : textFor('expandTitle')"
|
|
4432
|
+
(mousedown)="chatService.toggleMessageState = true"
|
|
4433
|
+
(click)="toggleMessageState($event)"
|
|
3630
4434
|
>
|
|
3631
|
-
|
|
4435
|
+
<kendo-icon-wrapper
|
|
4436
|
+
[name]="isMessageExpanded ? 'chevron-up' : 'chevron-down'"
|
|
4437
|
+
[svgIcon]="isMessageExpanded ? collapseIcon : expandIcon"
|
|
4438
|
+
>
|
|
4439
|
+
</kendo-icon-wrapper>
|
|
4440
|
+
</span>
|
|
3632
4441
|
</div>
|
|
3633
|
-
</div>
|
|
3634
4442
|
|
|
3635
|
-
|
|
3636
|
-
|
|
3637
|
-
|
|
3638
|
-
|
|
3639
|
-
|
|
3640
|
-
|
|
3641
|
-
|
|
3642
|
-
|
|
3643
|
-
|
|
3644
|
-
|
|
3645
|
-
|
|
3646
|
-
|
|
3647
|
-
|
|
3648
|
-
|
|
3649
|
-
|
|
3650
|
-
|
|
4443
|
+
<div
|
|
4444
|
+
class="k-chat-bubble k-bubble"
|
|
4445
|
+
*ngIf="!useCustomContentTemplate && hasMessageContent"
|
|
4446
|
+
[attr.tabindex]="0"
|
|
4447
|
+
[ngClass]="{
|
|
4448
|
+
'k-bubble-expandable': isMessageExpandable,
|
|
4449
|
+
'k-expanded': isMessageExpanded,
|
|
4450
|
+
'k-selected': selected,
|
|
4451
|
+
'k-focus': selected,
|
|
4452
|
+
'k-active': isActiveMessage
|
|
4453
|
+
}"
|
|
4454
|
+
>
|
|
4455
|
+
<div class="k-bubble-content">
|
|
4456
|
+
<ng-container *ngIf="message.text || message.isDeleted">
|
|
4457
|
+
<div
|
|
4458
|
+
class="k-message-reference k-message-reference-receiver"
|
|
4459
|
+
*ngIf="message.replyToId && !message.isDeleted"
|
|
4460
|
+
(click)="onReplyReferenceClick($event, message.replyToId)"
|
|
4461
|
+
>
|
|
4462
|
+
<chat-message-reference-content [message]="getMessageById(message.replyToId)"></chat-message-reference-content>
|
|
4463
|
+
</div>
|
|
4464
|
+
|
|
4465
|
+
<span class="k-chat-bubble-text" *ngIf="message.isDeleted">
|
|
4466
|
+
{{ getDeletedMessageText() }}
|
|
4467
|
+
</span>
|
|
4468
|
+
|
|
4469
|
+
<span class="k-chat-bubble-text" *ngIf="!message.isDeleted && parts.length > 0">
|
|
4470
|
+
<ng-container *ngFor="let part of parts">
|
|
4471
|
+
<ng-container *ngIf="part.type === 'text'">{{part.content}}</ng-container>
|
|
4472
|
+
<a *ngIf="part.type === 'link'" [href]="part.href" target="_blank">{{part.content}}</a>
|
|
4473
|
+
</ng-container>
|
|
4474
|
+
</span>
|
|
4475
|
+
</ng-container>
|
|
4476
|
+
|
|
4477
|
+
<ul
|
|
4478
|
+
class="k-chat-file-wrapper"
|
|
4479
|
+
*ngIf="hasFiles && !message.isDeleted"
|
|
4480
|
+
[ngClass]="{
|
|
4481
|
+
'k-chat-files-wrap': chatService.messageFilesLayout === 'wrap',
|
|
4482
|
+
'k-chat-files-horizontal': chatService.messageFilesLayout === 'horizontal'
|
|
4483
|
+
}"
|
|
4484
|
+
>
|
|
4485
|
+
<li
|
|
4486
|
+
*ngFor="let file of message.files"
|
|
4487
|
+
class="k-chat-file"
|
|
4488
|
+
[chatFile]="file"
|
|
4489
|
+
[fileActions]="fileActions"
|
|
4490
|
+
(actionClick)="onFileAction($event, file)"
|
|
4491
|
+
(actionsToggle)="onActionPopupChange($event)"
|
|
4492
|
+
(actionButtonClick)="onActionButtonClick($event)"
|
|
4493
|
+
></li>
|
|
4494
|
+
</ul>
|
|
4495
|
+
|
|
4496
|
+
<div class="k-chat-download-button-wrapper" *ngIf="hasMultipleFiles && !message.isDeleted">
|
|
4497
|
+
<button
|
|
4498
|
+
kendoButton
|
|
4499
|
+
class="k-chat-download-button"
|
|
4500
|
+
fillMode="flat"
|
|
4501
|
+
icon="download"
|
|
4502
|
+
[svgIcon]="downloadIcon"
|
|
4503
|
+
[attr.title]="textFor('downloadAllFilesText')"
|
|
4504
|
+
(click)="onDownloadAll()"
|
|
4505
|
+
>{{ textFor('downloadAllFilesText') }}</button>
|
|
3651
4506
|
</div>
|
|
3652
|
-
<ng-container *ngIf="message.isDeleted && isOwnMessage(message)">{{ textFor('deletedMessageSenderText') }}</ng-container>
|
|
3653
|
-
<ng-container *ngIf="message.isDeleted && !isOwnMessage(message)">{{ textFor('deletedMessageReceiverText') }}</ng-container>
|
|
3654
|
-
<ng-container *ngIf="!message.isDeleted && parts.length">
|
|
3655
|
-
<ng-container *ngFor="let part of parts">
|
|
3656
|
-
<ng-container *ngIf="part.type === 'text'">{{part.content}}</ng-container>
|
|
3657
|
-
<a *ngIf="part.type === 'link'" [href]="part.href" target="_blank">{{part.content}}</a>
|
|
3658
|
-
</ng-container>
|
|
3659
|
-
</ng-container>
|
|
3660
|
-
</span>
|
|
3661
|
-
<ul class="k-chat-file-wrapper" *ngIf="message.files && message.files.length > 0">
|
|
3662
|
-
<li
|
|
3663
|
-
*ngFor="let file of message.files"
|
|
3664
|
-
class="k-chat-file"
|
|
3665
|
-
[chatFile]="file"
|
|
3666
|
-
[fileActions]="fileActions"
|
|
3667
|
-
(actionClick)="onFileAction($event, file)"
|
|
3668
|
-
(actionsToggle)="onActionPopupChange($event)"
|
|
3669
|
-
(actionButtonClick)="onActionButtonClick($event)"
|
|
3670
|
-
></li>
|
|
3671
|
-
</ul>
|
|
3672
|
-
<div class="k-chat-download-button-wrapper" *ngIf="message.files?.length > 1">
|
|
3673
|
-
<button
|
|
3674
|
-
kendoButton
|
|
3675
|
-
class="k-chat-download-button"
|
|
3676
|
-
fillMode="flat"
|
|
3677
|
-
icon="download"
|
|
3678
|
-
[svgIcon]="downloadIcon"
|
|
3679
|
-
(click)="onDownloadAll()"
|
|
3680
|
-
>{{ textFor('downloadAllFilesText') }}</button>
|
|
3681
4507
|
</div>
|
|
3682
|
-
</div>
|
|
3683
|
-
<span
|
|
3684
|
-
class="k-bubble-expandable-indicator"
|
|
3685
|
-
*ngIf="chatService.allowMessageCollapse"
|
|
3686
|
-
[attr.role]="'button'"
|
|
3687
|
-
[attr.title]="isMessageExpanded ? textFor('collapseTitle') : textFor('expandTitle')"
|
|
3688
|
-
(mousedown)="chatService.toggleMessageState = true"
|
|
3689
|
-
(click)="toggleMessageState($event)"
|
|
3690
|
-
>
|
|
3691
|
-
<kendo-icon-wrapper
|
|
3692
|
-
[name]="isMessageExpanded ? 'chevron-up' : 'chevron-down'"
|
|
3693
|
-
[svgIcon]="isMessageExpanded ? collapseIcon : expandIcon"
|
|
3694
|
-
>
|
|
3695
|
-
</kendo-icon-wrapper>
|
|
3696
|
-
</span>
|
|
3697
|
-
</div>
|
|
3698
|
-
</ng-container>
|
|
3699
4508
|
|
|
3700
|
-
|
|
3701
|
-
|
|
3702
|
-
|
|
3703
|
-
|
|
3704
|
-
|
|
3705
|
-
|
|
3706
|
-
|
|
3707
|
-
|
|
3708
|
-
|
|
3709
|
-
|
|
3710
|
-
|
|
3711
|
-
|
|
3712
|
-
|
|
4509
|
+
<span
|
|
4510
|
+
class="k-bubble-expandable-indicator"
|
|
4511
|
+
*ngIf="isMessageExpandable && showExpandCollapseIcon"
|
|
4512
|
+
[attr.tabindex]="'0'"
|
|
4513
|
+
[attr.role]="'button'"
|
|
4514
|
+
[attr.title]="isMessageExpanded ? textFor('collapseTitle') : textFor('expandTitle')"
|
|
4515
|
+
(mousedown)="chatService.toggleMessageState = true"
|
|
4516
|
+
(click)="toggleMessageState($event)"
|
|
4517
|
+
>
|
|
4518
|
+
<kendo-icon-wrapper
|
|
4519
|
+
[name]="isMessageExpanded ? 'chevron-up' : 'chevron-down'"
|
|
4520
|
+
[svgIcon]="isMessageExpanded ? collapseIcon : expandIcon"
|
|
4521
|
+
>
|
|
4522
|
+
</kendo-icon-wrapper>
|
|
4523
|
+
</span>
|
|
4524
|
+
</div>
|
|
3713
4525
|
</ng-container>
|
|
3714
|
-
</span>
|
|
3715
4526
|
|
|
3716
|
-
|
|
4527
|
+
<span class="k-message-status" *ngIf="message.status">
|
|
4528
|
+
<ng-container *ngIf="statusTemplate?.templateRef">
|
|
4529
|
+
<ng-template
|
|
4530
|
+
[ngTemplateOutlet]="statusTemplate.templateRef"
|
|
4531
|
+
[ngTemplateOutletContext]="{ $implicit: message.status, message }"
|
|
4532
|
+
>
|
|
4533
|
+
</ng-template>
|
|
4534
|
+
</ng-container>
|
|
4535
|
+
<ng-container *ngIf="!statusTemplate?.templateRef">
|
|
4536
|
+
{{ message.status }}
|
|
4537
|
+
</ng-container>
|
|
4538
|
+
</span>
|
|
4539
|
+
</ng-container>
|
|
4540
|
+
<kendo-toolbar *ngIf="showToolbar" class="k-chat-message-toolbar" fillMode="flat">
|
|
3717
4541
|
<kendo-toolbar-button
|
|
3718
|
-
*ngFor="let action of
|
|
4542
|
+
*ngFor="let action of toolbarActions"
|
|
3719
4543
|
fillMode="flat"
|
|
3720
4544
|
[icon]="action.icon"
|
|
3721
4545
|
[svgIcon]="action.svgIcon"
|
|
@@ -3725,36 +4549,25 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
3725
4549
|
>
|
|
3726
4550
|
</kendo-toolbar-button>
|
|
3727
4551
|
</kendo-toolbar>
|
|
3728
|
-
|
|
3729
|
-
<ng-template #typing>
|
|
3730
|
-
<div class="k-chat-bubble k-bubble">
|
|
3731
|
-
<div class="k-typing-indicator">
|
|
3732
|
-
<span></span>
|
|
3733
|
-
<span></span>
|
|
3734
|
-
<span></span>
|
|
3735
|
-
</div>
|
|
3736
|
-
</div>
|
|
3737
|
-
</ng-template>
|
|
3738
|
-
|
|
3739
|
-
<kendo-contextmenu
|
|
3740
|
-
*ngIf="!message.isDeleted"
|
|
3741
|
-
[target]="element"
|
|
3742
|
-
[items]="contextMenuActions"
|
|
3743
|
-
(popupOpen)="handleMenuOpen()"
|
|
3744
|
-
(popupClose)="handleMenuClose($event)"
|
|
3745
|
-
(select)="onContextMenuAction($event.item.originalAction)"
|
|
3746
|
-
[popupAlign]="{ horizontal: 'right', vertical: 'top' }"
|
|
3747
|
-
[collision]="{ horizontal: 'flip', vertical: 'flip'}"
|
|
3748
|
-
></kendo-contextmenu>
|
|
3749
4552
|
`,
|
|
3750
4553
|
standalone: true,
|
|
3751
|
-
imports: [NgIf, NgClass, NgFor, NgTemplateOutlet, IconWrapperComponent, KENDO_BUTTONS, ChatFileComponent,
|
|
4554
|
+
imports: [NgIf, NgClass, NgFor, NgTemplateOutlet, IconWrapperComponent, KENDO_BUTTONS, ChatFileComponent, ToolBarComponent, ToolBarButtonComponent, MessageReferenceComponent],
|
|
3752
4555
|
}]
|
|
3753
|
-
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i1$1.IntlService }, { type: ChatService }, { type: i1.LocalizationService }], propDecorators: { message: [{
|
|
4556
|
+
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i1$1.IntlService }, { type: ChatService }, { type: i1.LocalizationService }, { type: i0.ChangeDetectorRef }], propDecorators: { message: [{
|
|
3754
4557
|
type: Input
|
|
3755
4558
|
}], tabbable: [{
|
|
3756
4559
|
type: Input
|
|
3757
|
-
}],
|
|
4560
|
+
}], authorMessageContentTemplate: [{
|
|
4561
|
+
type: Input
|
|
4562
|
+
}], receiverMessageContentTemplate: [{
|
|
4563
|
+
type: Input
|
|
4564
|
+
}], messageContentTemplate: [{
|
|
4565
|
+
type: Input
|
|
4566
|
+
}], authorMessageTemplate: [{
|
|
4567
|
+
type: Input
|
|
4568
|
+
}], receiverMessageTemplate: [{
|
|
4569
|
+
type: Input
|
|
4570
|
+
}], messageTemplate: [{
|
|
3758
4571
|
type: Input
|
|
3759
4572
|
}], statusTemplate: [{
|
|
3760
4573
|
type: Input
|
|
@@ -3762,8 +4575,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
3762
4575
|
type: Input
|
|
3763
4576
|
}], authorId: [{
|
|
3764
4577
|
type: Input
|
|
3765
|
-
}], contextMenuVisibilityChange: [{
|
|
3766
|
-
type: Output
|
|
3767
4578
|
}], cssClass: [{
|
|
3768
4579
|
type: HostBinding,
|
|
3769
4580
|
args: ['class.k-message']
|
|
@@ -3776,9 +4587,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
3776
4587
|
}], tabIndex: [{
|
|
3777
4588
|
type: HostBinding,
|
|
3778
4589
|
args: ['attr.tabIndex']
|
|
3779
|
-
}], onContextMenu: [{
|
|
3780
|
-
type: HostListener,
|
|
3781
|
-
args: ['contextmenu', ['$event']]
|
|
3782
4590
|
}] } });
|
|
3783
4591
|
|
|
3784
4592
|
/**
|
|
@@ -3894,10 +4702,10 @@ class MessageAttachmentsComponent extends ChatItem {
|
|
|
3894
4702
|
scrollSubscription;
|
|
3895
4703
|
direction;
|
|
3896
4704
|
get showLeftArrow() {
|
|
3897
|
-
return this.carousel && this.direction === 'rtl' ? this.scrollPosition > -1 : this.scrollPosition > 0;
|
|
4705
|
+
return this.carousel && (this.direction === 'rtl' ? this.scrollPosition > -1 : this.scrollPosition > 0);
|
|
3898
4706
|
}
|
|
3899
4707
|
get showRightArrow() {
|
|
3900
|
-
return this.carousel && this.direction === 'rtl' ? this.scrollPosition < 0 : this.scrollPosition < 1;
|
|
4708
|
+
return this.carousel && (this.direction === 'rtl' ? this.scrollPosition < 0 : this.scrollPosition < 1);
|
|
3901
4709
|
}
|
|
3902
4710
|
carouselKeyHandlers = {
|
|
3903
4711
|
[Keys.ArrowLeft]: (e) => this.navigateTo(e, this.direction === 'rtl' ? 1 : -1),
|
|
@@ -4100,6 +4908,39 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
4100
4908
|
args: ['item', { read: ElementRef }]
|
|
4101
4909
|
}] } });
|
|
4102
4910
|
|
|
4911
|
+
/**
|
|
4912
|
+
* Defines a template for displaying user status in the Chat.
|
|
4913
|
+
*
|
|
4914
|
+
* To define a user status template, nest an `<ng-template>` tag with the `kendoChatUserStatusTemplate` directive inside the `<kendo-chat>` component.
|
|
4915
|
+
* For more information, refer to the article on [message templates](slug:message_templates_chat).
|
|
4916
|
+
*
|
|
4917
|
+
* @example
|
|
4918
|
+
* ```html
|
|
4919
|
+
* <kendo-chat>
|
|
4920
|
+
* <ng-template kendoChatUserStatusTemplate let-status>
|
|
4921
|
+
* <div>{{ status }}</div>
|
|
4922
|
+
* </ng-template>
|
|
4923
|
+
* </kendo-chat>
|
|
4924
|
+
* ```
|
|
4925
|
+
*/
|
|
4926
|
+
class ChatUserStatusTemplateDirective {
|
|
4927
|
+
templateRef;
|
|
4928
|
+
constructor(templateRef) {
|
|
4929
|
+
this.templateRef = templateRef;
|
|
4930
|
+
}
|
|
4931
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ChatUserStatusTemplateDirective, deps: [{ token: i0.TemplateRef, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
|
|
4932
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.14", type: ChatUserStatusTemplateDirective, isStandalone: true, selector: "[kendoChatUserStatusTemplate]", ngImport: i0 });
|
|
4933
|
+
}
|
|
4934
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ChatUserStatusTemplateDirective, decorators: [{
|
|
4935
|
+
type: Directive,
|
|
4936
|
+
args: [{
|
|
4937
|
+
selector: '[kendoChatUserStatusTemplate]',
|
|
4938
|
+
standalone: true
|
|
4939
|
+
}]
|
|
4940
|
+
}], ctorParameters: () => [{ type: i0.TemplateRef, decorators: [{
|
|
4941
|
+
type: Optional
|
|
4942
|
+
}] }] });
|
|
4943
|
+
|
|
4103
4944
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
4104
4945
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
4105
4946
|
/**
|
|
@@ -4120,9 +4961,15 @@ class MessageListComponent {
|
|
|
4120
4961
|
return this._messages;
|
|
4121
4962
|
}
|
|
4122
4963
|
attachmentTemplate;
|
|
4964
|
+
authorMessageContentTemplate;
|
|
4965
|
+
receiverMessageContentTemplate;
|
|
4966
|
+
messageContentTemplate;
|
|
4967
|
+
authorMessageTemplate;
|
|
4968
|
+
receiverMessageTemplate;
|
|
4123
4969
|
messageTemplate;
|
|
4124
4970
|
timestampTemplate;
|
|
4125
4971
|
statusTemplate;
|
|
4972
|
+
userStatusTemplate;
|
|
4126
4973
|
localization;
|
|
4127
4974
|
authorId;
|
|
4128
4975
|
executeAction = new EventEmitter();
|
|
@@ -4140,6 +4987,7 @@ class MessageListComponent {
|
|
|
4140
4987
|
[Keys.ArrowUp]: (e) => this.navigateTo(e, -1),
|
|
4141
4988
|
[Keys.ArrowDown]: (e) => this.navigateTo(e, 1),
|
|
4142
4989
|
[Keys.Tab]: (e) => this.onTabKeyDown(e),
|
|
4990
|
+
[Keys.F10]: (e) => e.shiftKey && this.openContextMenu(e),
|
|
4143
4991
|
};
|
|
4144
4992
|
constructor(element, intl, renderer, chatService, cdr) {
|
|
4145
4993
|
this.element = element;
|
|
@@ -4152,9 +5000,25 @@ class MessageListComponent {
|
|
|
4152
5000
|
const elRef = this.element.nativeElement;
|
|
4153
5001
|
this.subs.add(this.renderer.listen(elRef, 'keydown', event => this.onKeydown(event)));
|
|
4154
5002
|
this.subs.add(this.renderer.listen(elRef, 'focusout', event => this.onBlur(event)));
|
|
5003
|
+
this.subs.add(this.renderer.listen(elRef, 'click', event => {
|
|
5004
|
+
const messageComponent = this.findMessageComponentFromEvent(event);
|
|
5005
|
+
if (messageComponent) {
|
|
5006
|
+
this.select(messageComponent, event);
|
|
5007
|
+
}
|
|
5008
|
+
}));
|
|
5009
|
+
this.subs.add(this.renderer.listen(elRef, 'contextmenu', event => {
|
|
5010
|
+
event.preventDefault();
|
|
5011
|
+
const messageComponent = this.findMessageComponentFromEvent(event);
|
|
5012
|
+
if (messageComponent) {
|
|
5013
|
+
this.onContextMenuClick(messageComponent.message, event, messageComponent);
|
|
5014
|
+
}
|
|
5015
|
+
}));
|
|
4155
5016
|
this.subs.add(this.chatService.replyReferenceClick$.subscribe((messageId) => {
|
|
4156
5017
|
this.scrollToAndSelectMessage(messageId);
|
|
4157
5018
|
}));
|
|
5019
|
+
this.subs.add(this.chatService.contextMenuVisibilityChange$.subscribe((isVisible) => {
|
|
5020
|
+
this.handleMenuClose(isVisible);
|
|
5021
|
+
}));
|
|
4158
5022
|
}
|
|
4159
5023
|
ngAfterViewInit() {
|
|
4160
5024
|
this.selectedItem = this.items.last;
|
|
@@ -4168,9 +5032,31 @@ class MessageListComponent {
|
|
|
4168
5032
|
onClick(message, event) {
|
|
4169
5033
|
this.select(message, event);
|
|
4170
5034
|
}
|
|
5035
|
+
onContextMenuClick(message, event, messageElement) {
|
|
5036
|
+
this.chatService.calculateContextMenuActions(this.isOwnMessage(message));
|
|
5037
|
+
if (this.chatService.calculatedContextMenuActions.length > 0) {
|
|
5038
|
+
this.chatService.messagesContextMenu.show({
|
|
5039
|
+
left: event.pageX,
|
|
5040
|
+
top: event.pageY,
|
|
5041
|
+
});
|
|
5042
|
+
this.chatService.activeMessageElement = messageElement;
|
|
5043
|
+
this.chatService.activeMessage = message;
|
|
5044
|
+
this.chatService.active = true;
|
|
5045
|
+
this.chatService.selectOnMenuClose = this.chatService.activeMessageElement?.selected;
|
|
5046
|
+
this.chatService.emit('contextMenuVisibilityChange', true);
|
|
5047
|
+
}
|
|
5048
|
+
}
|
|
4171
5049
|
formatTimeStamp(date) {
|
|
4172
5050
|
return this.intl.formatDate(date, { date: 'full' });
|
|
4173
5051
|
}
|
|
5052
|
+
calculateMessageWidthMode(message) {
|
|
5053
|
+
const isOwn = this.isOwnMessage(message);
|
|
5054
|
+
const messageSettings = isOwn ? this.chatService.authorMessageSettings : this.chatService.receiverMessageSettings;
|
|
5055
|
+
if (messageSettings?.messageWidthMode) {
|
|
5056
|
+
return messageSettings.messageWidthMode === 'full';
|
|
5057
|
+
}
|
|
5058
|
+
return this.chatService.messageWidthMode === 'full';
|
|
5059
|
+
}
|
|
4174
5060
|
onKeydown(e) {
|
|
4175
5061
|
// On some keyboards Numpad keys are used for Home/End/PageUp/PageDown.
|
|
4176
5062
|
const code = normalizeNumpadKeys(e);
|
|
@@ -4230,6 +5116,9 @@ class MessageListComponent {
|
|
|
4230
5116
|
this.select(null);
|
|
4231
5117
|
}
|
|
4232
5118
|
}
|
|
5119
|
+
textFor(key) {
|
|
5120
|
+
return this.localization.get(key);
|
|
5121
|
+
}
|
|
4233
5122
|
onHomeOrEndKeyDown(key) {
|
|
4234
5123
|
const items = this.items.toArray();
|
|
4235
5124
|
if (key === 'home') {
|
|
@@ -4276,11 +5165,49 @@ class MessageListComponent {
|
|
|
4276
5165
|
this.select(chatItem);
|
|
4277
5166
|
}
|
|
4278
5167
|
}
|
|
4279
|
-
|
|
4280
|
-
|
|
5168
|
+
openContextMenu(event) {
|
|
5169
|
+
event.preventDefault();
|
|
5170
|
+
const messageComponent = this.findMessageComponentFromActiveElement();
|
|
5171
|
+
if (messageComponent) {
|
|
5172
|
+
const messageContentElement = messageComponent.element.nativeElement.querySelector('.k-chat-bubble');
|
|
5173
|
+
if (messageContentElement) {
|
|
5174
|
+
const rect = messageContentElement?.getBoundingClientRect();
|
|
5175
|
+
this.onContextMenuClick(messageComponent.message, {
|
|
5176
|
+
pageX: rect.left + (rect.width / 2) + window.scrollX,
|
|
5177
|
+
pageY: rect.top + (rect.height / 2) + window.scrollY
|
|
5178
|
+
}, messageComponent);
|
|
5179
|
+
}
|
|
5180
|
+
else {
|
|
5181
|
+
const messageElement = messageComponent.element.nativeElement;
|
|
5182
|
+
const rect = messageElement?.getBoundingClientRect();
|
|
5183
|
+
this.onContextMenuClick(messageComponent.message, {
|
|
5184
|
+
pageX: rect.left + (rect.width / 2) + window.scrollX,
|
|
5185
|
+
pageY: rect.top + (rect.height / 2) + window.scrollY
|
|
5186
|
+
}, messageComponent);
|
|
5187
|
+
}
|
|
5188
|
+
}
|
|
5189
|
+
}
|
|
5190
|
+
findMessageComponentFromActiveElement() {
|
|
5191
|
+
const activeElement = document.activeElement;
|
|
5192
|
+
const messageComponents = this.items.filter(item => item instanceof MessageComponent);
|
|
5193
|
+
return messageComponents.find(component => {
|
|
5194
|
+
const componentElement = component.element?.nativeElement;
|
|
5195
|
+
return componentElement && (componentElement === activeElement || componentElement.contains(activeElement));
|
|
5196
|
+
});
|
|
5197
|
+
}
|
|
5198
|
+
findMessageComponentFromEvent(event) {
|
|
5199
|
+
const target = event.target;
|
|
5200
|
+
const clickedElement = target?.closest('.k-message');
|
|
5201
|
+
if (!clickedElement)
|
|
5202
|
+
return undefined;
|
|
5203
|
+
const messageComponents = this.items.filter(item => item instanceof MessageComponent);
|
|
5204
|
+
return messageComponents.find(component => {
|
|
5205
|
+
const componentElement = component.element?.nativeElement;
|
|
5206
|
+
return componentElement && (componentElement === clickedElement || componentElement.contains(clickedElement));
|
|
5207
|
+
});
|
|
4281
5208
|
}
|
|
4282
5209
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MessageListComponent, deps: [{ token: i0.ElementRef }, { token: i1$1.IntlService }, { token: i0.Renderer2 }, { token: ChatService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
4283
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", 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: `
|
|
5210
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: MessageListComponent, isStandalone: true, selector: "kendo-chat-message-list", inputs: { messages: "messages", attachmentTemplate: "attachmentTemplate", authorMessageContentTemplate: "authorMessageContentTemplate", receiverMessageContentTemplate: "receiverMessageContentTemplate", messageContentTemplate: "messageContentTemplate", authorMessageTemplate: "authorMessageTemplate", receiverMessageTemplate: "receiverMessageTemplate", messageTemplate: "messageTemplate", timestampTemplate: "timestampTemplate", statusTemplate: "statusTemplate", userStatusTemplate: "userStatusTemplate", 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: `
|
|
4284
5211
|
<ng-container *ngFor="let group of view; last as lastGroup; trackBy: trackGroup">
|
|
4285
5212
|
<ng-container [ngSwitch]="group.type">
|
|
4286
5213
|
<div
|
|
@@ -4301,10 +5228,10 @@ class MessageListComponent {
|
|
|
4301
5228
|
[class.k-message-group-sender]="isOwnMessage(group.messages[0])"
|
|
4302
5229
|
[class.k-message-group-receiver]="!isOwnMessage(group.messages[0])"
|
|
4303
5230
|
[class.k-no-avatar]="!group.author.avatarUrl"
|
|
4304
|
-
[class.k-message-group-full-width]="
|
|
5231
|
+
[class.k-message-group-full-width]="calculateMessageWidthMode(group.messages[0])"
|
|
4305
5232
|
>
|
|
4306
5233
|
<div
|
|
4307
|
-
*ngIf="group.author.avatarUrl"
|
|
5234
|
+
*ngIf="!userStatusTemplate?.templateRef && group.author.avatarUrl"
|
|
4308
5235
|
class="k-avatar k-avatar-md k-avatar-solid k-avatar-solid-primary k-rounded-full"
|
|
4309
5236
|
>
|
|
4310
5237
|
<span class="k-avatar-image">
|
|
@@ -4314,6 +5241,25 @@ class MessageListComponent {
|
|
|
4314
5241
|
/>
|
|
4315
5242
|
</span>
|
|
4316
5243
|
</div>
|
|
5244
|
+
<div class="k-chat-user-status-wrapper" *ngIf="group.author.avatarUrl && userStatusTemplate?.templateRef">
|
|
5245
|
+
<div
|
|
5246
|
+
class="k-avatar k-avatar-md k-avatar-solid k-avatar-solid-primary k-rounded-full"
|
|
5247
|
+
>
|
|
5248
|
+
<span class="k-avatar-image">
|
|
5249
|
+
<img
|
|
5250
|
+
[attr.src]="group.author.avatarUrl"
|
|
5251
|
+
[alt]="group.author.avatarAltText"
|
|
5252
|
+
/>
|
|
5253
|
+
</span>
|
|
5254
|
+
</div>
|
|
5255
|
+
<div class="k-chat-user-status" *ngIf="userStatusTemplate?.templateRef">
|
|
5256
|
+
<ng-template
|
|
5257
|
+
[ngTemplateOutlet]="userStatusTemplate.templateRef"
|
|
5258
|
+
[ngTemplateOutletContext]="{ $implicit: group.messages.at(-1) }"
|
|
5259
|
+
>
|
|
5260
|
+
</ng-template>
|
|
5261
|
+
</div>
|
|
5262
|
+
</div>
|
|
4317
5263
|
<div class="k-message-group-content">
|
|
4318
5264
|
<p *ngIf="group.author.name" class="k-message-author">{{ group.author.name }}</p>
|
|
4319
5265
|
<ng-container
|
|
@@ -4330,13 +5276,14 @@ class MessageListComponent {
|
|
|
4330
5276
|
<kendo-chat-message #message
|
|
4331
5277
|
[message]="msg"
|
|
4332
5278
|
[tabbable]="lastGroup && lastMessage"
|
|
4333
|
-
[
|
|
5279
|
+
[authorMessageContentTemplate]="authorMessageContentTemplate"
|
|
5280
|
+
[receiverMessageContentTemplate]="receiverMessageContentTemplate"
|
|
5281
|
+
[messageContentTemplate]="messageContentTemplate"
|
|
5282
|
+
[authorMessageTemplate]="authorMessageTemplate"
|
|
5283
|
+
[receiverMessageTemplate]="receiverMessageTemplate"
|
|
5284
|
+
[messageTemplate]="messageTemplate"
|
|
4334
5285
|
[statusTemplate]="statusTemplate"
|
|
4335
5286
|
[authorId]="authorId"
|
|
4336
|
-
(click)="onClick(message, $event)"
|
|
4337
|
-
(contextMenuVisibilityChange)="handleMenuClose($event)"
|
|
4338
|
-
[class.k-first]="group.messages.length > 1 && firstMessage"
|
|
4339
|
-
[class.k-last]="group.messages.length > 1 && lastMessage"
|
|
4340
5287
|
>
|
|
4341
5288
|
</kendo-chat-message>
|
|
4342
5289
|
|
|
@@ -4365,6 +5312,7 @@ class MessageListComponent {
|
|
|
4365
5312
|
<kendo-chat-suggested-actions #actions
|
|
4366
5313
|
*ngSwitchCase="'action-group'"
|
|
4367
5314
|
[actions]="group.actions"
|
|
5315
|
+
type="action"
|
|
4368
5316
|
[tabbable]="lastGroup"
|
|
4369
5317
|
(dispatchAction)="dispatchAction($event, last(view))"
|
|
4370
5318
|
(click)="select(actions, $event)"
|
|
@@ -4375,7 +5323,7 @@ class MessageListComponent {
|
|
|
4375
5323
|
</ng-container>
|
|
4376
5324
|
<kendo-resize-sensor (resize)="onResize()">
|
|
4377
5325
|
</kendo-resize-sensor>
|
|
4378
|
-
`, 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", "
|
|
5326
|
+
`, 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", "authorMessageContentTemplate", "receiverMessageContentTemplate", "messageContentTemplate", "authorMessageTemplate", "receiverMessageTemplate", "messageTemplate", "statusTemplate", "showMessageTime", "authorId"] }, { 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", "type", "suggestionTemplate"], outputs: ["dispatchAction", "dispatchSuggestion"] }, { kind: "component", type: ResizeSensorComponent, selector: "kendo-resize-sensor", inputs: ["rateLimit"], outputs: ["resize"] }] });
|
|
4379
5327
|
}
|
|
4380
5328
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MessageListComponent, decorators: [{
|
|
4381
5329
|
type: Component,
|
|
@@ -4402,10 +5350,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
4402
5350
|
[class.k-message-group-sender]="isOwnMessage(group.messages[0])"
|
|
4403
5351
|
[class.k-message-group-receiver]="!isOwnMessage(group.messages[0])"
|
|
4404
5352
|
[class.k-no-avatar]="!group.author.avatarUrl"
|
|
4405
|
-
[class.k-message-group-full-width]="
|
|
5353
|
+
[class.k-message-group-full-width]="calculateMessageWidthMode(group.messages[0])"
|
|
4406
5354
|
>
|
|
4407
5355
|
<div
|
|
4408
|
-
*ngIf="group.author.avatarUrl"
|
|
5356
|
+
*ngIf="!userStatusTemplate?.templateRef && group.author.avatarUrl"
|
|
4409
5357
|
class="k-avatar k-avatar-md k-avatar-solid k-avatar-solid-primary k-rounded-full"
|
|
4410
5358
|
>
|
|
4411
5359
|
<span class="k-avatar-image">
|
|
@@ -4415,6 +5363,25 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
4415
5363
|
/>
|
|
4416
5364
|
</span>
|
|
4417
5365
|
</div>
|
|
5366
|
+
<div class="k-chat-user-status-wrapper" *ngIf="group.author.avatarUrl && userStatusTemplate?.templateRef">
|
|
5367
|
+
<div
|
|
5368
|
+
class="k-avatar k-avatar-md k-avatar-solid k-avatar-solid-primary k-rounded-full"
|
|
5369
|
+
>
|
|
5370
|
+
<span class="k-avatar-image">
|
|
5371
|
+
<img
|
|
5372
|
+
[attr.src]="group.author.avatarUrl"
|
|
5373
|
+
[alt]="group.author.avatarAltText"
|
|
5374
|
+
/>
|
|
5375
|
+
</span>
|
|
5376
|
+
</div>
|
|
5377
|
+
<div class="k-chat-user-status" *ngIf="userStatusTemplate?.templateRef">
|
|
5378
|
+
<ng-template
|
|
5379
|
+
[ngTemplateOutlet]="userStatusTemplate.templateRef"
|
|
5380
|
+
[ngTemplateOutletContext]="{ $implicit: group.messages.at(-1) }"
|
|
5381
|
+
>
|
|
5382
|
+
</ng-template>
|
|
5383
|
+
</div>
|
|
5384
|
+
</div>
|
|
4418
5385
|
<div class="k-message-group-content">
|
|
4419
5386
|
<p *ngIf="group.author.name" class="k-message-author">{{ group.author.name }}</p>
|
|
4420
5387
|
<ng-container
|
|
@@ -4431,13 +5398,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
4431
5398
|
<kendo-chat-message #message
|
|
4432
5399
|
[message]="msg"
|
|
4433
5400
|
[tabbable]="lastGroup && lastMessage"
|
|
4434
|
-
[
|
|
5401
|
+
[authorMessageContentTemplate]="authorMessageContentTemplate"
|
|
5402
|
+
[receiverMessageContentTemplate]="receiverMessageContentTemplate"
|
|
5403
|
+
[messageContentTemplate]="messageContentTemplate"
|
|
5404
|
+
[authorMessageTemplate]="authorMessageTemplate"
|
|
5405
|
+
[receiverMessageTemplate]="receiverMessageTemplate"
|
|
5406
|
+
[messageTemplate]="messageTemplate"
|
|
4435
5407
|
[statusTemplate]="statusTemplate"
|
|
4436
5408
|
[authorId]="authorId"
|
|
4437
|
-
(click)="onClick(message, $event)"
|
|
4438
|
-
(contextMenuVisibilityChange)="handleMenuClose($event)"
|
|
4439
|
-
[class.k-first]="group.messages.length > 1 && firstMessage"
|
|
4440
|
-
[class.k-last]="group.messages.length > 1 && lastMessage"
|
|
4441
5409
|
>
|
|
4442
5410
|
</kendo-chat-message>
|
|
4443
5411
|
|
|
@@ -4466,6 +5434,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
4466
5434
|
<kendo-chat-suggested-actions #actions
|
|
4467
5435
|
*ngSwitchCase="'action-group'"
|
|
4468
5436
|
[actions]="group.actions"
|
|
5437
|
+
type="action"
|
|
4469
5438
|
[tabbable]="lastGroup"
|
|
4470
5439
|
(dispatchAction)="dispatchAction($event, last(view))"
|
|
4471
5440
|
(click)="select(actions, $event)"
|
|
@@ -4484,12 +5453,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
4484
5453
|
type: Input
|
|
4485
5454
|
}], attachmentTemplate: [{
|
|
4486
5455
|
type: Input
|
|
5456
|
+
}], authorMessageContentTemplate: [{
|
|
5457
|
+
type: Input
|
|
5458
|
+
}], receiverMessageContentTemplate: [{
|
|
5459
|
+
type: Input
|
|
5460
|
+
}], messageContentTemplate: [{
|
|
5461
|
+
type: Input
|
|
5462
|
+
}], authorMessageTemplate: [{
|
|
5463
|
+
type: Input
|
|
5464
|
+
}], receiverMessageTemplate: [{
|
|
5465
|
+
type: Input
|
|
4487
5466
|
}], messageTemplate: [{
|
|
4488
5467
|
type: Input
|
|
4489
5468
|
}], timestampTemplate: [{
|
|
4490
5469
|
type: Input
|
|
4491
5470
|
}], statusTemplate: [{
|
|
4492
5471
|
type: Input
|
|
5472
|
+
}], userStatusTemplate: [{
|
|
5473
|
+
type: Input
|
|
4493
5474
|
}], localization: [{
|
|
4494
5475
|
type: Input
|
|
4495
5476
|
}], authorId: [{
|
|
@@ -4652,8 +5633,16 @@ let Messages$1 = class Messages extends ComponentMessages {
|
|
|
4652
5633
|
* Sets the title of the DropDownButton that opens the File actions.
|
|
4653
5634
|
*/
|
|
4654
5635
|
fileActionsTitle;
|
|
5636
|
+
/**
|
|
5637
|
+
* Sets the title of the button that shows the **Scroll right** when the suggestions list is scrollable with buttons.
|
|
5638
|
+
*/
|
|
5639
|
+
nextSuggestionsButtonTitle;
|
|
5640
|
+
/**
|
|
5641
|
+
* Sets the title of the button that shows the **Scroll left** when the suggestions list is scrollable with buttons.
|
|
5642
|
+
*/
|
|
5643
|
+
previousSuggestionsButtonTitle;
|
|
4655
5644
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: Messages, deps: null, target: i0.ɵɵFactoryTarget.Directive });
|
|
4656
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.14", type: Messages, selector: "kendoConversationalUIMessages", inputs: { deletedMessageSenderText: "deletedMessageSenderText", deletedMessageReceiverText: "deletedMessageReceiverText", downloadAllFilesText: "downloadAllFilesText", messagePlaceholder: "messagePlaceholder", send: "send", messageListLabel: "messageListLabel", messageBoxInputLabel: "messageBoxInputLabel", messageAttachmentLeftArrow: "messageAttachmentLeftArrow", messageAttachmentRightArrow: "messageAttachmentRightArrow", speechToTextButtonTitle: "speechToTextButtonTitle", fileSelectButtonTitle: "fileSelectButtonTitle", removeReplyTitle: "removeReplyTitle", removeFileTitle: "removeFileTitle", expandTitle: "expandTitle", collapseTitle: "collapseTitle", fileActionsTitle: "fileActionsTitle" }, usesInheritance: true, ngImport: i0 });
|
|
5645
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.14", type: Messages, selector: "kendoConversationalUIMessages", inputs: { deletedMessageSenderText: "deletedMessageSenderText", deletedMessageReceiverText: "deletedMessageReceiverText", downloadAllFilesText: "downloadAllFilesText", messagePlaceholder: "messagePlaceholder", send: "send", messageListLabel: "messageListLabel", messageBoxInputLabel: "messageBoxInputLabel", messageAttachmentLeftArrow: "messageAttachmentLeftArrow", messageAttachmentRightArrow: "messageAttachmentRightArrow", speechToTextButtonTitle: "speechToTextButtonTitle", fileSelectButtonTitle: "fileSelectButtonTitle", removeReplyTitle: "removeReplyTitle", removeFileTitle: "removeFileTitle", expandTitle: "expandTitle", collapseTitle: "collapseTitle", fileActionsTitle: "fileActionsTitle", nextSuggestionsButtonTitle: "nextSuggestionsButtonTitle", previousSuggestionsButtonTitle: "previousSuggestionsButtonTitle" }, usesInheritance: true, ngImport: i0 });
|
|
4657
5646
|
};
|
|
4658
5647
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: Messages$1, decorators: [{
|
|
4659
5648
|
type: Directive,
|
|
@@ -4693,6 +5682,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
4693
5682
|
type: Input
|
|
4694
5683
|
}], fileActionsTitle: [{
|
|
4695
5684
|
type: Input
|
|
5685
|
+
}], nextSuggestionsButtonTitle: [{
|
|
5686
|
+
type: Input
|
|
5687
|
+
}], previousSuggestionsButtonTitle: [{
|
|
5688
|
+
type: Input
|
|
4696
5689
|
}] } });
|
|
4697
5690
|
|
|
4698
5691
|
// eslint-disable no-forward-ref
|
|
@@ -4755,6 +5748,39 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
4755
5748
|
}]
|
|
4756
5749
|
}], ctorParameters: () => [{ type: i0.TemplateRef }] });
|
|
4757
5750
|
|
|
5751
|
+
/**
|
|
5752
|
+
* Defines a template for displaying custom content when there are no messages in the Chat.
|
|
5753
|
+
*
|
|
5754
|
+
* To define an empty Chat template, nest an `<ng-template>` tag with the `kendoChatNoDataTemplate` directive inside the `<kendo-chat>` component.
|
|
5755
|
+
* For more information, refer to the article on [message templates](slug:message_templates_chat).
|
|
5756
|
+
*
|
|
5757
|
+
* @example
|
|
5758
|
+
* ```html
|
|
5759
|
+
* <kendo-chat>
|
|
5760
|
+
* <ng-template kendoChatNoDataTemplate>
|
|
5761
|
+
* <div>No messages.</div>
|
|
5762
|
+
* </ng-template>
|
|
5763
|
+
* </kendo-chat>
|
|
5764
|
+
* ```
|
|
5765
|
+
*/
|
|
5766
|
+
class NoDataTemplateDirective {
|
|
5767
|
+
templateRef;
|
|
5768
|
+
constructor(templateRef) {
|
|
5769
|
+
this.templateRef = templateRef;
|
|
5770
|
+
}
|
|
5771
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NoDataTemplateDirective, deps: [{ token: i0.TemplateRef, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
|
|
5772
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.14", type: NoDataTemplateDirective, isStandalone: true, selector: "[kendoChatNoDataTemplate]", ngImport: i0 });
|
|
5773
|
+
}
|
|
5774
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NoDataTemplateDirective, decorators: [{
|
|
5775
|
+
type: Directive,
|
|
5776
|
+
args: [{
|
|
5777
|
+
selector: '[kendoChatNoDataTemplate]',
|
|
5778
|
+
standalone: true
|
|
5779
|
+
}]
|
|
5780
|
+
}], ctorParameters: () => [{ type: i0.TemplateRef, decorators: [{
|
|
5781
|
+
type: Optional
|
|
5782
|
+
}] }] });
|
|
5783
|
+
|
|
4758
5784
|
/**
|
|
4759
5785
|
* Represents the [Kendo UI Chat component for Angular](slug:overview_convui).
|
|
4760
5786
|
*
|
|
@@ -4772,7 +5798,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
4772
5798
|
* ```
|
|
4773
5799
|
*
|
|
4774
5800
|
* @remarks
|
|
4775
|
-
* Supported children components are: {@link CustomMessagesComponent}, {@link HeroCardComponent}, {@link AttachmentTemplateDirective}, {@link ChatHeaderTemplateDirective}, {@link ChatMessageBoxTemplateDirective}, {@link
|
|
5801
|
+
* Supported children components are: {@link CustomMessagesComponent}, {@link HeroCardComponent}, {@link AttachmentTemplateDirective}, {@link ChatHeaderTemplateDirective}, {@link ChatMessageBoxTemplateDirective}, {@link MessageContentTemplateDirective}, {@link MessageTemplateDirective},{@link ChatStatusTemplateDirective}, {@link ChatSuggestionTemplateDirective}, {@link ChatTimestampTemplateDirective}, {@link ChatNoDataTemplateDirective}, {@link ChatUserStatusTemplateDirective}, {@link AuthorMessageContentTemplateDirective}, {@link ReceiverMessageContentTemplateDirective}, {@link ReceiverMessageTemplateDirective}, {@link AuthorMessageTemplateDirective}.
|
|
4776
5802
|
*/
|
|
4777
5803
|
class ChatComponent {
|
|
4778
5804
|
localization;
|
|
@@ -4781,13 +5807,13 @@ class ChatComponent {
|
|
|
4781
5807
|
element;
|
|
4782
5808
|
chatService;
|
|
4783
5809
|
/**
|
|
4784
|
-
*
|
|
4785
|
-
*
|
|
4786
|
-
* For more information,
|
|
5810
|
+
* Sets the Chat messages.
|
|
5811
|
+
* Accepts an array of `Message` objects, but can also accept custom data structures.
|
|
5812
|
+
* For more information, check [Data Binding](slug:databinding_chat) section in the documentation.
|
|
4787
5813
|
*/
|
|
4788
5814
|
messages;
|
|
4789
5815
|
/**
|
|
4790
|
-
*
|
|
5816
|
+
* Sets the ID that represents the local user.
|
|
4791
5817
|
*/
|
|
4792
5818
|
authorId;
|
|
4793
5819
|
/**
|
|
@@ -4815,13 +5841,14 @@ class ChatComponent {
|
|
|
4815
5841
|
*/
|
|
4816
5842
|
placeholder;
|
|
4817
5843
|
/**
|
|
4818
|
-
*
|
|
5844
|
+
* Controls the width of the message between the predefined options.
|
|
4819
5845
|
*
|
|
4820
5846
|
* @default 'standard'
|
|
4821
5847
|
*/
|
|
4822
5848
|
messageWidthMode = 'standard';
|
|
4823
5849
|
/**
|
|
4824
5850
|
* Enables the expand or collapse functionality for messages.
|
|
5851
|
+
*
|
|
4825
5852
|
* @default false
|
|
4826
5853
|
*/
|
|
4827
5854
|
allowMessageCollapse = false;
|
|
@@ -4838,24 +5865,34 @@ class ChatComponent {
|
|
|
4838
5865
|
*/
|
|
4839
5866
|
enableFileSelect = true;
|
|
4840
5867
|
/**
|
|
4841
|
-
*
|
|
5868
|
+
* Sets the actions of the message toolbar.
|
|
4842
5869
|
* These actions display in the message toolbar and let you perform specific operations on the message.
|
|
5870
|
+
*
|
|
4843
5871
|
* @default []
|
|
4844
5872
|
*/
|
|
4845
5873
|
messageToolbarActions = [];
|
|
4846
5874
|
/**
|
|
4847
5875
|
* Sets the value of the Message Box.
|
|
5876
|
+
*
|
|
4848
5877
|
* @default ''
|
|
4849
5878
|
*/
|
|
4850
5879
|
inputValue = '';
|
|
4851
5880
|
/**
|
|
4852
|
-
*
|
|
5881
|
+
* Sets the settings for the author's messages.
|
|
5882
|
+
*/
|
|
5883
|
+
authorMessageSettings;
|
|
5884
|
+
/**
|
|
5885
|
+
* Sets the settings for the receivers' messages.
|
|
5886
|
+
*/
|
|
5887
|
+
receiverMessageSettings;
|
|
5888
|
+
/**
|
|
5889
|
+
* Sets the default actions that display in the message context menu.
|
|
4853
5890
|
*
|
|
4854
5891
|
* @default [{ id: 'copy', label: 'Copy', icon: 'copy', svgIcon: copyIcon, disabled: false }, { id: 'reply', label: 'Reply', icon: 'undo', svgIcon: undoIcon, disabled: false }]
|
|
4855
5892
|
*/
|
|
4856
5893
|
defaultContextMenuActions = CONTEXT_MENU_ACTIONS;
|
|
4857
5894
|
/**
|
|
4858
|
-
*
|
|
5895
|
+
* Sets the actions that display in the message as a context menu.
|
|
4859
5896
|
* These actions display as menu items and let you perform specific operations on the message.
|
|
4860
5897
|
* The default actions are `copy` and `reply` and are defined by their `id`.
|
|
4861
5898
|
*/
|
|
@@ -4866,11 +5903,13 @@ class ChatComponent {
|
|
|
4866
5903
|
return this._messageContextMenuActions;
|
|
4867
5904
|
}
|
|
4868
5905
|
/**
|
|
4869
|
-
*
|
|
5906
|
+
* Sets the default actions that display in the file actions DropDownButton.
|
|
5907
|
+
*
|
|
5908
|
+
* @default [{ id: 'download', label: 'Download', icon: 'download', svgIcon: downloadIcon, disabled: false }]
|
|
4870
5909
|
*/
|
|
4871
5910
|
defaultFileActions = FILE_ACTIONS;
|
|
4872
5911
|
/**
|
|
4873
|
-
*
|
|
5912
|
+
* Sets the actions that display in the file as items of a DropDownButton.
|
|
4874
5913
|
* These actions display when you click the file DropDownButton and let you perform specific operations on the file.
|
|
4875
5914
|
* The default action is `download` and is defined by its `id`.
|
|
4876
5915
|
*
|
|
@@ -4883,17 +5922,40 @@ class ChatComponent {
|
|
|
4883
5922
|
return this._fileActions;
|
|
4884
5923
|
}
|
|
4885
5924
|
/**
|
|
4886
|
-
* Sets the
|
|
4887
|
-
*
|
|
4888
|
-
* @default
|
|
5925
|
+
* Sets the layout of the files in the message bubble.
|
|
5926
|
+
*
|
|
5927
|
+
* @default 'vertical'
|
|
4889
5928
|
*/
|
|
4890
|
-
|
|
5929
|
+
set messageFilesLayout(layout) {
|
|
5930
|
+
this.chatService.messageFilesLayout = layout;
|
|
5931
|
+
}
|
|
5932
|
+
/**
|
|
5933
|
+
* Sets the layout of the suggestions above the message input box.
|
|
5934
|
+
*
|
|
5935
|
+
* @default 'scroll'
|
|
5936
|
+
*/
|
|
5937
|
+
set suggestionsLayout(layoutMode) {
|
|
5938
|
+
if (layoutMode) {
|
|
5939
|
+
this.chatService.suggestionsLayout = layoutMode;
|
|
5940
|
+
}
|
|
5941
|
+
}
|
|
4891
5942
|
/**
|
|
4892
|
-
* Sets the
|
|
5943
|
+
* Sets the layout of the quick actions suggested below the messages.
|
|
4893
5944
|
*
|
|
4894
|
-
* @default '
|
|
5945
|
+
* @default 'scroll'
|
|
4895
5946
|
*/
|
|
4896
|
-
|
|
5947
|
+
set quickActionsLayout(layoutMode) {
|
|
5948
|
+
if (layoutMode) {
|
|
5949
|
+
this.chatService.quickActionsLayout = layoutMode;
|
|
5950
|
+
}
|
|
5951
|
+
}
|
|
5952
|
+
/**
|
|
5953
|
+
* Sets the suggestions that display in the message input box.
|
|
5954
|
+
* Suggestions display as a list of clickable items that let you quickly insert predefined text into the message input.
|
|
5955
|
+
*
|
|
5956
|
+
* @default []
|
|
5957
|
+
*/
|
|
5958
|
+
suggestions = [];
|
|
4897
5959
|
/**
|
|
4898
5960
|
* Sets the send button settings for the Chat component.
|
|
4899
5961
|
* Allows customization of the send button appearance, icons and disabled state.
|
|
@@ -4912,53 +5974,53 @@ class ChatComponent {
|
|
|
4912
5974
|
return this._modelFields;
|
|
4913
5975
|
}
|
|
4914
5976
|
/**
|
|
4915
|
-
*
|
|
5977
|
+
* Fires when the user sends a message by clicking the **Send** button or pressing **Enter**.
|
|
4916
5978
|
*
|
|
4917
5979
|
* The message is not automatically added to the `messages` array.
|
|
4918
5980
|
*/
|
|
4919
5981
|
sendMessage = new EventEmitter();
|
|
4920
5982
|
/**
|
|
4921
|
-
*
|
|
5983
|
+
* Fires when the user clicks a quick action button in the message toolbar.
|
|
4922
5984
|
*/
|
|
4923
5985
|
toolbarActionClick = new EventEmitter();
|
|
4924
5986
|
/**
|
|
4925
|
-
*
|
|
5987
|
+
* Fires when the user clicks an action in the message context menu.
|
|
4926
5988
|
*/
|
|
4927
5989
|
contextMenuActionClick = new EventEmitter();
|
|
4928
5990
|
/**
|
|
4929
|
-
*
|
|
5991
|
+
* Fires when the user clicks an action in the file context menu.
|
|
4930
5992
|
*/
|
|
4931
5993
|
fileActionClick = new EventEmitter();
|
|
4932
5994
|
/**
|
|
4933
|
-
*
|
|
5995
|
+
* Fires when the user clicks an action in the file context menu.
|
|
4934
5996
|
*/
|
|
4935
5997
|
download = new EventEmitter();
|
|
4936
5998
|
/**
|
|
4937
|
-
*
|
|
5999
|
+
* Fires when the user clicks a quick action button.
|
|
4938
6000
|
* The Chat internally handles [known actions](slug:api_conversational-ui_actiontype) such as `reply`, `openUrl`, and `call`.
|
|
4939
6001
|
*
|
|
4940
6002
|
* The event is preventable. Calling [`preventDefault`](https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault) suppresses the built-in action.
|
|
4941
6003
|
*/
|
|
4942
6004
|
executeAction = new EventEmitter();
|
|
4943
6005
|
/**
|
|
4944
|
-
*
|
|
6006
|
+
* Fires when the user clicks a suggestion in the message input box.
|
|
4945
6007
|
*/
|
|
4946
6008
|
suggestionExecute = new EventEmitter();
|
|
4947
6009
|
/**
|
|
4948
|
-
*
|
|
6010
|
+
* Fires when the user selects a file in the message input box.
|
|
4949
6011
|
*/
|
|
4950
6012
|
fileSelect = new EventEmitter();
|
|
4951
6013
|
/**
|
|
4952
|
-
*
|
|
6014
|
+
* Fires when the user removes a file from the message input box.
|
|
4953
6015
|
*/
|
|
4954
6016
|
fileRemove = new EventEmitter();
|
|
4955
6017
|
/**
|
|
4956
|
-
*
|
|
6018
|
+
* Fires when the user unpins the pinned message.
|
|
4957
6019
|
* This event triggers when the user clicks the delete button on the pinned message.
|
|
4958
6020
|
*/
|
|
4959
6021
|
unpin = new EventEmitter();
|
|
4960
6022
|
/**
|
|
4961
|
-
*
|
|
6023
|
+
* Fires when the user types in the message input box.
|
|
4962
6024
|
*/
|
|
4963
6025
|
inputValueChange = new EventEmitter();
|
|
4964
6026
|
get className() {
|
|
@@ -4967,13 +6029,23 @@ class ChatComponent {
|
|
|
4967
6029
|
get dirAttr() {
|
|
4968
6030
|
return this.direction;
|
|
4969
6031
|
}
|
|
6032
|
+
set messagesContextMenu(contextMenu) {
|
|
6033
|
+
this.chatService.messagesContextMenu = contextMenu;
|
|
6034
|
+
}
|
|
4970
6035
|
attachmentTemplate;
|
|
4971
6036
|
chatHeaderTemplate;
|
|
6037
|
+
chatNoDataTemplate;
|
|
6038
|
+
authorMessageContentTemplate;
|
|
6039
|
+
receiverMessageContentTemplate;
|
|
6040
|
+
messageContentTemplate;
|
|
6041
|
+
authorMessageTemplate;
|
|
6042
|
+
receiverMessageTemplate;
|
|
4972
6043
|
messageTemplate;
|
|
4973
6044
|
timestampTemplate;
|
|
4974
6045
|
suggestionTemplate;
|
|
4975
6046
|
statusTemplate;
|
|
4976
6047
|
messageBoxTemplate;
|
|
6048
|
+
userStatusTemplate;
|
|
4977
6049
|
messageBox;
|
|
4978
6050
|
/**
|
|
4979
6051
|
* @hidden
|
|
@@ -4981,17 +6053,30 @@ class ChatComponent {
|
|
|
4981
6053
|
messageList;
|
|
4982
6054
|
/**
|
|
4983
6055
|
* @hidden
|
|
4984
|
-
* Returns processed messages when model fields are used, otherwise returns original messages
|
|
6056
|
+
* Returns processed messages when model fields are used, otherwise returns original messages.
|
|
4985
6057
|
*/
|
|
4986
6058
|
get processedMessages() {
|
|
4987
6059
|
if (!this.messages || this.messages.length === 0) {
|
|
4988
6060
|
return [];
|
|
4989
6061
|
}
|
|
4990
6062
|
if (this._modelFields && Object.keys(this._modelFields).some(key => this._modelFields[key] !== defaultModelFields[key])) {
|
|
4991
|
-
|
|
6063
|
+
if (this.messages !== this._lastMessagesReference || this._modelFields !== this._lastModelFields) {
|
|
6064
|
+
this._cachedProcessedMessages = processMessages(this.messages, this._modelFields);
|
|
6065
|
+
this._lastMessagesReference = this.messages;
|
|
6066
|
+
this._lastModelFields = this._modelFields;
|
|
6067
|
+
}
|
|
6068
|
+
return this._cachedProcessedMessages;
|
|
4992
6069
|
}
|
|
4993
6070
|
return this.messages;
|
|
4994
6071
|
}
|
|
6072
|
+
/**
|
|
6073
|
+
* Gets the actions available in the message context menu.
|
|
6074
|
+
*
|
|
6075
|
+
* @hidden
|
|
6076
|
+
*/
|
|
6077
|
+
get contextMenuActions() {
|
|
6078
|
+
return transformActions(this.chatService.calculatedContextMenuActions);
|
|
6079
|
+
}
|
|
4995
6080
|
/**
|
|
4996
6081
|
* @hidden
|
|
4997
6082
|
*/
|
|
@@ -5019,6 +6104,9 @@ class ChatComponent {
|
|
|
5019
6104
|
_modelFields = defaultModelFields;
|
|
5020
6105
|
_messageContextMenuActions = CONTEXT_MENU_ACTIONS;
|
|
5021
6106
|
_fileActions = FILE_ACTIONS;
|
|
6107
|
+
_cachedProcessedMessages = [];
|
|
6108
|
+
_lastMessagesReference = null;
|
|
6109
|
+
_lastModelFields = null;
|
|
5022
6110
|
constructor(localization, zone, renderer, element, chatService) {
|
|
5023
6111
|
this.localization = localization;
|
|
5024
6112
|
this.zone = zone;
|
|
@@ -5043,7 +6131,8 @@ class ChatComponent {
|
|
|
5043
6131
|
this.chatService.messageToolbarActions = this.messageToolbarActions;
|
|
5044
6132
|
this.chatService.messageContextMenuActions = this.messageContextMenuActions;
|
|
5045
6133
|
this.chatService.fileActions = this.fileActions;
|
|
5046
|
-
this.chatService.
|
|
6134
|
+
this.chatService.authorMessageSettings = this.authorMessageSettings;
|
|
6135
|
+
this.chatService.receiverMessageSettings = this.receiverMessageSettings;
|
|
5047
6136
|
this.chatService.messages = this.processedMessages || [];
|
|
5048
6137
|
this.chatService.chatElement = this.messageList;
|
|
5049
6138
|
this.subs.add(this.chatService.toolbarAction$.subscribe((actionEvent) => {
|
|
@@ -5091,7 +6180,8 @@ class ChatComponent {
|
|
|
5091
6180
|
'messageToolbarActions',
|
|
5092
6181
|
'messageContextMenuActions',
|
|
5093
6182
|
'fileActions',
|
|
5094
|
-
'
|
|
6183
|
+
'authorMessageSettings',
|
|
6184
|
+
'receiverMessageSettings'
|
|
5095
6185
|
], changes);
|
|
5096
6186
|
}
|
|
5097
6187
|
/**
|
|
@@ -5140,6 +6230,43 @@ class ChatComponent {
|
|
|
5140
6230
|
this.chatService.scrollToMessage(this.pinnedMessage?.id);
|
|
5141
6231
|
}
|
|
5142
6232
|
}
|
|
6233
|
+
/**
|
|
6234
|
+
* @hidden
|
|
6235
|
+
*/
|
|
6236
|
+
onContextMenuAction(action) {
|
|
6237
|
+
if (action.id === 'reply') {
|
|
6238
|
+
this.chatService.reply = this.chatService.activeMessage;
|
|
6239
|
+
}
|
|
6240
|
+
if (action.id === 'copy') {
|
|
6241
|
+
navigator.clipboard.writeText(this.chatService.activeMessage.text);
|
|
6242
|
+
}
|
|
6243
|
+
this.chatService.emit('contextMenuAction', { action, message: this.chatService.activeMessage });
|
|
6244
|
+
}
|
|
6245
|
+
/**
|
|
6246
|
+
* @hidden
|
|
6247
|
+
*/
|
|
6248
|
+
handleMenuClose(event) {
|
|
6249
|
+
if (event) {
|
|
6250
|
+
const originalEvent = event.originalEvent;
|
|
6251
|
+
originalEvent && this.onActionButtonClick(originalEvent);
|
|
6252
|
+
}
|
|
6253
|
+
this.chatService.activeMessage = null;
|
|
6254
|
+
this.chatService.emit('contextMenuVisibilityChange', false);
|
|
6255
|
+
if (this.chatService.selectOnMenuClose) {
|
|
6256
|
+
this.chatService.activeMessageElement.selected = true;
|
|
6257
|
+
this.chatService.focusActiveMessageElement();
|
|
6258
|
+
}
|
|
6259
|
+
}
|
|
6260
|
+
/**
|
|
6261
|
+
* @hidden
|
|
6262
|
+
*/
|
|
6263
|
+
onActionButtonClick(event) {
|
|
6264
|
+
const clickOutsideMessage = event instanceof MouseEvent && !event.target?.closest('.k-chat-bubble');
|
|
6265
|
+
const menuItemClick = event instanceof MouseEvent && event.target?.closest(MENU_ITEM_SELECTOR);
|
|
6266
|
+
if (clickOutsideMessage && !menuItemClick) {
|
|
6267
|
+
this.chatService.selectOnMenuClose = false;
|
|
6268
|
+
}
|
|
6269
|
+
}
|
|
5143
6270
|
findLastPinnedMessage() {
|
|
5144
6271
|
return [...this.processedMessages].reverse().find((message) => message.isPinned);
|
|
5145
6272
|
}
|
|
@@ -5163,14 +6290,15 @@ class ChatComponent {
|
|
|
5163
6290
|
});
|
|
5164
6291
|
}
|
|
5165
6292
|
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 });
|
|
5166
|
-
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", messageContextMenuActions: "messageContextMenuActions", fileActions: "fileActions",
|
|
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: [
|
|
5167
6294
|
LocalizationService,
|
|
5168
6295
|
ChatService,
|
|
6296
|
+
SuggestionsScrollService,
|
|
5169
6297
|
{
|
|
5170
6298
|
provide: L10N_PREFIX,
|
|
5171
6299
|
useValue: 'kendo.chat'
|
|
5172
6300
|
}
|
|
5173
|
-
], queries: [{ propertyName: "attachmentTemplate", first: true, predicate: AttachmentTemplateDirective, descendants: true }, { propertyName: "chatHeaderTemplate", first: true, predicate: ChatHeaderTemplateDirective, descendants: true }, { propertyName: "messageTemplate", first: true, predicate: MessageTemplateDirective, descendants: true }, { propertyName: "timestampTemplate", first: true, predicate: ChatTimestampTemplateDirective, descendants: true }, { propertyName: "suggestionTemplate", first: true, predicate: ChatSuggestionTemplateDirective, descendants: true }, { propertyName: "statusTemplate", first: true, predicate: ChatStatusTemplateDirective, descendants: true }, { propertyName: "messageBoxTemplate", first: true, predicate: ChatMessageBoxTemplateDirective, descendants: true }], viewQueries: [{ propertyName: "messageBox", first: true, predicate: ["messageBox"], descendants: true }, { propertyName: "messageList", first: true, predicate: ["messageList"], descendants: true, read: ViewContainerRef, static: true }], usesOnChanges: true, ngImport: i0, template: `
|
|
6301
|
+
], queries: [{ propertyName: "attachmentTemplate", first: true, predicate: AttachmentTemplateDirective, descendants: true }, { propertyName: "chatHeaderTemplate", first: true, predicate: ChatHeaderTemplateDirective, descendants: true }, { propertyName: "chatNoDataTemplate", first: true, predicate: NoDataTemplateDirective, descendants: true }, { propertyName: "authorMessageContentTemplate", first: true, predicate: AuthorMessageContentTemplateDirective, descendants: true }, { propertyName: "receiverMessageContentTemplate", first: true, predicate: ReceiverMessageContentTemplateDirective, descendants: true }, { propertyName: "messageContentTemplate", first: true, predicate: MessageContentTemplateDirective, descendants: true }, { propertyName: "authorMessageTemplate", first: true, predicate: AuthorMessageTemplateDirective, descendants: true }, { propertyName: "receiverMessageTemplate", first: true, predicate: ReceiverMessageTemplateDirective, descendants: true }, { propertyName: "messageTemplate", first: true, predicate: MessageTemplateDirective, descendants: true }, { propertyName: "timestampTemplate", first: true, predicate: ChatTimestampTemplateDirective, descendants: true }, { propertyName: "suggestionTemplate", first: true, predicate: ChatSuggestionTemplateDirective, descendants: true }, { propertyName: "statusTemplate", first: true, predicate: ChatStatusTemplateDirective, descendants: true }, { propertyName: "messageBoxTemplate", first: true, predicate: ChatMessageBoxTemplateDirective, descendants: true }, { propertyName: "userStatusTemplate", first: true, predicate: ChatUserStatusTemplateDirective, descendants: true }], viewQueries: [{ propertyName: "messagesContextMenu", first: true, predicate: ["messagesContextMenu"], descendants: true }, { propertyName: "messageBox", first: true, predicate: ["messageBox"], descendants: true }, { propertyName: "messageList", first: true, predicate: ["messageList"], descendants: true, read: ViewContainerRef, static: true }], usesOnChanges: true, ngImport: i0, template: `
|
|
5174
6302
|
<ng-container kendoChatLocalizedMessages
|
|
5175
6303
|
i18n-deletedMessageSenderText="kendo.chat.deletedMessageSenderText|The text that is displayed when the sender deletes a message"
|
|
5176
6304
|
deletedMessageSenderText="You removed this message."
|
|
@@ -5219,10 +6347,16 @@ class ChatComponent {
|
|
|
5219
6347
|
|
|
5220
6348
|
i18n-downloadAllFilesText="kendo.chat.downloadAllFilesText|Sets the text that is displayed in the download section of the message."
|
|
5221
6349
|
downloadAllFilesText="Download all"
|
|
6350
|
+
|
|
6351
|
+
i18n-previousSuggestionsButtonTitle="kendo.chat.previousSuggestionsButtonTitle|The title of the button that scrolls to the previous suggestions"
|
|
6352
|
+
previousSuggestionsButtonTitle="Scroll left"
|
|
6353
|
+
|
|
6354
|
+
i18n-nextSuggestionsButtonTitle="kendo.chat.nextSuggestionsButtonTitle|The title of the button that scrolls to the next suggestions"
|
|
6355
|
+
nextSuggestionsButtonTitle="Scroll right"
|
|
5222
6356
|
>
|
|
5223
6357
|
</ng-container>
|
|
5224
6358
|
|
|
5225
|
-
<kendo-appbar *ngIf="chatHeaderTemplate" class="k-chat-header" positionMode="sticky">
|
|
6359
|
+
<kendo-appbar *ngIf="chatHeaderTemplate" class="k-chat-header" positionMode="sticky" themeColor="inherit">
|
|
5226
6360
|
<ng-container *ngTemplateOutlet="chatHeaderTemplate.templateRef"></ng-container>
|
|
5227
6361
|
</kendo-appbar>
|
|
5228
6362
|
<div class="k-message-reference k-message-reference-receiver k-message-pinned" *ngIf="pinnedMessage" (click)="scrollToPinnedMessage()">
|
|
@@ -5238,7 +6372,7 @@ class ChatComponent {
|
|
|
5238
6372
|
</div>
|
|
5239
6373
|
<div
|
|
5240
6374
|
#messageList
|
|
5241
|
-
class="k-message-list
|
|
6375
|
+
class="k-message-list"
|
|
5242
6376
|
aria-live="polite"
|
|
5243
6377
|
role="log"
|
|
5244
6378
|
kendoChatScrollAnchor
|
|
@@ -5246,19 +6380,32 @@ class ChatComponent {
|
|
|
5246
6380
|
#anchor="scrollAnchor"
|
|
5247
6381
|
[(autoScroll)]="autoScroll"
|
|
5248
6382
|
>
|
|
5249
|
-
<
|
|
5250
|
-
|
|
5251
|
-
|
|
5252
|
-
|
|
5253
|
-
|
|
5254
|
-
|
|
5255
|
-
|
|
5256
|
-
|
|
5257
|
-
|
|
5258
|
-
|
|
5259
|
-
|
|
5260
|
-
|
|
5261
|
-
|
|
6383
|
+
<div *ngIf="processedMessages && processedMessages.length === 0; else chatMessageList" class="k-message-list-content k-message-list-content-empty">
|
|
6384
|
+
<ng-template
|
|
6385
|
+
[ngTemplateOutlet]="chatNoDataTemplate?.templateRef">
|
|
6386
|
+
</ng-template>
|
|
6387
|
+
</div>
|
|
6388
|
+
<ng-template #chatMessageList>
|
|
6389
|
+
<kendo-chat-message-list
|
|
6390
|
+
[messages]="processedMessages"
|
|
6391
|
+
[authorMessageContentTemplate]="authorMessageContentTemplate"
|
|
6392
|
+
[receiverMessageContentTemplate]="receiverMessageContentTemplate"
|
|
6393
|
+
[messageContentTemplate]="messageContentTemplate"
|
|
6394
|
+
[authorMessageTemplate]="authorMessageTemplate"
|
|
6395
|
+
[receiverMessageTemplate]="receiverMessageTemplate"
|
|
6396
|
+
[messageTemplate]="messageTemplate"
|
|
6397
|
+
[timestampTemplate]="timestampTemplate"
|
|
6398
|
+
[statusTemplate]="statusTemplate"
|
|
6399
|
+
[userStatusTemplate]="userStatusTemplate"
|
|
6400
|
+
[localization]="localizationText"
|
|
6401
|
+
[attachmentTemplate]="attachmentTemplate"
|
|
6402
|
+
[authorId]="authorId"
|
|
6403
|
+
(executeAction)="dispatchAction($event)"
|
|
6404
|
+
(resize)="anchor.scrollToBottom()"
|
|
6405
|
+
(navigate)="this.autoScroll = false"
|
|
6406
|
+
>
|
|
6407
|
+
</kendo-chat-message-list>
|
|
6408
|
+
</ng-template>
|
|
5262
6409
|
</div>
|
|
5263
6410
|
<kendo-message-box
|
|
5264
6411
|
#messageBox
|
|
@@ -5276,7 +6423,16 @@ class ChatComponent {
|
|
|
5276
6423
|
(fileRemove)="fileRemove.emit($event)"
|
|
5277
6424
|
>
|
|
5278
6425
|
</kendo-message-box>
|
|
5279
|
-
|
|
6426
|
+
|
|
6427
|
+
<kendo-contextmenu
|
|
6428
|
+
#messagesContextMenu
|
|
6429
|
+
[items]="contextMenuActions"
|
|
6430
|
+
[popupAlign]="{ horizontal: 'right', vertical: 'top' }"
|
|
6431
|
+
[collision]="{ horizontal: 'flip', vertical: 'flip'}"
|
|
6432
|
+
(popupClose)="handleMenuClose($event)"
|
|
6433
|
+
(select)="onContextMenuAction($event.item.originalAction)"
|
|
6434
|
+
></kendo-contextmenu>
|
|
6435
|
+
`, isInline: true, dependencies: [{ kind: "directive", type: LocalizedMessagesDirective$1, selector: "[kendoChatLocalizedMessages]" }, { kind: "directive", type: ScrollAnchorDirective, selector: "[kendoChatScrollAnchor]", inputs: ["autoScroll"], outputs: ["autoScrollChange"], exportAs: ["scrollAnchor"] }, { kind: "component", type: MessageListComponent, selector: "kendo-chat-message-list", inputs: ["messages", "attachmentTemplate", "authorMessageContentTemplate", "receiverMessageContentTemplate", "messageContentTemplate", "authorMessageTemplate", "receiverMessageTemplate", "messageTemplate", "timestampTemplate", "statusTemplate", "userStatusTemplate", "localization", "authorId"], outputs: ["executeAction", "navigate", "resize"] }, { kind: "component", type: MessageBoxComponent, selector: "kendo-message-box", inputs: ["authorId", "autoScroll", "suggestions", "placeholder", "inputValue", "localization", "messageBoxTemplate", "suggestionTemplate"], outputs: ["sendMessage", "executeSuggestion", "fileSelect", "fileRemove"] }, { kind: "component", type: MessageReferenceComponent, selector: "chat-message-reference-content", inputs: ["message"] }, { kind: "component", type: AppBarComponent, selector: "kendo-appbar", inputs: ["position", "positionMode", "themeColor"], exportAs: ["kendoAppBar"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: IconWrapperComponent, selector: "kendo-icon-wrapper", inputs: ["name", "svgIcon", "innerCssClass", "customFontClass", "size"], exportAs: ["kendoIconWrapper"] }, { kind: "component", type: i2.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "component", type: ContextMenuComponent, selector: "kendo-contextmenu", inputs: ["showOn", "target", "filter", "alignToAnchor", "vertical", "popupAnimate", "popupAlign", "anchorAlign", "collision", "appendTo", "ariaLabel"], outputs: ["popupOpen", "popupClose", "select", "open", "close"], exportAs: ["kendoContextMenu"] }] });
|
|
5280
6436
|
}
|
|
5281
6437
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ChatComponent, decorators: [{
|
|
5282
6438
|
type: Component,
|
|
@@ -5284,6 +6440,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
5284
6440
|
providers: [
|
|
5285
6441
|
LocalizationService,
|
|
5286
6442
|
ChatService,
|
|
6443
|
+
SuggestionsScrollService,
|
|
5287
6444
|
{
|
|
5288
6445
|
provide: L10N_PREFIX,
|
|
5289
6446
|
useValue: 'kendo.chat'
|
|
@@ -5339,10 +6496,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
5339
6496
|
|
|
5340
6497
|
i18n-downloadAllFilesText="kendo.chat.downloadAllFilesText|Sets the text that is displayed in the download section of the message."
|
|
5341
6498
|
downloadAllFilesText="Download all"
|
|
6499
|
+
|
|
6500
|
+
i18n-previousSuggestionsButtonTitle="kendo.chat.previousSuggestionsButtonTitle|The title of the button that scrolls to the previous suggestions"
|
|
6501
|
+
previousSuggestionsButtonTitle="Scroll left"
|
|
6502
|
+
|
|
6503
|
+
i18n-nextSuggestionsButtonTitle="kendo.chat.nextSuggestionsButtonTitle|The title of the button that scrolls to the next suggestions"
|
|
6504
|
+
nextSuggestionsButtonTitle="Scroll right"
|
|
5342
6505
|
>
|
|
5343
6506
|
</ng-container>
|
|
5344
6507
|
|
|
5345
|
-
<kendo-appbar *ngIf="chatHeaderTemplate" class="k-chat-header" positionMode="sticky">
|
|
6508
|
+
<kendo-appbar *ngIf="chatHeaderTemplate" class="k-chat-header" positionMode="sticky" themeColor="inherit">
|
|
5346
6509
|
<ng-container *ngTemplateOutlet="chatHeaderTemplate.templateRef"></ng-container>
|
|
5347
6510
|
</kendo-appbar>
|
|
5348
6511
|
<div class="k-message-reference k-message-reference-receiver k-message-pinned" *ngIf="pinnedMessage" (click)="scrollToPinnedMessage()">
|
|
@@ -5358,7 +6521,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
5358
6521
|
</div>
|
|
5359
6522
|
<div
|
|
5360
6523
|
#messageList
|
|
5361
|
-
class="k-message-list
|
|
6524
|
+
class="k-message-list"
|
|
5362
6525
|
aria-live="polite"
|
|
5363
6526
|
role="log"
|
|
5364
6527
|
kendoChatScrollAnchor
|
|
@@ -5366,19 +6529,32 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
5366
6529
|
#anchor="scrollAnchor"
|
|
5367
6530
|
[(autoScroll)]="autoScroll"
|
|
5368
6531
|
>
|
|
5369
|
-
<
|
|
5370
|
-
|
|
5371
|
-
|
|
5372
|
-
|
|
5373
|
-
|
|
5374
|
-
|
|
5375
|
-
|
|
5376
|
-
|
|
5377
|
-
|
|
5378
|
-
|
|
5379
|
-
|
|
5380
|
-
|
|
5381
|
-
|
|
6532
|
+
<div *ngIf="processedMessages && processedMessages.length === 0; else chatMessageList" class="k-message-list-content k-message-list-content-empty">
|
|
6533
|
+
<ng-template
|
|
6534
|
+
[ngTemplateOutlet]="chatNoDataTemplate?.templateRef">
|
|
6535
|
+
</ng-template>
|
|
6536
|
+
</div>
|
|
6537
|
+
<ng-template #chatMessageList>
|
|
6538
|
+
<kendo-chat-message-list
|
|
6539
|
+
[messages]="processedMessages"
|
|
6540
|
+
[authorMessageContentTemplate]="authorMessageContentTemplate"
|
|
6541
|
+
[receiverMessageContentTemplate]="receiverMessageContentTemplate"
|
|
6542
|
+
[messageContentTemplate]="messageContentTemplate"
|
|
6543
|
+
[authorMessageTemplate]="authorMessageTemplate"
|
|
6544
|
+
[receiverMessageTemplate]="receiverMessageTemplate"
|
|
6545
|
+
[messageTemplate]="messageTemplate"
|
|
6546
|
+
[timestampTemplate]="timestampTemplate"
|
|
6547
|
+
[statusTemplate]="statusTemplate"
|
|
6548
|
+
[userStatusTemplate]="userStatusTemplate"
|
|
6549
|
+
[localization]="localizationText"
|
|
6550
|
+
[attachmentTemplate]="attachmentTemplate"
|
|
6551
|
+
[authorId]="authorId"
|
|
6552
|
+
(executeAction)="dispatchAction($event)"
|
|
6553
|
+
(resize)="anchor.scrollToBottom()"
|
|
6554
|
+
(navigate)="this.autoScroll = false"
|
|
6555
|
+
>
|
|
6556
|
+
</kendo-chat-message-list>
|
|
6557
|
+
</ng-template>
|
|
5382
6558
|
</div>
|
|
5383
6559
|
<kendo-message-box
|
|
5384
6560
|
#messageBox
|
|
@@ -5396,9 +6572,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
5396
6572
|
(fileRemove)="fileRemove.emit($event)"
|
|
5397
6573
|
>
|
|
5398
6574
|
</kendo-message-box>
|
|
6575
|
+
|
|
6576
|
+
<kendo-contextmenu
|
|
6577
|
+
#messagesContextMenu
|
|
6578
|
+
[items]="contextMenuActions"
|
|
6579
|
+
[popupAlign]="{ horizontal: 'right', vertical: 'top' }"
|
|
6580
|
+
[collision]="{ horizontal: 'flip', vertical: 'flip'}"
|
|
6581
|
+
(popupClose)="handleMenuClose($event)"
|
|
6582
|
+
(select)="onContextMenuAction($event.item.originalAction)"
|
|
6583
|
+
></kendo-contextmenu>
|
|
5399
6584
|
`,
|
|
5400
6585
|
standalone: true,
|
|
5401
|
-
imports: [LocalizedMessagesDirective$1, ScrollAnchorDirective, MessageListComponent, MessageBoxComponent, MessageReferenceComponent, AppBarComponent, NgTemplateOutlet, NgIf, IconWrapperComponent, KENDO_BUTTON]
|
|
6586
|
+
imports: [LocalizedMessagesDirective$1, ScrollAnchorDirective, MessageListComponent, MessageBoxComponent, MessageReferenceComponent, AppBarComponent, NgTemplateOutlet, NgIf, IconWrapperComponent, KENDO_BUTTON, ContextMenuComponent]
|
|
5402
6587
|
}]
|
|
5403
6588
|
}], ctorParameters: () => [{ type: i1.LocalizationService }, { type: i0.NgZone }, { type: i0.Renderer2 }, { type: i0.ElementRef }, { type: ChatService }], propDecorators: { messages: [{
|
|
5404
6589
|
type: Input
|
|
@@ -5424,13 +6609,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
5424
6609
|
type: Input
|
|
5425
6610
|
}], inputValue: [{
|
|
5426
6611
|
type: Input
|
|
6612
|
+
}], authorMessageSettings: [{
|
|
6613
|
+
type: Input
|
|
6614
|
+
}], receiverMessageSettings: [{
|
|
6615
|
+
type: Input
|
|
5427
6616
|
}], messageContextMenuActions: [{
|
|
5428
6617
|
type: Input
|
|
5429
6618
|
}], fileActions: [{
|
|
5430
6619
|
type: Input
|
|
5431
|
-
}],
|
|
6620
|
+
}], messageFilesLayout: [{
|
|
6621
|
+
type: Input
|
|
6622
|
+
}], suggestionsLayout: [{
|
|
5432
6623
|
type: Input
|
|
5433
|
-
}],
|
|
6624
|
+
}], quickActionsLayout: [{
|
|
6625
|
+
type: Input
|
|
6626
|
+
}], suggestions: [{
|
|
5434
6627
|
type: Input
|
|
5435
6628
|
}], sendButtonSettings: [{
|
|
5436
6629
|
type: Input
|
|
@@ -5464,12 +6657,33 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
5464
6657
|
}], dirAttr: [{
|
|
5465
6658
|
type: HostBinding,
|
|
5466
6659
|
args: ['attr.dir']
|
|
6660
|
+
}], messagesContextMenu: [{
|
|
6661
|
+
type: ViewChild,
|
|
6662
|
+
args: ['messagesContextMenu']
|
|
5467
6663
|
}], attachmentTemplate: [{
|
|
5468
6664
|
type: ContentChild,
|
|
5469
6665
|
args: [AttachmentTemplateDirective]
|
|
5470
6666
|
}], chatHeaderTemplate: [{
|
|
5471
6667
|
type: ContentChild,
|
|
5472
6668
|
args: [ChatHeaderTemplateDirective]
|
|
6669
|
+
}], chatNoDataTemplate: [{
|
|
6670
|
+
type: ContentChild,
|
|
6671
|
+
args: [NoDataTemplateDirective]
|
|
6672
|
+
}], authorMessageContentTemplate: [{
|
|
6673
|
+
type: ContentChild,
|
|
6674
|
+
args: [AuthorMessageContentTemplateDirective]
|
|
6675
|
+
}], receiverMessageContentTemplate: [{
|
|
6676
|
+
type: ContentChild,
|
|
6677
|
+
args: [ReceiverMessageContentTemplateDirective]
|
|
6678
|
+
}], messageContentTemplate: [{
|
|
6679
|
+
type: ContentChild,
|
|
6680
|
+
args: [MessageContentTemplateDirective]
|
|
6681
|
+
}], authorMessageTemplate: [{
|
|
6682
|
+
type: ContentChild,
|
|
6683
|
+
args: [AuthorMessageTemplateDirective]
|
|
6684
|
+
}], receiverMessageTemplate: [{
|
|
6685
|
+
type: ContentChild,
|
|
6686
|
+
args: [ReceiverMessageTemplateDirective]
|
|
5473
6687
|
}], messageTemplate: [{
|
|
5474
6688
|
type: ContentChild,
|
|
5475
6689
|
args: [MessageTemplateDirective]
|
|
@@ -5485,6 +6699,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
5485
6699
|
}], messageBoxTemplate: [{
|
|
5486
6700
|
type: ContentChild,
|
|
5487
6701
|
args: [ChatMessageBoxTemplateDirective]
|
|
6702
|
+
}], userStatusTemplate: [{
|
|
6703
|
+
type: ContentChild,
|
|
6704
|
+
args: [ChatUserStatusTemplateDirective]
|
|
5488
6705
|
}], messageBox: [{
|
|
5489
6706
|
type: ViewChild,
|
|
5490
6707
|
args: ['messageBox']
|
|
@@ -6724,13 +7941,20 @@ const KENDO_CHAT = [
|
|
|
6724
7941
|
ChatComponent,
|
|
6725
7942
|
CustomMessagesComponent,
|
|
6726
7943
|
AttachmentTemplateDirective,
|
|
7944
|
+
AuthorMessageContentTemplateDirective,
|
|
7945
|
+
ReceiverMessageContentTemplateDirective,
|
|
7946
|
+
MessageContentTemplateDirective,
|
|
7947
|
+
AuthorMessageTemplateDirective,
|
|
7948
|
+
ReceiverMessageTemplateDirective,
|
|
6727
7949
|
MessageTemplateDirective,
|
|
6728
7950
|
HeroCardComponent,
|
|
6729
7951
|
ChatMessageBoxTemplateDirective,
|
|
6730
7952
|
ChatHeaderTemplateDirective,
|
|
7953
|
+
NoDataTemplateDirective,
|
|
6731
7954
|
ChatTimestampTemplateDirective,
|
|
6732
7955
|
ChatStatusTemplateDirective,
|
|
6733
|
-
ChatSuggestionTemplateDirective
|
|
7956
|
+
ChatSuggestionTemplateDirective,
|
|
7957
|
+
ChatUserStatusTemplateDirective
|
|
6734
7958
|
];
|
|
6735
7959
|
/**
|
|
6736
7960
|
* Utility array that contains all InlineAIPrompt related components and directives.
|
|
@@ -6837,7 +8061,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
6837
8061
|
*/
|
|
6838
8062
|
class ChatModule {
|
|
6839
8063
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ChatModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
6840
|
-
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.14", ngImport: i0, type: ChatModule, imports: [ChatComponent, CustomMessagesComponent, AttachmentTemplateDirective, MessageTemplateDirective, HeroCardComponent, ChatMessageBoxTemplateDirective, ChatHeaderTemplateDirective, ChatTimestampTemplateDirective, ChatStatusTemplateDirective, ChatSuggestionTemplateDirective], exports: [ChatComponent, CustomMessagesComponent, AttachmentTemplateDirective, MessageTemplateDirective, HeroCardComponent, ChatMessageBoxTemplateDirective, ChatHeaderTemplateDirective, ChatTimestampTemplateDirective, ChatStatusTemplateDirective, ChatSuggestionTemplateDirective] });
|
|
8064
|
+
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.14", ngImport: i0, type: ChatModule, imports: [ChatComponent, CustomMessagesComponent, AttachmentTemplateDirective, AuthorMessageContentTemplateDirective, ReceiverMessageContentTemplateDirective, MessageContentTemplateDirective, AuthorMessageTemplateDirective, ReceiverMessageTemplateDirective, MessageTemplateDirective, HeroCardComponent, ChatMessageBoxTemplateDirective, ChatHeaderTemplateDirective, NoDataTemplateDirective, ChatTimestampTemplateDirective, ChatStatusTemplateDirective, ChatSuggestionTemplateDirective, ChatUserStatusTemplateDirective], exports: [ChatComponent, CustomMessagesComponent, AttachmentTemplateDirective, AuthorMessageContentTemplateDirective, ReceiverMessageContentTemplateDirective, MessageContentTemplateDirective, AuthorMessageTemplateDirective, ReceiverMessageTemplateDirective, MessageTemplateDirective, HeroCardComponent, ChatMessageBoxTemplateDirective, ChatHeaderTemplateDirective, NoDataTemplateDirective, ChatTimestampTemplateDirective, ChatStatusTemplateDirective, ChatSuggestionTemplateDirective, ChatUserStatusTemplateDirective] });
|
|
6841
8065
|
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ChatModule, providers: [IconsService, ResizeBatchService], imports: [ChatComponent, HeroCardComponent] });
|
|
6842
8066
|
}
|
|
6843
8067
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ChatModule, decorators: [{
|
|
@@ -6870,7 +8094,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
6870
8094
|
*/
|
|
6871
8095
|
class ConversationalUIModule {
|
|
6872
8096
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ConversationalUIModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
6873
|
-
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.14", ngImport: i0, type: ConversationalUIModule, imports: [AIPromptComponent, PromptViewComponent, OutputViewComponent, CommandViewComponent, CustomViewComponent, AIPromptCustomMessagesComponent, AIPromptToolbarActionsDirective, AIPromptToolbarFocusableDirective, AIPromptOutputTemplateDirective, AIPromptOutputBodyTemplateDirective, ChatComponent, CustomMessagesComponent, AttachmentTemplateDirective, MessageTemplateDirective, HeroCardComponent, ChatMessageBoxTemplateDirective, ChatHeaderTemplateDirective, ChatTimestampTemplateDirective, ChatStatusTemplateDirective, ChatSuggestionTemplateDirective, InlineAIPromptComponent, InlineAIPromptOutputTemplateDirective, InlineAIPromptCustomMessagesComponent], exports: [AIPromptComponent, PromptViewComponent, OutputViewComponent, CommandViewComponent, CustomViewComponent, AIPromptCustomMessagesComponent, AIPromptToolbarActionsDirective, AIPromptToolbarFocusableDirective, AIPromptOutputTemplateDirective, AIPromptOutputBodyTemplateDirective, ChatComponent, CustomMessagesComponent, AttachmentTemplateDirective, MessageTemplateDirective, HeroCardComponent, ChatMessageBoxTemplateDirective, ChatHeaderTemplateDirective, ChatTimestampTemplateDirective, ChatStatusTemplateDirective, ChatSuggestionTemplateDirective, InlineAIPromptComponent, InlineAIPromptOutputTemplateDirective, InlineAIPromptCustomMessagesComponent] });
|
|
8097
|
+
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.14", ngImport: i0, type: ConversationalUIModule, imports: [AIPromptComponent, PromptViewComponent, OutputViewComponent, CommandViewComponent, CustomViewComponent, AIPromptCustomMessagesComponent, AIPromptToolbarActionsDirective, AIPromptToolbarFocusableDirective, AIPromptOutputTemplateDirective, AIPromptOutputBodyTemplateDirective, ChatComponent, CustomMessagesComponent, AttachmentTemplateDirective, AuthorMessageContentTemplateDirective, ReceiverMessageContentTemplateDirective, MessageContentTemplateDirective, AuthorMessageTemplateDirective, ReceiverMessageTemplateDirective, MessageTemplateDirective, HeroCardComponent, ChatMessageBoxTemplateDirective, ChatHeaderTemplateDirective, NoDataTemplateDirective, ChatTimestampTemplateDirective, ChatStatusTemplateDirective, ChatSuggestionTemplateDirective, ChatUserStatusTemplateDirective, InlineAIPromptComponent, InlineAIPromptOutputTemplateDirective, InlineAIPromptCustomMessagesComponent], exports: [AIPromptComponent, PromptViewComponent, OutputViewComponent, CommandViewComponent, CustomViewComponent, AIPromptCustomMessagesComponent, AIPromptToolbarActionsDirective, AIPromptToolbarFocusableDirective, AIPromptOutputTemplateDirective, AIPromptOutputBodyTemplateDirective, ChatComponent, CustomMessagesComponent, AttachmentTemplateDirective, AuthorMessageContentTemplateDirective, ReceiverMessageContentTemplateDirective, MessageContentTemplateDirective, AuthorMessageTemplateDirective, ReceiverMessageTemplateDirective, MessageTemplateDirective, HeroCardComponent, ChatMessageBoxTemplateDirective, ChatHeaderTemplateDirective, NoDataTemplateDirective, ChatTimestampTemplateDirective, ChatStatusTemplateDirective, ChatSuggestionTemplateDirective, ChatUserStatusTemplateDirective, InlineAIPromptComponent, InlineAIPromptOutputTemplateDirective, InlineAIPromptCustomMessagesComponent] });
|
|
6874
8098
|
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ConversationalUIModule, providers: [IconsService, PopupService, ResizeBatchService, DialogContainerService, DialogService, WindowService, WindowContainerService], imports: [AIPromptComponent, PromptViewComponent, OutputViewComponent, CommandViewComponent, ChatComponent, HeroCardComponent, InlineAIPromptComponent] });
|
|
6875
8099
|
}
|
|
6876
8100
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ConversationalUIModule, decorators: [{
|
|
@@ -7058,5 +8282,5 @@ class InlineAIPromptSettings {
|
|
|
7058
8282
|
* Generated bundle index. Do not edit.
|
|
7059
8283
|
*/
|
|
7060
8284
|
|
|
7061
|
-
export { AIPromptComponent, AIPromptCustomMessagesComponent, AIPromptModule, AIPromptOutputBodyTemplateDirective, AIPromptOutputTemplateDirective, AIPromptToolbarActionsDirective, AIPromptToolbarFocusableDirective, AttachmentTemplateDirective, ChatComponent, ChatHeaderTemplateDirective, ChatMessageBoxTemplateDirective, ChatModule, ChatStatusTemplateDirective, ChatSuggestionTemplateDirective, ChatTimestampTemplateDirective, CommandViewComponent, ConversationalUIModule, CustomMessagesComponent, CustomViewComponent, ExecuteActionEvent, HeroCardComponent, InlineAIPromptComponent, InlineAIPromptCustomMessagesComponent, InlineAIPromptModule, InlineAIPromptOutputTemplateDirective, InlineAIPromptService, InlineAIPromptSettings, KENDO_AIPROMPT, KENDO_CHAT, KENDO_CONVERSATIONALUI, KENDO_INLINEAIPROMPT, MessageTemplateDirective, OutputViewComponent, PromptViewComponent, SendMessageEvent };
|
|
8285
|
+
export { AIPromptComponent, AIPromptCustomMessagesComponent, AIPromptModule, AIPromptOutputBodyTemplateDirective, AIPromptOutputTemplateDirective, AIPromptToolbarActionsDirective, AIPromptToolbarFocusableDirective, AttachmentTemplateDirective, AuthorMessageContentTemplateDirective, AuthorMessageTemplateDirective, ChatComponent, ChatHeaderTemplateDirective, ChatMessageBoxTemplateDirective, ChatModule, ChatStatusTemplateDirective, ChatSuggestionTemplateDirective, ChatTimestampTemplateDirective, ChatUserStatusTemplateDirective, CommandViewComponent, ConversationalUIModule, CustomMessagesComponent, CustomViewComponent, ExecuteActionEvent, HeroCardComponent, InlineAIPromptComponent, InlineAIPromptCustomMessagesComponent, InlineAIPromptModule, InlineAIPromptOutputTemplateDirective, InlineAIPromptService, InlineAIPromptSettings, KENDO_AIPROMPT, KENDO_CHAT, KENDO_CONVERSATIONALUI, KENDO_INLINEAIPROMPT, MessageContentTemplateDirective, MessageTemplateDirective, NoDataTemplateDirective, OutputViewComponent, PromptViewComponent, ReceiverMessageContentTemplateDirective, ReceiverMessageTemplateDirective, SendMessageEvent };
|
|
7062
8286
|
|