stream-chat-angular 3.0.0-beta.1 → 3.0.0-beta.10
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/README.md +44 -12
- package/assets/version.d.ts +1 -1
- package/bundles/stream-chat-angular.umd.js +919 -575
- package/bundles/stream-chat-angular.umd.js.map +1 -1
- package/esm2015/assets/version.js +2 -2
- package/esm2015/lib/attachment-list/attachment-list.component.js +27 -15
- package/esm2015/lib/attachment-preview-list/attachment-preview-list.component.js +28 -22
- package/esm2015/lib/attachment.service.js +11 -5
- package/esm2015/lib/avatar-placeholder/avatar-placeholder.component.js +41 -0
- package/esm2015/lib/channel-header/channel-header.component.js +26 -9
- package/esm2015/lib/channel-list/channel-list.component.js +23 -13
- package/esm2015/lib/channel-preview/channel-preview.component.js +3 -3
- package/esm2015/lib/channel.service.js +87 -82
- package/esm2015/lib/chat-client.service.js +29 -4
- package/esm2015/lib/custom-templates.service.js +139 -0
- package/esm2015/lib/icon-placeholder/icon-placeholder.component.js +34 -0
- package/esm2015/lib/loading-indicator-placeholder/loading-indicator-placeholder.component.js +42 -0
- package/esm2015/lib/message/message.component.js +67 -17
- package/esm2015/lib/message-actions-box/message-actions-box.component.js +114 -99
- package/esm2015/lib/message-input/autocomplete-textarea/autocomplete-textarea.component.js +13 -13
- package/esm2015/lib/message-input/message-input-config.service.js +1 -1
- package/esm2015/lib/message-input/message-input.component.js +55 -34
- package/esm2015/lib/message-input/textarea.directive.js +2 -18
- package/esm2015/lib/message-input/textarea.interface.js +1 -1
- package/esm2015/lib/message-list/message-list.component.js +31 -22
- package/esm2015/lib/message-preview.js +4 -17
- package/esm2015/lib/message-reactions/message-reactions.component.js +3 -3
- package/esm2015/lib/modal/modal.component.js +9 -6
- package/esm2015/lib/notification/notification.component.js +5 -2
- package/esm2015/lib/notification-list/notification-list.component.js +16 -11
- package/esm2015/lib/notification.service.js +34 -18
- package/esm2015/lib/read-by.js +1 -1
- package/esm2015/lib/stream-avatar.module.js +5 -4
- package/esm2015/lib/stream-chat.module.js +13 -3
- package/esm2015/lib/thread/thread.component.js +19 -11
- package/esm2015/lib/types.js +1 -1
- package/esm2015/public-api.js +5 -1
- package/fesm2015/stream-chat-angular.js +835 -419
- package/fesm2015/stream-chat-angular.js.map +1 -1
- package/lib/attachment-list/attachment-list.component.d.ts +12 -8
- package/lib/attachment-preview-list/attachment-preview-list.component.d.ts +17 -7
- package/lib/attachment.service.d.ts +1 -1
- package/lib/avatar-placeholder/avatar-placeholder.component.d.ts +25 -0
- package/lib/channel-header/channel-header.component.d.ts +14 -4
- package/lib/channel-list/channel-list.component.d.ts +14 -11
- package/lib/channel-preview/channel-preview.component.d.ts +3 -2
- package/lib/channel.service.d.ts +36 -35
- package/lib/chat-client.service.d.ts +18 -11
- package/lib/custom-templates.service.d.ts +132 -0
- package/lib/icon-placeholder/icon-placeholder.component.d.ts +22 -0
- package/lib/loading-indicator-placeholder/loading-indicator-placeholder.component.d.ts +21 -0
- package/lib/message/message.component.d.ts +40 -15
- package/lib/message-actions-box/message-actions-box.component.d.ts +22 -22
- package/lib/message-input/autocomplete-textarea/autocomplete-textarea.component.d.ts +7 -11
- package/lib/message-input/message-input-config.service.d.ts +0 -14
- package/lib/message-input/message-input.component.d.ts +40 -19
- package/lib/message-input/textarea.directive.d.ts +3 -6
- package/lib/message-input/textarea.interface.d.ts +1 -4
- package/lib/message-list/group-styles.d.ts +1 -1
- package/lib/message-list/message-list.component.d.ts +10 -22
- package/lib/message-preview.d.ts +2 -1
- package/lib/message-reactions/message-reactions.component.d.ts +4 -5
- package/lib/modal/modal.component.d.ts +7 -3
- package/lib/notification/notification.component.d.ts +7 -2
- package/lib/notification-list/notification-list.component.d.ts +9 -3
- package/lib/notification.service.d.ts +14 -13
- package/lib/read-by.d.ts +2 -1
- package/lib/stream-avatar.module.d.ts +4 -3
- package/lib/stream-chat.module.d.ts +6 -4
- package/lib/thread/thread.component.d.ts +6 -3
- package/lib/types.d.ts +126 -9
- package/package.json +2 -3
- package/public-api.d.ts +4 -0
- package/src/assets/styles/assets/EmojiOneColor.woff2 +0 -0
- package/src/assets/styles/assets/NotoColorEmoji-flags.woff2 +0 -0
- package/src/assets/styles/assets/Poweredby_100px-White_VertText.png +0 -0
- package/src/assets/styles/assets/str-chat__reaction-list-sprite@1x.png +0 -0
- package/src/assets/styles/assets/str-chat__reaction-list-sprite@2x.png +0 -0
- package/src/assets/styles/assets/str-chat__reaction-list-sprite@3x.png +0 -0
- package/src/assets/styles/css/index.css +1 -0
- package/src/assets/styles/css/index.css.map +1 -0
- package/src/assets/styles/scss/ActionsBox.scss +56 -0
- package/src/assets/styles/scss/Attachment.scss +227 -0
- package/src/assets/styles/scss/AttachmentActions.scss +44 -0
- package/src/assets/styles/scss/Audio.scss +112 -0
- package/src/assets/styles/scss/Avatar.scss +79 -0
- package/src/assets/styles/scss/Card.scss +100 -0
- package/src/assets/styles/scss/ChannelHeader.scss +284 -0
- package/src/assets/styles/scss/ChannelList.scss +117 -0
- package/src/assets/styles/scss/ChannelListMessenger.scss +9 -0
- package/src/assets/styles/scss/ChannelPreview.scss +108 -0
- package/src/assets/styles/scss/ChannelSearch.scss +111 -0
- package/src/assets/styles/scss/ChatDown.scss +15 -0
- package/src/assets/styles/scss/DateSeparator.scss +51 -0
- package/src/assets/styles/scss/EditMessageForm.scss +112 -0
- package/src/assets/styles/scss/EventComponent.scss +48 -0
- package/src/assets/styles/scss/Gallery.scss +135 -0
- package/src/assets/styles/scss/InfiniteScrollPaginator.scss +6 -0
- package/src/assets/styles/scss/LoadMoreButton.scss +44 -0
- package/src/assets/styles/scss/LoadingChannels.scss +70 -0
- package/src/assets/styles/scss/LoadingIndicator.scss +38 -0
- package/src/assets/styles/scss/Message.scss +1261 -0
- package/src/assets/styles/scss/MessageActions.scss +112 -0
- package/src/assets/styles/scss/MessageCommerce.scss +564 -0
- package/src/assets/styles/scss/MessageInput.scss +385 -0
- package/src/assets/styles/scss/MessageInputFlat.scss +305 -0
- package/src/assets/styles/scss/MessageList.scss +203 -0
- package/src/assets/styles/scss/MessageLivestream.scss +325 -0
- package/src/assets/styles/scss/MessageNotification.scss +49 -0
- package/src/assets/styles/scss/MessageRepliesCountButton.scss +33 -0
- package/src/assets/styles/scss/MessageTeam.scss +617 -0
- package/src/assets/styles/scss/Modal.scss +77 -0
- package/src/assets/styles/scss/ReactionList.scss +183 -0
- package/src/assets/styles/scss/ReactionSelector.scss +212 -0
- package/src/assets/styles/scss/SendButton.scss +14 -0
- package/src/assets/styles/scss/SimpleReactionsList.scss +76 -0
- package/src/assets/styles/scss/SmallMessageInput.scss +172 -0
- package/src/assets/styles/scss/Thread.scss +306 -0
- package/src/assets/styles/scss/Tooltip.scss +38 -0
- package/src/assets/styles/scss/TypingIndicator.scss +75 -0
- package/src/assets/styles/scss/VirtualMessage.scss +291 -0
- package/src/assets/styles/scss/_base.scss +206 -0
- package/src/assets/styles/scss/_variables.scss +158 -0
- package/src/assets/styles/scss/index.scss +50 -0
- package/src/assets/styles/scss/vendor/emoji-mart.scss +495 -0
- package/src/assets/styles/scss/vendor/mml-react.scss +1749 -0
- package/src/assets/styles/scss/vendor/react-file-utils.scss +378 -0
- package/src/assets/styles/scss/vendor/react-image-gallery.scss +224 -0
- package/src/assets/version.ts +1 -1
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
import { __awaiter } from 'tslib';
|
|
2
2
|
import * as i0 from '@angular/core';
|
|
3
|
-
import { Injectable, Component, Input,
|
|
3
|
+
import { Injectable, Component, Input, EventEmitter, Output, ViewChild, InjectionToken, Directive, Inject, HostBinding, NgModule } from '@angular/core';
|
|
4
4
|
import { BehaviorSubject, ReplaySubject, combineLatest, Subject, timer, of } from 'rxjs';
|
|
5
5
|
import { StreamChat } from 'stream-chat';
|
|
6
6
|
import { map, shareReplay, filter, first, take, tap, catchError, startWith, distinctUntilChanged, debounceTime } from 'rxjs/operators';
|
|
7
7
|
import { v4 } from 'uuid';
|
|
8
8
|
import * as i2 from '@ngx-translate/core';
|
|
9
9
|
import { TranslateModule } from '@ngx-translate/core';
|
|
10
|
-
import * as
|
|
10
|
+
import * as i3 from '@angular/common';
|
|
11
11
|
import { CommonModule } from '@angular/common';
|
|
12
12
|
import prettybytes from 'pretty-bytes';
|
|
13
13
|
import Dayjs from 'dayjs';
|
|
14
14
|
import calendar from 'dayjs/plugin/calendar';
|
|
15
15
|
import emojiRegex from 'emoji-regex';
|
|
16
16
|
import transliterate from '@stream-io/transliterate';
|
|
17
|
-
import * as
|
|
17
|
+
import * as i7 from 'angular-mentions';
|
|
18
18
|
import { MentionModule } from 'angular-mentions';
|
|
19
19
|
|
|
20
|
-
const version = '3.0.0-beta.
|
|
20
|
+
const version = '3.0.0-beta.10';
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
23
|
* The `NotificationService` can be used to add or remove notifications. By default the [`NotificationList`](../components/NotificationListComponent.mdx) component displays the currently active notifications.
|
|
@@ -29,40 +29,56 @@ class NotificationService {
|
|
|
29
29
|
}
|
|
30
30
|
/**
|
|
31
31
|
* Displays a notification for the given amount of time.
|
|
32
|
-
* @param
|
|
32
|
+
* @param content The text of the notification or the HTML template for the notification
|
|
33
33
|
* @param type The type of the notification
|
|
34
34
|
* @param timeout The number of milliseconds while the notification should be visible
|
|
35
|
-
* @param translateParams Translation parameters for the `text
|
|
35
|
+
* @param translateParams Translation parameters for the `content` (for text notifications)
|
|
36
|
+
* @param templateContext The input of the notification template (for HTML notifications)
|
|
36
37
|
* @returns A method to clear the notification (before the timeout).
|
|
37
38
|
*/
|
|
38
|
-
addTemporaryNotification(
|
|
39
|
-
this.
|
|
40
|
-
const id = setTimeout(() => this.removeNotification(
|
|
41
|
-
|
|
39
|
+
addTemporaryNotification(content, type = 'error', timeout = 5000, translateParams, templateContext) {
|
|
40
|
+
const notification = this.createNotification(content, type, translateParams, templateContext);
|
|
41
|
+
const id = setTimeout(() => this.removeNotification(notification.id), timeout);
|
|
42
|
+
notification.dismissFn = () => {
|
|
42
43
|
clearTimeout(id);
|
|
43
|
-
this.removeNotification(
|
|
44
|
+
this.removeNotification(notification.id);
|
|
44
45
|
};
|
|
46
|
+
this.notificationsSubject.next([
|
|
47
|
+
...this.notificationsSubject.getValue(),
|
|
48
|
+
notification,
|
|
49
|
+
]);
|
|
50
|
+
return notification.dismissFn;
|
|
45
51
|
}
|
|
46
52
|
/**
|
|
47
53
|
* Displays a notification, that will be visible until it's removed.
|
|
48
|
-
* @param
|
|
54
|
+
* @param content The text of the notification or the HTML template for the notification
|
|
49
55
|
* @param type The type of the notification
|
|
50
|
-
* @param translateParams Translation parameters for the `text
|
|
56
|
+
* @param translateParams Translation parameters for the `content` (for text notifications)
|
|
57
|
+
* @param templateContext The input of the notification template (for HTML notifications)
|
|
51
58
|
* @returns A method to clear the notification.
|
|
52
59
|
*/
|
|
53
|
-
addPermanentNotification(
|
|
54
|
-
this.
|
|
55
|
-
return () => this.removeNotification(text);
|
|
56
|
-
}
|
|
57
|
-
addNotification(text, type, translateParams) {
|
|
60
|
+
addPermanentNotification(content, type = 'error', translateParams, templateContext) {
|
|
61
|
+
const notification = this.createNotification(content, type, translateParams, templateContext);
|
|
58
62
|
this.notificationsSubject.next([
|
|
59
63
|
...this.notificationsSubject.getValue(),
|
|
60
|
-
|
|
64
|
+
notification,
|
|
61
65
|
]);
|
|
66
|
+
return notification.dismissFn;
|
|
67
|
+
}
|
|
68
|
+
createNotification(content, type, translateParams, templateContext) {
|
|
69
|
+
const id = new Date().getTime().toString() + Math.random().toString();
|
|
70
|
+
return {
|
|
71
|
+
id,
|
|
72
|
+
[typeof content === 'string' ? 'text' : 'template']: content,
|
|
73
|
+
type,
|
|
74
|
+
translateParams,
|
|
75
|
+
templateContext,
|
|
76
|
+
dismissFn: () => this.removeNotification(id),
|
|
77
|
+
};
|
|
62
78
|
}
|
|
63
|
-
removeNotification(
|
|
79
|
+
removeNotification(id) {
|
|
64
80
|
const notifications = this.notificationsSubject.getValue();
|
|
65
|
-
const index = notifications.findIndex((n) => n.
|
|
81
|
+
const index = notifications.findIndex((n) => n.id === id);
|
|
66
82
|
if (index === -1) {
|
|
67
83
|
return;
|
|
68
84
|
}
|
|
@@ -89,9 +105,11 @@ class ChatClientService {
|
|
|
89
105
|
this.notificationSubject = new ReplaySubject(1);
|
|
90
106
|
this.connectionStateSubject = new ReplaySubject(1);
|
|
91
107
|
this.appSettingsSubject = new BehaviorSubject(undefined);
|
|
92
|
-
this.
|
|
108
|
+
this.pendingInvitesSubject = new BehaviorSubject([]);
|
|
109
|
+
this.events$ = this.notificationSubject.asObservable();
|
|
93
110
|
this.connectionState$ = this.connectionStateSubject.asObservable();
|
|
94
111
|
this.appSettings$ = this.appSettingsSubject.asObservable();
|
|
112
|
+
this.pendingInvites$ = this.pendingInvitesSubject.asObservable();
|
|
95
113
|
}
|
|
96
114
|
/**
|
|
97
115
|
* Creates a [`StreamChat`](https://github.com/GetStream/stream-chat-js/blob/668b3e5521339f4e14fc657834531b4c8bf8176b/src/client.ts#L124) instance using the provided `apiKey`, and connects a user with the given meta data and token. More info about [connecting users](https://getstream.io/chat/docs/javascript/init_and_users/?language=javascript) can be found in the platform documentation.
|
|
@@ -100,16 +118,21 @@ class ChatClientService {
|
|
|
100
118
|
* @param userTokenOrProvider
|
|
101
119
|
*/
|
|
102
120
|
init(apiKey, userOrId, userTokenOrProvider) {
|
|
121
|
+
var _a;
|
|
103
122
|
return __awaiter(this, void 0, void 0, function* () {
|
|
104
123
|
this.chatClient = StreamChat.getInstance(apiKey);
|
|
124
|
+
this.chatClient.devToken;
|
|
105
125
|
yield this.ngZone.runOutsideAngular(() => __awaiter(this, void 0, void 0, function* () {
|
|
106
126
|
const user = typeof userOrId === 'string' ? { id: userOrId } : userOrId;
|
|
107
127
|
yield this.chatClient.connectUser(user, userTokenOrProvider);
|
|
108
128
|
this.chatClient.setUserAgent(`stream-chat-angular-${version}-${this.chatClient.getUserAgent()}`);
|
|
109
|
-
this.chatClient.getAppSettings;
|
|
110
129
|
}));
|
|
130
|
+
const channels = yield this.chatClient.queryChannels({ invite: 'pending' }, // TODO: find out why we need this typecast
|
|
131
|
+
{}, { user_id: (_a = this.chatClient.user) === null || _a === void 0 ? void 0 : _a.id });
|
|
132
|
+
this.pendingInvitesSubject.next(channels);
|
|
111
133
|
this.appSettingsSubject.next(undefined);
|
|
112
134
|
this.chatClient.on((e) => {
|
|
135
|
+
this.updatePendingInvites(e);
|
|
113
136
|
this.notificationSubject.next({
|
|
114
137
|
eventType: e.type,
|
|
115
138
|
event: e,
|
|
@@ -138,6 +161,7 @@ class ChatClientService {
|
|
|
138
161
|
*/
|
|
139
162
|
disconnectUser() {
|
|
140
163
|
return __awaiter(this, void 0, void 0, function* () {
|
|
164
|
+
this.pendingInvitesSubject.next([]);
|
|
141
165
|
yield this.chatClient.disconnectUser();
|
|
142
166
|
});
|
|
143
167
|
}
|
|
@@ -178,10 +202,27 @@ class ChatClientService {
|
|
|
178
202
|
{ name: { $autocomplete: searchTerm } },
|
|
179
203
|
],
|
|
180
204
|
id: { $ne: this.chatClient.userID },
|
|
181
|
-
});
|
|
205
|
+
}); // TODO: find out why we need this typecast
|
|
182
206
|
return result.users;
|
|
183
207
|
});
|
|
184
208
|
}
|
|
209
|
+
updatePendingInvites(e) {
|
|
210
|
+
var _a, _b, _c;
|
|
211
|
+
if (((_b = (_a = e.member) === null || _a === void 0 ? void 0 : _a.user) === null || _b === void 0 ? void 0 : _b.id) === ((_c = this.chatClient.user) === null || _c === void 0 ? void 0 : _c.id) && e.channel) {
|
|
212
|
+
const pendingInvites = this.pendingInvitesSubject.getValue();
|
|
213
|
+
if (e.type === 'notification.invited') {
|
|
214
|
+
this.pendingInvitesSubject.next([...pendingInvites, e.channel]);
|
|
215
|
+
}
|
|
216
|
+
else if (e.type === 'notification.invite_accepted' ||
|
|
217
|
+
e.type === 'notification.invite_rejected') {
|
|
218
|
+
const index = pendingInvites.findIndex((i) => { var _a; return (i === null || i === void 0 ? void 0 : i.cid) === ((_a = e.channel) === null || _a === void 0 ? void 0 : _a.cid); });
|
|
219
|
+
if (index !== -1) {
|
|
220
|
+
pendingInvites.splice(index, 1);
|
|
221
|
+
this.pendingInvitesSubject.next([...pendingInvites]);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
185
226
|
}
|
|
186
227
|
ChatClientService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ChatClientService, deps: [{ token: i0.NgZone }, { token: NotificationService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
187
228
|
ChatClientService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ChatClientService, providedIn: 'root' });
|
|
@@ -192,23 +233,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
192
233
|
}]
|
|
193
234
|
}], ctorParameters: function () { return [{ type: i0.NgZone }, { type: NotificationService }]; } });
|
|
194
235
|
|
|
195
|
-
const createMessagePreview = (user, text, attachments = [], mentionedUsers = [], parentId = undefined, quotedMessageId = undefined) => {
|
|
236
|
+
const createMessagePreview = (user, text, attachments = [], mentionedUsers = [], parentId = undefined, quotedMessageId = undefined, customData) => {
|
|
196
237
|
const clientSideId = `${user.id}-${v4()}`;
|
|
197
|
-
return {
|
|
198
|
-
|
|
199
|
-
created_at: new Date(),
|
|
200
|
-
html: text,
|
|
201
|
-
id: clientSideId,
|
|
202
|
-
reactions: [],
|
|
203
|
-
status: 'sending',
|
|
204
|
-
text,
|
|
205
|
-
type: 'regular',
|
|
206
|
-
user,
|
|
207
|
-
attachments,
|
|
208
|
-
mentioned_users: mentionedUsers,
|
|
209
|
-
parent_id: parentId,
|
|
210
|
-
quoted_message_id: quotedMessageId,
|
|
211
|
-
};
|
|
238
|
+
return Object.assign({ __html: text, created_at: new Date(), html: text, id: clientSideId, reactions: [], status: 'sending', text, type: 'regular', user,
|
|
239
|
+
attachments, mentioned_users: mentionedUsers, parent_id: parentId, quoted_message_id: quotedMessageId }, customData);
|
|
212
240
|
};
|
|
213
241
|
|
|
214
242
|
const getReadBy = (message, channel) => {
|
|
@@ -244,7 +272,14 @@ class ChannelService {
|
|
|
244
272
|
this.usersTypingInChannelSubject = new BehaviorSubject([]);
|
|
245
273
|
this.usersTypingInThreadSubject = new BehaviorSubject([]);
|
|
246
274
|
this.channelListSetter = (channels) => {
|
|
247
|
-
this.channelsSubject.
|
|
275
|
+
const currentChannels = this.channelsSubject.getValue() || [];
|
|
276
|
+
const newChannels = channels.filter((c) => !currentChannels.find((channel) => channel.cid === c.cid));
|
|
277
|
+
const deletedChannels = currentChannels.filter((c) => !(channels === null || channels === void 0 ? void 0 : channels.find((channel) => channel.cid === c.cid)));
|
|
278
|
+
this.addChannelsFromNotification(newChannels);
|
|
279
|
+
this.removeChannelsFromChannelList(deletedChannels.map((c) => c.cid));
|
|
280
|
+
if (!newChannels.length && !deletedChannels.length) {
|
|
281
|
+
this.channelsSubject.next(channels);
|
|
282
|
+
}
|
|
248
283
|
};
|
|
249
284
|
this.messageListSetter = (messages) => {
|
|
250
285
|
this.activeChannelMessagesSubject.next(messages);
|
|
@@ -395,7 +430,7 @@ class ChannelService {
|
|
|
395
430
|
};
|
|
396
431
|
this.sort = sort || { last_message_at: -1, updated_at: -1 };
|
|
397
432
|
yield this.queryChannels();
|
|
398
|
-
this.chatClientService.
|
|
433
|
+
this.chatClientService.events$.subscribe((notification) => void this.handleNotification(notification));
|
|
399
434
|
});
|
|
400
435
|
}
|
|
401
436
|
/**
|
|
@@ -423,13 +458,12 @@ class ChannelService {
|
|
|
423
458
|
* Adds a reaction to a message.
|
|
424
459
|
* @param messageId The id of the message to add the reaction to
|
|
425
460
|
* @param reactionType The type of the reaction
|
|
461
|
+
* @param customData
|
|
426
462
|
*/
|
|
427
|
-
addReaction(messageId, reactionType) {
|
|
463
|
+
addReaction(messageId, reactionType, customData) {
|
|
428
464
|
var _a;
|
|
429
465
|
return __awaiter(this, void 0, void 0, function* () {
|
|
430
|
-
yield ((_a = this.activeChannelSubject.getValue()) === null || _a === void 0 ? void 0 : _a.sendReaction(messageId, {
|
|
431
|
-
type: reactionType,
|
|
432
|
-
}));
|
|
466
|
+
yield ((_a = this.activeChannelSubject.getValue()) === null || _a === void 0 ? void 0 : _a.sendReaction(messageId, Object.assign({ type: reactionType }, customData)));
|
|
433
467
|
});
|
|
434
468
|
}
|
|
435
469
|
/**
|
|
@@ -451,14 +485,15 @@ class ChannelService {
|
|
|
451
485
|
* @param mentionedUsers Mentioned users
|
|
452
486
|
* @param parentId Id of the parent message (if sending a thread reply)
|
|
453
487
|
* @param quotedMessageId Id of the message to quote (if sending a quote reply)
|
|
488
|
+
* @param customData
|
|
454
489
|
*/
|
|
455
|
-
sendMessage(text, attachments = [], mentionedUsers = [], parentId = undefined, quotedMessageId = undefined) {
|
|
490
|
+
sendMessage(text, attachments = [], mentionedUsers = [], parentId = undefined, quotedMessageId = undefined, customData = undefined) {
|
|
456
491
|
return __awaiter(this, void 0, void 0, function* () {
|
|
457
|
-
const preview = createMessagePreview(this.chatClientService.chatClient.user, text, attachments, mentionedUsers, parentId, quotedMessageId);
|
|
492
|
+
const preview = createMessagePreview(this.chatClientService.chatClient.user, text, attachments, mentionedUsers, parentId, quotedMessageId, customData);
|
|
458
493
|
const channel = this.activeChannelSubject.getValue();
|
|
459
494
|
preview.readBy = [];
|
|
460
495
|
channel.state.addMessageSorted(preview, true);
|
|
461
|
-
yield this.sendMessageRequest(preview);
|
|
496
|
+
yield this.sendMessageRequest(preview, customData);
|
|
462
497
|
});
|
|
463
498
|
}
|
|
464
499
|
/**
|
|
@@ -553,7 +588,7 @@ class ChannelService {
|
|
|
553
588
|
const result = yield activeChannel.queryMembers({
|
|
554
589
|
name: { $autocomplete: searchTerm },
|
|
555
590
|
id: { $ne: this.chatClientService.chatClient.userID },
|
|
556
|
-
});
|
|
591
|
+
}); // TODO: find out why we need typecast here
|
|
557
592
|
return Object.values(result.members);
|
|
558
593
|
}
|
|
559
594
|
});
|
|
@@ -598,7 +633,7 @@ class ChannelService {
|
|
|
598
633
|
selectMessageToQuote(message) {
|
|
599
634
|
this.messageToQuoteSubject.next(message);
|
|
600
635
|
}
|
|
601
|
-
sendMessageRequest(preview) {
|
|
636
|
+
sendMessageRequest(preview, customData) {
|
|
602
637
|
var _a;
|
|
603
638
|
return __awaiter(this, void 0, void 0, function* () {
|
|
604
639
|
const channel = this.activeChannelSubject.getValue();
|
|
@@ -609,14 +644,7 @@ class ChannelService {
|
|
|
609
644
|
])
|
|
610
645
|
: this.activeChannelMessagesSubject.next([...channel.state.messages]);
|
|
611
646
|
try {
|
|
612
|
-
const response = yield channel.sendMessage({
|
|
613
|
-
text: preview.text,
|
|
614
|
-
attachments: preview.attachments,
|
|
615
|
-
mentioned_users: (_a = preview.mentioned_users) === null || _a === void 0 ? void 0 : _a.map((u) => u.id),
|
|
616
|
-
id: preview.id,
|
|
617
|
-
parent_id: preview.parent_id,
|
|
618
|
-
quoted_message_id: preview.quoted_message_id,
|
|
619
|
-
});
|
|
647
|
+
const response = yield channel.sendMessage(Object.assign({ id: preview.id, text: preview.text, attachments: preview.attachments, mentioned_users: (_a = preview.mentioned_users) === null || _a === void 0 ? void 0 : _a.map((u) => u.id), parent_id: preview.parent_id, quoted_message_id: preview.quoted_message_id }, customData)); // TODO: find out why we need typecast here
|
|
620
648
|
if (response === null || response === void 0 ? void 0 : response.message) {
|
|
621
649
|
channel.state.addMessageSorted(Object.assign(Object.assign({}, response.message), { status: 'received' }), true);
|
|
622
650
|
isThreadReply
|
|
@@ -640,76 +668,81 @@ class ChannelService {
|
|
|
640
668
|
}
|
|
641
669
|
});
|
|
642
670
|
}
|
|
643
|
-
handleNotification(
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
break;
|
|
656
|
-
}
|
|
657
|
-
case 'notification.added_to_channel': {
|
|
658
|
-
yield this.ngZone.run(() => __awaiter(this, void 0, void 0, function* () {
|
|
659
|
-
if (this.customAddedToChannelNotificationHandler) {
|
|
660
|
-
this.customAddedToChannelNotificationHandler(notification, this.channelListSetter);
|
|
661
|
-
}
|
|
662
|
-
else {
|
|
663
|
-
yield this.handleAddedToChannelNotification(notification);
|
|
664
|
-
}
|
|
665
|
-
}));
|
|
666
|
-
break;
|
|
667
|
-
}
|
|
668
|
-
case 'notification.removed_from_channel': {
|
|
669
|
-
this.ngZone.run(() => {
|
|
670
|
-
if (this.customRemovedFromChannelNotificationHandler) {
|
|
671
|
-
this.customRemovedFromChannelNotificationHandler(notification, this.channelListSetter);
|
|
672
|
-
}
|
|
673
|
-
else {
|
|
674
|
-
this.handleRemovedFromChannelNotification(notification);
|
|
675
|
-
}
|
|
676
|
-
});
|
|
677
|
-
}
|
|
671
|
+
handleNotification(clientEvent) {
|
|
672
|
+
switch (clientEvent.eventType) {
|
|
673
|
+
case 'notification.message_new': {
|
|
674
|
+
this.ngZone.run(() => {
|
|
675
|
+
if (this.customNewMessageNotificationHandler) {
|
|
676
|
+
this.customNewMessageNotificationHandler(clientEvent, this.channelListSetter);
|
|
677
|
+
}
|
|
678
|
+
else {
|
|
679
|
+
this.handleNewMessageNotification(clientEvent);
|
|
680
|
+
}
|
|
681
|
+
});
|
|
682
|
+
break;
|
|
678
683
|
}
|
|
679
|
-
|
|
684
|
+
case 'notification.added_to_channel': {
|
|
685
|
+
this.ngZone.run(() => {
|
|
686
|
+
if (this.customAddedToChannelNotificationHandler) {
|
|
687
|
+
this.customAddedToChannelNotificationHandler(clientEvent, this.channelListSetter);
|
|
688
|
+
}
|
|
689
|
+
else {
|
|
690
|
+
this.handleAddedToChannelNotification(clientEvent);
|
|
691
|
+
}
|
|
692
|
+
});
|
|
693
|
+
break;
|
|
694
|
+
}
|
|
695
|
+
case 'notification.removed_from_channel': {
|
|
696
|
+
this.ngZone.run(() => {
|
|
697
|
+
if (this.customRemovedFromChannelNotificationHandler) {
|
|
698
|
+
this.customRemovedFromChannelNotificationHandler(clientEvent, this.channelListSetter);
|
|
699
|
+
}
|
|
700
|
+
else {
|
|
701
|
+
this.handleRemovedFromChannelNotification(clientEvent);
|
|
702
|
+
}
|
|
703
|
+
});
|
|
704
|
+
}
|
|
705
|
+
}
|
|
680
706
|
}
|
|
681
|
-
handleRemovedFromChannelNotification(
|
|
682
|
-
const channelIdToBeRemoved =
|
|
683
|
-
this.
|
|
707
|
+
handleRemovedFromChannelNotification(clientEvent) {
|
|
708
|
+
const channelIdToBeRemoved = clientEvent.event.channel.cid;
|
|
709
|
+
this.removeChannelsFromChannelList([channelIdToBeRemoved]);
|
|
684
710
|
}
|
|
685
|
-
handleNewMessageNotification(
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
}
|
|
711
|
+
handleNewMessageNotification(clientEvent) {
|
|
712
|
+
if (clientEvent.event.channel) {
|
|
713
|
+
this.addChannelsFromNotification([clientEvent.event.channel]);
|
|
714
|
+
}
|
|
689
715
|
}
|
|
690
|
-
handleAddedToChannelNotification(
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
}
|
|
716
|
+
handleAddedToChannelNotification(clientEvent) {
|
|
717
|
+
if (clientEvent.event.channel) {
|
|
718
|
+
this.addChannelsFromNotification([clientEvent.event.channel]);
|
|
719
|
+
}
|
|
694
720
|
}
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
const channel = this.chatClientService.chatClient.channel(
|
|
699
|
-
|
|
721
|
+
addChannelsFromNotification(channelResponses) {
|
|
722
|
+
const newChannels = [];
|
|
723
|
+
channelResponses.forEach((channelResponse) => {
|
|
724
|
+
const channel = this.chatClientService.chatClient.channel(channelResponse.type, channelResponse.id);
|
|
725
|
+
void channel.watch();
|
|
700
726
|
this.watchForChannelEvents(channel);
|
|
701
|
-
|
|
702
|
-
channel,
|
|
703
|
-
...(this.channelsSubject.getValue() || []),
|
|
704
|
-
]);
|
|
727
|
+
newChannels.push(channel);
|
|
705
728
|
});
|
|
729
|
+
this.channelsSubject.next([
|
|
730
|
+
...newChannels,
|
|
731
|
+
...(this.channelsSubject.getValue() || []),
|
|
732
|
+
]);
|
|
706
733
|
}
|
|
707
|
-
|
|
708
|
-
|
|
734
|
+
removeChannelsFromChannelList(cids) {
|
|
735
|
+
var _a;
|
|
736
|
+
const channels = this.channels.filter((c) => !cids.includes(c.cid || ''));
|
|
709
737
|
if (channels.length < this.channels.length) {
|
|
710
738
|
this.channelsSubject.next(channels);
|
|
711
|
-
if (this.activeChannelSubject.getValue()
|
|
712
|
-
|
|
739
|
+
if (cids.includes(((_a = this.activeChannelSubject.getValue()) === null || _a === void 0 ? void 0 : _a.cid) || '')) {
|
|
740
|
+
if (channels.length > 0) {
|
|
741
|
+
this.setAsActiveChannel(channels[0]);
|
|
742
|
+
}
|
|
743
|
+
else {
|
|
744
|
+
this.activeChannelSubject.next(undefined);
|
|
745
|
+
}
|
|
713
746
|
}
|
|
714
747
|
}
|
|
715
748
|
}
|
|
@@ -927,10 +960,10 @@ class ChannelService {
|
|
|
927
960
|
this.channelsSubject.next([channel, ...this.channels]);
|
|
928
961
|
}
|
|
929
962
|
handleChannelHidden(event) {
|
|
930
|
-
this.
|
|
963
|
+
this.removeChannelsFromChannelList([event.channel.cid]);
|
|
931
964
|
}
|
|
932
965
|
handleChannelDeleted(event) {
|
|
933
|
-
this.
|
|
966
|
+
this.removeChannelsFromChannelList([event.channel.cid]);
|
|
934
967
|
}
|
|
935
968
|
handleChannelVisible(event, channel) {
|
|
936
969
|
if (!this.channels.find((c) => c.cid === event.cid)) {
|
|
@@ -1263,19 +1296,25 @@ class AttachmentService {
|
|
|
1263
1296
|
deleteAttachment(upload) {
|
|
1264
1297
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1265
1298
|
const attachmentUploads = this.attachmentUploadsSubject.getValue();
|
|
1299
|
+
let result;
|
|
1266
1300
|
if (upload.state === 'success') {
|
|
1267
1301
|
try {
|
|
1268
1302
|
yield this.channelService.deleteAttachment(upload);
|
|
1269
|
-
attachmentUploads
|
|
1303
|
+
result = [...attachmentUploads];
|
|
1304
|
+
const index = attachmentUploads.indexOf(upload);
|
|
1305
|
+
result.splice(index, 1);
|
|
1270
1306
|
}
|
|
1271
1307
|
catch (error) {
|
|
1308
|
+
result = attachmentUploads;
|
|
1272
1309
|
this.notificationService.addTemporaryNotification('streamChat.Error deleting attachment');
|
|
1273
1310
|
}
|
|
1274
1311
|
}
|
|
1275
1312
|
else {
|
|
1276
|
-
attachmentUploads
|
|
1313
|
+
result = [...attachmentUploads];
|
|
1314
|
+
const index = attachmentUploads.indexOf(upload);
|
|
1315
|
+
result.splice(index, 1);
|
|
1277
1316
|
}
|
|
1278
|
-
this.attachmentUploadsSubject.next([...
|
|
1317
|
+
this.attachmentUploadsSubject.next([...result]);
|
|
1279
1318
|
});
|
|
1280
1319
|
}
|
|
1281
1320
|
/**
|
|
@@ -1357,9 +1396,9 @@ class AttachmentService {
|
|
|
1357
1396
|
}
|
|
1358
1397
|
uploadAttachments(uploads) {
|
|
1359
1398
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1360
|
-
const attachmentUploads = this.attachmentUploadsSubject.getValue();
|
|
1361
1399
|
this.attachmentUploadInProgressCounterSubject.next(this.attachmentUploadInProgressCounterSubject.getValue() + 1);
|
|
1362
1400
|
const result = yield this.channelService.uploadAttachments(uploads);
|
|
1401
|
+
const attachmentUploads = this.attachmentUploadsSubject.getValue();
|
|
1363
1402
|
result.forEach((r) => {
|
|
1364
1403
|
const upload = attachmentUploads.find((upload) => upload.file === r.file);
|
|
1365
1404
|
if (!upload) {
|
|
@@ -1523,7 +1562,7 @@ class AvatarComponent {
|
|
|
1523
1562
|
}
|
|
1524
1563
|
}
|
|
1525
1564
|
AvatarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: AvatarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1526
|
-
AvatarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: AvatarComponent, selector: "stream-avatar", inputs: { name: "name", imageUrl: "imageUrl", size: "size" }, ngImport: i0, template: "<div\n class=\"str-chat__avatar str-chat__avatar--circle\"\n title=\"{{ name }}\"\n [style]=\"{\n flexBasis: size + 'px',\n fontSize: size / 2 + 'px',\n height: size + 'px',\n lineHeight: size + 'px',\n width: size + 'px'\n }\"\n>\n <img\n *ngIf=\"imageUrl && !isError; else fallback\"\n class=\"str-chat__avatar-image str-chat__avatar-image{{\n isLoaded ? ' str-chat__avatar-image--loaded' : ''\n }}\"\n src=\"{{ imageUrl }}\"\n alt=\"{{ initials }}\"\n data-testid=\"avatar-img\"\n (load)=\"isLoaded = true\"\n (error)=\"isError = true\"\n [style]=\"{\n flexBasis: size + 'px',\n height: size + 'px',\n objectFit: 'cover',\n width: size + 'px'\n }\"\n />\n <ng-template #fallback>\n <div data-testid=\"fallback-img\" class=\"str-chat__avatar-fallback\">\n {{ initials }}\n </div>\n </ng-template>\n</div>\n", styles: [""], directives: [{ type:
|
|
1565
|
+
AvatarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: AvatarComponent, selector: "stream-avatar", inputs: { name: "name", imageUrl: "imageUrl", size: "size" }, ngImport: i0, template: "<div\n class=\"str-chat__avatar str-chat__avatar--circle\"\n title=\"{{ name }}\"\n [style]=\"{\n flexBasis: size + 'px',\n fontSize: size / 2 + 'px',\n height: size + 'px',\n lineHeight: size + 'px',\n width: size + 'px'\n }\"\n>\n <img\n *ngIf=\"imageUrl && !isError; else fallback\"\n class=\"str-chat__avatar-image str-chat__avatar-image{{\n isLoaded ? ' str-chat__avatar-image--loaded' : ''\n }}\"\n src=\"{{ imageUrl }}\"\n alt=\"{{ initials }}\"\n data-testid=\"avatar-img\"\n (load)=\"isLoaded = true\"\n (error)=\"isError = true\"\n [style]=\"{\n flexBasis: size + 'px',\n height: size + 'px',\n objectFit: 'cover',\n width: size + 'px'\n }\"\n />\n <ng-template #fallback>\n <div data-testid=\"fallback-img\" class=\"str-chat__avatar-fallback\">\n {{ initials }}\n </div>\n </ng-template>\n</div>\n", styles: [""], directives: [{ type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
|
|
1527
1566
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: AvatarComponent, decorators: [{
|
|
1528
1567
|
type: Component,
|
|
1529
1568
|
args: [{
|
|
@@ -1539,6 +1578,178 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
1539
1578
|
type: Input
|
|
1540
1579
|
}] } });
|
|
1541
1580
|
|
|
1581
|
+
/**
|
|
1582
|
+
* A central location for registering your custom templates to override parts of the chat application.
|
|
1583
|
+
*
|
|
1584
|
+
* For code examples to the different customizations see our [customizations example application](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example), specifically the [AppComponent](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example/src/app) (see [README](https://github.com/GetStream/stream-chat-angular/blob/master/README.md#customization-examples) for instructions on how to start the application).
|
|
1585
|
+
*/
|
|
1586
|
+
class CustomTemplatesService {
|
|
1587
|
+
constructor() {
|
|
1588
|
+
/**
|
|
1589
|
+
* The autocomplete list item template for mentioning users (used in the [`AutocompleteTextareaComponent`](../components/AutocompleteTextareaComponent.mdx))
|
|
1590
|
+
*/
|
|
1591
|
+
this.mentionAutocompleteItemTemplate$ = new BehaviorSubject(undefined);
|
|
1592
|
+
/**
|
|
1593
|
+
* The autocomplete list item template for commands (used in the [`AutocompleteTextareaComponent`](../components/AutocompleteTextareaComponent.mdx))
|
|
1594
|
+
*
|
|
1595
|
+
* For code examples to the different customizations see our [customizations example application](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example), specifically the [AppComponent](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example/src/app) (see [README](https://github.com/GetStream/stream-chat-angular/blob/master/README.md#customization-examples) for instructions on how to start the application).
|
|
1596
|
+
*/
|
|
1597
|
+
this.commandAutocompleteItemTemplate$ = new BehaviorSubject(undefined);
|
|
1598
|
+
/**
|
|
1599
|
+
* Template used to display an item in the [channel list](../components/ChannelListComponent.mdx) (instead of the default [channal list item](../components/ChannelPreviewComponent.mdx))
|
|
1600
|
+
*
|
|
1601
|
+
* For code examples to the different customizations see our [customizations example application](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example), specifically the [AppComponent](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example/src/app) (see [README](https://github.com/GetStream/stream-chat-angular/blob/master/README.md#customization-examples) for instructions on how to start the application).
|
|
1602
|
+
*/
|
|
1603
|
+
this.channelPreviewTemplate$ = new BehaviorSubject(undefined);
|
|
1604
|
+
/**
|
|
1605
|
+
* The message input template used when editing a message (instead of the [default message input](../components/MessageInputComponent.mdx))
|
|
1606
|
+
*
|
|
1607
|
+
* For code examples to the different customizations see our [customizations example application](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example), specifically the [AppComponent](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example/src/app) (see [README](https://github.com/GetStream/stream-chat-angular/blob/master/README.md#customization-examples) for instructions on how to start the application).
|
|
1608
|
+
*/
|
|
1609
|
+
this.messageInputTemplate$ = new BehaviorSubject(undefined);
|
|
1610
|
+
/**
|
|
1611
|
+
* The template used for displaying a [mention inside a message](../code-examples/mention-actions.mdx)
|
|
1612
|
+
*
|
|
1613
|
+
* For code examples to the different customizations see our [customizations example application](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example), specifically the [AppComponent](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example/src/app) (see [README](https://github.com/GetStream/stream-chat-angular/blob/master/README.md#customization-examples) for instructions on how to start the application).
|
|
1614
|
+
*/
|
|
1615
|
+
this.mentionTemplate$ = new BehaviorSubject(undefined);
|
|
1616
|
+
/**
|
|
1617
|
+
* The template for [emoji picker](../code-examples/emoji-picker.mdx)
|
|
1618
|
+
*
|
|
1619
|
+
* For code examples to the different customizations see our [customizations example application](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example), specifically the [AppComponent](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example/src/app) (see [README](https://github.com/GetStream/stream-chat-angular/blob/master/README.md#customization-examples) for instructions on how to start the application).
|
|
1620
|
+
*/
|
|
1621
|
+
this.emojiPickerTemplate$ = new BehaviorSubject(undefined);
|
|
1622
|
+
/**
|
|
1623
|
+
* The typing indicator template used in the [message list](../components/MessageListComponent.mdx)
|
|
1624
|
+
*
|
|
1625
|
+
* For code examples to the different customizations see our [customizations example application](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example), specifically the [AppComponent](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example/src/app) (see [README](https://github.com/GetStream/stream-chat-angular/blob/master/README.md#customization-examples) for instructions on how to start the application).
|
|
1626
|
+
*/
|
|
1627
|
+
this.typingIndicatorTemplate$ = new BehaviorSubject(undefined);
|
|
1628
|
+
/**
|
|
1629
|
+
* The template used to display a message in the [message list](../components/MessageListComponent.mdx) (instead of the [default message component](../components/MessageComponent.mdx))
|
|
1630
|
+
*
|
|
1631
|
+
* For code examples to the different customizations see our [customizations example application](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example), specifically the [AppComponent](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example/src/app) (see [README](https://github.com/GetStream/stream-chat-angular/blob/master/README.md#customization-examples) for instructions on how to start the application).
|
|
1632
|
+
*/
|
|
1633
|
+
this.messageTemplate$ = new BehaviorSubject(undefined);
|
|
1634
|
+
/**
|
|
1635
|
+
* The template for channel actions displayed in the [channel header](../components/ChannelHeaderComponent.mdx) (by default no channel action is displayed)
|
|
1636
|
+
*
|
|
1637
|
+
* For code examples to the different customizations see our [customizations example application](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example), specifically the [AppComponent](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example/src/app) (see [README](https://github.com/GetStream/stream-chat-angular/blob/master/README.md#customization-examples) for instructions on how to start the application).
|
|
1638
|
+
*/
|
|
1639
|
+
this.channelActionsTemplate$ = new BehaviorSubject(undefined);
|
|
1640
|
+
/**
|
|
1641
|
+
* The template used to display attachments of a [message](../components/MessageComponent.mdx) (instead of the [default attachment list](../components/AttachmentListComponent.mdx))
|
|
1642
|
+
*
|
|
1643
|
+
* For code examples to the different customizations see our [customizations example application](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example), specifically the [AppComponent](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example/src/app) (see [README](https://github.com/GetStream/stream-chat-angular/blob/master/README.md#customization-examples) for instructions on how to start the application).
|
|
1644
|
+
*/
|
|
1645
|
+
this.attachmentListTemplate$ = new BehaviorSubject(undefined);
|
|
1646
|
+
/**
|
|
1647
|
+
* The template used to display attachments in the [message input](../components/MessageInputComponent.mdx) component (instead of the [default attachment preview](../components/AttachmentPreviewListComponent.mdx))
|
|
1648
|
+
*
|
|
1649
|
+
* For code examples to the different customizations see our [customizations example application](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example), specifically the [AppComponent](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example/src/app) (see [README](https://github.com/GetStream/stream-chat-angular/blob/master/README.md#customization-examples) for instructions on how to start the application).
|
|
1650
|
+
*/
|
|
1651
|
+
this.attachmentPreviewListTemplate$ = new BehaviorSubject(undefined);
|
|
1652
|
+
/**
|
|
1653
|
+
* The template used to display avatars for channels and users (instead of the [default avatar](../components/AvatarComponent.mdx))
|
|
1654
|
+
*
|
|
1655
|
+
* For code examples to the different customizations see our [customizations example application](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example), specifically the [AppComponent](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example/src/app) (see [README](https://github.com/GetStream/stream-chat-angular/blob/master/README.md#customization-examples) for instructions on how to start the application).
|
|
1656
|
+
*/
|
|
1657
|
+
this.avatarTemplate$ = new BehaviorSubject(undefined);
|
|
1658
|
+
/**
|
|
1659
|
+
* Template for displaying icons (instead of the [default icon component](../components/IconComponent.mdx))
|
|
1660
|
+
*
|
|
1661
|
+
* For code examples to the different customizations see our [customizations example application](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example), specifically the [AppComponent](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example/src/app) (see [README](https://github.com/GetStream/stream-chat-angular/blob/master/README.md#customization-examples) for instructions on how to start the application).
|
|
1662
|
+
*/
|
|
1663
|
+
this.iconTemplate$ = new BehaviorSubject(undefined);
|
|
1664
|
+
/**
|
|
1665
|
+
* Template for displaying the loading indicator (instead of the [default loading indicator](../components/LoadingIndicatorComponent.mdx))
|
|
1666
|
+
*
|
|
1667
|
+
* For code examples to the different customizations see our [customizations example application](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example), specifically the [AppComponent](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example/src/app) (see [README](https://github.com/GetStream/stream-chat-angular/blob/master/README.md#customization-examples) for instructions on how to start the application).
|
|
1668
|
+
*/
|
|
1669
|
+
this.loadingIndicatorTemplate$ = new BehaviorSubject(undefined);
|
|
1670
|
+
/**
|
|
1671
|
+
* Template for displaying the message actions box (instead of the [default message actions box](../components/MessageActionsBoxComponent.mdx))
|
|
1672
|
+
*
|
|
1673
|
+
* For code examples to the different customizations see our [customizations example application](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example), specifically the [AppComponent](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example/src/app) (see [README](https://github.com/GetStream/stream-chat-angular/blob/master/README.md#customization-examples) for instructions on how to start the application).
|
|
1674
|
+
*/
|
|
1675
|
+
this.messageActionsBoxTemplate$ = new BehaviorSubject(undefined);
|
|
1676
|
+
/**
|
|
1677
|
+
* The template used for displaying an item in the [message actions box](../components/MessageActionsBoxComponent.mdx)
|
|
1678
|
+
*
|
|
1679
|
+
* For code examples to the different customizations see our [customizations example application](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example), specifically the [AppComponent](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example/src/app) (see [README](https://github.com/GetStream/stream-chat-angular/blob/master/README.md#customization-examples) for instructions on how to start the application).
|
|
1680
|
+
*/
|
|
1681
|
+
this.messageActionsBoxItemTemplate$ = new BehaviorSubject(undefined);
|
|
1682
|
+
/**
|
|
1683
|
+
* The template used to display the reactions of a [message](../components/MessageComponent.mdx), and the selector to add a reaction to a message (instead of the [default message reactions component](../components/MessageReactionsComponent.mdx))
|
|
1684
|
+
*
|
|
1685
|
+
* For code examples to the different customizations see our [customizations example application](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example), specifically the [AppComponent](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example/src/app) (see [README](https://github.com/GetStream/stream-chat-angular/blob/master/README.md#customization-examples) for instructions on how to start the application).
|
|
1686
|
+
*/
|
|
1687
|
+
this.messageReactionsTemplate$ = new BehaviorSubject(undefined);
|
|
1688
|
+
/**
|
|
1689
|
+
* The template used to display a modal window (instead of the [default modal](../components/ModalComponent.mdx))
|
|
1690
|
+
*
|
|
1691
|
+
* For code examples to the different customizations see our [customizations example application](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example), specifically the [AppComponent](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example/src/app) (see [README](https://github.com/GetStream/stream-chat-angular/blob/master/README.md#customization-examples) for instructions on how to start the application).
|
|
1692
|
+
*/
|
|
1693
|
+
this.modalTemplate$ = new BehaviorSubject(undefined);
|
|
1694
|
+
/**
|
|
1695
|
+
* The template used to override the [default notification component](../components/NotificationComponent.mdx)
|
|
1696
|
+
*
|
|
1697
|
+
* For code examples to the different customizations see our [customizations example application](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example), specifically the [AppComponent](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example/src/app) (see [README](https://github.com/GetStream/stream-chat-angular/blob/master/README.md#customization-examples) for instructions on how to start the application).
|
|
1698
|
+
*/
|
|
1699
|
+
this.notificationTemplate$ = new BehaviorSubject(undefined);
|
|
1700
|
+
/**
|
|
1701
|
+
* The template used for header of a [thread](../components/ThreadComponent.mdx)
|
|
1702
|
+
*
|
|
1703
|
+
* For code examples to the different customizations see our [customizations example application](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example), specifically the [AppComponent](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example/src/app) (see [README](https://github.com/GetStream/stream-chat-angular/blob/master/README.md#customization-examples) for instructions on how to start the application).
|
|
1704
|
+
*/
|
|
1705
|
+
this.threadHeaderTemplate$ = new BehaviorSubject(undefined);
|
|
1706
|
+
}
|
|
1707
|
+
}
|
|
1708
|
+
CustomTemplatesService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: CustomTemplatesService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1709
|
+
CustomTemplatesService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: CustomTemplatesService, providedIn: 'root' });
|
|
1710
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: CustomTemplatesService, decorators: [{
|
|
1711
|
+
type: Injectable,
|
|
1712
|
+
args: [{
|
|
1713
|
+
providedIn: 'root',
|
|
1714
|
+
}]
|
|
1715
|
+
}], ctorParameters: function () { return []; } });
|
|
1716
|
+
|
|
1717
|
+
/**
|
|
1718
|
+
* The `AvatarPlaceholder` component displays the [default avatar](./AvatarComponent.mdx) unless a [custom template](../services/CustomTemplatesService.mdx) is provided. This componet is used by the SDK internally, you likely won't need to use it.
|
|
1719
|
+
*/
|
|
1720
|
+
class AvatarPlaceholderComponent {
|
|
1721
|
+
constructor(customTemplatesService) {
|
|
1722
|
+
this.customTemplatesService = customTemplatesService;
|
|
1723
|
+
/**
|
|
1724
|
+
* The size in pixels of the avatar image.
|
|
1725
|
+
*/
|
|
1726
|
+
this.size = 32;
|
|
1727
|
+
}
|
|
1728
|
+
getAvatarContext() {
|
|
1729
|
+
return {
|
|
1730
|
+
name: this.name,
|
|
1731
|
+
imageUrl: this.imageUrl,
|
|
1732
|
+
size: this.size,
|
|
1733
|
+
};
|
|
1734
|
+
}
|
|
1735
|
+
}
|
|
1736
|
+
AvatarPlaceholderComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: AvatarPlaceholderComponent, deps: [{ token: CustomTemplatesService }], target: i0.ɵɵFactoryTarget.Component });
|
|
1737
|
+
AvatarPlaceholderComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: AvatarPlaceholderComponent, selector: "stream-avatar-placeholder", inputs: { name: "name", imageUrl: "imageUrl", size: "size" }, ngImport: i0, template: "<ng-template\n #defaultAvatar\n let-name=\"name\"\n let-imageUrl=\"imageUrl\"\n let-size=\"size\"\n>\n <stream-avatar\n [name]=\"name\"\n [imageUrl]=\"imageUrl\"\n [size]=\"size\"\n ></stream-avatar>\n</ng-template>\n<ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.avatarTemplate$ | async) || defaultAvatar;\n context: getAvatarContext()\n \"\n></ng-container>\n", components: [{ type: AvatarComponent, selector: "stream-avatar", inputs: ["name", "imageUrl", "size"] }], directives: [{ type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], pipes: { "async": i3.AsyncPipe } });
|
|
1738
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: AvatarPlaceholderComponent, decorators: [{
|
|
1739
|
+
type: Component,
|
|
1740
|
+
args: [{
|
|
1741
|
+
selector: 'stream-avatar-placeholder',
|
|
1742
|
+
templateUrl: './avatar-placeholder.component.html',
|
|
1743
|
+
styles: [],
|
|
1744
|
+
}]
|
|
1745
|
+
}], ctorParameters: function () { return [{ type: CustomTemplatesService }]; }, propDecorators: { name: [{
|
|
1746
|
+
type: Input
|
|
1747
|
+
}], imageUrl: [{
|
|
1748
|
+
type: Input
|
|
1749
|
+
}], size: [{
|
|
1750
|
+
type: Input
|
|
1751
|
+
}] } });
|
|
1752
|
+
|
|
1542
1753
|
/**
|
|
1543
1754
|
* The `Icon` component can be used to display different icons (i. e. message delivered icon).
|
|
1544
1755
|
*/
|
|
@@ -1546,7 +1757,7 @@ class IconComponent {
|
|
|
1546
1757
|
constructor() { }
|
|
1547
1758
|
}
|
|
1548
1759
|
IconComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: IconComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1549
|
-
IconComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: IconComponent, selector: "stream-icon", inputs: { icon: "icon", size: "size" }, ngImport: i0, template: "<svg\n data-testid=\"action-icon\"\n *ngIf=\"icon === 'action-icon'\"\n height=\"4\"\n viewBox=\"0 0 11 4\"\n width=\"11\"\n xmlns=\"http://www.w3.org/2000/svg\"\n>\n <path\n d=\"M1.5 3a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm4 0a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm4 0a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3z\"\n fillRule=\"nonzero\"\n />\n</svg>\n<svg\n *ngIf=\"icon === 'delivered-icon'\"\n height=\"16\"\n width=\"16\"\n xmlns=\"http://www.w3.org/2000/svg\"\n data-testid=\"delivered-icon\"\n>\n <path\n d=\"M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0zm3.72 6.633a.955.955 0 1 0-1.352-1.352L6.986 8.663 5.633 7.31A.956.956 0 1 0 4.28 8.663l2.029 2.028a.956.956 0 0 0 1.353 0l4.058-4.058z\"\n fill=\"#006CFF\"\n fillRule=\"evenodd\"\n />\n</svg>\n<svg\n *ngIf=\"icon === 'reaction-icon'\"\n height=\"12\"\n viewBox=\"0 0 12 12\"\n width=\"12\"\n xmlns=\"http://www.w3.org/2000/svg\"\n data-testid=\"reaction-icon\"\n>\n <g clipRule=\"evenodd\" fillRule=\"evenodd\">\n <path\n d=\"M6 1.2C3.3 1.2 1.2 3.3 1.2 6c0 2.7 2.1 4.8 4.8 4.8 2.7 0 4.8-2.1 4.8-4.8 0-2.7-2.1-4.8-4.8-4.8zM0 6c0-3.3 2.7-6 6-6s6 2.7 6 6-2.7 6-6 6-6-2.7-6-6z\"\n ></path>\n <path\n d=\"M5.4 4.5c0 .5-.4.9-.9.9s-.9-.4-.9-.9.4-.9.9-.9.9.4.9.9zM8.4 4.5c0 .5-.4.9-.9.9s-.9-.4-.9-.9.4-.9.9-.9.9.4.9.9zM3.3 6.7c.3-.2.6-.1.8.1.3.4.8.9 1.5 1 .6.2 1.4.1 2.4-1 .2-.2.6-.3.8 0 .2.2.3.6 0 .8-1.1 1.3-2.4 1.7-3.5 1.5-1-.2-1.8-.9-2.2-1.5-.2-.3-.1-.7.2-.9z\"\n ></path>\n </g>\n</svg>\n<svg\n data-testid=\"connection-error\"\n *ngIf=\"icon === 'connection-error'\"\n width=\"78px\"\n height=\"78px\"\n viewBox=\"0 0 78 78\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n>\n <!-- Generator: Sketch 52.6 (67491) - http://www.bohemiancoding.com/sketch -->\n <title>Combined Shape</title>\n <desc>Created with Sketch.</desc>\n <g\n id=\"Interactions\"\n stroke=\"none\"\n stroke-width=\"1\"\n fill=\"none\"\n fill-rule=\"evenodd\"\n >\n <g\n id=\"Connection-Error-_-Connectivity\"\n transform=\"translate(-270.000000, -30.000000)\"\n fill=\"#CF1F25\"\n >\n <g\n id=\"109-network-connection\"\n transform=\"translate(270.000000, 30.000000)\"\n >\n <path\n d=\"M66.4609744,11.414231 C81.6225232,26.5757798 81.6225232,51.157545 66.4609744,66.3188467 C51.2994256,81.4803954 26.7176604,81.4803954 11.5563587,66.3188467 C-3.60519004,51.1572979 -3.60519004,26.5755327 11.5563587,11.414231 C26.7179075,-3.74731776 51.2996727,-3.74731776 66.4609744,11.414231 Z M54.7853215,45.8823776 L54.7853215,40.5882574 C54.7853215,39.613638 53.9952341,38.8235506 53.0206147,38.8235506 L44.9576695,38.8235506 L41.428256,42.3529641 L51.255555,42.3529641 L51.255555,45.8823776 L54.7853215,45.8823776 Z M40.6659027,43.1153174 L37.8988425,45.8823776 L40.6659027,45.8823776 L40.6659027,43.1153174 Z M51.1764962,56.4702653 L58.2353232,56.4702653 C59.2099355,56.4702653 60.00003,55.6801708 60.00003,54.7055585 L60.00003,51.176145 C60.00003,50.2015327 59.2099355,49.4114382 58.2353232,49.4114382 L51.1764962,49.4114382 C50.2018839,49.4114382 49.4117894,50.2015327 49.4117894,51.176145 L49.4117894,54.7055585 C49.4117894,55.6801708 50.2018839,56.4702653 51.1764962,56.4702653 Z M35.2941353,56.4702653 L42.3529624,56.4702653 C43.3275746,56.4702653 44.1176691,55.6801708 44.1176691,54.7055585 L44.1176691,51.176145 C44.1176691,50.2015327 43.3275746,49.4114382 42.3529624,49.4114382 L35.2941353,49.4114382 C34.319523,49.4114382 33.5294285,50.2015327 33.5294285,51.176145 L33.5294285,54.7055585 C33.5294285,55.6801708 34.319523,56.4702653 35.2941353,56.4702653 Z M56.6964989,19.0874231 C56.007381,18.3985134 54.8903216,18.3985134 54.2012036,19.087423 L45.882376,27.4062507 L45.882376,19.4117761 C45.882376,18.4371568 45.0922885,17.6470693 44.1176692,17.6470693 L33.5294286,17.6470693 C32.5548092,17.6470694 31.7647218,18.4371568 31.7647218,19.4117761 L31.7647218,30.0000167 C31.7647219,30.9746363 32.5548092,31.7647237 33.5294285,31.7647237 L41.5239031,31.7647237 L34.4650761,38.8235508 L24.7058947,38.8235508 C23.7312753,38.8235508 22.9411879,39.6136382 22.9411879,40.5882575 L22.9411879,45.8823778 L26.4706014,45.8823778 L26.4706014,42.3529643 L30.9356624,42.3529643 L23.8768354,49.4117914 L19.4117743,49.4117914 C18.4371549,49.4117914 17.6470675,50.2018788 17.6470675,51.1764981 L17.6470675,54.7059117 C17.6504049,54.9674302 17.7129076,55.2248042 17.8298886,55.4587302 L16.4456526,56.8429662 C15.7446193,57.5200453 15.7252005,58.6372282 16.4022825,59.3382615 C17.0793616,60.0392948 18.1965445,60.0587136 18.8975778,59.3816316 C18.9122847,59.3674273 18.9267436,59.3529684 18.940948,59.3382615 L56.6964963,21.5830662 C57.3856425,20.8939094 57.3856425,19.7765747 56.6964963,19.0874179 Z\"\n id=\"Combined-Shape\"\n ></path>\n </g>\n </g>\n </g>\n</svg>\n<svg\n *ngIf=\"icon === 'send'\"\n data-testid=\"send\"\n height=\"17\"\n viewBox=\"0 0 18 17\"\n width=\"18\"\n xmlns=\"http://www.w3.org/2000/svg\"\n>\n <title translate>streamChat.Send</title>\n <path\n d=\"M0 17.015l17.333-8.508L0 0v6.617l12.417 1.89L0 10.397z\"\n fill=\"#006cff\"\n fillRule=\"evenodd\"\n />\n</svg>\n<svg\n *ngIf=\"icon === 'file-upload'\"\n data-testid=\"file-upload\"\n height=\"14\"\n width=\"14\"\n xmlns=\"http://www.w3.org/2000/svg\"\n>\n <title translate>streamChat.Attach files</title>\n <path\n d=\"M1.667.333h10.666c.737 0 1.334.597 1.334 1.334v10.666c0 .737-.597 1.334-1.334 1.334H1.667a1.333 1.333 0 0 1-1.334-1.334V1.667C.333.93.93.333 1.667.333zm2 1.334a1.667 1.667 0 1 0 0 3.333 1.667 1.667 0 0 0 0-3.333zm-2 9.333v1.333h10.666v-4l-2-2-4 4-2-2L1.667 11z\"\n fillRule=\"nonzero\"\n />\n</svg>\n<svg\n data-testid=\"retry\"\n *ngIf=\"icon === 'retry'\"\n width=\"22\"\n height=\"20\"\n viewBox=\"0 0 22 20\"\n xmlns=\"http://www.w3.org/2000/svg\"\n>\n <path\n d=\"M20 5.535V2a1 1 0 0 1 2 0v6a1 1 0 0 1-1 1h-6a1 1 0 0 1 0-2h3.638l-2.975-2.653a8 8 0 1 0 1.884 8.32 1 1 0 1 1 1.886.666A10 10 0 1 1 5.175 1.245c3.901-2.15 8.754-1.462 11.88 1.667L20 5.535z\"\n fill=\"#FFF\"\n fill-rule=\"nonzero\"\n />\n</svg>\n<svg\n *ngIf=\"icon === 'close'\"\n data-testid=\"close\"\n width=\"28\"\n height=\"28\"\n viewBox=\"0 0 28 28\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n>\n <defs>\n <path\n d=\"M465 5c5.53 0 10 4.47 10 10s-4.47 10-10 10-10-4.47-10-10 4.47-10 10-10zm3.59 5L465 13.59 461.41 10 460 11.41l3.59 3.59-3.59 3.59 1.41 1.41 3.59-3.59 3.59 3.59 1.41-1.41-3.59-3.59 3.59-3.59-1.41-1.41z\"\n id=\"b\"\n />\n <filter\n x=\"-30%\"\n y=\"-30%\"\n width=\"160%\"\n height=\"160%\"\n filterUnits=\"objectBoundingBox\"\n id=\"a\"\n >\n <feOffset in=\"SourceAlpha\" result=\"shadowOffsetOuter1\" />\n <feGaussianBlur\n stdDeviation=\"2\"\n in=\"shadowOffsetOuter1\"\n result=\"shadowBlurOuter1\"\n />\n <feColorMatrix\n values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.5 0\"\n in=\"shadowBlurOuter1\"\n />\n </filter>\n </defs>\n <g transform=\"translate(-451 -1)\" fill-rule=\"nonzero\" fill=\"none\">\n <use fill=\"#000\" filter=\"url(#a)\" xlink:href=\"#b\" />\n <use fill=\"#FFF\" fill-rule=\"evenodd\" xlink:href=\"#b\" />\n </g>\n</svg>\n<svg\n *ngIf=\"icon === 'file'\"\n data-testid=\"file\"\n className=\"rfu-file-icon--small fa-file-fallback\"\n [attr.height]=\"size || 20\"\n [attr.width]=\"size || 20\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 384 512\"\n>\n <path\n d=\"M369.9 97.9L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM332.1 128H256V51.9l76.1 76.1zM48 464V48h160v104c0 13.3 10.7 24 24 24h104v288H48z\"\n fill=\"#414D54\"\n />\n</svg>\n<svg\n *ngIf=\"icon === 'reply'\"\n data-testid=\"reply\"\n height=\"15\"\n width=\"18\"\n xmlns=\"http://www.w3.org/2000/svg\"\n>\n <path\n d=\"M.56 10.946H.06l-.002-.498L.025.92a.5.5 0 1 1 1-.004l.032 9.029H9.06v-4l9 4.5-9 4.5v-4H.56z\"\n fillRule=\"nonzero\"\n />\n</svg>\n<svg\n height=\"10\"\n width=\"10\"\n xmlns=\"http://www.w3.org/2000/svg\"\n data-testid=\"close-no-outline\"\n *ngIf=\"icon === 'close-no-outline'\"\n>\n <path\n d=\"M9.916 1.027L8.973.084 5 4.058 1.027.084l-.943.943L4.058 5 .084 8.973l.943.943L5 5.942l3.973 3.974.943-.943L5.942 5z\"\n fillRule=\"evenodd\"\n />\n</svg>\n<svg\n height=\"10\"\n width=\"14\"\n xmlns=\"http://www.w3.org/2000/svg\"\n data-testid=\"reply-in-thread\"\n *ngIf=\"icon === 'reply-in-thread'\"\n>\n <path\n d=\"M8.516 3c4.78 0 4.972 6.5 4.972 6.5-1.6-2.906-2.847-3.184-4.972-3.184v2.872L3.772 4.994 8.516.5V3zM.484 5l4.5-4.237v1.78L2.416 5l2.568 2.125v1.828L.484 5z\"\n fillRule=\"evenodd\"\n />\n</svg>\n<svg\n *ngIf=\"icon === 'arrow-left'\"\n data-testid=\"arrow-left\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n>\n <path\n d=\"M15.7049 7.41L14.2949 6L8.29492 12L14.2949 18L15.7049 16.59L11.1249 12L15.7049 7.41Z\"\n fill=\"var(--black)\"\n />\n</svg>\n\n<svg\n *ngIf=\"icon === 'arrow-right'\"\n data-testid=\"arrow-right\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n>\n <path\n d=\"M9.70492 6L8.29492 7.41L12.8749 12L8.29492 16.59L9.70492 18L15.7049 12L9.70492 6Z\"\n fill=\"var(--black)\"\n />\n</svg>\n<svg\n *ngIf=\"icon === 'menu'\"\n data-testid=\"menu\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n>\n <path\n fill-rule=\"evenodd\"\n clip-rule=\"evenodd\"\n d=\"M3 8V6H21V8H3ZM3 13H21V11H3V13ZM3 18H21V16H3V18Z\"\n fill=\"black\"\n />\n</svg>\n", directives: [{ type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }] });
|
|
1760
|
+
IconComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: IconComponent, selector: "stream-icon", inputs: { icon: "icon", size: "size" }, ngImport: i0, template: "<svg\n data-testid=\"action-icon\"\n *ngIf=\"icon === 'action-icon'\"\n height=\"4\"\n viewBox=\"0 0 11 4\"\n width=\"11\"\n xmlns=\"http://www.w3.org/2000/svg\"\n>\n <path\n d=\"M1.5 3a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm4 0a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm4 0a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3z\"\n fillRule=\"nonzero\"\n />\n</svg>\n<svg\n *ngIf=\"icon === 'delivered-icon'\"\n height=\"16\"\n width=\"16\"\n xmlns=\"http://www.w3.org/2000/svg\"\n data-testid=\"delivered-icon\"\n>\n <path\n d=\"M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0zm3.72 6.633a.955.955 0 1 0-1.352-1.352L6.986 8.663 5.633 7.31A.956.956 0 1 0 4.28 8.663l2.029 2.028a.956.956 0 0 0 1.353 0l4.058-4.058z\"\n fill=\"#006CFF\"\n fillRule=\"evenodd\"\n />\n</svg>\n<svg\n *ngIf=\"icon === 'reaction-icon'\"\n height=\"12\"\n viewBox=\"0 0 12 12\"\n width=\"12\"\n xmlns=\"http://www.w3.org/2000/svg\"\n data-testid=\"reaction-icon\"\n>\n <g clipRule=\"evenodd\" fillRule=\"evenodd\">\n <path\n d=\"M6 1.2C3.3 1.2 1.2 3.3 1.2 6c0 2.7 2.1 4.8 4.8 4.8 2.7 0 4.8-2.1 4.8-4.8 0-2.7-2.1-4.8-4.8-4.8zM0 6c0-3.3 2.7-6 6-6s6 2.7 6 6-2.7 6-6 6-6-2.7-6-6z\"\n ></path>\n <path\n d=\"M5.4 4.5c0 .5-.4.9-.9.9s-.9-.4-.9-.9.4-.9.9-.9.9.4.9.9zM8.4 4.5c0 .5-.4.9-.9.9s-.9-.4-.9-.9.4-.9.9-.9.9.4.9.9zM3.3 6.7c.3-.2.6-.1.8.1.3.4.8.9 1.5 1 .6.2 1.4.1 2.4-1 .2-.2.6-.3.8 0 .2.2.3.6 0 .8-1.1 1.3-2.4 1.7-3.5 1.5-1-.2-1.8-.9-2.2-1.5-.2-.3-.1-.7.2-.9z\"\n ></path>\n </g>\n</svg>\n<svg\n data-testid=\"connection-error\"\n *ngIf=\"icon === 'connection-error'\"\n width=\"78px\"\n height=\"78px\"\n viewBox=\"0 0 78 78\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n>\n <!-- Generator: Sketch 52.6 (67491) - http://www.bohemiancoding.com/sketch -->\n <title>Combined Shape</title>\n <desc>Created with Sketch.</desc>\n <g\n id=\"Interactions\"\n stroke=\"none\"\n stroke-width=\"1\"\n fill=\"none\"\n fill-rule=\"evenodd\"\n >\n <g\n id=\"Connection-Error-_-Connectivity\"\n transform=\"translate(-270.000000, -30.000000)\"\n fill=\"#CF1F25\"\n >\n <g\n id=\"109-network-connection\"\n transform=\"translate(270.000000, 30.000000)\"\n >\n <path\n d=\"M66.4609744,11.414231 C81.6225232,26.5757798 81.6225232,51.157545 66.4609744,66.3188467 C51.2994256,81.4803954 26.7176604,81.4803954 11.5563587,66.3188467 C-3.60519004,51.1572979 -3.60519004,26.5755327 11.5563587,11.414231 C26.7179075,-3.74731776 51.2996727,-3.74731776 66.4609744,11.414231 Z M54.7853215,45.8823776 L54.7853215,40.5882574 C54.7853215,39.613638 53.9952341,38.8235506 53.0206147,38.8235506 L44.9576695,38.8235506 L41.428256,42.3529641 L51.255555,42.3529641 L51.255555,45.8823776 L54.7853215,45.8823776 Z M40.6659027,43.1153174 L37.8988425,45.8823776 L40.6659027,45.8823776 L40.6659027,43.1153174 Z M51.1764962,56.4702653 L58.2353232,56.4702653 C59.2099355,56.4702653 60.00003,55.6801708 60.00003,54.7055585 L60.00003,51.176145 C60.00003,50.2015327 59.2099355,49.4114382 58.2353232,49.4114382 L51.1764962,49.4114382 C50.2018839,49.4114382 49.4117894,50.2015327 49.4117894,51.176145 L49.4117894,54.7055585 C49.4117894,55.6801708 50.2018839,56.4702653 51.1764962,56.4702653 Z M35.2941353,56.4702653 L42.3529624,56.4702653 C43.3275746,56.4702653 44.1176691,55.6801708 44.1176691,54.7055585 L44.1176691,51.176145 C44.1176691,50.2015327 43.3275746,49.4114382 42.3529624,49.4114382 L35.2941353,49.4114382 C34.319523,49.4114382 33.5294285,50.2015327 33.5294285,51.176145 L33.5294285,54.7055585 C33.5294285,55.6801708 34.319523,56.4702653 35.2941353,56.4702653 Z M56.6964989,19.0874231 C56.007381,18.3985134 54.8903216,18.3985134 54.2012036,19.087423 L45.882376,27.4062507 L45.882376,19.4117761 C45.882376,18.4371568 45.0922885,17.6470693 44.1176692,17.6470693 L33.5294286,17.6470693 C32.5548092,17.6470694 31.7647218,18.4371568 31.7647218,19.4117761 L31.7647218,30.0000167 C31.7647219,30.9746363 32.5548092,31.7647237 33.5294285,31.7647237 L41.5239031,31.7647237 L34.4650761,38.8235508 L24.7058947,38.8235508 C23.7312753,38.8235508 22.9411879,39.6136382 22.9411879,40.5882575 L22.9411879,45.8823778 L26.4706014,45.8823778 L26.4706014,42.3529643 L30.9356624,42.3529643 L23.8768354,49.4117914 L19.4117743,49.4117914 C18.4371549,49.4117914 17.6470675,50.2018788 17.6470675,51.1764981 L17.6470675,54.7059117 C17.6504049,54.9674302 17.7129076,55.2248042 17.8298886,55.4587302 L16.4456526,56.8429662 C15.7446193,57.5200453 15.7252005,58.6372282 16.4022825,59.3382615 C17.0793616,60.0392948 18.1965445,60.0587136 18.8975778,59.3816316 C18.9122847,59.3674273 18.9267436,59.3529684 18.940948,59.3382615 L56.6964963,21.5830662 C57.3856425,20.8939094 57.3856425,19.7765747 56.6964963,19.0874179 Z\"\n id=\"Combined-Shape\"\n ></path>\n </g>\n </g>\n </g>\n</svg>\n<svg\n *ngIf=\"icon === 'send'\"\n data-testid=\"send\"\n height=\"17\"\n viewBox=\"0 0 18 17\"\n width=\"18\"\n xmlns=\"http://www.w3.org/2000/svg\"\n>\n <title translate>streamChat.Send</title>\n <path\n d=\"M0 17.015l17.333-8.508L0 0v6.617l12.417 1.89L0 10.397z\"\n fill=\"#006cff\"\n fillRule=\"evenodd\"\n />\n</svg>\n<svg\n *ngIf=\"icon === 'file-upload'\"\n data-testid=\"file-upload\"\n height=\"14\"\n width=\"14\"\n xmlns=\"http://www.w3.org/2000/svg\"\n>\n <title translate>streamChat.Attach files</title>\n <path\n d=\"M1.667.333h10.666c.737 0 1.334.597 1.334 1.334v10.666c0 .737-.597 1.334-1.334 1.334H1.667a1.333 1.333 0 0 1-1.334-1.334V1.667C.333.93.93.333 1.667.333zm2 1.334a1.667 1.667 0 1 0 0 3.333 1.667 1.667 0 0 0 0-3.333zm-2 9.333v1.333h10.666v-4l-2-2-4 4-2-2L1.667 11z\"\n fillRule=\"nonzero\"\n />\n</svg>\n<svg\n data-testid=\"retry\"\n *ngIf=\"icon === 'retry'\"\n width=\"22\"\n height=\"20\"\n viewBox=\"0 0 22 20\"\n xmlns=\"http://www.w3.org/2000/svg\"\n>\n <path\n d=\"M20 5.535V2a1 1 0 0 1 2 0v6a1 1 0 0 1-1 1h-6a1 1 0 0 1 0-2h3.638l-2.975-2.653a8 8 0 1 0 1.884 8.32 1 1 0 1 1 1.886.666A10 10 0 1 1 5.175 1.245c3.901-2.15 8.754-1.462 11.88 1.667L20 5.535z\"\n fill=\"#FFF\"\n fill-rule=\"nonzero\"\n />\n</svg>\n<svg\n *ngIf=\"icon === 'close'\"\n data-testid=\"close\"\n width=\"28\"\n height=\"28\"\n viewBox=\"0 0 28 28\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n>\n <defs>\n <path\n d=\"M465 5c5.53 0 10 4.47 10 10s-4.47 10-10 10-10-4.47-10-10 4.47-10 10-10zm3.59 5L465 13.59 461.41 10 460 11.41l3.59 3.59-3.59 3.59 1.41 1.41 3.59-3.59 3.59 3.59 1.41-1.41-3.59-3.59 3.59-3.59-1.41-1.41z\"\n id=\"b\"\n />\n <filter\n x=\"-30%\"\n y=\"-30%\"\n width=\"160%\"\n height=\"160%\"\n filterUnits=\"objectBoundingBox\"\n id=\"a\"\n >\n <feOffset in=\"SourceAlpha\" result=\"shadowOffsetOuter1\" />\n <feGaussianBlur\n stdDeviation=\"2\"\n in=\"shadowOffsetOuter1\"\n result=\"shadowBlurOuter1\"\n />\n <feColorMatrix\n values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.5 0\"\n in=\"shadowBlurOuter1\"\n />\n </filter>\n </defs>\n <g transform=\"translate(-451 -1)\" fill-rule=\"nonzero\" fill=\"none\">\n <use fill=\"#000\" filter=\"url(#a)\" xlink:href=\"#b\" />\n <use fill=\"#FFF\" fill-rule=\"evenodd\" xlink:href=\"#b\" />\n </g>\n</svg>\n<svg\n *ngIf=\"icon === 'file'\"\n data-testid=\"file\"\n className=\"rfu-file-icon--small fa-file-fallback\"\n [attr.height]=\"size || 20\"\n [attr.width]=\"size || 20\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 384 512\"\n>\n <path\n d=\"M369.9 97.9L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM332.1 128H256V51.9l76.1 76.1zM48 464V48h160v104c0 13.3 10.7 24 24 24h104v288H48z\"\n fill=\"#414D54\"\n />\n</svg>\n<svg\n *ngIf=\"icon === 'reply'\"\n data-testid=\"reply\"\n height=\"15\"\n width=\"18\"\n xmlns=\"http://www.w3.org/2000/svg\"\n>\n <path\n d=\"M.56 10.946H.06l-.002-.498L.025.92a.5.5 0 1 1 1-.004l.032 9.029H9.06v-4l9 4.5-9 4.5v-4H.56z\"\n fillRule=\"nonzero\"\n />\n</svg>\n<svg\n height=\"10\"\n width=\"10\"\n xmlns=\"http://www.w3.org/2000/svg\"\n data-testid=\"close-no-outline\"\n *ngIf=\"icon === 'close-no-outline'\"\n>\n <path\n d=\"M9.916 1.027L8.973.084 5 4.058 1.027.084l-.943.943L4.058 5 .084 8.973l.943.943L5 5.942l3.973 3.974.943-.943L5.942 5z\"\n fillRule=\"evenodd\"\n />\n</svg>\n<svg\n height=\"10\"\n width=\"14\"\n xmlns=\"http://www.w3.org/2000/svg\"\n data-testid=\"reply-in-thread\"\n *ngIf=\"icon === 'reply-in-thread'\"\n>\n <path\n d=\"M8.516 3c4.78 0 4.972 6.5 4.972 6.5-1.6-2.906-2.847-3.184-4.972-3.184v2.872L3.772 4.994 8.516.5V3zM.484 5l4.5-4.237v1.78L2.416 5l2.568 2.125v1.828L.484 5z\"\n fillRule=\"evenodd\"\n />\n</svg>\n<svg\n *ngIf=\"icon === 'arrow-left'\"\n data-testid=\"arrow-left\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n>\n <path\n d=\"M15.7049 7.41L14.2949 6L8.29492 12L14.2949 18L15.7049 16.59L11.1249 12L15.7049 7.41Z\"\n fill=\"var(--black)\"\n />\n</svg>\n\n<svg\n *ngIf=\"icon === 'arrow-right'\"\n data-testid=\"arrow-right\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n>\n <path\n d=\"M9.70492 6L8.29492 7.41L12.8749 12L8.29492 16.59L9.70492 18L15.7049 12L9.70492 6Z\"\n fill=\"var(--black)\"\n />\n</svg>\n<svg\n *ngIf=\"icon === 'menu'\"\n data-testid=\"menu\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n>\n <path\n fill-rule=\"evenodd\"\n clip-rule=\"evenodd\"\n d=\"M3 8V6H21V8H3ZM3 13H21V11H3V13ZM3 18H21V16H3V18Z\"\n fill=\"black\"\n />\n</svg>\n", directives: [{ type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }] });
|
|
1550
1761
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: IconComponent, decorators: [{
|
|
1551
1762
|
type: Component,
|
|
1552
1763
|
args: [{
|
|
@@ -1560,6 +1771,35 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
1560
1771
|
type: Input
|
|
1561
1772
|
}] } });
|
|
1562
1773
|
|
|
1774
|
+
/**
|
|
1775
|
+
* The `IconPlaceholder` component displays the [default icons](./IconComponent.mdx) unless a [custom template](../services/CustomTemplatesService.mdx) is provided. This componet is used by the SDK internally, you likely won't need to use it.
|
|
1776
|
+
*/
|
|
1777
|
+
class IconPlaceholderComponent {
|
|
1778
|
+
constructor(customTemplatesService) {
|
|
1779
|
+
this.customTemplatesService = customTemplatesService;
|
|
1780
|
+
}
|
|
1781
|
+
getIconContext() {
|
|
1782
|
+
return {
|
|
1783
|
+
icon: this.icon,
|
|
1784
|
+
size: this.size,
|
|
1785
|
+
};
|
|
1786
|
+
}
|
|
1787
|
+
}
|
|
1788
|
+
IconPlaceholderComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: IconPlaceholderComponent, deps: [{ token: CustomTemplatesService }], target: i0.ɵɵFactoryTarget.Component });
|
|
1789
|
+
IconPlaceholderComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: { icon: "icon", size: "size" }, ngImport: i0, template: "<ng-template #defaultIcon let-icon=\"icon\" let-size=\"size\">\n <stream-icon [icon]=\"icon\" [size]=\"size\"></stream-icon>\n</ng-template>\n<ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.iconTemplate$ | async) || defaultIcon;\n context: getIconContext()\n \"\n></ng-container>\n", components: [{ type: IconComponent, selector: "stream-icon", inputs: ["icon", "size"] }], directives: [{ type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], pipes: { "async": i3.AsyncPipe } });
|
|
1790
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: IconPlaceholderComponent, decorators: [{
|
|
1791
|
+
type: Component,
|
|
1792
|
+
args: [{
|
|
1793
|
+
selector: 'stream-icon-placeholder',
|
|
1794
|
+
templateUrl: './icon-placeholder.component.html',
|
|
1795
|
+
styles: [],
|
|
1796
|
+
}]
|
|
1797
|
+
}], ctorParameters: function () { return [{ type: CustomTemplatesService }]; }, propDecorators: { icon: [{
|
|
1798
|
+
type: Input
|
|
1799
|
+
}], size: [{
|
|
1800
|
+
type: Input
|
|
1801
|
+
}] } });
|
|
1802
|
+
|
|
1563
1803
|
/**
|
|
1564
1804
|
* The `LoadingIndicator` component displays a spinner to indicate that an action is in progress.
|
|
1565
1805
|
*/
|
|
@@ -1576,7 +1816,7 @@ class LoadingIndicatorComponent {
|
|
|
1576
1816
|
}
|
|
1577
1817
|
}
|
|
1578
1818
|
LoadingIndicatorComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: LoadingIndicatorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1579
|
-
LoadingIndicatorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: LoadingIndicatorComponent, selector: "stream-loading-indicator", inputs: { size: "size", color: "color" }, ngImport: i0, template: "<div class=\"str-chat__loading-indicator\">\n <svg\n [attr.height]=\"size\"\n viewBox=\"0 0 30 30\"\n [attr.width]=\"size\"\n data-testid=\"loading-indicator\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <defs>\n <linearGradient id=\"a\" x1=\"50%\" x2=\"50%\" y1=\"0%\" y2=\"100%\">\n <stop offset=\"0%\" stop-color=\"#FFF\" stop-opacity=\"0\" />\n <stop\n data-testid=\"stop-color\"\n offset=\"100%\"\n [attr.stop-color]=\"color\"\n stop-opacity=\"1\"\n [ngStyle]=\"{ stopColor: color }\"\n />\n </linearGradient>\n </defs>\n <path\n d=\"M2.518 23.321l1.664-1.11A12.988 12.988 0 0 0 15 28c7.18 0 13-5.82 13-13S22.18 2 15 2V0c8.284 0 15 6.716 15 15 0 8.284-6.716 15-15 15-5.206 0-9.792-2.652-12.482-6.679z\"\n fill=\"url(#a)\"\n fillRule=\"evenodd\"\n />\n </svg>\n</div>\n", directives: [{ type:
|
|
1819
|
+
LoadingIndicatorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: LoadingIndicatorComponent, selector: "stream-loading-indicator", inputs: { size: "size", color: "color" }, ngImport: i0, template: "<div class=\"str-chat__loading-indicator\">\n <svg\n [attr.height]=\"size\"\n viewBox=\"0 0 30 30\"\n [attr.width]=\"size\"\n data-testid=\"loading-indicator\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <defs>\n <linearGradient id=\"a\" x1=\"50%\" x2=\"50%\" y1=\"0%\" y2=\"100%\">\n <stop offset=\"0%\" stop-color=\"#FFF\" stop-opacity=\"0\" />\n <stop\n data-testid=\"stop-color\"\n offset=\"100%\"\n [attr.stop-color]=\"color\"\n stop-opacity=\"1\"\n [ngStyle]=\"{ stopColor: color }\"\n />\n </linearGradient>\n </defs>\n <path\n d=\"M2.518 23.321l1.664-1.11A12.988 12.988 0 0 0 15 28c7.18 0 13-5.82 13-13S22.18 2 15 2V0c8.284 0 15 6.716 15 15 0 8.284-6.716 15-15 15-5.206 0-9.792-2.652-12.482-6.679z\"\n fill=\"url(#a)\"\n fillRule=\"evenodd\"\n />\n </svg>\n</div>\n", directives: [{ type: i3.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] });
|
|
1580
1820
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: LoadingIndicatorComponent, decorators: [{
|
|
1581
1821
|
type: Component,
|
|
1582
1822
|
args: [{
|
|
@@ -1590,6 +1830,113 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
1590
1830
|
type: Input
|
|
1591
1831
|
}] } });
|
|
1592
1832
|
|
|
1833
|
+
/**
|
|
1834
|
+
* The `LoadingInficatorPlaceholder` component displays the [default loading indicator](./LoadingIndicatorComponent.mdx) unless a [custom template](../services/CustomTemplatesService.mdx) is provided. This componet is used by the SDK internally, you likely won't need to use it.
|
|
1835
|
+
*/
|
|
1836
|
+
class LoadingIndicatorPlaceholderComponent {
|
|
1837
|
+
constructor(customTemplatesService) {
|
|
1838
|
+
this.customTemplatesService = customTemplatesService;
|
|
1839
|
+
/**
|
|
1840
|
+
* The size of the indicator (in pixels)
|
|
1841
|
+
*/
|
|
1842
|
+
this.size = 15;
|
|
1843
|
+
/**
|
|
1844
|
+
* The color of the indicator
|
|
1845
|
+
*/
|
|
1846
|
+
this.color = '#006CFF';
|
|
1847
|
+
}
|
|
1848
|
+
getLoadingIndicatorContext() {
|
|
1849
|
+
return {
|
|
1850
|
+
size: this.size,
|
|
1851
|
+
color: this.color,
|
|
1852
|
+
};
|
|
1853
|
+
}
|
|
1854
|
+
}
|
|
1855
|
+
LoadingIndicatorPlaceholderComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: LoadingIndicatorPlaceholderComponent, deps: [{ token: CustomTemplatesService }], target: i0.ɵɵFactoryTarget.Component });
|
|
1856
|
+
LoadingIndicatorPlaceholderComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: LoadingIndicatorPlaceholderComponent, selector: "stream-loading-indicator-placeholder", inputs: { size: "size", color: "color" }, ngImport: i0, template: "<ng-template #defaultLoadingIndicator let-size=\"size\" let-color=\"color\">\n <stream-loading-indicator\n [size]=\"size\"\n [color]=\"color\"\n ></stream-loading-indicator>\n</ng-template>\n<ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.loadingIndicatorTemplate$ | async) ||\n defaultLoadingIndicator;\n context: getLoadingIndicatorContext()\n \"\n></ng-container>\n", components: [{ type: LoadingIndicatorComponent, selector: "stream-loading-indicator", inputs: ["size", "color"] }], directives: [{ type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], pipes: { "async": i3.AsyncPipe } });
|
|
1857
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: LoadingIndicatorPlaceholderComponent, decorators: [{
|
|
1858
|
+
type: Component,
|
|
1859
|
+
args: [{
|
|
1860
|
+
selector: 'stream-loading-indicator-placeholder',
|
|
1861
|
+
templateUrl: './loading-indicator-placeholder.component.html',
|
|
1862
|
+
styles: [],
|
|
1863
|
+
}]
|
|
1864
|
+
}], ctorParameters: function () { return [{ type: CustomTemplatesService }]; }, propDecorators: { size: [{
|
|
1865
|
+
type: Input
|
|
1866
|
+
}], color: [{
|
|
1867
|
+
type: Input
|
|
1868
|
+
}] } });
|
|
1869
|
+
|
|
1870
|
+
/**
|
|
1871
|
+
* The `Modal` component displays its content in an overlay. The modal can be closed with a close button, if the user clicks outside of the modal content, or if the escape button is pressed. The modal can also be closed from outside.
|
|
1872
|
+
*/
|
|
1873
|
+
class ModalComponent {
|
|
1874
|
+
constructor() {
|
|
1875
|
+
/**
|
|
1876
|
+
* If `true` the modal will be displayed, if `false` the modal will be hidden
|
|
1877
|
+
*/
|
|
1878
|
+
this.isOpen = false;
|
|
1879
|
+
/**
|
|
1880
|
+
* Emits `true` if the modal becomes visible, and `false` if the modal is closed.
|
|
1881
|
+
*/
|
|
1882
|
+
this.isOpenChange = new EventEmitter();
|
|
1883
|
+
this.watchForEscPress = (event) => {
|
|
1884
|
+
if (event.key === 'Escape') {
|
|
1885
|
+
this.close();
|
|
1886
|
+
}
|
|
1887
|
+
};
|
|
1888
|
+
this.stopWatchForEscPress = () => {
|
|
1889
|
+
window.removeEventListener('keyup', this.watchForEscPress);
|
|
1890
|
+
};
|
|
1891
|
+
this.watchForOutsideClicks = (event) => {
|
|
1892
|
+
var _a;
|
|
1893
|
+
if (!((_a = this.innerContainer) === null || _a === void 0 ? void 0 : _a.nativeElement.contains(event.target))) {
|
|
1894
|
+
this.close();
|
|
1895
|
+
}
|
|
1896
|
+
};
|
|
1897
|
+
}
|
|
1898
|
+
ngOnChanges(changes) {
|
|
1899
|
+
if (changes.isOpen) {
|
|
1900
|
+
if (this.isOpen) {
|
|
1901
|
+
window.addEventListener('keyup', this.watchForEscPress);
|
|
1902
|
+
setTimeout(() => window.addEventListener('click', this.watchForOutsideClicks), 0);
|
|
1903
|
+
}
|
|
1904
|
+
else {
|
|
1905
|
+
this.stopWatchForOutsideClicks();
|
|
1906
|
+
this.stopWatchForEscPress();
|
|
1907
|
+
}
|
|
1908
|
+
}
|
|
1909
|
+
}
|
|
1910
|
+
close() {
|
|
1911
|
+
this.isOpen = false;
|
|
1912
|
+
this.isOpenChange.emit(false);
|
|
1913
|
+
this.stopWatchForOutsideClicks();
|
|
1914
|
+
this.stopWatchForEscPress();
|
|
1915
|
+
}
|
|
1916
|
+
stopWatchForOutsideClicks() {
|
|
1917
|
+
window.removeEventListener('click', this.watchForOutsideClicks);
|
|
1918
|
+
}
|
|
1919
|
+
}
|
|
1920
|
+
ModalComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1921
|
+
ModalComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: ModalComponent, selector: "stream-modal", inputs: { isOpen: "isOpen", content: "content" }, outputs: { isOpenChange: "isOpenChange" }, viewQueries: [{ propertyName: "innerContainer", first: true, predicate: ["modalInner"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div\n data-testid=\"modal\"\n class=\"str-chat__modal str-chat__modal--{{ isOpen ? 'open' : 'close' }}\"\n>\n <div\n data-testid=\"close\"\n class=\"str-chat__modal__close-button\"\n (click)=\"close()\"\n (keyup.enter)=\"close()\"\n translate\n >\n streamChat.Close\n <stream-icon-placeholder icon=\"close\"></stream-icon-placeholder>\n </div>\n <div class=\"str-chat__modal__inner\" #modalInner>\n <ng-container *ngIf=\"content; else elseContent\">\n <ng-container *ngTemplateOutlet=\"content\"></ng-container>\n </ng-container>\n <ng-template #elseContent>\n <ng-content></ng-content>\n </ng-template>\n </div>\n</div>\n", components: [{ type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon", "size"] }], directives: [{ type: i2.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }] });
|
|
1922
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ModalComponent, decorators: [{
|
|
1923
|
+
type: Component,
|
|
1924
|
+
args: [{
|
|
1925
|
+
selector: 'stream-modal',
|
|
1926
|
+
templateUrl: './modal.component.html',
|
|
1927
|
+
styles: [],
|
|
1928
|
+
}]
|
|
1929
|
+
}], ctorParameters: function () { return []; }, propDecorators: { isOpen: [{
|
|
1930
|
+
type: Input
|
|
1931
|
+
}], content: [{
|
|
1932
|
+
type: Input
|
|
1933
|
+
}], isOpenChange: [{
|
|
1934
|
+
type: Output
|
|
1935
|
+
}], innerContainer: [{
|
|
1936
|
+
type: ViewChild,
|
|
1937
|
+
args: ['modalInner']
|
|
1938
|
+
}] } });
|
|
1939
|
+
|
|
1593
1940
|
const textareaInjectionToken = new InjectionToken('textareaInjectionToken');
|
|
1594
1941
|
|
|
1595
1942
|
class TextareaDirective {
|
|
@@ -1616,10 +1963,6 @@ class TextareaDirective {
|
|
|
1616
1963
|
this.subscriptions.push(this.componentRef.instance.userMentions.subscribe((value) => this.userMentions.next(value)));
|
|
1617
1964
|
}
|
|
1618
1965
|
this.componentRef.instance.areMentionsEnabled = this.areMentionsEnabled;
|
|
1619
|
-
this.componentRef.instance.mentionAutocompleteItemTemplate =
|
|
1620
|
-
this.mentionAutocompleteItemTemplate;
|
|
1621
|
-
this.componentRef.instance.commandAutocompleteItemTemplate =
|
|
1622
|
-
this.commandAutocompleteItemTemplate;
|
|
1623
1966
|
this.componentRef.instance.mentionScope = this.mentionScope;
|
|
1624
1967
|
this.componentRef.instance.value = this.value;
|
|
1625
1968
|
}
|
|
@@ -1627,14 +1970,6 @@ class TextareaDirective {
|
|
|
1627
1970
|
if (changes.areMentionsEnabled) {
|
|
1628
1971
|
this.componentRef.instance.areMentionsEnabled = this.areMentionsEnabled;
|
|
1629
1972
|
}
|
|
1630
|
-
if (changes.mentionAutocompleteItemTemplate) {
|
|
1631
|
-
this.componentRef.instance.mentionAutocompleteItemTemplate =
|
|
1632
|
-
this.mentionAutocompleteItemTemplate;
|
|
1633
|
-
}
|
|
1634
|
-
if (changes.commandAutocompleteItemTemplate) {
|
|
1635
|
-
this.componentRef.instance.commandAutocompleteItemTemplate =
|
|
1636
|
-
this.commandAutocompleteItemTemplate;
|
|
1637
|
-
}
|
|
1638
1973
|
if (changes.mentionScope) {
|
|
1639
1974
|
this.componentRef.instance.mentionScope = this.mentionScope;
|
|
1640
1975
|
}
|
|
@@ -1650,7 +1985,7 @@ class TextareaDirective {
|
|
|
1650
1985
|
}
|
|
1651
1986
|
}
|
|
1652
1987
|
TextareaDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: TextareaDirective, deps: [{ token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Directive });
|
|
1653
|
-
TextareaDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "12.2.5", type: TextareaDirective, selector: "[streamTextarea]", inputs: { componentRef: "componentRef", areMentionsEnabled: "areMentionsEnabled",
|
|
1988
|
+
TextareaDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "12.2.5", type: TextareaDirective, selector: "[streamTextarea]", inputs: { componentRef: "componentRef", areMentionsEnabled: "areMentionsEnabled", mentionScope: "mentionScope", value: "value" }, outputs: { valueChange: "valueChange", send: "send", userMentions: "userMentions" }, usesOnChanges: true, ngImport: i0 });
|
|
1654
1989
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: TextareaDirective, decorators: [{
|
|
1655
1990
|
type: Directive,
|
|
1656
1991
|
args: [{
|
|
@@ -1660,12 +1995,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
1660
1995
|
type: Input
|
|
1661
1996
|
}], areMentionsEnabled: [{
|
|
1662
1997
|
type: Input
|
|
1663
|
-
}], mentionAutocompleteItemTemplate: [{
|
|
1664
|
-
type: Input
|
|
1665
1998
|
}], mentionScope: [{
|
|
1666
1999
|
type: Input
|
|
1667
|
-
}], commandAutocompleteItemTemplate: [{
|
|
1668
|
-
type: Input
|
|
1669
2000
|
}], value: [{
|
|
1670
2001
|
type: Input
|
|
1671
2002
|
}], valueChange: [{
|
|
@@ -1748,79 +2079,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
1748
2079
|
}]
|
|
1749
2080
|
}], ctorParameters: function () { return []; } });
|
|
1750
2081
|
|
|
1751
|
-
/**
|
|
1752
|
-
* The `Modal` component displays its content in an overlay. The modal can be closed with a close button, if the user clicks outside of the modal content, or if the escape button is pressed. The modal can also be closed from outside.
|
|
1753
|
-
*/
|
|
1754
|
-
class ModalComponent {
|
|
1755
|
-
constructor() {
|
|
1756
|
-
/**
|
|
1757
|
-
* If `true` the modal will be displayed, if `false` the modal will be hidden
|
|
1758
|
-
*/
|
|
1759
|
-
this.isOpen = false;
|
|
1760
|
-
/**
|
|
1761
|
-
* Emits `true` if the modal becomes visible, and `false` if the modal is closed.
|
|
1762
|
-
*/
|
|
1763
|
-
this.isOpenChange = new EventEmitter();
|
|
1764
|
-
this.watchForEscPress = (event) => {
|
|
1765
|
-
if (event.key === 'Escape') {
|
|
1766
|
-
this.close();
|
|
1767
|
-
}
|
|
1768
|
-
};
|
|
1769
|
-
this.stopWatchForEscPress = () => {
|
|
1770
|
-
window.removeEventListener('keyup', this.watchForEscPress);
|
|
1771
|
-
};
|
|
1772
|
-
this.watchForOutsideClicks = (event) => {
|
|
1773
|
-
var _a;
|
|
1774
|
-
if (!((_a = this.content) === null || _a === void 0 ? void 0 : _a.nativeElement.contains(event.target))) {
|
|
1775
|
-
this.close();
|
|
1776
|
-
}
|
|
1777
|
-
};
|
|
1778
|
-
}
|
|
1779
|
-
ngOnChanges(changes) {
|
|
1780
|
-
if (changes.isOpen) {
|
|
1781
|
-
if (this.isOpen) {
|
|
1782
|
-
window.addEventListener('keyup', this.watchForEscPress);
|
|
1783
|
-
setTimeout(() => window.addEventListener('click', this.watchForOutsideClicks), 0);
|
|
1784
|
-
}
|
|
1785
|
-
else {
|
|
1786
|
-
this.stopWatchForOutsideClicks();
|
|
1787
|
-
this.stopWatchForEscPress();
|
|
1788
|
-
}
|
|
1789
|
-
}
|
|
1790
|
-
}
|
|
1791
|
-
close() {
|
|
1792
|
-
this.isOpen = false;
|
|
1793
|
-
this.isOpenChange.emit(false);
|
|
1794
|
-
this.stopWatchForOutsideClicks();
|
|
1795
|
-
this.stopWatchForEscPress();
|
|
1796
|
-
}
|
|
1797
|
-
stopWatchForOutsideClicks() {
|
|
1798
|
-
window.removeEventListener('click', this.watchForOutsideClicks);
|
|
1799
|
-
}
|
|
1800
|
-
}
|
|
1801
|
-
ModalComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1802
|
-
ModalComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: ModalComponent, selector: "stream-modal", inputs: { isOpen: "isOpen" }, outputs: { isOpenChange: "isOpenChange" }, viewQueries: [{ propertyName: "content", first: true, predicate: ["content"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div\n data-testid=\"modal\"\n class=\"str-chat__modal str-chat__modal--{{ isOpen ? 'open' : 'close' }}\"\n>\n <div\n data-testid=\"close\"\n class=\"str-chat__modal__close-button\"\n (click)=\"close()\"\n (keyup.enter)=\"close()\"\n translate\n >\n streamChat.Close\n <stream-icon icon=\"close\"></stream-icon>\n </div>\n <div class=\"str-chat__modal__inner\" #content>\n <ng-content></ng-content>\n </div>\n</div>\n", components: [{ type: IconComponent, selector: "stream-icon", inputs: ["icon", "size"] }], directives: [{ type: i2.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }] });
|
|
1803
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ModalComponent, decorators: [{
|
|
1804
|
-
type: Component,
|
|
1805
|
-
args: [{
|
|
1806
|
-
selector: 'stream-modal',
|
|
1807
|
-
templateUrl: './modal.component.html',
|
|
1808
|
-
styles: [],
|
|
1809
|
-
}]
|
|
1810
|
-
}], ctorParameters: function () { return []; }, propDecorators: { isOpen: [{
|
|
1811
|
-
type: Input
|
|
1812
|
-
}], isOpenChange: [{
|
|
1813
|
-
type: Output
|
|
1814
|
-
}], content: [{
|
|
1815
|
-
type: ViewChild,
|
|
1816
|
-
args: ['content']
|
|
1817
|
-
}] } });
|
|
1818
|
-
|
|
1819
2082
|
/**
|
|
1820
2083
|
* The `AttachmentList` compontent displays the attachments of a message
|
|
1821
2084
|
*/
|
|
1822
2085
|
class AttachmentListComponent {
|
|
1823
|
-
constructor(imageLoadService, channelService) {
|
|
2086
|
+
constructor(customTemplatesService, imageLoadService, channelService) {
|
|
2087
|
+
this.customTemplatesService = customTemplatesService;
|
|
1824
2088
|
this.imageLoadService = imageLoadService;
|
|
1825
2089
|
this.channelService = channelService;
|
|
1826
2090
|
/**
|
|
@@ -1866,6 +2130,13 @@ class AttachmentListComponent {
|
|
|
1866
2130
|
getFileSize(attachment) {
|
|
1867
2131
|
return prettybytes(Number(attachment.file_size));
|
|
1868
2132
|
}
|
|
2133
|
+
getModalContext() {
|
|
2134
|
+
return {
|
|
2135
|
+
isOpen: this.imagesToView && this.imagesToView.length > 0,
|
|
2136
|
+
isOpenChangeHandler: (isOpen) => (isOpen ? null : this.closeImageModal()),
|
|
2137
|
+
content: this.modalContent,
|
|
2138
|
+
};
|
|
2139
|
+
}
|
|
1869
2140
|
trimUrl(url) {
|
|
1870
2141
|
if (url !== undefined && url !== null) {
|
|
1871
2142
|
const [trimmedUrl] = url
|
|
@@ -1887,9 +2158,6 @@ class AttachmentListComponent {
|
|
|
1887
2158
|
this.imagesToView = attachments;
|
|
1888
2159
|
this.imagesToViewCurrentIndex = selectedIndex;
|
|
1889
2160
|
}
|
|
1890
|
-
closeImageModal() {
|
|
1891
|
-
this.imagesToView = [];
|
|
1892
|
-
}
|
|
1893
2161
|
stepImages(dir) {
|
|
1894
2162
|
this.imagesToViewCurrentIndex += dir * 1;
|
|
1895
2163
|
}
|
|
@@ -1910,9 +2178,12 @@ class AttachmentListComponent {
|
|
|
1910
2178
|
},
|
|
1911
2179
|
];
|
|
1912
2180
|
}
|
|
2181
|
+
closeImageModal() {
|
|
2182
|
+
this.imagesToView = [];
|
|
2183
|
+
}
|
|
1913
2184
|
}
|
|
1914
|
-
AttachmentListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: AttachmentListComponent, deps: [{ token: ImageLoadService }, { token: ChannelService }], target: i0.ɵɵFactoryTarget.Component });
|
|
1915
|
-
AttachmentListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: AttachmentListComponent, selector: "stream-attachment-list", inputs: { messageId: "messageId", attachments: "attachments" }, usesOnChanges: true, ngImport: i0, template: "<ng-container *ngFor=\"let attachment of orderedAttachments; trackBy: trackById\">\n <div\n data-testclass=\"attachment-container\"\n class=\"str-chat__message-attachment str-chat__message-attachment--{{\n attachment.type\n }}\"\n [class.str-chat__message-attachment--card]=\"isCard(attachment)\"\n [class.str-chat-angular__message-attachment-file-single]=\"\n isFile(attachment)\n \"\n >\n <img\n *ngIf=\"isImage(attachment)\"\n class=\"str-chat__message-attachment--img\"\n data-testclass=\"image\"\n [src]=\"attachment.img_url || attachment.thumb_url || attachment.image_url\"\n [alt]=\"attachment?.fallback\"\n (load)=\"imageLoaded()\"\n (click)=\"openImageModal([attachment])\"\n (keyup.enter)=\"openImageModal([attachment])\"\n />\n <div\n class=\"str-chat__gallery\"\n data-testid=\"image-gallery\"\n *ngIf=\"isGallery(attachment)\"\n [class.str-chat__gallery--square]=\"(attachment?.images)!.length > 3\"\n >\n <ng-container\n *ngFor=\"\n let galleryImage of attachment.images;\n let index = index;\n let isLast = last;\n trackBy: trackByImageUrl\n \"\n >\n <button\n *ngIf=\"index < 3 || (index === 3 && isLast)\"\n class=\"str-chat__gallery-image\"\n data-testclass=\"gallery-image\"\n (click)=\"openImageModal(attachment.images!, index)\"\n (keyup.enter)=\"openImageModal(attachment.images!, index)\"\n >\n <img\n [src]=\"\n galleryImage.img_url ||\n galleryImage.thumb_url ||\n galleryImage.image_url\n \"\n [alt]=\"galleryImage.fallback\"\n (load)=\"imageLoaded()\"\n />\n </button>\n <button\n *ngIf=\"index === 3 && !isLast\"\n class=\"str-chat__gallery-placeholder\"\n data-testclass=\"gallery-image\"\n (click)=\"openImageModal(attachment.images!, index)\"\n (keyup.enter)=\"openImageModal(attachment.images!, index)\"\n [ngStyle]=\"{\n 'background-image':\n 'url(' +\n (galleryImage.img_url ||\n galleryImage.thumb_url ||\n galleryImage.image_url) +\n ')'\n }\"\n >\n <p\n [innerHTML]=\"\n 'streamChat.{{ imageCount }} more'\n | translate: { imageCount: attachment!.images!.length - 4 }\n \"\n ></p>\n </button>\n </ng-container>\n </div>\n <div\n *ngIf=\"isFile(attachment)\"\n class=\"\n str-chat__message-attachment-file--item\n str-chat-angular__message-attachment-file-single\n \"\n >\n <stream-icon
|
|
2185
|
+
AttachmentListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: AttachmentListComponent, deps: [{ token: CustomTemplatesService }, { token: ImageLoadService }, { token: ChannelService }], target: i0.ɵɵFactoryTarget.Component });
|
|
2186
|
+
AttachmentListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: AttachmentListComponent, selector: "stream-attachment-list", inputs: { messageId: "messageId", attachments: "attachments" }, viewQueries: [{ propertyName: "modalContent", first: true, predicate: ["modalContent"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<ng-container *ngFor=\"let attachment of orderedAttachments; trackBy: trackById\">\n <div\n data-testclass=\"attachment-container\"\n class=\"str-chat__message-attachment str-chat__message-attachment--{{\n attachment.type\n }}\"\n [class.str-chat__message-attachment--card]=\"isCard(attachment)\"\n [class.str-chat-angular__message-attachment-file-single]=\"\n isFile(attachment)\n \"\n >\n <img\n *ngIf=\"isImage(attachment)\"\n class=\"str-chat__message-attachment--img\"\n data-testclass=\"image\"\n [src]=\"attachment.img_url || attachment.thumb_url || attachment.image_url\"\n [alt]=\"attachment?.fallback\"\n (load)=\"imageLoaded()\"\n (click)=\"openImageModal([attachment])\"\n (keyup.enter)=\"openImageModal([attachment])\"\n />\n <div\n class=\"str-chat__gallery\"\n data-testid=\"image-gallery\"\n *ngIf=\"isGallery(attachment)\"\n [class.str-chat__gallery--square]=\"(attachment?.images)!.length > 3\"\n >\n <ng-container\n *ngFor=\"\n let galleryImage of attachment.images;\n let index = index;\n let isLast = last;\n trackBy: trackByImageUrl\n \"\n >\n <button\n *ngIf=\"index < 3 || (index === 3 && isLast)\"\n class=\"str-chat__gallery-image\"\n data-testclass=\"gallery-image\"\n (click)=\"openImageModal(attachment.images!, index)\"\n (keyup.enter)=\"openImageModal(attachment.images!, index)\"\n >\n <img\n [src]=\"\n galleryImage.img_url ||\n galleryImage.thumb_url ||\n galleryImage.image_url\n \"\n [alt]=\"galleryImage.fallback\"\n (load)=\"imageLoaded()\"\n />\n </button>\n <button\n *ngIf=\"index === 3 && !isLast\"\n class=\"str-chat__gallery-placeholder\"\n data-testclass=\"gallery-image\"\n (click)=\"openImageModal(attachment.images!, index)\"\n (keyup.enter)=\"openImageModal(attachment.images!, index)\"\n [ngStyle]=\"{\n 'background-image':\n 'url(' +\n (galleryImage.img_url ||\n galleryImage.thumb_url ||\n galleryImage.image_url) +\n ')'\n }\"\n >\n <p\n [innerHTML]=\"\n 'streamChat.{{ imageCount }} more'\n | translate: { imageCount: attachment!.images!.length - 4 }\n \"\n ></p>\n </button>\n </ng-container>\n </div>\n <div\n *ngIf=\"isFile(attachment)\"\n class=\"\n str-chat__message-attachment-file--item\n str-chat-angular__message-attachment-file-single\n \"\n >\n <stream-icon-placeholder\n icon=\"file\"\n [size]=\"30\"\n ></stream-icon-placeholder>\n <div class=\"str-chat__message-attachment-file--item-text\">\n <a\n data-testclass=\"file-link\"\n download\n href=\"{{ attachment.asset_url }}\"\n target=\"_blank\"\n >\n {{ attachment.title }}\n </a>\n <span data-testclass=\"size\" *ngIf=\"hasFileSize(attachment)\">{{\n getFileSize(attachment)\n }}</span>\n </div>\n </div>\n <div\n *ngIf=\"isCard(attachment)\"\n class=\"str-chat__message-attachment-card str-chat__message-attachment-card--{{\n attachment.type\n }}\"\n >\n <div\n *ngIf=\"attachment.image_url || attachment.thumb_url\"\n class=\"str-chat__message-attachment-card--header\"\n >\n <img\n data-testclass=\"card-img\"\n alt=\"{{ attachment.image_url || attachment.thumb_url }}\"\n src=\"{{ attachment.image_url || attachment.thumb_url }}\"\n />\n </div>\n <div class=\"str-chat__message-attachment-card--content\">\n <div class=\"str-chat__message-attachment-card--flex\">\n <div\n *ngIf=\"attachment.title\"\n data-testclass=\"card-title\"\n class=\"str-chat__message-attachment-card--title\"\n >\n {{ attachment.title }}\n </div>\n <div\n *ngIf=\"attachment.text\"\n class=\"str-chat__message-attachment-card--text\"\n data-testclass=\"card-text\"\n >\n {{ attachment.text }}\n </div>\n <a\n class=\"str-chat__message-attachment-card--url\"\n *ngIf=\"attachment.title_link || attachment.og_scrape_url\"\n data-testclass=\"url-link\"\n noopener\n noreferrer\n href=\"{{ attachment.title_link || attachment.og_scrape_url }}\"\n target=\"_blank\"\n >\n {{ trimUrl(attachment.title_link || attachment.og_scrape_url) }}\n </a>\n </div>\n </div>\n </div>\n <div\n class=\"str-chat__message-attachment-actions\"\n *ngIf=\"attachment.actions && attachment.actions.length > 0\"\n >\n <div class=\"str-chat__message-attachment-actions-form\">\n <button\n *ngFor=\"let action of attachment.actions; trackBy: trackByActionValue\"\n class=\"str-chat__message-attachment-actions-button str-chat__message-attachment-actions-button--{{\n action.style\n }}\"\n data-testclass=\"attachment-action\"\n (click)=\"sendAction(action)\"\n (keyup.enter)=\"sendAction(action)\"\n >\n {{ action.text }}\n </button>\n </div>\n </div>\n </div>\n</ng-container>\n\n<ng-container *ngIf=\"imagesToView && imagesToView.length > 0\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.modalTemplate$ | async) || defaultModal;\n context: getModalContext()\n \"\n ></ng-container>\n</ng-container>\n\n<ng-template\n #defaultModal\n let-isOpen=\"isOpen\"\n let-isOpenChangeHandler=\"isOpenChangeHandler\"\n let-content=\"content\"\n>\n <stream-modal\n [isOpen]=\"isOpen\"\n (isOpenChange)=\"isOpenChangeHandler($event)\"\n [content]=\"content\"\n >\n </stream-modal>\n</ng-template>\n\n<ng-template #modalContent>\n <div class=\"stream-chat-angular__image-modal\">\n <button\n class=\"stream-chat-angular__image-modal-stepper\"\n [ngStyle]=\"{\n visibility: isImageModalPrevButtonVisible ? 'visible' : 'hidden'\n }\"\n data-testid=\"image-modal-prev\"\n type=\"button\"\n (click)=\"stepImages(-1)\"\n (keyup.enter)=\"stepImages(-1)\"\n >\n <stream-icon-placeholder icon=\"arrow-left\"></stream-icon-placeholder>\n </button>\n <img\n class=\"stream-chat-angular__image-modal-image\"\n data-testid=\"modal-image\"\n [src]=\"\n imagesToView[imagesToViewCurrentIndex].img_url ||\n imagesToView[imagesToViewCurrentIndex].thumb_url ||\n imagesToView[imagesToViewCurrentIndex].image_url\n \"\n [alt]=\"imagesToView[imagesToViewCurrentIndex].fallback\"\n />\n <button\n class=\"stream-chat-angular__image-modal-stepper\"\n type=\"button\"\n [ngStyle]=\"{\n visibility: isImageModalNextButtonVisible ? 'visible' : 'hidden'\n }\"\n data-testid=\"image-modal-next\"\n (click)=\"stepImages(1)\"\n (keyup.enter)=\"stepImages(1)\"\n >\n <stream-icon-placeholder icon=\"arrow-right\"></stream-icon-placeholder>\n </button>\n </div>\n</ng-template>\n", components: [{ type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon", "size"] }, { type: ModalComponent, selector: "stream-modal", inputs: ["isOpen", "content"], outputs: ["isOpenChange"] }], directives: [{ type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], pipes: { "translate": i2.TranslatePipe, "async": i3.AsyncPipe } });
|
|
1916
2187
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: AttachmentListComponent, decorators: [{
|
|
1917
2188
|
type: Component,
|
|
1918
2189
|
args: [{
|
|
@@ -1920,36 +2191,41 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
1920
2191
|
templateUrl: './attachment-list.component.html',
|
|
1921
2192
|
styles: [],
|
|
1922
2193
|
}]
|
|
1923
|
-
}], ctorParameters: function () { return [{ type: ImageLoadService }, { type: ChannelService }]; }, propDecorators: { messageId: [{
|
|
2194
|
+
}], ctorParameters: function () { return [{ type: CustomTemplatesService }, { type: ImageLoadService }, { type: ChannelService }]; }, propDecorators: { messageId: [{
|
|
1924
2195
|
type: Input
|
|
1925
2196
|
}], attachments: [{
|
|
1926
2197
|
type: Input
|
|
2198
|
+
}], modalContent: [{
|
|
2199
|
+
type: ViewChild,
|
|
2200
|
+
args: ['modalContent', { static: true }]
|
|
1927
2201
|
}] } });
|
|
1928
2202
|
|
|
1929
2203
|
/**
|
|
1930
2204
|
* The `AttachmentPreviewList` compontent displays a preview of the attachments uploaded to a message. Users can delete attachments using the preview component, or retry upload if it failed previously.
|
|
1931
2205
|
*/
|
|
1932
2206
|
class AttachmentPreviewListComponent {
|
|
1933
|
-
constructor(
|
|
1934
|
-
|
|
1935
|
-
|
|
2207
|
+
constructor() {
|
|
2208
|
+
/**
|
|
2209
|
+
* An output to notify the parent component if the user tries to retry a failed upload
|
|
2210
|
+
*/
|
|
2211
|
+
this.retryAttachmentUpload = new EventEmitter();
|
|
2212
|
+
/**
|
|
2213
|
+
* An output to notify the parent component if the user wants to delete a file
|
|
2214
|
+
*/
|
|
2215
|
+
this.deleteAttachment = new EventEmitter();
|
|
1936
2216
|
}
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
yield this.attachmentService.retryAttachmentUpload(file);
|
|
1940
|
-
});
|
|
2217
|
+
attachmentUploadRetried(file) {
|
|
2218
|
+
this.retryAttachmentUpload.emit(file);
|
|
1941
2219
|
}
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
yield this.attachmentService.deleteAttachment(upload);
|
|
1945
|
-
});
|
|
2220
|
+
attachmentDeleted(upload) {
|
|
2221
|
+
this.deleteAttachment.emit(upload);
|
|
1946
2222
|
}
|
|
1947
2223
|
trackByFile(_, item) {
|
|
1948
2224
|
return item.file;
|
|
1949
2225
|
}
|
|
1950
2226
|
}
|
|
1951
|
-
AttachmentPreviewListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: AttachmentPreviewListComponent, deps: [
|
|
1952
|
-
AttachmentPreviewListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: AttachmentPreviewListComponent, selector: "stream-attachment-preview-list", ngImport: i0, template: "<div class=\"rfu-image-previewer\" *ngIf=\"(attachmentUploads$ | async)?.length\">\n <ng-container\n *ngFor=\"\n let attachmentUpload of attachmentUploads$ | async;\n trackBy: trackByFile\n \"\n >\n <div\n *ngIf=\"attachmentUpload.type === 'image'\"\n class=\"rfu-image-previewer__image\"\n [class.rfu-image-previewer__image--loaded]=\"\n attachmentUpload.state === 'success'\n \"\n data-testclass=\"attachment-image-preview\"\n >\n <div\n *ngIf=\"attachmentUpload.state === 'error'\"\n class=\"rfu-image-previewer__retry\"\n (click)=\"
|
|
2227
|
+
AttachmentPreviewListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: AttachmentPreviewListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2228
|
+
AttachmentPreviewListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: AttachmentPreviewListComponent, selector: "stream-attachment-preview-list", inputs: { attachmentUploads$: "attachmentUploads$" }, outputs: { retryAttachmentUpload: "retryAttachmentUpload", deleteAttachment: "deleteAttachment" }, ngImport: i0, template: "<div class=\"rfu-image-previewer\" *ngIf=\"(attachmentUploads$ | async)?.length\">\n <ng-container\n *ngFor=\"\n let attachmentUpload of attachmentUploads$ | async;\n trackBy: trackByFile\n \"\n >\n <div\n *ngIf=\"attachmentUpload.type === 'image'\"\n class=\"rfu-image-previewer__image\"\n [class.rfu-image-previewer__image--loaded]=\"\n attachmentUpload.state === 'success'\n \"\n data-testclass=\"attachment-image-preview\"\n >\n <div\n *ngIf=\"attachmentUpload.state === 'error'\"\n class=\"rfu-image-previewer__retry\"\n (click)=\"attachmentUploadRetried(attachmentUpload.file)\"\n (keyup.enter)=\"attachmentUploadRetried(attachmentUpload.file)\"\n data-testclass=\"upload-error\"\n >\n <stream-icon-placeholder icon=\"retry\"></stream-icon-placeholder>\n </div>\n <div class=\"rfu-thumbnail__wrapper\" style=\"width: 100; height: 100\">\n <div class=\"rfu-thumbnail__overlay\">\n <div\n class=\"rfu-icon-button\"\n data-testclass=\"delete-attachment\"\n role=\"button\"\n (click)=\"attachmentDeleted(attachmentUpload)\"\n (keyup.enter)=\"attachmentDeleted(attachmentUpload)\"\n >\n <stream-icon-placeholder icon=\"close\"></stream-icon-placeholder>\n </div>\n </div>\n <img\n *ngIf=\"attachmentUpload.url || attachmentUpload.previewUri\"\n src=\"{{\n attachmentUpload.url\n ? attachmentUpload.url\n : attachmentUpload.previewUri\n }}\"\n alt=\"attachmentUpload.file.name\"\n class=\"rfu-thumbnail__image\"\n data-testclass=\"attachment-image\"\n />\n </div>\n <stream-loading-indicator-placeholder\n data-testclass=\"loading-indicator\"\n color=\"rgba(255,255,255,0.7)\"\n *ngIf=\"attachmentUpload.state === 'uploading'\"\n ></stream-loading-indicator-placeholder>\n </div>\n <div\n class=\"rfu-file-previewer\"\n *ngIf=\"attachmentUpload.type === 'file'\"\n data-testclass=\"attachment-file-preview\"\n >\n <ol>\n <li\n class=\"rfu-file-previewer__file\"\n [class.rfu-file-previewer__file--uploading]=\"\n attachmentUpload.state === 'uploading'\n \"\n [class.rfu-file-previewer__file--failed]=\"\n attachmentUpload.state === 'error'\n \"\n >\n <stream-icon-placeholder icon=\"file\"></stream-icon-placeholder>\n\n <a\n data-testclass=\"file-download-link\"\n href=\"{{ attachmentUpload.url }}\"\n (click)=\"attachmentUpload.url ? null : $event.preventDefault()\"\n (keyup.enter)=\"\n attachmentUpload.url ? null : $event.preventDefault()\n \"\n download\n >\n {{ attachmentUpload.file.name }}\n <ng-container *ngIf=\"attachmentUpload.state === 'error'\">\n <div\n data-testclass=\"file-upload-retry\"\n class=\"rfu-file-previewer__failed\"\n (click)=\"attachmentUploadRetried(attachmentUpload.file)\"\n (keyup.enter)=\"attachmentUploadRetried(attachmentUpload.file)\"\n translate\n >\n streamChat.failed\n </div>\n <div\n class=\"rfu-file-previewer__retry\"\n (click)=\"attachmentUploadRetried(attachmentUpload.file)\"\n (keyup.enter)=\"attachmentUploadRetried(attachmentUpload.file)\"\n translate\n >\n streamChat.retry\n </div>\n </ng-container>\n </a>\n\n <span\n data-testclass=\"file-delete\"\n class=\"rfu-file-previewer__close-button\"\n (click)=\"attachmentDeleted(attachmentUpload)\"\n (keyup.enter)=\"attachmentDeleted(attachmentUpload)\"\n >\n \u2718\n </span>\n <div\n *ngIf=\"attachmentUpload.state === 'uploading'\"\n class=\"rfu-file-previewer__loading-indicator\"\n >\n <stream-loading-indicator-placeholder></stream-loading-indicator-placeholder>\n </div>\n </li>\n </ol>\n </div>\n </ng-container>\n</div>\n", components: [{ type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon", "size"] }, { type: LoadingIndicatorPlaceholderComponent, selector: "stream-loading-indicator-placeholder", inputs: ["size", "color"] }], directives: [{ type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }], pipes: { "async": i3.AsyncPipe } });
|
|
1953
2229
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: AttachmentPreviewListComponent, decorators: [{
|
|
1954
2230
|
type: Component,
|
|
1955
2231
|
args: [{
|
|
@@ -1957,13 +2233,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
1957
2233
|
templateUrl: './attachment-preview-list.component.html',
|
|
1958
2234
|
styles: [],
|
|
1959
2235
|
}]
|
|
1960
|
-
}], ctorParameters: function () { return [
|
|
2236
|
+
}], ctorParameters: function () { return []; }, propDecorators: { attachmentUploads$: [{
|
|
2237
|
+
type: Input
|
|
2238
|
+
}], retryAttachmentUpload: [{
|
|
2239
|
+
type: Output
|
|
2240
|
+
}], deleteAttachment: [{
|
|
2241
|
+
type: Output
|
|
2242
|
+
}] } });
|
|
1961
2243
|
|
|
1962
2244
|
/**
|
|
1963
2245
|
* The `MessageInput` component displays an input where users can type their messages and upload files, and sends the message to the active channel. The component can be used to compose new messages or update existing ones. To send messages, the chat user needs to have the necessary [channel capability](https://getstream.io/chat/docs/javascript/channel_capabilities/?language=javascript).
|
|
1964
2246
|
*/
|
|
1965
2247
|
class MessageInputComponent {
|
|
1966
|
-
constructor(channelService, notificationService, attachmentService, configService, textareaType, componentFactoryResolver, cdRef, chatClient, emojiInputService) {
|
|
2248
|
+
constructor(channelService, notificationService, attachmentService, configService, textareaType, componentFactoryResolver, cdRef, chatClient, emojiInputService, customTemplatesService) {
|
|
1967
2249
|
this.channelService = channelService;
|
|
1968
2250
|
this.notificationService = notificationService;
|
|
1969
2251
|
this.attachmentService = attachmentService;
|
|
@@ -1973,6 +2255,7 @@ class MessageInputComponent {
|
|
|
1973
2255
|
this.cdRef = cdRef;
|
|
1974
2256
|
this.chatClient = chatClient;
|
|
1975
2257
|
this.emojiInputService = emojiInputService;
|
|
2258
|
+
this.customTemplatesService = customTemplatesService;
|
|
1976
2259
|
/**
|
|
1977
2260
|
* Determines if the message is being dispalyed in a channel or in a [thread](https://getstream.io/chat/docs/javascript/threads/?language=javascript).
|
|
1978
2261
|
*/
|
|
@@ -2020,12 +2303,7 @@ class MessageInputComponent {
|
|
|
2020
2303
|
this.isMultipleFileUploadEnabled =
|
|
2021
2304
|
this.configService.isMultipleFileUploadEnabled;
|
|
2022
2305
|
this.areMentionsEnabled = this.configService.areMentionsEnabled;
|
|
2023
|
-
this.mentionAutocompleteItemTemplate =
|
|
2024
|
-
this.configService.mentionAutocompleteItemTemplate;
|
|
2025
2306
|
this.mentionScope = this.configService.mentionScope;
|
|
2026
|
-
this.commandAutocompleteItemTemplate =
|
|
2027
|
-
this.configService.commandAutocompleteItemTemplate;
|
|
2028
|
-
this.emojiPickerTemplate = this.configService.emojiPickerTemplate;
|
|
2029
2307
|
this.subscriptions.push(this.typingStart$.subscribe(() => void this.channelService.typingStarted(this.parentMessageId)));
|
|
2030
2308
|
this.subscriptions.push(combineLatest([
|
|
2031
2309
|
this.channelService.latestMessageDateByUserByChannels$,
|
|
@@ -2048,6 +2326,16 @@ class MessageInputComponent {
|
|
|
2048
2326
|
}
|
|
2049
2327
|
}));
|
|
2050
2328
|
}
|
|
2329
|
+
ngOnInit() {
|
|
2330
|
+
this.subscriptions.push(this.customTemplatesService.emojiPickerTemplate$.subscribe((template) => {
|
|
2331
|
+
this.emojiPickerTemplate = template;
|
|
2332
|
+
this.cdRef.detectChanges();
|
|
2333
|
+
}));
|
|
2334
|
+
this.subscriptions.push(this.customTemplatesService.attachmentPreviewListTemplate$.subscribe((template) => {
|
|
2335
|
+
this.attachmentPreviewListTemplate = template;
|
|
2336
|
+
this.cdRef.detectChanges();
|
|
2337
|
+
}));
|
|
2338
|
+
}
|
|
2051
2339
|
ngAfterViewInit() {
|
|
2052
2340
|
this.isViewInited = true;
|
|
2053
2341
|
this.initTextarea();
|
|
@@ -2070,25 +2358,25 @@ class MessageInputComponent {
|
|
|
2070
2358
|
if (changes.areMentionsEnabled) {
|
|
2071
2359
|
this.configService.areMentionsEnabled = this.areMentionsEnabled;
|
|
2072
2360
|
}
|
|
2073
|
-
if (changes.mentionAutocompleteItemTemplate) {
|
|
2074
|
-
this.configService.mentionAutocompleteItemTemplate =
|
|
2075
|
-
this.mentionAutocompleteItemTemplate;
|
|
2076
|
-
}
|
|
2077
|
-
if (changes.commandAutocompleteItemTemplate) {
|
|
2078
|
-
this.configService.commandAutocompleteItemTemplate =
|
|
2079
|
-
this.commandAutocompleteItemTemplate;
|
|
2080
|
-
}
|
|
2081
2361
|
if (changes.mentionScope) {
|
|
2082
2362
|
this.configService.mentionScope = this.mentionScope;
|
|
2083
2363
|
}
|
|
2084
|
-
if (changes.emojiPickerTemplate) {
|
|
2085
|
-
this.configService.emojiPickerTemplate = this.emojiPickerTemplate;
|
|
2086
|
-
}
|
|
2087
2364
|
if (changes.mode) {
|
|
2088
2365
|
this.setCanSendMessages();
|
|
2089
2366
|
}
|
|
2367
|
+
if (changes.sendMessage$) {
|
|
2368
|
+
if (this.sendMessageSubcription) {
|
|
2369
|
+
this.sendMessageSubcription.unsubscribe();
|
|
2370
|
+
}
|
|
2371
|
+
if (this.sendMessage$) {
|
|
2372
|
+
this.sendMessageSubcription = this.sendMessage$.subscribe(() => void this.messageSent());
|
|
2373
|
+
}
|
|
2374
|
+
}
|
|
2090
2375
|
}
|
|
2091
2376
|
ngOnDestroy() {
|
|
2377
|
+
if (this.sendMessageSubcription) {
|
|
2378
|
+
this.sendMessageSubcription.unsubscribe();
|
|
2379
|
+
}
|
|
2092
2380
|
this.subscriptions.forEach((s) => s.unsubscribe());
|
|
2093
2381
|
}
|
|
2094
2382
|
messageSent() {
|
|
@@ -2170,6 +2458,24 @@ class MessageInputComponent {
|
|
|
2170
2458
|
deselectMessageToQuote() {
|
|
2171
2459
|
this.channelService.selectMessageToQuote(undefined);
|
|
2172
2460
|
}
|
|
2461
|
+
getEmojiPickerContext() {
|
|
2462
|
+
return {
|
|
2463
|
+
emojiInput$: this.emojiInputService.emojiInput$,
|
|
2464
|
+
};
|
|
2465
|
+
}
|
|
2466
|
+
getAttachmentPreviewListContext() {
|
|
2467
|
+
return {
|
|
2468
|
+
attachmentUploads$: this.attachmentService.attachmentUploads$,
|
|
2469
|
+
deleteUploadHandler: this.deleteUpload.bind(this),
|
|
2470
|
+
retryUploadHandler: this.retryUpload.bind(this),
|
|
2471
|
+
};
|
|
2472
|
+
}
|
|
2473
|
+
deleteUpload(upload) {
|
|
2474
|
+
void this.attachmentService.deleteAttachment(upload);
|
|
2475
|
+
}
|
|
2476
|
+
retryUpload(file) {
|
|
2477
|
+
void this.attachmentService.retryAttachmentUpload(file);
|
|
2478
|
+
}
|
|
2173
2479
|
clearFileInput() {
|
|
2174
2480
|
this.fileInput.nativeElement.value = '';
|
|
2175
2481
|
}
|
|
@@ -2276,8 +2582,8 @@ class MessageInputComponent {
|
|
|
2276
2582
|
setTimeout(() => this.initTextarea());
|
|
2277
2583
|
}
|
|
2278
2584
|
}
|
|
2279
|
-
MessageInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: MessageInputComponent, deps: [{ token: ChannelService }, { token: NotificationService }, { token: AttachmentService }, { token: MessageInputConfigService }, { token: textareaInjectionToken }, { token: i0.ComponentFactoryResolver }, { token: i0.ChangeDetectorRef }, { token: ChatClientService }, { token: EmojiInputService }], target: i0.ɵɵFactoryTarget.Component });
|
|
2280
|
-
MessageInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: MessageInputComponent, selector: "stream-message-input", inputs: { isFileUploadEnabled: "isFileUploadEnabled", areMentionsEnabled: "areMentionsEnabled", mentionScope: "mentionScope",
|
|
2585
|
+
MessageInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: MessageInputComponent, deps: [{ token: ChannelService }, { token: NotificationService }, { token: AttachmentService }, { token: MessageInputConfigService }, { token: textareaInjectionToken }, { token: i0.ComponentFactoryResolver }, { token: i0.ChangeDetectorRef }, { token: ChatClientService }, { token: EmojiInputService }, { token: CustomTemplatesService }], target: i0.ɵɵFactoryTarget.Component });
|
|
2586
|
+
MessageInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: MessageInputComponent, selector: "stream-message-input", inputs: { isFileUploadEnabled: "isFileUploadEnabled", areMentionsEnabled: "areMentionsEnabled", mentionScope: "mentionScope", mode: "mode", isMultipleFileUploadEnabled: "isMultipleFileUploadEnabled", message: "message", sendMessage$: "sendMessage$" }, outputs: { messageUpdate: "messageUpdate" }, providers: [AttachmentService, EmojiInputService], viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true }, { propertyName: "textareaAnchor", first: true, predicate: TextareaDirective, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div\n class=\"{{\n mode === 'main' ? 'str-chat__input-flat' : 'str-chat__small-message-input'\n }}\"\n [class.str-chat__input-flat-has-attachments]=\"\n (attachmentUploads$ | async)!.length > 0\n \"\n [class.str-chat__input-flat-quoted]=\"!!quotedMessage\"\n>\n <div\n data-testid=\"quoted-message-container\"\n class=\"quoted-message-preview\"\n *ngIf=\"quotedMessage\"\n >\n <div class=\"quoted-message-preview-header\">\n <div>{{ \"streamChat.Reply to Message\" | translate }}</div>\n <button\n class=\"str-chat__square-button\"\n data-testid=\"remove-quote\"\n (click)=\"deselectMessageToQuote()\"\n (keyup.enter)=\"deselectMessageToQuote()\"\n >\n <stream-icon-placeholder\n icon=\"close-no-outline\"\n style=\"font-size: 10px; line-height: 10px\"\n ></stream-icon-placeholder>\n </button>\n </div>\n <div class=\"quoted-message-preview-content\">\n <stream-avatar-placeholder\n data-testid=\"qouted-message-avatar\"\n class=\"str-chat-angular__avatar-host\"\n [imageUrl]=\"quotedMessage?.user?.image\"\n [name]=\"quotedMessage?.user?.name || quotedMessage?.user?.id\"\n [size]=\"20\"\n ></stream-avatar-placeholder>\n <div class=\"quoted-message-preview-content-inner\">\n <stream-attachment-list\n *ngIf=\"\n quotedMessage?.attachments && quotedMessage?.attachments?.length\n \"\n [attachments]=\"quotedMessageAttachments\"\n [messageId]=\"quotedMessage?.id\"\n ></stream-attachment-list>\n <div\n data-testid=\"quoted-message-text\"\n [innerHTML]=\"quotedMessage?.html || quotedMessage?.text\"\n ></div>\n </div>\n </div>\n </div>\n <div class=\"str-chat__input-flat-wrapper\" style=\"width: 100%\">\n <div\n class=\"{{\n mode === 'main'\n ? 'str-chat__input-flat--textarea-wrapper'\n : 'str-chat__small-message-input--textarea-wrapper'\n }}\"\n >\n <ng-template\n #defaultAttachmentsPreview\n let-attachmentUploads$=\"attachmentUploads$\"\n let-retryUploadHandler=\"retryUploadHandler\"\n let-deleteUploadHandler=\"deleteUploadHandler\"\n >\n <stream-attachment-preview-list\n [attachmentUploads$]=\"attachmentUploads$\"\n (retryAttachmentUpload)=\"retryUploadHandler($event)\"\n (deleteAttachment)=\"deleteUploadHandler($event)\"\n class=\"rfu-image-previewer-angular-host\"\n ></stream-attachment-preview-list>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n attachmentPreviewListTemplate || defaultAttachmentsPreview;\n context: getAttachmentPreviewListContext()\n \"\n ></ng-container>\n <div class=\"rta str-chat__textarea str-chat-angular__textarea\">\n <ng-container\n *ngIf=\"emojiPickerTemplate && !isCooldownInProgress\"\n data-testid=\"emoji-picker\"\n >\n <div\n class=\"\n str-chat__input-flat-emojiselect\n str-chat-angular__emojiselect\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n emojiPickerTemplate;\n context: getEmojiPickerContext()\n \"\n ></ng-container>\n </div>\n </ng-container>\n <div\n class=\"str-chat__input-flat-cooldown str-chat-angular__cooldown\"\n *ngIf=\"isCooldownInProgress\"\n data-testid=\"cooldown-timer\"\n >\n {{ cooldown$ | async }}\n </div>\n <ng-template\n *ngIf=\"canSendMessages && !isCooldownInProgress; else notAllowed\"\n streamTextarea\n [(value)]=\"textareaValue\"\n (valueChange)=\"typingStart$.next()\"\n (send)=\"messageSent()\"\n [componentRef]=\"textareaRef\"\n (userMentions)=\"mentionedUsers = $event\"\n [areMentionsEnabled]=\"areMentionsEnabled\"\n [mentionScope]=\"mentionScope\"\n ></ng-template>\n <ng-template #notAllowed>\n <textarea\n disabled\n rows=\"1\"\n [value]=\"disabledTextareaText | translate\"\n class=\"rta__textarea str-chat__textarea__textarea\"\n data-testid=\"disabled-textarea\"\n ></textarea>\n </ng-template>\n </div>\n <div\n *ngIf=\"\n isFileUploadEnabled &&\n isFileUploadAuthorized &&\n canSendMessages &&\n !isCooldownInProgress\n \"\n class=\"str-chat__fileupload-wrapper\"\n data-testid=\"file-upload-button\"\n >\n <div class=\"str-chat__tooltip\">\n {{ \"streamChat.Attach files\" | translate }}\n </div>\n <div class=\"rfu-file-upload-button\">\n <label>\n <input\n #fileInput\n type=\"file\"\n class=\"rfu-file-input\"\n data-testid=\"file-input\"\n [multiple]=\"isMultipleFileUploadEnabled\"\n (change)=\"filesSelected(fileInput.files)\"\n />\n <span class=\"str-chat__input-flat-fileupload\">\n <stream-icon-placeholder\n icon=\"file-upload\"\n ></stream-icon-placeholder>\n </span>\n </label>\n </div>\n </div>\n </div>\n <button\n *ngIf=\"canSendMessages\"\n data-testid=\"send-button\"\n class=\"str-chat__send-button\"\n (click)=\"messageSent()\"\n (keyup.enter)=\"messageSent()\"\n >\n <stream-icon-placeholder icon=\"send\"></stream-icon-placeholder>\n </button>\n </div>\n</div>\n", components: [{ type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon", "size"] }, { type: AvatarPlaceholderComponent, selector: "stream-avatar-placeholder", inputs: ["name", "imageUrl", "size"] }, { type: AttachmentListComponent, selector: "stream-attachment-list", inputs: ["messageId", "attachments"] }, { type: AttachmentPreviewListComponent, selector: "stream-attachment-preview-list", inputs: ["attachmentUploads$"], outputs: ["retryAttachmentUpload", "deleteAttachment"] }], directives: [{ type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: TextareaDirective, selector: "[streamTextarea]", inputs: ["componentRef", "areMentionsEnabled", "mentionScope", "value"], outputs: ["valueChange", "send", "userMentions"] }], pipes: { "async": i3.AsyncPipe, "translate": i2.TranslatePipe } });
|
|
2281
2587
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: MessageInputComponent, decorators: [{
|
|
2282
2588
|
type: Component,
|
|
2283
2589
|
args: [{
|
|
@@ -2289,24 +2595,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
2289
2595
|
}], ctorParameters: function () { return [{ type: ChannelService }, { type: NotificationService }, { type: AttachmentService }, { type: MessageInputConfigService }, { type: i0.Type, decorators: [{
|
|
2290
2596
|
type: Inject,
|
|
2291
2597
|
args: [textareaInjectionToken]
|
|
2292
|
-
}] }, { type: i0.ComponentFactoryResolver }, { type: i0.ChangeDetectorRef }, { type: ChatClientService }, { type: EmojiInputService }]; }, propDecorators: { isFileUploadEnabled: [{
|
|
2598
|
+
}] }, { type: i0.ComponentFactoryResolver }, { type: i0.ChangeDetectorRef }, { type: ChatClientService }, { type: EmojiInputService }, { type: CustomTemplatesService }]; }, propDecorators: { isFileUploadEnabled: [{
|
|
2293
2599
|
type: Input
|
|
2294
2600
|
}], areMentionsEnabled: [{
|
|
2295
2601
|
type: Input
|
|
2296
2602
|
}], mentionScope: [{
|
|
2297
2603
|
type: Input
|
|
2298
|
-
}], mentionAutocompleteItemTemplate: [{
|
|
2299
|
-
type: Input
|
|
2300
|
-
}], commandAutocompleteItemTemplate: [{
|
|
2301
|
-
type: Input
|
|
2302
|
-
}], emojiPickerTemplate: [{
|
|
2303
|
-
type: Input
|
|
2304
2604
|
}], mode: [{
|
|
2305
2605
|
type: Input
|
|
2306
2606
|
}], isMultipleFileUploadEnabled: [{
|
|
2307
2607
|
type: Input
|
|
2308
2608
|
}], message: [{
|
|
2309
2609
|
type: Input
|
|
2610
|
+
}], sendMessage$: [{
|
|
2611
|
+
type: Input
|
|
2310
2612
|
}], messageUpdate: [{
|
|
2311
2613
|
type: Output
|
|
2312
2614
|
}], fileInput: [{
|
|
@@ -2324,7 +2626,7 @@ class NotificationComponent {
|
|
|
2324
2626
|
constructor() { }
|
|
2325
2627
|
}
|
|
2326
2628
|
NotificationComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: NotificationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2327
|
-
NotificationComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: NotificationComponent, selector: "stream-notification", inputs: { type: "type" }, ngImport: i0, template: "<div\n class=\"str-chat__custom-notification notification-{{ type }}\"\n data-testid=\"custom-notification\"\n>\n <ng-content></ng-content>\n</div>\n" });
|
|
2629
|
+
NotificationComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: NotificationComponent, selector: "stream-notification", inputs: { type: "type", content: "content" }, ngImport: i0, template: "<div\n class=\"str-chat__custom-notification notification-{{ type }}\"\n data-testid=\"custom-notification\"\n>\n <ng-container *ngIf=\"content; else elseContent\">\n <ng-container *ngTemplateOutlet=\"content\"></ng-container>\n </ng-container>\n <ng-template #elseContent>\n <ng-content></ng-content>\n </ng-template>\n</div>\n", directives: [{ type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }] });
|
|
2328
2630
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: NotificationComponent, decorators: [{
|
|
2329
2631
|
type: Component,
|
|
2330
2632
|
args: [{
|
|
@@ -2334,22 +2636,28 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
2334
2636
|
}]
|
|
2335
2637
|
}], ctorParameters: function () { return []; }, propDecorators: { type: [{
|
|
2336
2638
|
type: Input
|
|
2639
|
+
}], content: [{
|
|
2640
|
+
type: Input
|
|
2337
2641
|
}] } });
|
|
2338
2642
|
|
|
2339
2643
|
/**
|
|
2340
2644
|
* The `NotificationList` component displays the list of active notifications.
|
|
2341
2645
|
*/
|
|
2342
2646
|
class NotificationListComponent {
|
|
2343
|
-
constructor(notificationService) {
|
|
2647
|
+
constructor(customTemplatesService, notificationService) {
|
|
2648
|
+
this.customTemplatesService = customTemplatesService;
|
|
2344
2649
|
this.notificationService = notificationService;
|
|
2345
2650
|
this.notifications$ = this.notificationService.notifications$;
|
|
2346
2651
|
}
|
|
2347
|
-
|
|
2348
|
-
return item;
|
|
2652
|
+
trackById(_, item) {
|
|
2653
|
+
return item.id;
|
|
2654
|
+
}
|
|
2655
|
+
getNotificationContentContext(notification) {
|
|
2656
|
+
return Object.assign(Object.assign({}, notification.templateContext), { dismissFn: notification.dismissFn });
|
|
2349
2657
|
}
|
|
2350
2658
|
}
|
|
2351
|
-
NotificationListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: NotificationListComponent, deps: [{ token: NotificationService }], target: i0.ɵɵFactoryTarget.Component });
|
|
2352
|
-
NotificationListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: NotificationListComponent, selector: "stream-notification-list", ngImport: i0, template: "<div class=\"str-chat__list-notifications\">\n <
|
|
2659
|
+
NotificationListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: NotificationListComponent, deps: [{ token: CustomTemplatesService }, { token: NotificationService }], target: i0.ɵɵFactoryTarget.Component });
|
|
2660
|
+
NotificationListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: NotificationListComponent, selector: "stream-notification-list", ngImport: i0, template: "<div class=\"str-chat__list-notifications\">\n <ng-container\n *ngFor=\"let notification of notifications$ | async; trackBy: trackById\"\n >\n <ng-template #notificationContent>\n <div\n *ngIf=\"notification.text !== undefined\"\n data-testclass=\"notification-content\"\n >\n {{ notification.text | translate: notification.translateParams }}\n </div>\n <ng-container *ngIf=\"notification.template !== undefined\">\n <ng-container\n *ngTemplateOutlet=\"\n notification.template;\n context: getNotificationContentContext(notification)\n \"\n ></ng-container>\n </ng-container>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.notificationTemplate$ | async) ||\n defaultNotification;\n context: { type: notification.type, content: notificationContent }\n \"\n ></ng-container>\n </ng-container>\n</div>\n\n<ng-template #defaultNotification let-type=\"type\" let-content=\"content\">\n <stream-notification [type]=\"type\" [content]=\"content\"></stream-notification>\n</ng-template>\n", components: [{ type: NotificationComponent, selector: "stream-notification", inputs: ["type", "content"] }], directives: [{ type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], pipes: { "async": i3.AsyncPipe, "translate": i2.TranslatePipe } });
|
|
2353
2661
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: NotificationListComponent, decorators: [{
|
|
2354
2662
|
type: Component,
|
|
2355
2663
|
args: [{
|
|
@@ -2357,16 +2665,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
2357
2665
|
templateUrl: './notification-list.component.html',
|
|
2358
2666
|
styles: [],
|
|
2359
2667
|
}]
|
|
2360
|
-
}], ctorParameters: function () { return [{ type: NotificationService }]; } });
|
|
2668
|
+
}], ctorParameters: function () { return [{ type: CustomTemplatesService }, { type: NotificationService }]; } });
|
|
2361
2669
|
|
|
2362
2670
|
/**
|
|
2363
2671
|
* The `MessageActionsBox` component displays a list of message actions (i.e edit), that can be opened or closed. You can find the [list of the supported actions](../concepts/message-interactions.mdx) in the message interaction guide.
|
|
2364
2672
|
*/
|
|
2365
2673
|
class MessageActionsBoxComponent {
|
|
2366
|
-
constructor(chatClientService, notificationService, channelService) {
|
|
2674
|
+
constructor(chatClientService, notificationService, channelService, customTemplatesService) {
|
|
2367
2675
|
this.chatClientService = chatClientService;
|
|
2368
2676
|
this.notificationService = notificationService;
|
|
2369
2677
|
this.channelService = channelService;
|
|
2678
|
+
this.customTemplatesService = customTemplatesService;
|
|
2370
2679
|
/**
|
|
2371
2680
|
* Indicates if the list should be opened or closed. Adding a UI element to open and close the list is the parent's component responsibility.
|
|
2372
2681
|
*/
|
|
@@ -2388,107 +2697,122 @@ class MessageActionsBoxComponent {
|
|
|
2388
2697
|
*/
|
|
2389
2698
|
this.isEditing = new EventEmitter();
|
|
2390
2699
|
this.isEditModalOpen = false;
|
|
2700
|
+
this.subscriptions = [];
|
|
2701
|
+
this.visibleMessageActionItems = [];
|
|
2702
|
+
this.sendMessageSubject = new Subject();
|
|
2391
2703
|
this.modalClosed = () => {
|
|
2392
2704
|
this.isEditModalOpen = false;
|
|
2393
2705
|
this.isEditing.emit(false);
|
|
2394
2706
|
};
|
|
2707
|
+
this.subscriptions.push(this.customTemplatesService.messageInputTemplate$.subscribe((template) => (this.messageInputTemplate = template)));
|
|
2708
|
+
this.subscriptions.push(this.customTemplatesService.messageActionsBoxItemTemplate$.subscribe((template) => (this.messageActionItemTemplate = template)));
|
|
2709
|
+
this.subscriptions.push(this.customTemplatesService.modalTemplate$.subscribe((template) => (this.modalTemplate = template)));
|
|
2710
|
+
this.messageActionItems = [
|
|
2711
|
+
{
|
|
2712
|
+
actionName: 'quote',
|
|
2713
|
+
actionLabelOrTranslationKey: 'streamChat.Reply',
|
|
2714
|
+
actionHandler: (message) => this.channelService.selectMessageToQuote(message),
|
|
2715
|
+
isVisible: (enabledActions, isMine, message) => enabledActions.indexOf('quote-message') !== -1 &&
|
|
2716
|
+
!(message === null || message === void 0 ? void 0 : message.quoted_message),
|
|
2717
|
+
},
|
|
2718
|
+
{
|
|
2719
|
+
actionName: 'pin',
|
|
2720
|
+
actionLabelOrTranslationKey: () => { var _a; return ((_a = this.message) === null || _a === void 0 ? void 0 : _a.pinned) ? 'streamChat.Unpin' : 'streamChat.Pin'; },
|
|
2721
|
+
actionHandler: () => alert('Feature not yet implemented'),
|
|
2722
|
+
isVisible: () => false,
|
|
2723
|
+
},
|
|
2724
|
+
{
|
|
2725
|
+
actionName: 'flag',
|
|
2726
|
+
actionLabelOrTranslationKey: 'streamChat.Flag',
|
|
2727
|
+
actionHandler: (message) => __awaiter(this, void 0, void 0, function* () {
|
|
2728
|
+
try {
|
|
2729
|
+
yield this.chatClientService.flagMessage(message.id);
|
|
2730
|
+
this.notificationService.addTemporaryNotification('streamChat.Message has been successfully flagged', 'success');
|
|
2731
|
+
}
|
|
2732
|
+
catch (err) {
|
|
2733
|
+
this.notificationService.addTemporaryNotification('streamChat.Error adding flag');
|
|
2734
|
+
}
|
|
2735
|
+
}),
|
|
2736
|
+
isVisible: (enabledActions, isMine) => enabledActions.indexOf('flag-message') !== -1 && !isMine,
|
|
2737
|
+
},
|
|
2738
|
+
{
|
|
2739
|
+
actionName: 'edit',
|
|
2740
|
+
actionLabelOrTranslationKey: 'streamChat.Edit Message',
|
|
2741
|
+
actionHandler: () => {
|
|
2742
|
+
this.isEditing.emit(true);
|
|
2743
|
+
this.isEditModalOpen = true;
|
|
2744
|
+
},
|
|
2745
|
+
isVisible: (enabledActions, isMine) => (enabledActions.indexOf('update-own-message') !== -1 && isMine) ||
|
|
2746
|
+
enabledActions.indexOf('update-any-message') !== -1,
|
|
2747
|
+
},
|
|
2748
|
+
{
|
|
2749
|
+
actionName: 'delete',
|
|
2750
|
+
actionLabelOrTranslationKey: 'streamChat.Delete',
|
|
2751
|
+
actionHandler: (message) => __awaiter(this, void 0, void 0, function* () {
|
|
2752
|
+
try {
|
|
2753
|
+
yield this.channelService.deleteMessage(message);
|
|
2754
|
+
}
|
|
2755
|
+
catch (error) {
|
|
2756
|
+
this.notificationService.addTemporaryNotification('streamChat.Error deleting message');
|
|
2757
|
+
}
|
|
2758
|
+
}),
|
|
2759
|
+
isVisible: (enabledActions, isMine) => ((enabledActions.indexOf('delete') !== -1 ||
|
|
2760
|
+
enabledActions.indexOf('delete-own-message') !== -1) &&
|
|
2761
|
+
isMine) ||
|
|
2762
|
+
enabledActions.indexOf('delete-any') !== -1 ||
|
|
2763
|
+
enabledActions.indexOf('delete-any-message') !== -1,
|
|
2764
|
+
},
|
|
2765
|
+
];
|
|
2766
|
+
this.sendMessage$ = this.sendMessageSubject.asObservable();
|
|
2395
2767
|
}
|
|
2396
2768
|
ngOnChanges(changes) {
|
|
2397
|
-
if (changes.isMine || changes.enabledActions) {
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
}
|
|
2402
|
-
if (this.isEditVisible) {
|
|
2403
|
-
displayedActionsCount++;
|
|
2404
|
-
}
|
|
2405
|
-
if (this.isDeleteVisible) {
|
|
2406
|
-
displayedActionsCount++;
|
|
2407
|
-
}
|
|
2408
|
-
if (this.isMuteVisible) {
|
|
2409
|
-
displayedActionsCount++;
|
|
2410
|
-
}
|
|
2411
|
-
if (this.isFlagVisible) {
|
|
2412
|
-
displayedActionsCount++;
|
|
2413
|
-
}
|
|
2414
|
-
if (this.isPinVisible) {
|
|
2415
|
-
displayedActionsCount++;
|
|
2416
|
-
}
|
|
2417
|
-
this.displayedActionsCount.next(displayedActionsCount);
|
|
2769
|
+
if (changes.isMine || changes.enabledActions || changes.message) {
|
|
2770
|
+
this.messageActionItems.forEach((i) => (i.actionHandler = i.actionHandler.bind(this, this.message, this.isMine)));
|
|
2771
|
+
this.visibleMessageActionItems = this.messageActionItems.filter((item) => item.isVisible(this.enabledActions, this.isMine, this.message));
|
|
2772
|
+
this.displayedActionsCount.emit(this.visibleMessageActionItems.length);
|
|
2418
2773
|
}
|
|
2419
2774
|
}
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
return ((this.enabledActions.indexOf('quote') !== -1 ||
|
|
2423
|
-
this.enabledActions.indexOf('quote-message') !== -1) &&
|
|
2424
|
-
!((_a = this.message) === null || _a === void 0 ? void 0 : _a.quoted_message));
|
|
2425
|
-
}
|
|
2426
|
-
get isEditVisible() {
|
|
2427
|
-
return (((this.enabledActions.indexOf('edit') !== -1 ||
|
|
2428
|
-
this.enabledActions.indexOf('update-own-message') !== -1) &&
|
|
2429
|
-
this.isMine) ||
|
|
2430
|
-
this.enabledActions.indexOf('edit-any') !== -1 ||
|
|
2431
|
-
this.enabledActions.indexOf('update-any-message') !== -1);
|
|
2432
|
-
}
|
|
2433
|
-
get isDeleteVisible() {
|
|
2434
|
-
return (((this.enabledActions.indexOf('delete') !== -1 ||
|
|
2435
|
-
this.enabledActions.indexOf('delete-own-message') !== -1) &&
|
|
2436
|
-
this.isMine) ||
|
|
2437
|
-
this.enabledActions.indexOf('delete-any') !== -1 ||
|
|
2438
|
-
this.enabledActions.indexOf('delete-any-message') !== -1);
|
|
2439
|
-
}
|
|
2440
|
-
get isMuteVisible() {
|
|
2441
|
-
return this.enabledActions.indexOf('mute') !== -1;
|
|
2442
|
-
}
|
|
2443
|
-
get isFlagVisible() {
|
|
2444
|
-
return ((this.enabledActions.indexOf('flag') !== -1 ||
|
|
2445
|
-
this.enabledActions.indexOf('flag-message') !== -1) &&
|
|
2446
|
-
!this.isMine);
|
|
2447
|
-
}
|
|
2448
|
-
get isPinVisible() {
|
|
2449
|
-
return this.enabledActions.indexOf('pin') !== -1;
|
|
2450
|
-
}
|
|
2451
|
-
pinClicked() {
|
|
2452
|
-
alert('Feature not yet implemented');
|
|
2453
|
-
}
|
|
2454
|
-
flagClicked() {
|
|
2455
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
2456
|
-
try {
|
|
2457
|
-
yield this.chatClientService.flagMessage(this.message.id);
|
|
2458
|
-
this.notificationService.addTemporaryNotification('streamChat.Message has been successfully flagged', 'success');
|
|
2459
|
-
}
|
|
2460
|
-
catch (err) {
|
|
2461
|
-
this.notificationService.addTemporaryNotification('streamChat.Error adding flag');
|
|
2462
|
-
}
|
|
2463
|
-
});
|
|
2464
|
-
}
|
|
2465
|
-
muteClicked() {
|
|
2466
|
-
alert('Feature not yet implemented');
|
|
2467
|
-
}
|
|
2468
|
-
quoteClicked() {
|
|
2469
|
-
this.channelService.selectMessageToQuote(this.message);
|
|
2775
|
+
ngOnDestroy() {
|
|
2776
|
+
this.subscriptions.forEach((s) => s.unsubscribe());
|
|
2470
2777
|
}
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2778
|
+
getActionLabel(actionLabelOrTranslationKey) {
|
|
2779
|
+
return typeof actionLabelOrTranslationKey === 'string'
|
|
2780
|
+
? actionLabelOrTranslationKey
|
|
2781
|
+
: actionLabelOrTranslationKey();
|
|
2474
2782
|
}
|
|
2475
2783
|
sendClicked() {
|
|
2476
|
-
|
|
2477
|
-
|
|
2784
|
+
this.sendMessageSubject.next();
|
|
2785
|
+
}
|
|
2786
|
+
getMessageInputContext() {
|
|
2787
|
+
return {
|
|
2788
|
+
message: this.message,
|
|
2789
|
+
messageUpdateHandler: this.modalClosed,
|
|
2790
|
+
isFileUploadEnabled: undefined,
|
|
2791
|
+
areMentionsEnabled: undefined,
|
|
2792
|
+
isMultipleFileUploadEnabled: undefined,
|
|
2793
|
+
mentionScope: undefined,
|
|
2794
|
+
mode: undefined,
|
|
2795
|
+
sendMessage$: this.sendMessage$,
|
|
2796
|
+
};
|
|
2478
2797
|
}
|
|
2479
|
-
|
|
2480
|
-
return
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2798
|
+
getEditModalContext() {
|
|
2799
|
+
return {
|
|
2800
|
+
isOpen: this.isEditModalOpen,
|
|
2801
|
+
isOpenChangeHandler: (isOpen) => {
|
|
2802
|
+
this.isEditModalOpen = isOpen;
|
|
2803
|
+
if (!this.isEditModalOpen) {
|
|
2804
|
+
this.modalClosed();
|
|
2805
|
+
}
|
|
2806
|
+
},
|
|
2807
|
+
content: this.modalContent,
|
|
2808
|
+
};
|
|
2809
|
+
}
|
|
2810
|
+
trackByActionName(_, item) {
|
|
2811
|
+
return item.actionName;
|
|
2488
2812
|
}
|
|
2489
2813
|
}
|
|
2490
|
-
MessageActionsBoxComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: MessageActionsBoxComponent, deps: [{ token: ChatClientService }, { token: NotificationService }, { token: ChannelService }], target: i0.ɵɵFactoryTarget.Component });
|
|
2491
|
-
MessageActionsBoxComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: MessageActionsBoxComponent, selector: "stream-message-actions-box", inputs: {
|
|
2814
|
+
MessageActionsBoxComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: MessageActionsBoxComponent, deps: [{ token: ChatClientService }, { token: NotificationService }, { token: ChannelService }, { token: CustomTemplatesService }], target: i0.ɵɵFactoryTarget.Component });
|
|
2815
|
+
MessageActionsBoxComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: MessageActionsBoxComponent, selector: "stream-message-actions-box", inputs: { isOpen: "isOpen", isMine: "isMine", message: "message", enabledActions: "enabledActions" }, outputs: { displayedActionsCount: "displayedActionsCount", isEditing: "isEditing" }, viewQueries: [{ propertyName: "modalContent", first: true, predicate: ["modalContent"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<div\n data-testid=\"action-box\"\n class=\"str-chat__message-actions-box\"\n [class.str-chat__message-actions-box--open]=\"isOpen\"\n [class.str-chat__message-actions-box--mine]=\"isMine\"\n>\n <ul class=\"str-chat__message-actions-list\">\n <ng-container\n *ngFor=\"let item of visibleMessageActionItems; trackBy: trackByActionName\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n messageActionItemTemplate || defaultMessageActionItem;\n context: item\n \"\n ></ng-container>\n </ng-container>\n </ul>\n</div>\n\n<ng-template\n #defaultMessageActionItem\n let-actionName=\"actionName\"\n let-actionHandler=\"actionHandler\"\n let-actionLabelOrTranslationKey=\"actionLabelOrTranslationKey\"\n>\n <button [attr.data-testid]=\"actionName + '-action'\" (click)=\"actionHandler()\">\n <li class=\"str-chat__message-actions-list-item\">\n {{ getActionLabel(actionLabelOrTranslationKey) | translate }}\n </li>\n </button>\n</ng-template>\n\n<ng-container\n *ngTemplateOutlet=\"\n modalTemplate || defaultModal;\n context: getEditModalContext()\n \"\n></ng-container>\n\n<ng-template\n #defaultModal\n let-isOpen=\"isOpen\"\n let-isOpenChangeHandler=\"isOpenChangeHandler\"\n let-content=\"content\"\n>\n <stream-modal\n [isOpen]=\"isOpen\"\n (isOpenChange)=\"isOpenChangeHandler($event)\"\n [content]=\"content\"\n >\n </stream-modal>\n</ng-template>\n\n<ng-template #modalContent>\n <div class=\"str-chat__edit-message-form\" *ngIf=\"isEditModalOpen\">\n <ng-template\n #defaultInput\n let-messageInput=\"message\"\n let-messageUpdateHandler=\"messageUpdateHandler\"\n let-sendMessage$Input=\"sendMessage$\"\n >\n <stream-message-input\n [message]=\"messageInput\"\n (messageUpdate)=\"messageUpdateHandler()\"\n [sendMessage$]=\"sendMessage$Input\"\n ></stream-message-input>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n messageInputTemplate || defaultInput;\n context: getMessageInputContext()\n \"\n >\n </ng-container>\n\n <stream-notification-list></stream-notification-list>\n <div\n class=\"\n str-chat__message-team-form-footer\n str-chat__message-team-form-footer-angular\n \"\n >\n <div class=\"str-chat__edit-message-form-options\">\n <button translate data-testid=\"cancel-button\" (click)=\"modalClosed()\">\n streamChat.Cancel\n </button>\n <button\n type=\"submit\"\n translate\n data-testid=\"send-button\"\n (click)=\"sendClicked()\"\n (keyup.enter)=\"sendClicked()\"\n >\n streamChat.Send\n </button>\n </div>\n </div>\n </div>\n</ng-template>\n", components: [{ type: ModalComponent, selector: "stream-modal", inputs: ["isOpen", "content"], outputs: ["isOpenChange"] }, { type: MessageInputComponent, selector: "stream-message-input", inputs: ["isFileUploadEnabled", "areMentionsEnabled", "mentionScope", "mode", "isMultipleFileUploadEnabled", "message", "sendMessage$"], outputs: ["messageUpdate"] }, { type: NotificationListComponent, selector: "stream-notification-list" }], directives: [{ type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }], pipes: { "translate": i2.TranslatePipe } });
|
|
2492
2816
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: MessageActionsBoxComponent, decorators: [{
|
|
2493
2817
|
type: Component,
|
|
2494
2818
|
args: [{
|
|
@@ -2496,9 +2820,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
2496
2820
|
templateUrl: './message-actions-box.component.html',
|
|
2497
2821
|
styles: [],
|
|
2498
2822
|
}]
|
|
2499
|
-
}], ctorParameters: function () { return [{ type: ChatClientService }, { type: NotificationService }, { type: ChannelService }]; }, propDecorators: {
|
|
2500
|
-
type: Input
|
|
2501
|
-
}], isOpen: [{
|
|
2823
|
+
}], ctorParameters: function () { return [{ type: ChatClientService }, { type: NotificationService }, { type: ChannelService }, { type: CustomTemplatesService }]; }, propDecorators: { isOpen: [{
|
|
2502
2824
|
type: Input
|
|
2503
2825
|
}], isMine: [{
|
|
2504
2826
|
type: Input
|
|
@@ -2510,9 +2832,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
2510
2832
|
type: Output
|
|
2511
2833
|
}], isEditing: [{
|
|
2512
2834
|
type: Output
|
|
2513
|
-
}],
|
|
2835
|
+
}], modalContent: [{
|
|
2514
2836
|
type: ViewChild,
|
|
2515
|
-
args: [
|
|
2837
|
+
args: ['modalContent', { static: true }]
|
|
2516
2838
|
}] } });
|
|
2517
2839
|
|
|
2518
2840
|
/**
|
|
@@ -2528,7 +2850,7 @@ class ChannelComponent {
|
|
|
2528
2850
|
}
|
|
2529
2851
|
}
|
|
2530
2852
|
ChannelComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ChannelComponent, deps: [{ token: ChannelService }], target: i0.ɵɵFactoryTarget.Component });
|
|
2531
|
-
ChannelComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: ChannelComponent, selector: "stream-channel", ngImport: i0, template: "<div\n *ngIf=\"(isError$ | async) === false && (isInitializing$ | async) === false\"\n class=\"str-chat str-chat-channel messaging\"\n>\n <div class=\"str-chat__container\">\n <div class=\"str-chat__main-panel\">\n <ng-content></ng-content>\n </div>\n <ng-content\n *ngIf=\"isActiveThread$ | async\"\n select='[name=\"thread\"]'\n ></ng-content>\n </div>\n</div>\n", directives: [{ type:
|
|
2853
|
+
ChannelComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: ChannelComponent, selector: "stream-channel", ngImport: i0, template: "<div\n *ngIf=\"(isError$ | async) === false && (isInitializing$ | async) === false\"\n class=\"str-chat str-chat-channel messaging\"\n>\n <div class=\"str-chat__container\">\n <div class=\"str-chat__main-panel\">\n <ng-content></ng-content>\n </div>\n <ng-content\n *ngIf=\"isActiveThread$ | async\"\n select='[name=\"thread\"]'\n ></ng-content>\n </div>\n</div>\n", directives: [{ type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], pipes: { "async": i3.AsyncPipe } });
|
|
2532
2854
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ChannelComponent, decorators: [{
|
|
2533
2855
|
type: Component,
|
|
2534
2856
|
args: [{
|
|
@@ -2622,9 +2944,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
2622
2944
|
* The `ChannelHeader` component displays the avatar and name of the currently active channel along with member and watcher information. You can read about [the difference between members and watchers](https://getstream.io/chat/docs/javascript/watch_channel/?language=javascript#watchers-vs-members) in the platform documentation. Please note that number of watchers is only displayed if the user has [`connect-events` capability](https://getstream.io/chat/docs/javascript/channel_capabilities/?language=javascript)
|
|
2623
2945
|
*/
|
|
2624
2946
|
class ChannelHeaderComponent {
|
|
2625
|
-
constructor(channelService, channelListToggleService) {
|
|
2947
|
+
constructor(channelService, channelListToggleService, customTemplatesService, cdRef) {
|
|
2626
2948
|
this.channelService = channelService;
|
|
2627
2949
|
this.channelListToggleService = channelListToggleService;
|
|
2950
|
+
this.customTemplatesService = customTemplatesService;
|
|
2951
|
+
this.cdRef = cdRef;
|
|
2952
|
+
this.subscriptions = [];
|
|
2628
2953
|
this.channelService.activeChannel$.subscribe((c) => {
|
|
2629
2954
|
var _a, _b;
|
|
2630
2955
|
this.activeChannel = c;
|
|
@@ -2636,10 +2961,22 @@ class ChannelHeaderComponent {
|
|
|
2636
2961
|
capabilities.indexOf('connect-events') !== -1;
|
|
2637
2962
|
});
|
|
2638
2963
|
}
|
|
2964
|
+
ngOnInit() {
|
|
2965
|
+
this.subscriptions.push(this.customTemplatesService.channelActionsTemplate$.subscribe((template) => {
|
|
2966
|
+
this.channelActionsTemplate = template;
|
|
2967
|
+
this.cdRef.detectChanges();
|
|
2968
|
+
}));
|
|
2969
|
+
}
|
|
2970
|
+
ngOnDestroy() {
|
|
2971
|
+
this.subscriptions.forEach((s) => s.unsubscribe());
|
|
2972
|
+
}
|
|
2639
2973
|
toggleMenu(event) {
|
|
2640
2974
|
event.stopPropagation();
|
|
2641
2975
|
this.channelListToggleService.toggle();
|
|
2642
2976
|
}
|
|
2977
|
+
getChannelActionsContext() {
|
|
2978
|
+
return { channel: this.activeChannel };
|
|
2979
|
+
}
|
|
2643
2980
|
get memberCountParam() {
|
|
2644
2981
|
var _a, _b;
|
|
2645
2982
|
return { memberCount: ((_b = (_a = this.activeChannel) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.member_count) || 0 };
|
|
@@ -2649,8 +2986,8 @@ class ChannelHeaderComponent {
|
|
|
2649
2986
|
return { watcherCount: ((_b = (_a = this.activeChannel) === null || _a === void 0 ? void 0 : _a.state) === null || _b === void 0 ? void 0 : _b.watcher_count) || 0 };
|
|
2650
2987
|
}
|
|
2651
2988
|
}
|
|
2652
|
-
ChannelHeaderComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ChannelHeaderComponent, deps: [{ token: ChannelService }, { token: ChannelListToggleService }], target: i0.ɵɵFactoryTarget.Component });
|
|
2653
|
-
ChannelHeaderComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: ChannelHeaderComponent, selector: "stream-channel-header", ngImport: i0, template: "<div class=\"str-chat__header-livestream\">\n <div\n class=\"str-chat__header-hamburger\"\n (click)=\"toggleMenu($event)\"\n (keyup.enter)=\"toggleMenu($event)\"\n >\n <stream-icon icon=\"menu\"></stream-icon>\n </div>\n <stream-avatar\n imageUrl=\"{{ activeChannel?.data?.image }}\"\n name=\"{{ activeChannel?.data?.name }}\"\n ></stream-avatar>\n <div class=\"str-chat__header-livestream-left\">\n <p data-testid=\"name\" class=\"str-chat__header-livestream-left--title\">\n {{ activeChannel?.data?.name }}\n </p>\n <p data-testid=\"info\" class=\"str-chat__header-livestream-left--members\">\n {{'streamChat.{{ memberCount }} members' | translate:memberCountParam}}\n {{canReceiveConnectEvents ? ('streamChat.{{ watcherCount }} online' |\n translate:watcherCountParam) : ''}}\n </p>\n </div>\n</div>\n", components: [{ type:
|
|
2989
|
+
ChannelHeaderComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ChannelHeaderComponent, deps: [{ token: ChannelService }, { token: ChannelListToggleService }, { token: CustomTemplatesService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
2990
|
+
ChannelHeaderComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: ChannelHeaderComponent, selector: "stream-channel-header", ngImport: i0, template: "<div class=\"str-chat__header-livestream\">\n <div\n class=\"str-chat__header-hamburger\"\n (click)=\"toggleMenu($event)\"\n (keyup.enter)=\"toggleMenu($event)\"\n >\n <stream-icon-placeholder icon=\"menu\"></stream-icon-placeholder>\n </div>\n <stream-avatar-placeholder\n imageUrl=\"{{ activeChannel?.data?.image }}\"\n name=\"{{ activeChannel?.data?.name }}\"\n ></stream-avatar-placeholder>\n <div class=\"str-chat__header-livestream-left\">\n <p data-testid=\"name\" class=\"str-chat__header-livestream-left--title\">\n {{ activeChannel?.data?.name }}\n </p>\n <p data-testid=\"info\" class=\"str-chat__header-livestream-left--members\">\n {{'streamChat.{{ memberCount }} members' | translate:memberCountParam}}\n {{canReceiveConnectEvents ? ('streamChat.{{ watcherCount }} online' |\n translate:watcherCountParam) : ''}}\n </p>\n </div>\n <ng-container *ngIf=\"channelActionsTemplate\">\n <ng-container\n *ngTemplateOutlet=\"\n channelActionsTemplate;\n context: getChannelActionsContext()\n \"\n ></ng-container>\n </ng-container>\n</div>\n", components: [{ type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon", "size"] }, { type: AvatarPlaceholderComponent, selector: "stream-avatar-placeholder", inputs: ["name", "imageUrl", "size"] }], directives: [{ type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], pipes: { "translate": i2.TranslatePipe } });
|
|
2654
2991
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ChannelHeaderComponent, decorators: [{
|
|
2655
2992
|
type: Component,
|
|
2656
2993
|
args: [{
|
|
@@ -2658,7 +2995,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
2658
2995
|
templateUrl: './channel-header.component.html',
|
|
2659
2996
|
styles: [],
|
|
2660
2997
|
}]
|
|
2661
|
-
}], ctorParameters: function () { return [{ type: ChannelService }, { type: ChannelListToggleService }]; } });
|
|
2998
|
+
}], ctorParameters: function () { return [{ type: ChannelService }, { type: ChannelListToggleService }, { type: CustomTemplatesService }, { type: i0.ChangeDetectorRef }]; } });
|
|
2662
2999
|
|
|
2663
3000
|
/**
|
|
2664
3001
|
* The `ChannelPreview` component displays a channel preview in the channel list, it consists of the image, name and latest message of the channel.
|
|
@@ -2738,7 +3075,7 @@ class ChannelPreviewComponent {
|
|
|
2738
3075
|
}
|
|
2739
3076
|
}
|
|
2740
3077
|
ChannelPreviewComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ChannelPreviewComponent, deps: [{ token: ChannelService }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
|
|
2741
|
-
ChannelPreviewComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: ChannelPreviewComponent, selector: "stream-channel-preview", inputs: { channel: "channel" }, ngImport: i0, template: "<button\n class=\"str-chat__channel-preview-messenger\"\n [class.str-chat__channel-preview-messenger--active]=\"isActive\"\n [class.str-chat__channel-preview-messenger--unread]=\"isUnread\"\n (click)=\"setAsActiveChannel()\"\n data-testid=\"channel-preview-container\"\n>\n <div class=\"str-chat__channel-preview-messenger--left\">\n <stream-avatar\n imageUrl=\"{{ avatarImage }}\"\n name=\"{{ avatarName }}\"\n [size]=\"40\"\n ></stream-avatar>\n </div>\n <div class=\"str-chat__channel-preview-messenger--right\">\n <div class=\"str-chat__channel-preview-messenger--name\">\n <span data-testid=\"channel-preview-title\">{{ title }}</span>\n </div>\n <div\n data-testid=\"latest-message\"\n class=\"str-chat__channel-preview-messenger--last-message\"\n >\n {{ latestMessage | translate }}\n </div>\n </div>\n</button>\n", components: [{ type:
|
|
3078
|
+
ChannelPreviewComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: ChannelPreviewComponent, selector: "stream-channel-preview", inputs: { channel: "channel" }, ngImport: i0, template: "<button\n class=\"str-chat__channel-preview-messenger\"\n [class.str-chat__channel-preview-messenger--active]=\"isActive\"\n [class.str-chat__channel-preview-messenger--unread]=\"isUnread\"\n (click)=\"setAsActiveChannel()\"\n data-testid=\"channel-preview-container\"\n>\n <div class=\"str-chat__channel-preview-messenger--left\">\n <stream-avatar-placeholder\n imageUrl=\"{{ avatarImage }}\"\n name=\"{{ avatarName }}\"\n [size]=\"40\"\n ></stream-avatar-placeholder>\n </div>\n <div class=\"str-chat__channel-preview-messenger--right\">\n <div class=\"str-chat__channel-preview-messenger--name\">\n <span data-testid=\"channel-preview-title\">{{ title }}</span>\n </div>\n <div\n data-testid=\"latest-message\"\n class=\"str-chat__channel-preview-messenger--last-message\"\n >\n {{ latestMessage | translate }}\n </div>\n </div>\n</button>\n", components: [{ type: AvatarPlaceholderComponent, selector: "stream-avatar-placeholder", inputs: ["name", "imageUrl", "size"] }], pipes: { "translate": i2.TranslatePipe } });
|
|
2742
3079
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ChannelPreviewComponent, decorators: [{
|
|
2743
3080
|
type: Component,
|
|
2744
3081
|
args: [{
|
|
@@ -2754,19 +3091,25 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
2754
3091
|
* The `ChannelList` component renders the list of channels.
|
|
2755
3092
|
*/
|
|
2756
3093
|
class ChannelListComponent {
|
|
2757
|
-
constructor(channelService, channelListToggleService) {
|
|
3094
|
+
constructor(channelService, channelListToggleService, customTemplatesService) {
|
|
2758
3095
|
this.channelService = channelService;
|
|
2759
3096
|
this.channelListToggleService = channelListToggleService;
|
|
3097
|
+
this.customTemplatesService = customTemplatesService;
|
|
2760
3098
|
this.isLoadingMoreChannels = false;
|
|
3099
|
+
this.subscriptions = [];
|
|
2761
3100
|
this.isOpen$ = this.channelListToggleService.isOpen$;
|
|
2762
3101
|
this.channels$ = this.channelService.channels$;
|
|
2763
3102
|
this.hasMoreChannels$ = this.channelService.hasMoreChannels$;
|
|
2764
3103
|
this.isError$ = this.channels$.pipe(map(() => false), catchError(() => of(true)), startWith(false));
|
|
2765
3104
|
this.isInitializing$ = this.channels$.pipe(map((channels) => !channels), catchError(() => of(false)));
|
|
3105
|
+
this.subscriptions.push(this.customTemplatesService.channelPreviewTemplate$.subscribe((template) => (this.customChannelPreviewTemplate = template)));
|
|
2766
3106
|
}
|
|
2767
3107
|
ngAfterViewInit() {
|
|
2768
3108
|
this.channelListToggleService.setMenuElement(this.container.nativeElement);
|
|
2769
3109
|
}
|
|
3110
|
+
ngOnDestroy() {
|
|
3111
|
+
this.subscriptions.forEach((s) => s.unsubscribe());
|
|
3112
|
+
}
|
|
2770
3113
|
loadMoreChannels() {
|
|
2771
3114
|
return __awaiter(this, void 0, void 0, function* () {
|
|
2772
3115
|
this.isLoadingMoreChannels = true;
|
|
@@ -2780,9 +3123,14 @@ class ChannelListComponent {
|
|
|
2780
3123
|
channelSelected() {
|
|
2781
3124
|
this.channelListToggleService.channelSelected();
|
|
2782
3125
|
}
|
|
3126
|
+
getChannelPreviewContext(channel) {
|
|
3127
|
+
return {
|
|
3128
|
+
channel,
|
|
3129
|
+
};
|
|
3130
|
+
}
|
|
2783
3131
|
}
|
|
2784
|
-
ChannelListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ChannelListComponent, deps: [{ token: ChannelService }, { token: ChannelListToggleService }], target: i0.ɵɵFactoryTarget.Component });
|
|
2785
|
-
ChannelListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: ChannelListComponent, selector: "stream-channel-list",
|
|
3132
|
+
ChannelListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ChannelListComponent, deps: [{ token: ChannelService }, { token: ChannelListToggleService }, { token: CustomTemplatesService }], target: i0.ɵɵFactoryTarget.Component });
|
|
3133
|
+
ChannelListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: ChannelListComponent, selector: "stream-channel-list", viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true }], ngImport: i0, template: "<div\n #container\n data-testid=\"channel-list-container\"\n class=\"str-chat str-chat-channel-list messaging\"\n [class.str-chat-channel-list--open]=\"(isOpen$ | async) === true\"\n>\n <div\n *ngIf=\"\n (isError$ | async) === false && (isInitializing$ | async) === false;\n else statusIndicator\n \"\n class=\"str-chat__channel-list-messenger\"\n >\n <div class=\"str-chat__channel-list-messenger__main\">\n <p\n data-testid=\"empty-channel-list-indicator\"\n *ngIf=\"!(channels$ | async)?.length\"\n >\n {{ \"streamChat.You have no channels currently\" | translate }}\n </p>\n <ng-container\n *ngFor=\"let channel of channels$ | async; trackBy: trackByChannelId\"\n >\n <ng-template #defaultTemplate let-channelInput=\"channel\">\n <stream-channel-preview\n data-testclass=\"channel-preview\"\n [channel]=\"channelInput\"\n ></stream-channel-preview>\n </ng-template>\n <div (click)=\"channelSelected()\" (keyup.enter)=\"channelSelected()\">\n <ng-container\n *ngTemplateOutlet=\"\n customChannelPreviewTemplate || defaultTemplate;\n context: getChannelPreviewContext(channel)\n \"\n ></ng-container>\n </div>\n </ng-container>\n <div\n *ngIf=\"hasMoreChannels$ | async\"\n class=\"str-chat__load-more-button\"\n (click)=\"loadMoreChannels()\"\n (keyup.enter)=\"loadMoreChannels()\"\n data-testid=\"load-more\"\n >\n <button\n class=\"str-chat__load-more-button__button\"\n data-testid=\"load-more-button\"\n [disabled]=\"isLoadingMoreChannels\"\n >\n <span *ngIf=\"!isLoadingMoreChannels; else loadingIndicator\">{{\n \"Load more\" | translate\n }}</span>\n <ng-template #loadingIndicator\n ><stream-loading-indicator-placeholder></stream-loading-indicator-placeholder\n ></ng-template>\n </button>\n </div>\n </div>\n </div>\n</div>\n\n<ng-template #statusIndicator>\n <ng-container *ngIf=\"isError$ | async\">\n <ng-container *ngTemplateOutlet=\"chatDown\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"isInitializing$ | async\">\n <ng-container *ngTemplateOutlet=\"loadingChannels\"></ng-container>\n </ng-container>\n</ng-template>\n\n<ng-template #chatDown>\n <div data-testid=\"chatdown-container\" class=\"str-chat__down\">\n <ng-container *ngTemplateOutlet=\"loadingChannels\"></ng-container>\n <div class=\"str-chat__down-main\">\n <stream-icon-placeholder\n icon=\"connection-error\"\n ></stream-icon-placeholder>\n <h1>{{ \"streamChat.Connection error\" | translate }}</h1>\n <h3>\n {{\n \"streamChat.Error connecting to chat, refresh the page to try again.\"\n | translate\n }}\n </h3>\n </div>\n </div>\n</ng-template>\n\n<ng-template #loadingChannels>\n <div data-testid=\"loading-indicator\" class=\"str-chat__loading-channels\">\n <ng-container *ngTemplateOutlet=\"loadingChannel\"></ng-container>\n <ng-container *ngTemplateOutlet=\"loadingChannel\"></ng-container>\n <ng-container *ngTemplateOutlet=\"loadingChannel\"></ng-container>\n </div>\n</ng-template>\n\n<ng-template #loadingChannel>\n <div class=\"str-chat__loading-channels-item\">\n <div class=\"str-chat__loading-channels-avatar\"></div>\n <div class=\"str-chat__loading-channels-meta\">\n <div class=\"str-chat__loading-channels-username\"></div>\n <div class=\"str-chat__loading-channels-status\"></div>\n </div>\n </div>\n</ng-template>\n", components: [{ type: ChannelPreviewComponent, selector: "stream-channel-preview", inputs: ["channel"] }, { type: LoadingIndicatorPlaceholderComponent, selector: "stream-loading-indicator-placeholder", inputs: ["size", "color"] }, { type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon", "size"] }], directives: [{ type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], pipes: { "async": i3.AsyncPipe, "translate": i2.TranslatePipe } });
|
|
2786
3134
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ChannelListComponent, decorators: [{
|
|
2787
3135
|
type: Component,
|
|
2788
3136
|
args: [{
|
|
@@ -2790,9 +3138,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
2790
3138
|
templateUrl: './channel-list.component.html',
|
|
2791
3139
|
styles: [],
|
|
2792
3140
|
}]
|
|
2793
|
-
}], ctorParameters: function () { return [{ type: ChannelService }, { type: ChannelListToggleService }]; }, propDecorators: {
|
|
2794
|
-
type: Input
|
|
2795
|
-
}], container: [{
|
|
3141
|
+
}], ctorParameters: function () { return [{ type: ChannelService }, { type: ChannelListToggleService }, { type: CustomTemplatesService }]; }, propDecorators: { container: [{
|
|
2796
3142
|
type: ViewChild,
|
|
2797
3143
|
args: ['container']
|
|
2798
3144
|
}] } });
|
|
@@ -2951,7 +3297,7 @@ class MessageReactionsComponent {
|
|
|
2951
3297
|
}
|
|
2952
3298
|
}
|
|
2953
3299
|
MessageReactionsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: MessageReactionsComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: ChannelService }], target: i0.ɵɵFactoryTarget.Component });
|
|
2954
|
-
MessageReactionsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: MessageReactionsComponent, selector: "stream-message-reactions", inputs: { messageId: "messageId", messageReactionCounts: "messageReactionCounts", isSelectorOpen: "isSelectorOpen", latestReactions: "latestReactions", ownReactions: "ownReactions" }, outputs: { isSelectorOpenChange: "isSelectorOpenChange" }, viewQueries: [{ propertyName: "selectorContainer", first: true, predicate: ["selectorContainer"], descendants: true }, { propertyName: "selectorTooltip", first: true, predicate: ["selectorTooltip"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div\n *ngIf=\"existingReactions.length > 0 && !isSelectorOpen\"\n class=\"str-chat__reaction-list\"\n [class.str-chat__reaction-list--reverse]=\"true\"\n data-testid=\"reaction-list\"\n>\n <ul>\n <li\n *ngFor=\"\n let reactionType of existingReactions;\n trackBy: trackByMessageReaction\n \"\n data-testclass=\"emoji\"\n >\n <span class=\"emoji\">\n {{ getEmojiByReaction(reactionType) }}\n </span>\n \n </li>\n <li>\n <span\n data-testid=\"reactions-count\"\n class=\"str-chat__reaction-list--counter\"\n >{{ reactionsCount }}</span\n >\n </li>\n </ul>\n</div>\n\n<div\n #selectorContainer\n class=\"str-chat__reaction-selector\"\n *ngIf=\"isSelectorOpen\"\n data-testid=\"reaction-selector\"\n>\n <div\n *ngIf=\"tooltipText\"\n data-testid=\"tooltip\"\n #selectorTooltip\n class=\"str-chat__reaction-selector-tooltip\"\n [ngStyle]=\"{\n left: tooltipPositions?.tooltip + 'px',\n visibility: tooltipPositions ? 'visible' : 'hidden'\n }\"\n >\n <div\n class=\"arrow\"\n [ngStyle]=\"{ left: tooltipPositions?.arrow + 'px' }\"\n ></div>\n <span class=\"latest-user-username\">\n {{ tooltipText }}\n </span>\n </div>\n <ul class=\"str-chat__message-reactions-list\">\n <li\n class=\"str-chat__message-reactions-list-item str-chat__emoji\"\n *ngFor=\"\n let reactionType of reactionOptions;\n trackBy: trackByMessageReaction\n \"\n data-testclass=\"emoji-option\"\n (click)=\"react(reactionType)\"\n (keyup.enter)=\"react(reactionType)\"\n >\n <div\n *ngIf=\"getLatestUserByReaction(reactionType) as user\"\n class=\"latest-user\"\n (click)=\"hideTooltip()\"\n (keyup.enter)=\"hideTooltip()\"\n (mouseenter)=\"showTooltip($event, reactionType)\"\n (mouseleave)=\"hideTooltip()\"\n attr.data-testid=\"{{ reactionType }}-last-user\"\n >\n <stream-avatar\n attr.data-testid=\"{{ reactionType }}-avatar\"\n [imageUrl]=\"user.image\"\n [name]=\"user.name || user.id\"\n [size]=\"20\"\n ></stream-avatar>\n </div>\n <span class=\"emoji\" style=\"width: 20px; height: 20px; top: 10px\">\n {{ getEmojiByReaction(reactionType) }}\n </span>\n <span\n *ngIf=\"\n messageReactionCounts[reactionType] &&\n messageReactionCounts[reactionType]! > 0\n \"\n class=\"str-chat__message-reactions-list-item__count\"\n attr.data-testid=\"{{ reactionType }}-reaction-count\"\n >\n {{ messageReactionCounts[reactionType] }}\n </span>\n </li>\n </ul>\n</div>\n", styles: [".emoji {position: relative; display: inline-block; }"], components: [{ type:
|
|
3300
|
+
MessageReactionsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: MessageReactionsComponent, selector: "stream-message-reactions", inputs: { messageId: "messageId", messageReactionCounts: "messageReactionCounts", isSelectorOpen: "isSelectorOpen", latestReactions: "latestReactions", ownReactions: "ownReactions" }, outputs: { isSelectorOpenChange: "isSelectorOpenChange" }, viewQueries: [{ propertyName: "selectorContainer", first: true, predicate: ["selectorContainer"], descendants: true }, { propertyName: "selectorTooltip", first: true, predicate: ["selectorTooltip"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div\n *ngIf=\"existingReactions.length > 0 && !isSelectorOpen\"\n class=\"str-chat__reaction-list\"\n [class.str-chat__reaction-list--reverse]=\"true\"\n data-testid=\"reaction-list\"\n>\n <ul>\n <li\n *ngFor=\"\n let reactionType of existingReactions;\n trackBy: trackByMessageReaction\n \"\n data-testclass=\"emoji\"\n >\n <span class=\"emoji\">\n {{ getEmojiByReaction(reactionType) }}\n </span>\n \n </li>\n <li>\n <span\n data-testid=\"reactions-count\"\n class=\"str-chat__reaction-list--counter\"\n >{{ reactionsCount }}</span\n >\n </li>\n </ul>\n</div>\n\n<div\n #selectorContainer\n class=\"str-chat__reaction-selector\"\n *ngIf=\"isSelectorOpen\"\n data-testid=\"reaction-selector\"\n>\n <div\n *ngIf=\"tooltipText\"\n data-testid=\"tooltip\"\n #selectorTooltip\n class=\"str-chat__reaction-selector-tooltip\"\n [ngStyle]=\"{\n left: tooltipPositions?.tooltip + 'px',\n visibility: tooltipPositions ? 'visible' : 'hidden'\n }\"\n >\n <div\n class=\"arrow\"\n [ngStyle]=\"{ left: tooltipPositions?.arrow + 'px' }\"\n ></div>\n <span class=\"latest-user-username\">\n {{ tooltipText }}\n </span>\n </div>\n <ul class=\"str-chat__message-reactions-list\">\n <li\n class=\"str-chat__message-reactions-list-item str-chat__emoji\"\n *ngFor=\"\n let reactionType of reactionOptions;\n trackBy: trackByMessageReaction\n \"\n data-testclass=\"emoji-option\"\n (click)=\"react(reactionType)\"\n (keyup.enter)=\"react(reactionType)\"\n >\n <div\n *ngIf=\"getLatestUserByReaction(reactionType) as user\"\n class=\"latest-user\"\n (click)=\"hideTooltip()\"\n (keyup.enter)=\"hideTooltip()\"\n (mouseenter)=\"showTooltip($event, reactionType)\"\n (mouseleave)=\"hideTooltip()\"\n attr.data-testid=\"{{ reactionType }}-last-user\"\n >\n <stream-avatar-placeholder\n attr.data-testid=\"{{ reactionType }}-avatar\"\n [imageUrl]=\"user.image\"\n [name]=\"user.name || user.id\"\n [size]=\"20\"\n ></stream-avatar-placeholder>\n </div>\n <span class=\"emoji\" style=\"width: 20px; height: 20px; top: 10px\">\n {{ getEmojiByReaction(reactionType) }}\n </span>\n <span\n *ngIf=\"\n messageReactionCounts[reactionType] &&\n messageReactionCounts[reactionType]! > 0\n \"\n class=\"str-chat__message-reactions-list-item__count\"\n attr.data-testid=\"{{ reactionType }}-reaction-count\"\n >\n {{ messageReactionCounts[reactionType] }}\n </span>\n </li>\n </ul>\n</div>\n", styles: [".emoji {position: relative; display: inline-block; }"], components: [{ type: AvatarPlaceholderComponent, selector: "stream-avatar-placeholder", inputs: ["name", "imageUrl", "size"] }], directives: [{ type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i3.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] });
|
|
2955
3301
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: MessageReactionsComponent, decorators: [{
|
|
2956
3302
|
type: Component,
|
|
2957
3303
|
args: [{
|
|
@@ -2983,9 +3329,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
2983
3329
|
* The `Message` component displays a message with additional information such as sender and date, and enables [interaction with the message (i.e. edit or react)](../concepts/message-interactions.mdx).
|
|
2984
3330
|
*/
|
|
2985
3331
|
class MessageComponent {
|
|
2986
|
-
constructor(chatClientService, channelService) {
|
|
3332
|
+
constructor(chatClientService, channelService, customTemplatesService, cdRef) {
|
|
2987
3333
|
this.chatClientService = chatClientService;
|
|
2988
3334
|
this.channelService = channelService;
|
|
3335
|
+
this.customTemplatesService = customTemplatesService;
|
|
3336
|
+
this.cdRef = cdRef;
|
|
2989
3337
|
/**
|
|
2990
3338
|
* The list of [channel capabilities](https://getstream.io/chat/docs/javascript/channel_capabilities/?language=javascript) that are enabled for the current user, the list of [supported interactions](../concepts/message-interactions.mdx) can be found in our message interaction guide. Unathorized actions won't be displayed on the UI. The [`MessageList`](./MessageListComponent.mdx) component automatically sets this based on [channel capabilities](https://getstream.io/chat/docs/javascript/channel_capabilities/?language=javascript).
|
|
2991
3339
|
*/
|
|
@@ -2999,8 +3347,15 @@ class MessageComponent {
|
|
|
2999
3347
|
this.isPressedOnMobile = false;
|
|
3000
3348
|
this.visibleMessageActionsCount = 0;
|
|
3001
3349
|
this.messageTextParts = [];
|
|
3350
|
+
this.subscriptions = [];
|
|
3002
3351
|
this.user = this.chatClientService.chatClient.user;
|
|
3003
3352
|
}
|
|
3353
|
+
ngOnInit() {
|
|
3354
|
+
this.subscriptions.push(this.customTemplatesService.mentionTemplate$.subscribe((template) => (this.mentionTemplate = template)));
|
|
3355
|
+
this.subscriptions.push(this.customTemplatesService.attachmentListTemplate$.subscribe((template) => (this.attachmentListTemplate = template)));
|
|
3356
|
+
this.subscriptions.push(this.customTemplatesService.messageActionsBoxTemplate$.subscribe((template) => (this.messageActionsBoxTemplate = template)));
|
|
3357
|
+
this.subscriptions.push(this.customTemplatesService.messageReactionsTemplate$.subscribe((template) => (this.messageReactionsTemplate = template)));
|
|
3358
|
+
}
|
|
3004
3359
|
ngOnChanges(changes) {
|
|
3005
3360
|
if (changes.message) {
|
|
3006
3361
|
this.createMessageParts();
|
|
@@ -3012,6 +3367,9 @@ class MessageComponent {
|
|
|
3012
3367
|
this.enabledMessageActions.indexOf('read-events') !== -1;
|
|
3013
3368
|
}
|
|
3014
3369
|
}
|
|
3370
|
+
ngOnDestroy() {
|
|
3371
|
+
this.subscriptions.forEach((s) => s.unsubscribe());
|
|
3372
|
+
}
|
|
3015
3373
|
get isSentByCurrentUser() {
|
|
3016
3374
|
var _a, _b, _c;
|
|
3017
3375
|
return ((_b = (_a = this.message) === null || _a === void 0 ? void 0 : _a.user) === null || _b === void 0 ? void 0 : _b.id) === ((_c = this.user) === null || _c === void 0 ? void 0 : _c.id);
|
|
@@ -3078,6 +3436,24 @@ class MessageComponent {
|
|
|
3078
3436
|
? [originalAttachments[0]]
|
|
3079
3437
|
: [];
|
|
3080
3438
|
}
|
|
3439
|
+
getAttachmentListContext() {
|
|
3440
|
+
var _a, _b;
|
|
3441
|
+
return {
|
|
3442
|
+
messageId: ((_a = this.message) === null || _a === void 0 ? void 0 : _a.id) || '',
|
|
3443
|
+
attachments: ((_b = this.message) === null || _b === void 0 ? void 0 : _b.attachments) || [],
|
|
3444
|
+
};
|
|
3445
|
+
}
|
|
3446
|
+
getMessageReactionsContext() {
|
|
3447
|
+
var _a, _b, _c, _d;
|
|
3448
|
+
return {
|
|
3449
|
+
messageReactionCounts: ((_a = this.message) === null || _a === void 0 ? void 0 : _a.reaction_counts) || {},
|
|
3450
|
+
latestReactions: ((_b = this.message) === null || _b === void 0 ? void 0 : _b.latest_reactions) || [],
|
|
3451
|
+
isSelectorOpen: this.isReactionSelectorOpen,
|
|
3452
|
+
isSelectorOpenChangeHandler: (isOpen) => (this.isReactionSelectorOpen = isOpen),
|
|
3453
|
+
messageId: (_c = this.message) === null || _c === void 0 ? void 0 : _c.id,
|
|
3454
|
+
ownReactions: ((_d = this.message) === null || _d === void 0 ? void 0 : _d.own_reactions) || [],
|
|
3455
|
+
};
|
|
3456
|
+
}
|
|
3081
3457
|
resendMessage() {
|
|
3082
3458
|
void this.channelService.resendMessage(this.message);
|
|
3083
3459
|
}
|
|
@@ -3102,6 +3478,29 @@ class MessageComponent {
|
|
|
3102
3478
|
setAsActiveParentMessage() {
|
|
3103
3479
|
void this.channelService.setAsActiveParentMessage(this.message);
|
|
3104
3480
|
}
|
|
3481
|
+
getMentionContext(messagePart) {
|
|
3482
|
+
return {
|
|
3483
|
+
content: messagePart.content,
|
|
3484
|
+
user: messagePart.user,
|
|
3485
|
+
};
|
|
3486
|
+
}
|
|
3487
|
+
getMessageActionsBoxContext() {
|
|
3488
|
+
return {
|
|
3489
|
+
isOpen: this.isActionBoxOpen,
|
|
3490
|
+
isMine: this.isSentByCurrentUser,
|
|
3491
|
+
enabledActions: this.enabledMessageActions,
|
|
3492
|
+
message: this.message,
|
|
3493
|
+
displayedActionsCountChaneHanler: (count) => {
|
|
3494
|
+
this.visibleMessageActionsCount = count;
|
|
3495
|
+
// message action box changes UI bindings in parent, so we'll have to rerun change detection
|
|
3496
|
+
this.cdRef.detectChanges();
|
|
3497
|
+
},
|
|
3498
|
+
isEditingChangeHandler: (isEditing) => {
|
|
3499
|
+
this.isEditing = isEditing;
|
|
3500
|
+
this.isActionBoxOpen = !this.isEditing;
|
|
3501
|
+
},
|
|
3502
|
+
};
|
|
3503
|
+
}
|
|
3105
3504
|
createMessageParts() {
|
|
3106
3505
|
var _a, _b;
|
|
3107
3506
|
let content = ((_a = this.message) === null || _a === void 0 ? void 0 : _a.html) || ((_b = this.message) === null || _b === void 0 ? void 0 : _b.text);
|
|
@@ -3147,8 +3546,8 @@ class MessageComponent {
|
|
|
3147
3546
|
}
|
|
3148
3547
|
}
|
|
3149
3548
|
}
|
|
3150
|
-
MessageComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: MessageComponent, deps: [{ token: ChatClientService }, { token: ChannelService }], target: i0.ɵɵFactoryTarget.Component });
|
|
3151
|
-
MessageComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: MessageComponent, selector: "stream-message", inputs: { messageInputTemplate: "messageInputTemplate", mentionTemplate: "mentionTemplate", message: "message", enabledMessageActions: "enabledMessageActions", isLastSentMessage: "isLastSentMessage", mode: "mode" }, viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div\n #container\n class=\"str-chat__message-simple str-chat__message str-chat__message--{{\n message?.type\n }} str-chat__message--{{ message?.status }} {{\n message?.text ? 'str-chat__message--has-text' : 'has-no-text'\n }}\"\n [class.str-chat__message--me]=\"isSentByCurrentUser\"\n [class.str-chat__message-simple--me]=\"isSentByCurrentUser\"\n [class.mobile-press]=\"isPressedOnMobile\"\n [class.str-chat__message--has-attachment]=\"hasAttachment\"\n [class.str-chat__message--with-reactions]=\"hasReactions\"\n data-testid=\"message-container\"\n (mouseleave)=\"isActionBoxOpen = false\"\n>\n <ng-container *ngIf=\"!message?.deleted_at; else deletedMessage\">\n <ng-container *ngIf=\"message?.type !== 'system'; else systemMessage\">\n <ng-container\n *ngIf=\"\n isSentByCurrentUser &&\n ((isLastSentMessage && message?.status === 'received') ||\n message?.status === 'sending')\n \"\n >\n <ng-container *ngIf=\"message?.status === 'sending'; else sentStatus\">\n <ng-container *ngTemplateOutlet=\"sendingStatus\"></ng-container>\n </ng-container>\n <ng-template #sentStatus>\n <ng-container\n *ngIf=\"\n mode === 'main' &&\n isMessageDeliveredAndRead &&\n canDisplayReadStatus;\n else deliveredStatus\n \"\n >\n <ng-container *ngTemplateOutlet=\"readStatus\"></ng-container>\n </ng-container>\n </ng-template>\n </ng-container>\n <stream-avatar\n data-testid=\"avatar\"\n class=\"str-chat-angular__avatar-host\"\n [imageUrl]=\"message?.user?.image\"\n [name]=\"message?.user?.name || message?.user?.id\"\n ></stream-avatar>\n <div class=\"str-chat__message-inner\">\n <div\n class=\"str-chat__message-simple__actions\"\n data-testid=\"message-options\"\n *ngIf=\"areOptionsVisible\"\n >\n <div\n data-testid=\"message-actions-container\"\n class=\"\n str-chat__message-simple__actions__action\n str-chat__message-simple__actions__action--options\n \"\n [class.str-chat-angular__message-simple__actions__action--options--editing]=\"\n isEditing\n \"\n >\n <stream-message-actions-box\n [isOpen]=\"isActionBoxOpen\"\n [isMine]=\"isSentByCurrentUser\"\n [enabledActions]=\"enabledMessageActions\"\n [message]=\"message\"\n (displayedActionsCount)=\"visibleMessageActionsCount = $event\"\n (isEditing)=\"isEditing = $event; isActionBoxOpen = !isEditing\"\n [messageInputTemplate]=\"messageInputTemplate\"\n ></stream-message-actions-box>\n <stream-icon\n *ngIf=\"visibleMessageActionsCount > 0\"\n data-testid=\"action-icon\"\n icon=\"action-icon\"\n (keyup.enter)=\"isActionBoxOpen = !isActionBoxOpen\"\n (click)=\"isActionBoxOpen = !isActionBoxOpen\"\n ></stream-icon>\n </div>\n <!-- eslint-disable @angular-eslint/template/conditional-complexity -->\n <div\n *ngIf=\"\n enabledMessageActions.indexOf('send-reply') !== -1 &&\n mode === 'main'\n \"\n class=\"\n str-chat__message-simple__actions__action\n str-chat__message-simple__actions__action--thread\n \"\n data-testid=\"reply-in-thread\"\n (click)=\"setAsActiveParentMessage()\"\n (keyup.enter)=\"setAsActiveParentMessage()\"\n >\n <stream-icon icon=\"reply-in-thread\"></stream-icon>\n </div>\n <div\n *ngIf=\"canReactToMessage\"\n class=\"\n str-chat__message-simple__actions__action\n str-chat__message-simple__actions__action--reactions\n \"\n data-testid=\"reaction-icon\"\n (click)=\"isReactionSelectorOpen = !isReactionSelectorOpen\"\n (keyup.enter)=\"isReactionSelectorOpen = !isReactionSelectorOpen\"\n >\n <stream-icon icon=\"reaction-icon\"></stream-icon>\n </div>\n </div>\n <!-- eslint-enable @angular-eslint/template/conditional-complexity -->\n <stream-message-reactions\n [messageReactionCounts]=\"message?.reaction_counts || {}\"\n [latestReactions]=\"message?.latest_reactions || []\"\n [(isSelectorOpen)]=\"isReactionSelectorOpen\"\n [messageId]=\"message?.id\"\n [ownReactions]=\"message?.own_reactions || []\"\n ></stream-message-reactions>\n <stream-attachment-list\n *ngIf=\"hasAttachment && !message?.quoted_message\"\n [attachments]=\"message!.attachments!\"\n [messageId]=\"message!.id\"\n ></stream-attachment-list>\n <div class=\"str-chat__message-text\" *ngIf=\"message?.text\">\n <div\n data-testid=\"inner-message\"\n class=\"\n str-chat__message-text-inner str-chat__message-simple-text-inner\n \"\n [class.str-chat__message-light-text-inner--has-attachment]=\"\n hasAttachment\n \"\n (click)=\"\n message?.status === 'failed' && message?.errorStatusCode !== 403\n ? resendMessage()\n : undefined\n \"\n (keyup.enter)=\"\n message?.status === 'failed' && message?.errorStatusCode !== 403\n ? resendMessage()\n : undefined\n \"\n >\n <ng-container *ngTemplateOutlet=\"quotedMessage\"></ng-container>\n <stream-attachment-list\n *ngIf=\"hasAttachment && message?.quoted_message\"\n [attachments]=\"message!.attachments!\"\n [messageId]=\"message!.id\"\n ></stream-attachment-list>\n <div\n data-testid=\"client-error-message\"\n *ngIf=\"message?.type === 'error'\"\n class=\"str-chat__simple-message--error-message\"\n >\n {{ \"streamChat.Error \u00B7 Unsent\" | translate }}\n </div>\n <div\n data-testid=\"error-message\"\n *ngIf=\"message?.status === 'failed'\"\n class=\"str-chat__simple-message--error-message\"\n >\n {{\n (message?.errorStatusCode === 403\n ? \"streamChat.Message Failed \u00B7 Unauthorized\"\n : \"streamChat.Message Failed \u00B7 Click to try again\"\n ) | translate\n }}\n </div>\n <div\n (click)=\"textClicked()\"\n (keyup.enter)=\"textClicked()\"\n data-testid=\"text\"\n >\n <p>\n <!-- eslint-disable-next-line @angular-eslint/template/use-track-by-function -->\n <ng-container *ngFor=\"let part of messageTextParts\">\n <span\n *ngIf=\"part.type === 'text'; else mention\"\n [innerHTML]=\"part.content\"\n ></span>\n <ng-template #mention>\n <ng-container *ngIf=\"mentionTemplate; else defaultMention\">\n <ng-container\n *ngTemplateOutlet=\"\n mentionTemplate;\n context: { user: part.user! }\n \"\n ></ng-container>\n </ng-container>\n <ng-template #defaultMention>\n <b>{{ part.content }}</b>\n </ng-template>\n </ng-template>\n </ng-container>\n </p>\n </div>\n </div>\n </div>\n <div class=\"str-chat__message-simple-reply-button\">\n <button\n *ngIf=\"\n !!message?.reply_count &&\n mode !== 'thread' &&\n enabledMessageActions.indexOf('send-reply') !== -1\n \"\n class=\"str-chat__message-replies-count-button\"\n data-testid=\"reply-count-button\"\n (click)=\"setAsActiveParentMessage()\"\n >\n <stream-icon icon=\"reply\"></stream-icon>\n {{message?.reply_count === 1 ? ('streamChat.1 reply' | translate) : ('streamChat.{{ replyCount }}\n replies' | translate:replyCountParam)}}\n </button>\n </div>\n <div class=\"str-chat__message-data str-chat__message-simple-data\">\n <span\n data-testid=\"sender\"\n *ngIf=\"!isSentByCurrentUser\"\n class=\"str-chat__message-simple-name\"\n >\n {{ message?.user?.name ? message?.user?.name : message?.user?.id }}\n </span>\n <span data-testid=\"date\" class=\"str-chat__message-simple-timestamp\">\n {{ parsedDate }}\n </span>\n </div>\n </div>\n </ng-container>\n </ng-container>\n</div>\n\n<ng-template #sendingStatus>\n <span\n class=\"\n str-chat__message-simple-status str-chat__message-simple-status-angular\n \"\n data-testid=\"sending-indicator\"\n >\n <div class=\"str-chat__tooltip\">\n {{ \"streamChat.Sending...\" | translate }}\n </div>\n <stream-loading-indicator\n data-testid=\"loading-indicator\"\n ></stream-loading-indicator>\n </span>\n</ng-template>\n<ng-template #readStatus>\n <span\n class=\"\n str-chat__message-simple-status str-chat__message-simple-status-angular\n \"\n data-testid=\"read-indicator\"\n >\n <div class=\"str-chat__tooltip\" data-testid=\"read-by-tooltip\">\n {{ readByText }}\n </div>\n <stream-avatar\n class=\"str-chat-angular__avatar-host\"\n data-test-id=\"last-read-user-avatar\"\n [size]=\"15\"\n [imageUrl]=\"lastReadUser?.image\"\n [name]=\"lastReadUser?.name || lastReadUser?.id\"\n ></stream-avatar>\n <span\n data-test-id=\"read-by-length\"\n *ngIf=\"isReadByMultipleUsers\"\n class=\"str-chat__message-simple-status-number\"\n >\n {{ (message?.readBy)!.length }}\n </span>\n </span>\n</ng-template>\n<ng-template #deliveredStatus>\n <span\n *ngIf=\"mode === 'main'\"\n class=\"\n str-chat__message-simple-status str-chat__message-simple-status-angular\n \"\n data-testid=\"delivered-indicator\"\n >\n <div class=\"str-chat__tooltip\">\n {{ \"streamChat.Delivered\" | translate }}\n </div>\n <stream-icon\n data-testid=\"delivered-icon\"\n icon=\"delivered-icon\"\n ></stream-icon>\n </span>\n</ng-template>\n\n<ng-template #deletedMessage>\n <div data-testid=\"message-deleted-component\">\n <div class=\"str-chat__message--deleted-inner\" translate>\n streamChat.This message was deleted...\n </div>\n </div>\n</ng-template>\n\n<ng-template #systemMessage>\n <div data-testid=\"system-message\" class=\"str-chat__message--system\">\n <div class=\"str-chat__message--system__text\">\n <div class=\"str-chat__message--system__line\"></div>\n <p>{{ message?.text }}</p>\n <div class=\"str-chat__message--system__line\"></div>\n </div>\n <div class=\"str-chat__message--system__date\">\n {{ parsedDate }}\n </div>\n </div>\n</ng-template>\n\n<ng-template #quotedMessage>\n <div\n *ngIf=\"message?.quoted_message\"\n class=\"quoted-message\"\n data-testid=\"quoted-message-container\"\n [class.mine]=\"isSentByCurrentUser\"\n >\n <stream-avatar\n data-testid=\"qouted-message-avatar\"\n class=\"str-chat-angular__avatar-host\"\n [imageUrl]=\"message?.quoted_message?.user?.image\"\n [name]=\"\n message?.quoted_message?.user?.name || message?.quoted_message?.user?.id\n \"\n [size]=\"20\"\n ></stream-avatar>\n <div class=\"quoted-message-inner\">\n <stream-attachment-list\n *ngIf=\"\n message?.quoted_message?.attachments &&\n message?.quoted_message?.attachments?.length\n \"\n [attachments]=\"quotedMessageAttachments\"\n [messageId]=\"message?.quoted_message?.id\"\n ></stream-attachment-list>\n <div\n data-testid=\"quoted-message-text\"\n [innerHTML]=\"\n message?.quoted_message?.html || message?.quoted_message?.text\n \"\n ></div>\n </div>\n </div>\n</ng-template>\n", components: [{ type: AvatarComponent, selector: "stream-avatar", inputs: ["name", "imageUrl", "size"] }, { type: MessageActionsBoxComponent, selector: "stream-message-actions-box", inputs: ["messageInputTemplate", "isOpen", "isMine", "message", "enabledActions"], outputs: ["displayedActionsCount", "isEditing"] }, { type: IconComponent, selector: "stream-icon", inputs: ["icon", "size"] }, { type: MessageReactionsComponent, selector: "stream-message-reactions", inputs: ["messageId", "messageReactionCounts", "isSelectorOpen", "latestReactions", "ownReactions"], outputs: ["isSelectorOpenChange"] }, { type: AttachmentListComponent, selector: "stream-attachment-list", inputs: ["messageId", "attachments"] }, { type: LoadingIndicatorComponent, selector: "stream-loading-indicator", inputs: ["size", "color"] }], directives: [{ type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i6.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }], pipes: { "translate": i2.TranslatePipe } });
|
|
3549
|
+
MessageComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: MessageComponent, deps: [{ token: ChatClientService }, { token: ChannelService }, { token: CustomTemplatesService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
3550
|
+
MessageComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: MessageComponent, selector: "stream-message", inputs: { message: "message", enabledMessageActions: "enabledMessageActions", isLastSentMessage: "isLastSentMessage", mode: "mode" }, viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div\n #container\n class=\"str-chat__message-simple str-chat__message str-chat__message--{{\n message?.type\n }} str-chat__message--{{ message?.status }} {{\n message?.text ? 'str-chat__message--has-text' : 'has-no-text'\n }}\"\n [class.str-chat__message--me]=\"isSentByCurrentUser\"\n [class.str-chat__message-simple--me]=\"isSentByCurrentUser\"\n [class.mobile-press]=\"isPressedOnMobile\"\n [class.str-chat__message--has-attachment]=\"hasAttachment\"\n [class.str-chat__message--with-reactions]=\"hasReactions\"\n data-testid=\"message-container\"\n (mouseleave)=\"isActionBoxOpen = false\"\n>\n <ng-container *ngIf=\"!message?.deleted_at; else deletedMessage\">\n <ng-container *ngIf=\"message?.type !== 'system'; else systemMessage\">\n <ng-container\n *ngIf=\"\n isSentByCurrentUser &&\n ((isLastSentMessage && message?.status === 'received') ||\n message?.status === 'sending')\n \"\n >\n <ng-container *ngIf=\"message?.status === 'sending'; else sentStatus\">\n <ng-container *ngTemplateOutlet=\"sendingStatus\"></ng-container>\n </ng-container>\n <ng-template #sentStatus>\n <ng-container\n *ngIf=\"\n mode === 'main' &&\n isMessageDeliveredAndRead &&\n canDisplayReadStatus;\n else deliveredStatus\n \"\n >\n <ng-container *ngTemplateOutlet=\"readStatus\"></ng-container>\n </ng-container>\n </ng-template>\n </ng-container>\n <stream-avatar-placeholder\n data-testid=\"avatar\"\n class=\"str-chat-angular__avatar-host\"\n [imageUrl]=\"message?.user?.image\"\n [name]=\"message?.user?.name || message?.user?.id\"\n ></stream-avatar-placeholder>\n <div class=\"str-chat__message-inner\">\n <div\n class=\"str-chat__message-simple__actions\"\n data-testid=\"message-options\"\n *ngIf=\"areOptionsVisible\"\n >\n <div\n data-testid=\"message-actions-container\"\n class=\"\n str-chat__message-simple__actions__action\n str-chat__message-simple__actions__action--options\n \"\n [class.str-chat-angular__message-simple__actions__action--options--editing]=\"\n isEditing\n \"\n >\n <ng-template\n #defaultMessageActionsBox\n let-isOpen=\"isOpen\"\n let-isMine=\"isMine\"\n let-enabledActions=\"enabledActions\"\n let-messageInput=\"message\"\n let-displayedActionsCountChaneHanler=\"displayedActionsCountChaneHanler\"\n let-isEditingChangeHandler=\"isEditingChangeHandler\"\n >\n <stream-message-actions-box\n [isOpen]=\"isOpen\"\n [isMine]=\"isMine\"\n [enabledActions]=\"enabledActions\"\n [message]=\"messageInput\"\n (displayedActionsCount)=\"\n displayedActionsCountChaneHanler($event)\n \"\n (isEditing)=\"isEditingChangeHandler($event)\"\n ></stream-message-actions-box>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n messageActionsBoxTemplate || defaultMessageActionsBox;\n context: getMessageActionsBoxContext()\n \"\n ></ng-container>\n <stream-icon-placeholder\n *ngIf=\"visibleMessageActionsCount > 0\"\n data-testid=\"action-icon\"\n icon=\"action-icon\"\n (keyup.enter)=\"isActionBoxOpen = !isActionBoxOpen\"\n (click)=\"isActionBoxOpen = !isActionBoxOpen\"\n ></stream-icon-placeholder>\n </div>\n <!-- eslint-disable @angular-eslint/template/conditional-complexity -->\n <div\n *ngIf=\"\n enabledMessageActions.indexOf('send-reply') !== -1 &&\n mode === 'main'\n \"\n class=\"\n str-chat__message-simple__actions__action\n str-chat__message-simple__actions__action--thread\n \"\n data-testid=\"reply-in-thread\"\n (click)=\"setAsActiveParentMessage()\"\n (keyup.enter)=\"setAsActiveParentMessage()\"\n >\n <stream-icon-placeholder\n icon=\"reply-in-thread\"\n ></stream-icon-placeholder>\n </div>\n <div\n *ngIf=\"canReactToMessage\"\n class=\"\n str-chat__message-simple__actions__action\n str-chat__message-simple__actions__action--reactions\n \"\n data-testid=\"reaction-icon\"\n (click)=\"isReactionSelectorOpen = !isReactionSelectorOpen\"\n (keyup.enter)=\"isReactionSelectorOpen = !isReactionSelectorOpen\"\n >\n <stream-icon-placeholder\n icon=\"reaction-icon\"\n ></stream-icon-placeholder>\n </div>\n </div>\n <!-- eslint-enable @angular-eslint/template/conditional-complexity -->\n <ng-template\n #defaultMessageReactions\n let-messageReactionCounts=\"messageReactionCounts\"\n let-latestReactions=\"latestReactions\"\n let-isSelectorOpen=\"isSelectorOpen\"\n let-isSelectorOpenChangeHandler=\"isSelectorOpenChangeHandler\"\n let-messageId=\"messageId\"\n let-ownReactions=\"ownReactions\"\n >\n <stream-message-reactions\n [messageReactionCounts]=\"messageReactionCounts\"\n [latestReactions]=\"latestReactions\"\n [isSelectorOpen]=\"isSelectorOpen\"\n (isSelectorOpenChange)=\"isSelectorOpenChangeHandler($event)\"\n [messageId]=\"messageId\"\n [ownReactions]=\"ownReactions\"\n ></stream-message-reactions>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n messageReactionsTemplate || defaultMessageReactions;\n context: getMessageReactionsContext()\n \"\n ></ng-container>\n <ng-container *ngIf=\"hasAttachment && !message?.quoted_message\">\n <ng-template\n #defaultAttachments\n let-messageId=\"messageId\"\n let-attachments=\"attachments\"\n >\n <stream-attachment-list\n [messageId]=\"messageId\"\n [attachments]=\"attachments\"\n ></stream-attachment-list>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n attachmentListTemplate || defaultAttachments;\n context: getAttachmentListContext()\n \"\n ></ng-container>\n </ng-container>\n <div class=\"str-chat__message-text\" *ngIf=\"message?.text\">\n <div\n data-testid=\"inner-message\"\n class=\"\n str-chat__message-text-inner str-chat__message-simple-text-inner\n \"\n [class.str-chat__message-light-text-inner--has-attachment]=\"\n hasAttachment\n \"\n (click)=\"\n message?.status === 'failed' && message?.errorStatusCode !== 403\n ? resendMessage()\n : undefined\n \"\n (keyup.enter)=\"\n message?.status === 'failed' && message?.errorStatusCode !== 403\n ? resendMessage()\n : undefined\n \"\n >\n <ng-container *ngTemplateOutlet=\"quotedMessage\"></ng-container>\n <stream-attachment-list\n *ngIf=\"hasAttachment && message?.quoted_message\"\n [attachments]=\"message!.attachments!\"\n [messageId]=\"message!.id\"\n ></stream-attachment-list>\n <div\n data-testid=\"client-error-message\"\n *ngIf=\"message?.type === 'error'\"\n class=\"str-chat__simple-message--error-message\"\n >\n {{ \"streamChat.Error \u00B7 Unsent\" | translate }}\n </div>\n <div\n data-testid=\"error-message\"\n *ngIf=\"message?.status === 'failed'\"\n class=\"str-chat__simple-message--error-message\"\n >\n {{\n (message?.errorStatusCode === 403\n ? \"streamChat.Message Failed \u00B7 Unauthorized\"\n : \"streamChat.Message Failed \u00B7 Click to try again\"\n ) | translate\n }}\n </div>\n <div\n (click)=\"textClicked()\"\n (keyup.enter)=\"textClicked()\"\n data-testid=\"text\"\n >\n <p>\n <!-- eslint-disable-next-line @angular-eslint/template/use-track-by-function -->\n <ng-container *ngFor=\"let part of messageTextParts\">\n <span\n *ngIf=\"part.type === 'text'; else mention\"\n [innerHTML]=\"part.content\"\n ></span>\n <ng-template #mention>\n <ng-template #defaultMention let-content=\"content\">\n <b>{{ content }}</b>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n mentionTemplate || defaultMention;\n context: getMentionContext(part)\n \"\n ></ng-container>\n </ng-template>\n </ng-container>\n </p>\n </div>\n </div>\n </div>\n <div class=\"str-chat__message-simple-reply-button\">\n <button\n *ngIf=\"\n !!message?.reply_count &&\n mode !== 'thread' &&\n enabledMessageActions.indexOf('send-reply') !== -1\n \"\n class=\"str-chat__message-replies-count-button\"\n data-testid=\"reply-count-button\"\n (click)=\"setAsActiveParentMessage()\"\n >\n <stream-icon-placeholder icon=\"reply\"></stream-icon-placeholder>\n {{message?.reply_count === 1 ? ('streamChat.1 reply' | translate) : ('streamChat.{{ replyCount }}\n replies' | translate:replyCountParam)}}\n </button>\n </div>\n <div class=\"str-chat__message-data str-chat__message-simple-data\">\n <span\n data-testid=\"sender\"\n *ngIf=\"!isSentByCurrentUser\"\n class=\"str-chat__message-simple-name\"\n >\n {{ message?.user?.name ? message?.user?.name : message?.user?.id }}\n </span>\n <span data-testid=\"date\" class=\"str-chat__message-simple-timestamp\">\n {{ parsedDate }}\n </span>\n </div>\n </div>\n </ng-container>\n </ng-container>\n</div>\n\n<ng-template #sendingStatus>\n <span\n class=\"\n str-chat__message-simple-status str-chat__message-simple-status-angular\n \"\n data-testid=\"sending-indicator\"\n >\n <div class=\"str-chat__tooltip\">\n {{ \"streamChat.Sending...\" | translate }}\n </div>\n <stream-loading-indicator-placeholder\n data-testid=\"loading-indicator\"\n ></stream-loading-indicator-placeholder>\n </span>\n</ng-template>\n<ng-template #readStatus>\n <span\n class=\"\n str-chat__message-simple-status str-chat__message-simple-status-angular\n \"\n data-testid=\"read-indicator\"\n >\n <div class=\"str-chat__tooltip\" data-testid=\"read-by-tooltip\">\n {{ readByText }}\n </div>\n <stream-avatar-placeholder\n class=\"str-chat-angular__avatar-host\"\n data-test-id=\"last-read-user-avatar\"\n [size]=\"15\"\n [imageUrl]=\"lastReadUser?.image\"\n [name]=\"lastReadUser?.name || lastReadUser?.id\"\n ></stream-avatar-placeholder>\n <span\n data-test-id=\"read-by-length\"\n *ngIf=\"isReadByMultipleUsers\"\n class=\"str-chat__message-simple-status-number\"\n >\n {{ (message?.readBy)!.length }}\n </span>\n </span>\n</ng-template>\n<ng-template #deliveredStatus>\n <span\n *ngIf=\"mode === 'main'\"\n class=\"\n str-chat__message-simple-status str-chat__message-simple-status-angular\n \"\n data-testid=\"delivered-indicator\"\n >\n <div class=\"str-chat__tooltip\">\n {{ \"streamChat.Delivered\" | translate }}\n </div>\n <stream-icon-placeholder\n data-testid=\"delivered-icon\"\n icon=\"delivered-icon\"\n ></stream-icon-placeholder>\n </span>\n</ng-template>\n\n<ng-template #deletedMessage>\n <div data-testid=\"message-deleted-component\">\n <div class=\"str-chat__message--deleted-inner\" translate>\n streamChat.This message was deleted...\n </div>\n </div>\n</ng-template>\n\n<ng-template #systemMessage>\n <div data-testid=\"system-message\" class=\"str-chat__message--system\">\n <div class=\"str-chat__message--system__text\">\n <div class=\"str-chat__message--system__line\"></div>\n <p>{{ message?.text }}</p>\n <div class=\"str-chat__message--system__line\"></div>\n </div>\n <div class=\"str-chat__message--system__date\">\n {{ parsedDate }}\n </div>\n </div>\n</ng-template>\n\n<ng-template #quotedMessage>\n <div\n *ngIf=\"message?.quoted_message\"\n class=\"quoted-message\"\n data-testid=\"quoted-message-container\"\n [class.mine]=\"isSentByCurrentUser\"\n >\n <stream-avatar-placeholder\n data-testid=\"qouted-message-avatar\"\n class=\"str-chat-angular__avatar-host\"\n [imageUrl]=\"message?.quoted_message?.user?.image\"\n [name]=\"\n message?.quoted_message?.user?.name || message?.quoted_message?.user?.id\n \"\n [size]=\"20\"\n ></stream-avatar-placeholder>\n <div class=\"quoted-message-inner\">\n <stream-attachment-list\n *ngIf=\"\n message?.quoted_message?.attachments &&\n message?.quoted_message?.attachments?.length\n \"\n [attachments]=\"quotedMessageAttachments\"\n [messageId]=\"message?.quoted_message?.id\"\n ></stream-attachment-list>\n <div\n data-testid=\"quoted-message-text\"\n [innerHTML]=\"\n message?.quoted_message?.html || message?.quoted_message?.text\n \"\n ></div>\n </div>\n </div>\n</ng-template>\n", components: [{ type: AvatarPlaceholderComponent, selector: "stream-avatar-placeholder", inputs: ["name", "imageUrl", "size"] }, { type: MessageActionsBoxComponent, selector: "stream-message-actions-box", inputs: ["isOpen", "isMine", "message", "enabledActions"], outputs: ["displayedActionsCount", "isEditing"] }, { type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon", "size"] }, { type: MessageReactionsComponent, selector: "stream-message-reactions", inputs: ["messageId", "messageReactionCounts", "isSelectorOpen", "latestReactions", "ownReactions"], outputs: ["isSelectorOpenChange"] }, { type: AttachmentListComponent, selector: "stream-attachment-list", inputs: ["messageId", "attachments"] }, { type: LoadingIndicatorPlaceholderComponent, selector: "stream-loading-indicator-placeholder", inputs: ["size", "color"] }], directives: [{ type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }], pipes: { "translate": i2.TranslatePipe } });
|
|
3152
3551
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: MessageComponent, decorators: [{
|
|
3153
3552
|
type: Component,
|
|
3154
3553
|
args: [{
|
|
@@ -3156,11 +3555,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
3156
3555
|
templateUrl: './message.component.html',
|
|
3157
3556
|
styles: [],
|
|
3158
3557
|
}]
|
|
3159
|
-
}], ctorParameters: function () { return [{ type: ChatClientService }, { type: ChannelService }]; }, propDecorators: {
|
|
3160
|
-
type: Input
|
|
3161
|
-
}], mentionTemplate: [{
|
|
3162
|
-
type: Input
|
|
3163
|
-
}], message: [{
|
|
3558
|
+
}], ctorParameters: function () { return [{ type: ChatClientService }, { type: ChannelService }, { type: CustomTemplatesService }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { message: [{
|
|
3164
3559
|
type: Input
|
|
3165
3560
|
}], enabledMessageActions: [{
|
|
3166
3561
|
type: Input
|
|
@@ -3264,11 +3659,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
3264
3659
|
* The `AutocompleteTextarea` component is used by the [`MessageInput`](./MessageInputComponent.mdx) component to display the input HTML element where users can type their message.
|
|
3265
3660
|
*/
|
|
3266
3661
|
class AutocompleteTextareaComponent {
|
|
3267
|
-
constructor(channelService, chatClientService, transliterationService, emojiInputService) {
|
|
3662
|
+
constructor(channelService, chatClientService, transliterationService, emojiInputService, customTemplatesService) {
|
|
3268
3663
|
this.channelService = channelService;
|
|
3269
3664
|
this.chatClientService = chatClientService;
|
|
3270
3665
|
this.transliterationService = transliterationService;
|
|
3271
3666
|
this.emojiInputService = emojiInputService;
|
|
3667
|
+
this.customTemplatesService = customTemplatesService;
|
|
3272
3668
|
this.class = 'str-chat__textarea';
|
|
3273
3669
|
/**
|
|
3274
3670
|
* The value of the input HTML element.
|
|
@@ -3344,6 +3740,8 @@ class AutocompleteTextareaComponent {
|
|
|
3344
3740
|
selectionStart + emoji.length;
|
|
3345
3741
|
this.inputChanged();
|
|
3346
3742
|
}));
|
|
3743
|
+
this.subscriptions.push(this.customTemplatesService.mentionAutocompleteItemTemplate$.subscribe((template) => (this.mentionAutocompleteItemTemplate = template)));
|
|
3744
|
+
this.subscriptions.push(this.customTemplatesService.commandAutocompleteItemTemplate$.subscribe((template) => (this.commandAutocompleteItemTemplate = template)));
|
|
3347
3745
|
this.autocompleteConfig.mentions = [
|
|
3348
3746
|
this.userMentionConfig,
|
|
3349
3747
|
this.slashCommandConfig,
|
|
@@ -3442,8 +3840,8 @@ class AutocompleteTextareaComponent {
|
|
|
3442
3840
|
}
|
|
3443
3841
|
}
|
|
3444
3842
|
}
|
|
3445
|
-
AutocompleteTextareaComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: AutocompleteTextareaComponent, deps: [{ token: ChannelService }, { token: ChatClientService }, { token: TransliterationService }, { token: EmojiInputService }], target: i0.ɵɵFactoryTarget.Component });
|
|
3446
|
-
AutocompleteTextareaComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: AutocompleteTextareaComponent, selector: "stream-autocomplete-textarea", inputs: { value: "value", areMentionsEnabled: "areMentionsEnabled",
|
|
3843
|
+
AutocompleteTextareaComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: AutocompleteTextareaComponent, deps: [{ token: ChannelService }, { token: ChatClientService }, { token: TransliterationService }, { token: EmojiInputService }, { token: CustomTemplatesService }], target: i0.ɵɵFactoryTarget.Component });
|
|
3844
|
+
AutocompleteTextareaComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: AutocompleteTextareaComponent, selector: "stream-autocomplete-textarea", inputs: { value: "value", areMentionsEnabled: "areMentionsEnabled", mentionScope: "mentionScope" }, outputs: { valueChange: "valueChange", send: "send", userMentions: "userMentions" }, host: { properties: { "class": "this.class" } }, viewQueries: [{ propertyName: "messageInput", first: true, predicate: ["input"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<textarea\n [value]=\"value || ''\"\n autofocus\n data-testid=\"textarea\"\n #input\n placeholder=\"{{ 'streamChat.Type your message' | translate }}\"\n class=\"rta__textarea str-chat__textarea__textarea str-chat__angular-textarea\"\n rows=\"1\"\n (input)=\"inputChanged()\"\n (keydown.enter)=\"sent($event)\"\n [mentionConfig]=\"autocompleteConfig\"\n (searchTerm)=\"autcompleteSearchTermChanged($event)\"\n [mentionListTemplate]=\"autocompleteItem\"\n (blur)=\"inputLeft()\"\n></textarea>\n<ng-template #autocompleteItem let-item=\"item\">\n <div class=\"rta rta__item str-chat__emojisearch__item\" [ngSwitch]=\"item.type\">\n <div class=\"rta__entity\" *ngSwitchCase=\"'mention'\">\n <ng-container\n *ngTemplateOutlet=\"\n mentionAutocompleteItemTemplate || defaultMentionTemplate;\n context: { item: item }\n \"\n ></ng-container>\n </div>\n <div class=\"rta__entity\" *ngSwitchCase=\"'command'\">\n <ng-container\n *ngTemplateOutlet=\"\n commandAutocompleteItemTemplate || defaultCommandTemplate;\n context: { item: item }\n \"\n ></ng-container>\n </div>\n </div>\n</ng-template>\n\n<ng-template #defaultCommandTemplate let-item=\"item\">\n <div class=\"str-chat__slash-command\">\n <span class=\"str-chat__slash-command-header\">\n <strong data-testclass=\"command-name\">{{ item.name }}</strong>\n {{ item.args }}\n </span>\n <br />\n <span class=\"str-chat__slash-command-description\">{{\n item.description\n }}</span>\n </div>\n</ng-template>\n\n<ng-template #defaultMentionTemplate let-item=\"item\">\n <div class=\"str-chat__user-item\">\n <stream-avatar-placeholder\n data-testclass=\"avatar\"\n class=\"str-chat__avatar str-chat__avatar--circle\"\n style=\"height: 20px\"\n [size]=\"20\"\n [imageUrl]=\"item.image || item.user?.image\"\n [name]=\"item.autocompleteLabel\"\n ></stream-avatar-placeholder>\n <span data-testclass=\"username\" class=\"str-chat__user-item--name\">{{\n item.autocompleteLabel\n }}</span>\n </div>\n</ng-template>\n", components: [{ type: AvatarPlaceholderComponent, selector: "stream-avatar-placeholder", inputs: ["name", "imageUrl", "size"] }], directives: [{ type: i7.MentionDirective, selector: "[mention], [mentionConfig]", inputs: ["mentionConfig", "mention", "mentionListTemplate"], outputs: ["searchTerm", "itemSelected", "opened", "closed"] }, { type: i3.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { type: i3.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], pipes: { "translate": i2.TranslatePipe } });
|
|
3447
3845
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: AutocompleteTextareaComponent, decorators: [{
|
|
3448
3846
|
type: Component,
|
|
3449
3847
|
args: [{
|
|
@@ -3451,16 +3849,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
3451
3849
|
templateUrl: './autocomplete-textarea.component.html',
|
|
3452
3850
|
styles: [],
|
|
3453
3851
|
}]
|
|
3454
|
-
}], ctorParameters: function () { return [{ type: ChannelService }, { type: ChatClientService }, { type: TransliterationService }, { type: EmojiInputService }]; }, propDecorators: { class: [{
|
|
3852
|
+
}], ctorParameters: function () { return [{ type: ChannelService }, { type: ChatClientService }, { type: TransliterationService }, { type: EmojiInputService }, { type: CustomTemplatesService }]; }, propDecorators: { class: [{
|
|
3455
3853
|
type: HostBinding
|
|
3456
3854
|
}], value: [{
|
|
3457
3855
|
type: Input
|
|
3458
3856
|
}], areMentionsEnabled: [{
|
|
3459
3857
|
type: Input
|
|
3460
|
-
}], mentionAutocompleteItemTemplate: [{
|
|
3461
|
-
type: Input
|
|
3462
|
-
}], commandAutocompleteItemTemplate: [{
|
|
3463
|
-
type: Input
|
|
3464
3858
|
}], mentionScope: [{
|
|
3465
3859
|
type: Input
|
|
3466
3860
|
}], valueChange: [{
|
|
@@ -3518,10 +3912,11 @@ const isOnSameDay = (date1, date2) => {
|
|
|
3518
3912
|
* The `MessageList` component renders a scrollable list of messages.
|
|
3519
3913
|
*/
|
|
3520
3914
|
class MessageListComponent {
|
|
3521
|
-
constructor(channelService, chatClientService, imageLoadService) {
|
|
3915
|
+
constructor(channelService, chatClientService, imageLoadService, customTemplatesService) {
|
|
3522
3916
|
this.channelService = channelService;
|
|
3523
3917
|
this.chatClientService = chatClientService;
|
|
3524
3918
|
this.imageLoadService = imageLoadService;
|
|
3919
|
+
this.customTemplatesService = customTemplatesService;
|
|
3525
3920
|
/**
|
|
3526
3921
|
* Determines if the message list should display channel messages or [thread messages](https://getstream.io/chat/docs/javascript/threads/?language=javascript).
|
|
3527
3922
|
*/
|
|
@@ -3558,6 +3953,8 @@ class MessageListComponent {
|
|
|
3558
3953
|
}
|
|
3559
3954
|
this.parentMessage = message;
|
|
3560
3955
|
}));
|
|
3956
|
+
this.subscriptions.push(this.customTemplatesService.messageTemplate$.subscribe((template) => (this.messageTemplate = template)));
|
|
3957
|
+
this.subscriptions.push(this.customTemplatesService.typingIndicatorTemplate$.subscribe((template) => (this.typingIndicatorTemplate = template)));
|
|
3561
3958
|
this.usersTypingInChannel$ = this.channelService.usersTypingInChannel$;
|
|
3562
3959
|
this.usersTypingInThread$ = this.channelService.usersTypingInThread$;
|
|
3563
3960
|
}
|
|
@@ -3596,11 +3993,6 @@ class MessageListComponent {
|
|
|
3596
3993
|
ngOnDestroy() {
|
|
3597
3994
|
this.subscriptions.forEach((s) => s.unsubscribe());
|
|
3598
3995
|
}
|
|
3599
|
-
get usersTyping$() {
|
|
3600
|
-
return this.mode === 'thread'
|
|
3601
|
-
? this.usersTypingInThread$
|
|
3602
|
-
: this.usersTypingInChannel$;
|
|
3603
|
-
}
|
|
3604
3996
|
trackByMessageId(index, item) {
|
|
3605
3997
|
return item.id;
|
|
3606
3998
|
}
|
|
@@ -3633,6 +4025,19 @@ class MessageListComponent {
|
|
|
3633
4025
|
}
|
|
3634
4026
|
this.prevScrollTop = this.scrollContainer.nativeElement.scrollTop;
|
|
3635
4027
|
}
|
|
4028
|
+
getTypingIndicatorContext() {
|
|
4029
|
+
return {
|
|
4030
|
+
usersTyping$: this.usersTyping$,
|
|
4031
|
+
};
|
|
4032
|
+
}
|
|
4033
|
+
getMessageContext(message) {
|
|
4034
|
+
return {
|
|
4035
|
+
message,
|
|
4036
|
+
isLastSentMessage: !!(this.lastSentMessageId && (message === null || message === void 0 ? void 0 : message.id) === this.lastSentMessageId),
|
|
4037
|
+
enabledMessageActions: this.enabledMessageActions,
|
|
4038
|
+
mode: this.mode,
|
|
4039
|
+
};
|
|
4040
|
+
}
|
|
3636
4041
|
preserveScrollbarPosition() {
|
|
3637
4042
|
this.scrollContainer.nativeElement.scrollTop =
|
|
3638
4043
|
(this.prevScrollTop || 0) +
|
|
@@ -3690,9 +4095,14 @@ class MessageListComponent {
|
|
|
3690
4095
|
this.prevScrollTop = undefined;
|
|
3691
4096
|
this.isNewMessageSentByUser = undefined;
|
|
3692
4097
|
}
|
|
4098
|
+
get usersTyping$() {
|
|
4099
|
+
return this.mode === 'thread'
|
|
4100
|
+
? this.usersTypingInThread$
|
|
4101
|
+
: this.usersTypingInChannel$;
|
|
4102
|
+
}
|
|
3693
4103
|
}
|
|
3694
|
-
MessageListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: MessageListComponent, deps: [{ token: ChannelService }, { token: ChatClientService }, { token: ImageLoadService }], target: i0.ɵɵFactoryTarget.Component });
|
|
3695
|
-
MessageListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: MessageListComponent, selector: "stream-message-list", inputs: {
|
|
4104
|
+
MessageListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: MessageListComponent, deps: [{ token: ChannelService }, { token: ChatClientService }, { token: ImageLoadService }, { token: CustomTemplatesService }], target: i0.ɵɵFactoryTarget.Component });
|
|
4105
|
+
MessageListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: MessageListComponent, selector: "stream-message-list", inputs: { mode: "mode" }, host: { properties: { "class": "this.class" } }, viewQueries: [{ propertyName: "scrollContainer", first: true, predicate: ["scrollContainer"], descendants: true }, { propertyName: "parentMessageElement", first: true, predicate: ["parentMessageElement"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div\n #scrollContainer\n data-testid=\"scroll-container\"\n class=\"str-chat__list\"\n (scroll)=\"scrolled()\"\n>\n <div class=\"str-chat__reverse-infinite-scroll\">\n <ul class=\"str-chat__ul\">\n <li\n #parentMessageElement\n *ngIf=\"mode === 'thread'\"\n data-testid=\"parent-message\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n messageTemplateContainer;\n context: { message: parentMessage }\n \"\n ></ng-container>\n <div class=\"str-chat__thread-start\" translate>\n streamChat.Start of a new thread\n </div>\n </li>\n <li\n data-testclass=\"message\"\n *ngFor=\"\n let message of messages$ | async;\n let i = index;\n trackBy: trackByMessageId\n \"\n class=\"str-chat__li str-chat__li--{{ groupStyles[i] }}\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n messageTemplateContainer;\n context: { message: message }\n \"\n ></ng-container>\n </li>\n </ul>\n <ng-template #defaultTypingIndicator let-usersTyping$=\"usersTyping$\">\n <div\n *ngIf=\"$any(usersTyping$ | async)?.length\"\n data-testid=\"typing-indicator\"\n class=\"str-chat__typing-indicator str-chat__typing-indicator--typing\"\n >\n <stream-avatar-placeholder\n *ngFor=\"let user of usersTyping$ | async; trackBy: trackByUserId\"\n [name]=\"user.name || user.id\"\n [imageUrl]=\"user.image\"\n ></stream-avatar-placeholder>\n <div class=\"str-chat__typing-indicator__dots\">\n <span class=\"str-chat__typing-indicator__dot\"></span>\n <span class=\"str-chat__typing-indicator__dot\"></span>\n <span class=\"str-chat__typing-indicator__dot\"></span>\n </div>\n </div>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n typingIndicatorTemplate || defaultTypingIndicator;\n context: getTypingIndicatorContext()\n \"\n ></ng-container>\n </div>\n</div>\n<div class=\"str-chat__list-notifications\">\n <button\n data-testid=\"scroll-to-bottom\"\n *ngIf=\"isUserScrolledUp\"\n class=\"\n str-chat__message-notification\n str-chat__message-notification-right\n str-chat__message-notification-scroll-down\n \"\n (keyup.enter)=\"scrollToBottom()\"\n (click)=\"scrollToBottom()\"\n >\n <div\n *ngIf=\"unreadMessageCount > 0\"\n class=\"\n str-chat__message-notification\n str-chat__message-notification-scroll-down-unread-count\n \"\n >\n {{ unreadMessageCount }}\n </div>\n </button>\n</div>\n\n<ng-template #messageTemplateContainer let-message=\"message\">\n <ng-template\n #defaultMessageTemplate\n let-messageInput=\"message\"\n let-isLastSentMessage=\"isLastSentMessage\"\n let-enabledMessageActions=\"enabledMessageActions\"\n let-mode=\"mode\"\n >\n <stream-message\n [message]=\"messageInput\"\n [isLastSentMessage]=\"isLastSentMessage\"\n [enabledMessageActions]=\"enabledMessageActions\"\n [mode]=\"mode\"\n ></stream-message>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n messageTemplate || defaultMessageTemplate;\n context: getMessageContext(message)\n \"\n ></ng-container>\n</ng-template>\n", components: [{ type: AvatarPlaceholderComponent, selector: "stream-avatar-placeholder", inputs: ["name", "imageUrl", "size"] }, { type: MessageComponent, selector: "stream-message", inputs: ["message", "enabledMessageActions", "isLastSentMessage", "mode"] }], directives: [{ type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i2.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], pipes: { "async": i3.AsyncPipe } });
|
|
3696
4106
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: MessageListComponent, decorators: [{
|
|
3697
4107
|
type: Component,
|
|
3698
4108
|
args: [{
|
|
@@ -3700,15 +4110,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
3700
4110
|
templateUrl: './message-list.component.html',
|
|
3701
4111
|
styles: [],
|
|
3702
4112
|
}]
|
|
3703
|
-
}], ctorParameters: function () { return [{ type: ChannelService }, { type: ChatClientService }, { type: ImageLoadService }]; }, propDecorators: {
|
|
3704
|
-
type: Input
|
|
3705
|
-
}], messageInputTemplate: [{
|
|
3706
|
-
type: Input
|
|
3707
|
-
}], mentionTemplate: [{
|
|
3708
|
-
type: Input
|
|
3709
|
-
}], typingIndicatorTemplate: [{
|
|
3710
|
-
type: Input
|
|
3711
|
-
}], mode: [{
|
|
4113
|
+
}], ctorParameters: function () { return [{ type: ChannelService }, { type: ChatClientService }, { type: ImageLoadService }, { type: CustomTemplatesService }]; }, propDecorators: { mode: [{
|
|
3712
4114
|
type: Input
|
|
3713
4115
|
}], class: [{
|
|
3714
4116
|
type: HostBinding,
|
|
@@ -3725,7 +4127,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
3725
4127
|
* The `Thread` component represents a [message thread](https://getstream.io/chat/docs/javascript/threads/?language=javascript), it is a container component that displays a thread with a header, [`MessageList`](./MessageListComponent.mdx) and [`MessageInput`](./MessageInputComponent.mdx) components.
|
|
3726
4128
|
*/
|
|
3727
4129
|
class ThreadComponent {
|
|
3728
|
-
constructor(channelService) {
|
|
4130
|
+
constructor(customTemplatesService, channelService) {
|
|
4131
|
+
this.customTemplatesService = customTemplatesService;
|
|
3729
4132
|
this.channelService = channelService;
|
|
3730
4133
|
this.class = 'str-chat__thread';
|
|
3731
4134
|
this.subscriptions = [];
|
|
@@ -3734,16 +4137,21 @@ class ThreadComponent {
|
|
|
3734
4137
|
ngOnDestroy() {
|
|
3735
4138
|
this.subscriptions.forEach((s) => s.unsubscribe());
|
|
3736
4139
|
}
|
|
3737
|
-
|
|
3738
|
-
|
|
3739
|
-
|
|
4140
|
+
getThreadHeaderContext() {
|
|
4141
|
+
return {
|
|
4142
|
+
parentMessage: this.parentMessage,
|
|
4143
|
+
closeThreadHandler: () => this.closeThread(),
|
|
4144
|
+
};
|
|
4145
|
+
}
|
|
4146
|
+
getReplyCountParam(parentMessage) {
|
|
4147
|
+
return { replyCount: parentMessage === null || parentMessage === void 0 ? void 0 : parentMessage.reply_count };
|
|
3740
4148
|
}
|
|
3741
4149
|
closeThread() {
|
|
3742
4150
|
void this.channelService.setAsActiveParentMessage(undefined);
|
|
3743
4151
|
}
|
|
3744
4152
|
}
|
|
3745
|
-
ThreadComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ThreadComponent, deps: [{ token: ChannelService }], target: i0.ɵɵFactoryTarget.Component });
|
|
3746
|
-
ThreadComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: ThreadComponent, selector: "stream-thread", host: { properties: { "class": "this.class" } }, ngImport: i0, template: "<div class=\"str-chat__thread-header\">\n
|
|
4153
|
+
ThreadComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ThreadComponent, deps: [{ token: CustomTemplatesService }, { token: ChannelService }], target: i0.ɵɵFactoryTarget.Component });
|
|
4154
|
+
ThreadComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: ThreadComponent, selector: "stream-thread", host: { properties: { "class": "this.class" } }, ngImport: i0, template: "<ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.threadHeaderTemplate$ | async) ||\n defaultThreadHeader;\n context: getThreadHeaderContext()\n \"\n></ng-container>\n<ng-content select='[name=\"thread-message-list\"]'></ng-content>\n<div class=\"str-chat__small-message-input__wrapper\">\n <ng-content select='[name=\"thread-message-input\"]'></ng-content>\n</div>\n\n<ng-template\n #defaultThreadHeader\n let-parentMessage=\"parentMessage\"\n let-closeThreadHandler=\"closeThreadHandler\"\n>\n <div class=\"str-chat__thread-header\">\n <div class=\"str-chat__thread-header-details\">\n <strong translate>streamChat.Thread</strong>\n <small data-testid=\"reply-count\">\n {{parentMessage?.reply_count === 1 ? ('streamChat.1 reply' | translate) : ('streamChat.{{ replyCount }}\n replies' | translate:getReplyCountParam(parentMessage))}}\n </small>\n </div>\n <button\n class=\"str-chat__square-button\"\n data-testid=\"close-button\"\n (click)=\"closeThreadHandler()\"\n >\n <stream-icon-placeholder\n icon=\"close-no-outline\"\n ></stream-icon-placeholder>\n </button>\n </div>\n</ng-template>\n", components: [{ type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon", "size"] }], directives: [{ type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i2.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }], pipes: { "async": i3.AsyncPipe, "translate": i2.TranslatePipe } });
|
|
3747
4155
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ThreadComponent, decorators: [{
|
|
3748
4156
|
type: Component,
|
|
3749
4157
|
args: [{
|
|
@@ -3751,7 +4159,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
3751
4159
|
templateUrl: './thread.component.html',
|
|
3752
4160
|
styles: [],
|
|
3753
4161
|
}]
|
|
3754
|
-
}], ctorParameters: function () { return [{ type: ChannelService }]; }, propDecorators: { class: [{
|
|
4162
|
+
}], ctorParameters: function () { return [{ type: CustomTemplatesService }, { type: ChannelService }]; }, propDecorators: { class: [{
|
|
3755
4163
|
type: HostBinding,
|
|
3756
4164
|
args: ['class']
|
|
3757
4165
|
}] } });
|
|
@@ -3759,14 +4167,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
3759
4167
|
class StreamAvatarModule {
|
|
3760
4168
|
}
|
|
3761
4169
|
StreamAvatarModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: StreamAvatarModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
3762
|
-
StreamAvatarModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: StreamAvatarModule, declarations: [AvatarComponent], imports: [CommonModule, TranslateModule], exports: [AvatarComponent] });
|
|
4170
|
+
StreamAvatarModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: StreamAvatarModule, declarations: [AvatarComponent, AvatarPlaceholderComponent], imports: [CommonModule, TranslateModule], exports: [AvatarComponent, AvatarPlaceholderComponent] });
|
|
3763
4171
|
StreamAvatarModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: StreamAvatarModule, imports: [[CommonModule, TranslateModule]] });
|
|
3764
4172
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: StreamAvatarModule, decorators: [{
|
|
3765
4173
|
type: NgModule,
|
|
3766
4174
|
args: [{
|
|
3767
|
-
declarations: [AvatarComponent],
|
|
4175
|
+
declarations: [AvatarComponent, AvatarPlaceholderComponent],
|
|
3768
4176
|
imports: [CommonModule, TranslateModule],
|
|
3769
|
-
exports: [AvatarComponent],
|
|
4177
|
+
exports: [AvatarComponent, AvatarPlaceholderComponent],
|
|
3770
4178
|
}]
|
|
3771
4179
|
}] });
|
|
3772
4180
|
|
|
@@ -3790,7 +4198,9 @@ StreamChatModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", versio
|
|
|
3790
4198
|
AttachmentPreviewListComponent,
|
|
3791
4199
|
ModalComponent,
|
|
3792
4200
|
TextareaDirective,
|
|
3793
|
-
ThreadComponent
|
|
4201
|
+
ThreadComponent,
|
|
4202
|
+
IconPlaceholderComponent,
|
|
4203
|
+
LoadingIndicatorPlaceholderComponent], imports: [CommonModule, TranslateModule, StreamAvatarModule], exports: [ChannelComponent,
|
|
3794
4204
|
ChannelHeaderComponent,
|
|
3795
4205
|
ChannelListComponent,
|
|
3796
4206
|
ChannelPreviewComponent,
|
|
@@ -3807,7 +4217,9 @@ StreamChatModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", versio
|
|
|
3807
4217
|
AttachmentPreviewListComponent,
|
|
3808
4218
|
ModalComponent,
|
|
3809
4219
|
StreamAvatarModule,
|
|
3810
|
-
ThreadComponent
|
|
4220
|
+
ThreadComponent,
|
|
4221
|
+
IconPlaceholderComponent,
|
|
4222
|
+
LoadingIndicatorPlaceholderComponent] });
|
|
3811
4223
|
StreamChatModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: StreamChatModule, imports: [[CommonModule, TranslateModule, StreamAvatarModule], StreamAvatarModule] });
|
|
3812
4224
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: StreamChatModule, decorators: [{
|
|
3813
4225
|
type: NgModule,
|
|
@@ -3831,6 +4243,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
3831
4243
|
ModalComponent,
|
|
3832
4244
|
TextareaDirective,
|
|
3833
4245
|
ThreadComponent,
|
|
4246
|
+
IconPlaceholderComponent,
|
|
4247
|
+
LoadingIndicatorPlaceholderComponent,
|
|
3834
4248
|
],
|
|
3835
4249
|
imports: [CommonModule, TranslateModule, StreamAvatarModule],
|
|
3836
4250
|
exports: [
|
|
@@ -3852,6 +4266,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
3852
4266
|
ModalComponent,
|
|
3853
4267
|
StreamAvatarModule,
|
|
3854
4268
|
ThreadComponent,
|
|
4269
|
+
IconPlaceholderComponent,
|
|
4270
|
+
LoadingIndicatorPlaceholderComponent,
|
|
3855
4271
|
],
|
|
3856
4272
|
}]
|
|
3857
4273
|
}] });
|
|
@@ -3914,5 +4330,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
3914
4330
|
* Generated bundle index. Do not edit.
|
|
3915
4331
|
*/
|
|
3916
4332
|
|
|
3917
|
-
export { AttachmentListComponent, AttachmentPreviewListComponent, AttachmentService, AutocompleteTextareaComponent, AvatarComponent, ChannelComponent, ChannelHeaderComponent, ChannelListComponent, ChannelListToggleService, ChannelPreviewComponent, ChannelService, ChatClientService, EmojiInputService, IconComponent, ImageLoadService, LoadingIndicatorComponent, MessageActionsBoxComponent, MessageComponent, MessageInputComponent, MessageInputConfigService, MessageListComponent, MessageReactionsComponent, ModalComponent, NotificationComponent, NotificationListComponent, NotificationService, StreamAutocompleteTextareaModule, StreamAvatarModule, StreamChatModule, StreamI18nService, StreamTextareaModule, TextareaComponent, TextareaDirective, ThemeService, ThreadComponent, TransliterationService, createMessagePreview, getDeviceWidth, getGroupStyles, getReadBy, getReadByText, isImageAttachment, isImageFile, parseDate, textareaInjectionToken };
|
|
4333
|
+
export { AttachmentListComponent, AttachmentPreviewListComponent, AttachmentService, AutocompleteTextareaComponent, AvatarComponent, AvatarPlaceholderComponent, ChannelComponent, ChannelHeaderComponent, ChannelListComponent, ChannelListToggleService, ChannelPreviewComponent, ChannelService, ChatClientService, CustomTemplatesService, EmojiInputService, IconComponent, IconPlaceholderComponent, ImageLoadService, LoadingIndicatorComponent, LoadingIndicatorPlaceholderComponent, MessageActionsBoxComponent, MessageComponent, MessageInputComponent, MessageInputConfigService, MessageListComponent, MessageReactionsComponent, ModalComponent, NotificationComponent, NotificationListComponent, NotificationService, StreamAutocompleteTextareaModule, StreamAvatarModule, StreamChatModule, StreamI18nService, StreamTextareaModule, TextareaComponent, TextareaDirective, ThemeService, ThreadComponent, TransliterationService, createMessagePreview, getDeviceWidth, getGroupStyles, getReadBy, getReadByText, isImageAttachment, isImageFile, parseDate, textareaInjectionToken };
|
|
3918
4334
|
//# sourceMappingURL=stream-chat-angular.js.map
|