stream-chat-angular 2.21.0 → 3.0.0-beta.11
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 +796 -566
- 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 -12
- 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 +40 -64
- package/esm2015/lib/chat-client.service.js +5 -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 +74 -29
- 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 +56 -45
- 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 +32 -93
- 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 +12 -10
- 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 +735 -478
- 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 +15 -12
- 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 +33 -38
- package/lib/chat-client.service.d.ts +12 -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 +42 -30
- package/lib/message-actions-box/message-actions-box.component.d.ts +22 -26
- package/lib/message-input/autocomplete-textarea/autocomplete-textarea.component.d.ts +7 -11
- package/lib/message-input/message-input-config.service.d.ts +0 -19
- package/lib/message-input/message-input.component.d.ts +40 -26
- 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 -34
- 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 +6 -1
- package/lib/notification-list/notification-list.component.d.ts +4 -2
- 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 +115 -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 = '
|
|
20
|
+
const version = '3.0.0-beta.11';
|
|
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.
|
|
@@ -106,7 +106,7 @@ class ChatClientService {
|
|
|
106
106
|
this.connectionStateSubject = new ReplaySubject(1);
|
|
107
107
|
this.appSettingsSubject = new BehaviorSubject(undefined);
|
|
108
108
|
this.pendingInvitesSubject = new BehaviorSubject([]);
|
|
109
|
-
this.
|
|
109
|
+
this.events$ = this.notificationSubject.asObservable();
|
|
110
110
|
this.connectionState$ = this.connectionStateSubject.asObservable();
|
|
111
111
|
this.appSettings$ = this.appSettingsSubject.asObservable();
|
|
112
112
|
this.pendingInvites$ = this.pendingInvitesSubject.asObservable();
|
|
@@ -127,7 +127,8 @@ class ChatClientService {
|
|
|
127
127
|
yield this.chatClient.connectUser(user, userTokenOrProvider);
|
|
128
128
|
this.chatClient.setUserAgent(`stream-chat-angular-${version}-${this.chatClient.getUserAgent()}`);
|
|
129
129
|
}));
|
|
130
|
-
const channels = yield this.chatClient.queryChannels({ invite: 'pending' },
|
|
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 });
|
|
131
132
|
this.pendingInvitesSubject.next(channels);
|
|
132
133
|
this.appSettingsSubject.next(undefined);
|
|
133
134
|
this.chatClient.on((e) => {
|
|
@@ -201,7 +202,7 @@ class ChatClientService {
|
|
|
201
202
|
{ name: { $autocomplete: searchTerm } },
|
|
202
203
|
],
|
|
203
204
|
id: { $ne: this.chatClient.userID },
|
|
204
|
-
});
|
|
205
|
+
}); // TODO: find out why we need this typecast
|
|
205
206
|
return result.users;
|
|
206
207
|
});
|
|
207
208
|
}
|
|
@@ -232,23 +233,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
232
233
|
}]
|
|
233
234
|
}], ctorParameters: function () { return [{ type: i0.NgZone }, { type: NotificationService }]; } });
|
|
234
235
|
|
|
235
|
-
const createMessagePreview = (user, text, attachments = [], mentionedUsers = [], parentId = undefined, quotedMessageId = undefined) => {
|
|
236
|
+
const createMessagePreview = (user, text, attachments = [], mentionedUsers = [], parentId = undefined, quotedMessageId = undefined, customData) => {
|
|
236
237
|
const clientSideId = `${user.id}-${v4()}`;
|
|
237
|
-
return {
|
|
238
|
-
|
|
239
|
-
created_at: new Date(),
|
|
240
|
-
html: text,
|
|
241
|
-
id: clientSideId,
|
|
242
|
-
reactions: [],
|
|
243
|
-
status: 'sending',
|
|
244
|
-
text,
|
|
245
|
-
type: 'regular',
|
|
246
|
-
user,
|
|
247
|
-
attachments,
|
|
248
|
-
mentioned_users: mentionedUsers,
|
|
249
|
-
parent_id: parentId,
|
|
250
|
-
quoted_message_id: quotedMessageId,
|
|
251
|
-
};
|
|
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);
|
|
252
240
|
};
|
|
253
241
|
|
|
254
242
|
const getReadBy = (message, channel) => {
|
|
@@ -265,7 +253,7 @@ const getReadBy = (message, channel) => {
|
|
|
265
253
|
};
|
|
266
254
|
|
|
267
255
|
/**
|
|
268
|
-
* The `ChannelService` provides data and interaction for the channel list and message list.
|
|
256
|
+
* The `ChannelService` provides data and interaction for the channel list and message list.
|
|
269
257
|
*/
|
|
270
258
|
class ChannelService {
|
|
271
259
|
constructor(chatClientService, ngZone) {
|
|
@@ -358,21 +346,6 @@ class ChannelService {
|
|
|
358
346
|
this.activeThreadMessagesSubject.next([]);
|
|
359
347
|
this.messageToQuoteSubject.next(undefined);
|
|
360
348
|
}
|
|
361
|
-
/**
|
|
362
|
-
* Deselects the currently active (if any) channel
|
|
363
|
-
*/
|
|
364
|
-
deselectActiveChannel() {
|
|
365
|
-
const activeChannel = this.activeChannelSubject.getValue();
|
|
366
|
-
if (!activeChannel) {
|
|
367
|
-
return;
|
|
368
|
-
}
|
|
369
|
-
this.activeChannelMessagesSubject.next([]);
|
|
370
|
-
this.activeChannelSubject.next(undefined);
|
|
371
|
-
this.activeParentMessageIdSubject.next(undefined);
|
|
372
|
-
this.activeThreadMessagesSubject.next([]);
|
|
373
|
-
this.latestMessageDateByUserByChannelsSubject.next({});
|
|
374
|
-
this.selectMessageToQuote(undefined);
|
|
375
|
-
}
|
|
376
349
|
/**
|
|
377
350
|
* Sets the given `message` as an active parent message. If `undefined` is provided, it will deleselect the current parent message.
|
|
378
351
|
* @param message
|
|
@@ -443,10 +416,8 @@ class ChannelService {
|
|
|
443
416
|
* @param filters
|
|
444
417
|
* @param sort
|
|
445
418
|
* @param options
|
|
446
|
-
* @param shouldSetActiveChannel Decides if the first channel in the result should be made as an active channel, or no channel should be marked as active
|
|
447
|
-
* @returns the list of channels found by the query
|
|
448
419
|
*/
|
|
449
|
-
init(filters, sort, options
|
|
420
|
+
init(filters, sort, options) {
|
|
450
421
|
return __awaiter(this, void 0, void 0, function* () {
|
|
451
422
|
this.filters = filters;
|
|
452
423
|
this.options = options || {
|
|
@@ -458,17 +429,21 @@ class ChannelService {
|
|
|
458
429
|
message_limit: this.messagePageSize,
|
|
459
430
|
};
|
|
460
431
|
this.sort = sort || { last_message_at: -1, updated_at: -1 };
|
|
461
|
-
|
|
462
|
-
this.chatClientService.
|
|
463
|
-
return result;
|
|
432
|
+
yield this.queryChannels();
|
|
433
|
+
this.chatClientService.events$.subscribe((notification) => void this.handleNotification(notification));
|
|
464
434
|
});
|
|
465
435
|
}
|
|
466
436
|
/**
|
|
467
437
|
* Resets the `activeChannel$`, `channels$` and `activeChannelMessages$` Observables. Useful when disconnecting a chat user, use in combination with [`disconnectUser`](./ChatClientService.mdx/#disconnectuser).
|
|
468
438
|
*/
|
|
469
439
|
reset() {
|
|
470
|
-
this.
|
|
440
|
+
this.activeChannelMessagesSubject.next([]);
|
|
441
|
+
this.activeChannelSubject.next(undefined);
|
|
442
|
+
this.activeParentMessageIdSubject.next(undefined);
|
|
443
|
+
this.activeThreadMessagesSubject.next([]);
|
|
471
444
|
this.channelsSubject.next(undefined);
|
|
445
|
+
this.latestMessageDateByUserByChannelsSubject.next({});
|
|
446
|
+
this.selectMessageToQuote(undefined);
|
|
472
447
|
}
|
|
473
448
|
/**
|
|
474
449
|
* Loads the next page of channels. The page size can be set in the [query option](https://getstream.io/chat/docs/javascript/query_channels/?language=javascript#query-options) object.
|
|
@@ -476,20 +451,19 @@ class ChannelService {
|
|
|
476
451
|
loadMoreChannels() {
|
|
477
452
|
return __awaiter(this, void 0, void 0, function* () {
|
|
478
453
|
this.options.offset = this.channels.length;
|
|
479
|
-
yield this.queryChannels(
|
|
454
|
+
yield this.queryChannels();
|
|
480
455
|
});
|
|
481
456
|
}
|
|
482
457
|
/**
|
|
483
458
|
* Adds a reaction to a message.
|
|
484
459
|
* @param messageId The id of the message to add the reaction to
|
|
485
460
|
* @param reactionType The type of the reaction
|
|
461
|
+
* @param customData
|
|
486
462
|
*/
|
|
487
|
-
addReaction(messageId, reactionType) {
|
|
463
|
+
addReaction(messageId, reactionType, customData) {
|
|
488
464
|
var _a;
|
|
489
465
|
return __awaiter(this, void 0, void 0, function* () {
|
|
490
|
-
yield ((_a = this.activeChannelSubject.getValue()) === null || _a === void 0 ? void 0 : _a.sendReaction(messageId, {
|
|
491
|
-
type: reactionType,
|
|
492
|
-
}));
|
|
466
|
+
yield ((_a = this.activeChannelSubject.getValue()) === null || _a === void 0 ? void 0 : _a.sendReaction(messageId, Object.assign({ type: reactionType }, customData)));
|
|
493
467
|
});
|
|
494
468
|
}
|
|
495
469
|
/**
|
|
@@ -511,14 +485,15 @@ class ChannelService {
|
|
|
511
485
|
* @param mentionedUsers Mentioned users
|
|
512
486
|
* @param parentId Id of the parent message (if sending a thread reply)
|
|
513
487
|
* @param quotedMessageId Id of the message to quote (if sending a quote reply)
|
|
488
|
+
* @param customData
|
|
514
489
|
*/
|
|
515
|
-
sendMessage(text, attachments = [], mentionedUsers = [], parentId = undefined, quotedMessageId = undefined) {
|
|
490
|
+
sendMessage(text, attachments = [], mentionedUsers = [], parentId = undefined, quotedMessageId = undefined, customData = undefined) {
|
|
516
491
|
return __awaiter(this, void 0, void 0, function* () {
|
|
517
|
-
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);
|
|
518
493
|
const channel = this.activeChannelSubject.getValue();
|
|
519
494
|
preview.readBy = [];
|
|
520
495
|
channel.state.addMessageSorted(preview, true);
|
|
521
|
-
yield this.sendMessageRequest(preview);
|
|
496
|
+
yield this.sendMessageRequest(preview, customData);
|
|
522
497
|
});
|
|
523
498
|
}
|
|
524
499
|
/**
|
|
@@ -613,7 +588,7 @@ class ChannelService {
|
|
|
613
588
|
const result = yield activeChannel.queryMembers({
|
|
614
589
|
name: { $autocomplete: searchTerm },
|
|
615
590
|
id: { $ne: this.chatClientService.chatClient.userID },
|
|
616
|
-
});
|
|
591
|
+
}); // TODO: find out why we need typecast here
|
|
617
592
|
return Object.values(result.members);
|
|
618
593
|
}
|
|
619
594
|
});
|
|
@@ -658,7 +633,7 @@ class ChannelService {
|
|
|
658
633
|
selectMessageToQuote(message) {
|
|
659
634
|
this.messageToQuoteSubject.next(message);
|
|
660
635
|
}
|
|
661
|
-
sendMessageRequest(preview) {
|
|
636
|
+
sendMessageRequest(preview, customData) {
|
|
662
637
|
var _a;
|
|
663
638
|
return __awaiter(this, void 0, void 0, function* () {
|
|
664
639
|
const channel = this.activeChannelSubject.getValue();
|
|
@@ -669,14 +644,7 @@ class ChannelService {
|
|
|
669
644
|
])
|
|
670
645
|
: this.activeChannelMessagesSubject.next([...channel.state.messages]);
|
|
671
646
|
try {
|
|
672
|
-
const response = yield channel.sendMessage({
|
|
673
|
-
text: preview.text,
|
|
674
|
-
attachments: preview.attachments,
|
|
675
|
-
mentioned_users: (_a = preview.mentioned_users) === null || _a === void 0 ? void 0 : _a.map((u) => u.id),
|
|
676
|
-
id: preview.id,
|
|
677
|
-
parent_id: preview.parent_id,
|
|
678
|
-
quoted_message_id: preview.quoted_message_id,
|
|
679
|
-
});
|
|
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
|
|
680
648
|
if (response === null || response === void 0 ? void 0 : response.message) {
|
|
681
649
|
channel.state.addMessageSorted(Object.assign(Object.assign({}, response.message), { status: 'received' }), true);
|
|
682
650
|
isThreadReply
|
|
@@ -700,15 +668,15 @@ class ChannelService {
|
|
|
700
668
|
}
|
|
701
669
|
});
|
|
702
670
|
}
|
|
703
|
-
handleNotification(
|
|
704
|
-
switch (
|
|
671
|
+
handleNotification(clientEvent) {
|
|
672
|
+
switch (clientEvent.eventType) {
|
|
705
673
|
case 'notification.message_new': {
|
|
706
674
|
this.ngZone.run(() => {
|
|
707
675
|
if (this.customNewMessageNotificationHandler) {
|
|
708
|
-
this.customNewMessageNotificationHandler(
|
|
676
|
+
this.customNewMessageNotificationHandler(clientEvent, this.channelListSetter);
|
|
709
677
|
}
|
|
710
678
|
else {
|
|
711
|
-
this.handleNewMessageNotification(
|
|
679
|
+
this.handleNewMessageNotification(clientEvent);
|
|
712
680
|
}
|
|
713
681
|
});
|
|
714
682
|
break;
|
|
@@ -716,10 +684,10 @@ class ChannelService {
|
|
|
716
684
|
case 'notification.added_to_channel': {
|
|
717
685
|
this.ngZone.run(() => {
|
|
718
686
|
if (this.customAddedToChannelNotificationHandler) {
|
|
719
|
-
this.customAddedToChannelNotificationHandler(
|
|
687
|
+
this.customAddedToChannelNotificationHandler(clientEvent, this.channelListSetter);
|
|
720
688
|
}
|
|
721
689
|
else {
|
|
722
|
-
this.handleAddedToChannelNotification(
|
|
690
|
+
this.handleAddedToChannelNotification(clientEvent);
|
|
723
691
|
}
|
|
724
692
|
});
|
|
725
693
|
break;
|
|
@@ -727,27 +695,27 @@ class ChannelService {
|
|
|
727
695
|
case 'notification.removed_from_channel': {
|
|
728
696
|
this.ngZone.run(() => {
|
|
729
697
|
if (this.customRemovedFromChannelNotificationHandler) {
|
|
730
|
-
this.customRemovedFromChannelNotificationHandler(
|
|
698
|
+
this.customRemovedFromChannelNotificationHandler(clientEvent, this.channelListSetter);
|
|
731
699
|
}
|
|
732
700
|
else {
|
|
733
|
-
this.handleRemovedFromChannelNotification(
|
|
701
|
+
this.handleRemovedFromChannelNotification(clientEvent);
|
|
734
702
|
}
|
|
735
703
|
});
|
|
736
704
|
}
|
|
737
705
|
}
|
|
738
706
|
}
|
|
739
|
-
handleRemovedFromChannelNotification(
|
|
740
|
-
const channelIdToBeRemoved =
|
|
707
|
+
handleRemovedFromChannelNotification(clientEvent) {
|
|
708
|
+
const channelIdToBeRemoved = clientEvent.event.channel.cid;
|
|
741
709
|
this.removeChannelsFromChannelList([channelIdToBeRemoved]);
|
|
742
710
|
}
|
|
743
|
-
handleNewMessageNotification(
|
|
744
|
-
if (
|
|
745
|
-
this.addChannelsFromNotification([
|
|
711
|
+
handleNewMessageNotification(clientEvent) {
|
|
712
|
+
if (clientEvent.event.channel) {
|
|
713
|
+
this.addChannelsFromNotification([clientEvent.event.channel]);
|
|
746
714
|
}
|
|
747
715
|
}
|
|
748
|
-
handleAddedToChannelNotification(
|
|
749
|
-
if (
|
|
750
|
-
this.addChannelsFromNotification([
|
|
716
|
+
handleAddedToChannelNotification(clientEvent) {
|
|
717
|
+
if (clientEvent.event.channel) {
|
|
718
|
+
this.addChannelsFromNotification([clientEvent.event.channel]);
|
|
751
719
|
}
|
|
752
720
|
}
|
|
753
721
|
addChannelsFromNotification(channelResponses) {
|
|
@@ -897,24 +865,20 @@ class ChannelService {
|
|
|
897
865
|
this.activeChannelSubscriptions.forEach((s) => s.unsubscribe());
|
|
898
866
|
this.activeChannelSubscriptions = [];
|
|
899
867
|
}
|
|
900
|
-
queryChannels(
|
|
868
|
+
queryChannels() {
|
|
901
869
|
return __awaiter(this, void 0, void 0, function* () {
|
|
902
870
|
try {
|
|
903
871
|
const channels = yield this.chatClientService.chatClient.queryChannels(this.filters, this.sort, this.options);
|
|
904
872
|
channels.forEach((c) => this.watchForChannelEvents(c));
|
|
905
873
|
const prevChannels = this.channelsSubject.getValue() || [];
|
|
906
874
|
this.channelsSubject.next([...prevChannels, ...channels]);
|
|
907
|
-
if (channels.length > 0 &&
|
|
908
|
-
!this.activeChannelSubject.getValue() &&
|
|
909
|
-
shouldSetActiveChannel) {
|
|
875
|
+
if (channels.length > 0 && !this.activeChannelSubject.getValue()) {
|
|
910
876
|
this.setAsActiveChannel(channels[0]);
|
|
911
877
|
}
|
|
912
878
|
this.hasMoreChannelsSubject.next(channels.length >= this.options.limit);
|
|
913
|
-
return channels;
|
|
914
879
|
}
|
|
915
880
|
catch (error) {
|
|
916
881
|
this.channelsSubject.error(error);
|
|
917
|
-
throw error;
|
|
918
882
|
}
|
|
919
883
|
});
|
|
920
884
|
}
|
|
@@ -1332,19 +1296,25 @@ class AttachmentService {
|
|
|
1332
1296
|
deleteAttachment(upload) {
|
|
1333
1297
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1334
1298
|
const attachmentUploads = this.attachmentUploadsSubject.getValue();
|
|
1299
|
+
let result;
|
|
1335
1300
|
if (upload.state === 'success') {
|
|
1336
1301
|
try {
|
|
1337
1302
|
yield this.channelService.deleteAttachment(upload);
|
|
1338
|
-
attachmentUploads
|
|
1303
|
+
result = [...attachmentUploads];
|
|
1304
|
+
const index = attachmentUploads.indexOf(upload);
|
|
1305
|
+
result.splice(index, 1);
|
|
1339
1306
|
}
|
|
1340
1307
|
catch (error) {
|
|
1308
|
+
result = attachmentUploads;
|
|
1341
1309
|
this.notificationService.addTemporaryNotification('streamChat.Error deleting attachment');
|
|
1342
1310
|
}
|
|
1343
1311
|
}
|
|
1344
1312
|
else {
|
|
1345
|
-
attachmentUploads
|
|
1313
|
+
result = [...attachmentUploads];
|
|
1314
|
+
const index = attachmentUploads.indexOf(upload);
|
|
1315
|
+
result.splice(index, 1);
|
|
1346
1316
|
}
|
|
1347
|
-
this.attachmentUploadsSubject.next([...
|
|
1317
|
+
this.attachmentUploadsSubject.next([...result]);
|
|
1348
1318
|
});
|
|
1349
1319
|
}
|
|
1350
1320
|
/**
|
|
@@ -1426,9 +1396,9 @@ class AttachmentService {
|
|
|
1426
1396
|
}
|
|
1427
1397
|
uploadAttachments(uploads) {
|
|
1428
1398
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1429
|
-
const attachmentUploads = this.attachmentUploadsSubject.getValue();
|
|
1430
1399
|
this.attachmentUploadInProgressCounterSubject.next(this.attachmentUploadInProgressCounterSubject.getValue() + 1);
|
|
1431
1400
|
const result = yield this.channelService.uploadAttachments(uploads);
|
|
1401
|
+
const attachmentUploads = this.attachmentUploadsSubject.getValue();
|
|
1432
1402
|
result.forEach((r) => {
|
|
1433
1403
|
const upload = attachmentUploads.find((upload) => upload.file === r.file);
|
|
1434
1404
|
if (!upload) {
|
|
@@ -1592,7 +1562,7 @@ class AvatarComponent {
|
|
|
1592
1562
|
}
|
|
1593
1563
|
}
|
|
1594
1564
|
AvatarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: AvatarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1595
|
-
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"] }] });
|
|
1596
1566
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: AvatarComponent, decorators: [{
|
|
1597
1567
|
type: Component,
|
|
1598
1568
|
args: [{
|
|
@@ -1608,6 +1578,178 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
1608
1578
|
type: Input
|
|
1609
1579
|
}] } });
|
|
1610
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
|
+
|
|
1611
1753
|
/**
|
|
1612
1754
|
* The `Icon` component can be used to display different icons (i. e. message delivered icon).
|
|
1613
1755
|
*/
|
|
@@ -1615,7 +1757,7 @@ class IconComponent {
|
|
|
1615
1757
|
constructor() { }
|
|
1616
1758
|
}
|
|
1617
1759
|
IconComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: IconComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1618
|
-
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"] }] });
|
|
1619
1761
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: IconComponent, decorators: [{
|
|
1620
1762
|
type: Component,
|
|
1621
1763
|
args: [{
|
|
@@ -1629,6 +1771,35 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
1629
1771
|
type: Input
|
|
1630
1772
|
}] } });
|
|
1631
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
|
+
|
|
1632
1803
|
/**
|
|
1633
1804
|
* The `LoadingIndicator` component displays a spinner to indicate that an action is in progress.
|
|
1634
1805
|
*/
|
|
@@ -1645,7 +1816,7 @@ class LoadingIndicatorComponent {
|
|
|
1645
1816
|
}
|
|
1646
1817
|
}
|
|
1647
1818
|
LoadingIndicatorComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: LoadingIndicatorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1648
|
-
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"] }] });
|
|
1649
1820
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: LoadingIndicatorComponent, decorators: [{
|
|
1650
1821
|
type: Component,
|
|
1651
1822
|
args: [{
|
|
@@ -1659,6 +1830,113 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
1659
1830
|
type: Input
|
|
1660
1831
|
}] } });
|
|
1661
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
|
+
|
|
1662
1940
|
const textareaInjectionToken = new InjectionToken('textareaInjectionToken');
|
|
1663
1941
|
|
|
1664
1942
|
class TextareaDirective {
|
|
@@ -1685,10 +1963,6 @@ class TextareaDirective {
|
|
|
1685
1963
|
this.subscriptions.push(this.componentRef.instance.userMentions.subscribe((value) => this.userMentions.next(value)));
|
|
1686
1964
|
}
|
|
1687
1965
|
this.componentRef.instance.areMentionsEnabled = this.areMentionsEnabled;
|
|
1688
|
-
this.componentRef.instance.mentionAutocompleteItemTemplate =
|
|
1689
|
-
this.mentionAutocompleteItemTemplate;
|
|
1690
|
-
this.componentRef.instance.commandAutocompleteItemTemplate =
|
|
1691
|
-
this.commandAutocompleteItemTemplate;
|
|
1692
1966
|
this.componentRef.instance.mentionScope = this.mentionScope;
|
|
1693
1967
|
this.componentRef.instance.value = this.value;
|
|
1694
1968
|
}
|
|
@@ -1696,14 +1970,6 @@ class TextareaDirective {
|
|
|
1696
1970
|
if (changes.areMentionsEnabled) {
|
|
1697
1971
|
this.componentRef.instance.areMentionsEnabled = this.areMentionsEnabled;
|
|
1698
1972
|
}
|
|
1699
|
-
if (changes.mentionAutocompleteItemTemplate) {
|
|
1700
|
-
this.componentRef.instance.mentionAutocompleteItemTemplate =
|
|
1701
|
-
this.mentionAutocompleteItemTemplate;
|
|
1702
|
-
}
|
|
1703
|
-
if (changes.commandAutocompleteItemTemplate) {
|
|
1704
|
-
this.componentRef.instance.commandAutocompleteItemTemplate =
|
|
1705
|
-
this.commandAutocompleteItemTemplate;
|
|
1706
|
-
}
|
|
1707
1973
|
if (changes.mentionScope) {
|
|
1708
1974
|
this.componentRef.instance.mentionScope = this.mentionScope;
|
|
1709
1975
|
}
|
|
@@ -1719,7 +1985,7 @@ class TextareaDirective {
|
|
|
1719
1985
|
}
|
|
1720
1986
|
}
|
|
1721
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 });
|
|
1722
|
-
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 });
|
|
1723
1989
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: TextareaDirective, decorators: [{
|
|
1724
1990
|
type: Directive,
|
|
1725
1991
|
args: [{
|
|
@@ -1729,12 +1995,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
1729
1995
|
type: Input
|
|
1730
1996
|
}], areMentionsEnabled: [{
|
|
1731
1997
|
type: Input
|
|
1732
|
-
}], mentionAutocompleteItemTemplate: [{
|
|
1733
|
-
type: Input
|
|
1734
1998
|
}], mentionScope: [{
|
|
1735
1999
|
type: Input
|
|
1736
|
-
}], commandAutocompleteItemTemplate: [{
|
|
1737
|
-
type: Input
|
|
1738
2000
|
}], value: [{
|
|
1739
2001
|
type: Input
|
|
1740
2002
|
}], valueChange: [{
|
|
@@ -1817,79 +2079,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
1817
2079
|
}]
|
|
1818
2080
|
}], ctorParameters: function () { return []; } });
|
|
1819
2081
|
|
|
1820
|
-
/**
|
|
1821
|
-
* 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.
|
|
1822
|
-
*/
|
|
1823
|
-
class ModalComponent {
|
|
1824
|
-
constructor() {
|
|
1825
|
-
/**
|
|
1826
|
-
* If `true` the modal will be displayed, if `false` the modal will be hidden
|
|
1827
|
-
*/
|
|
1828
|
-
this.isOpen = false;
|
|
1829
|
-
/**
|
|
1830
|
-
* Emits `true` if the modal becomes visible, and `false` if the modal is closed.
|
|
1831
|
-
*/
|
|
1832
|
-
this.isOpenChange = new EventEmitter();
|
|
1833
|
-
this.watchForEscPress = (event) => {
|
|
1834
|
-
if (event.key === 'Escape') {
|
|
1835
|
-
this.close();
|
|
1836
|
-
}
|
|
1837
|
-
};
|
|
1838
|
-
this.stopWatchForEscPress = () => {
|
|
1839
|
-
window.removeEventListener('keyup', this.watchForEscPress);
|
|
1840
|
-
};
|
|
1841
|
-
this.watchForOutsideClicks = (event) => {
|
|
1842
|
-
var _a;
|
|
1843
|
-
if (!((_a = this.content) === null || _a === void 0 ? void 0 : _a.nativeElement.contains(event.target))) {
|
|
1844
|
-
this.close();
|
|
1845
|
-
}
|
|
1846
|
-
};
|
|
1847
|
-
}
|
|
1848
|
-
ngOnChanges(changes) {
|
|
1849
|
-
if (changes.isOpen) {
|
|
1850
|
-
if (this.isOpen) {
|
|
1851
|
-
window.addEventListener('keyup', this.watchForEscPress);
|
|
1852
|
-
setTimeout(() => window.addEventListener('click', this.watchForOutsideClicks), 0);
|
|
1853
|
-
}
|
|
1854
|
-
else {
|
|
1855
|
-
this.stopWatchForOutsideClicks();
|
|
1856
|
-
this.stopWatchForEscPress();
|
|
1857
|
-
}
|
|
1858
|
-
}
|
|
1859
|
-
}
|
|
1860
|
-
close() {
|
|
1861
|
-
this.isOpen = false;
|
|
1862
|
-
this.isOpenChange.emit(false);
|
|
1863
|
-
this.stopWatchForOutsideClicks();
|
|
1864
|
-
this.stopWatchForEscPress();
|
|
1865
|
-
}
|
|
1866
|
-
stopWatchForOutsideClicks() {
|
|
1867
|
-
window.removeEventListener('click', this.watchForOutsideClicks);
|
|
1868
|
-
}
|
|
1869
|
-
}
|
|
1870
|
-
ModalComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1871
|
-
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"] }] });
|
|
1872
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ModalComponent, decorators: [{
|
|
1873
|
-
type: Component,
|
|
1874
|
-
args: [{
|
|
1875
|
-
selector: 'stream-modal',
|
|
1876
|
-
templateUrl: './modal.component.html',
|
|
1877
|
-
styles: [],
|
|
1878
|
-
}]
|
|
1879
|
-
}], ctorParameters: function () { return []; }, propDecorators: { isOpen: [{
|
|
1880
|
-
type: Input
|
|
1881
|
-
}], isOpenChange: [{
|
|
1882
|
-
type: Output
|
|
1883
|
-
}], content: [{
|
|
1884
|
-
type: ViewChild,
|
|
1885
|
-
args: ['content']
|
|
1886
|
-
}] } });
|
|
1887
|
-
|
|
1888
2082
|
/**
|
|
1889
2083
|
* The `AttachmentList` compontent displays the attachments of a message
|
|
1890
2084
|
*/
|
|
1891
2085
|
class AttachmentListComponent {
|
|
1892
|
-
constructor(imageLoadService, channelService) {
|
|
2086
|
+
constructor(customTemplatesService, imageLoadService, channelService) {
|
|
2087
|
+
this.customTemplatesService = customTemplatesService;
|
|
1893
2088
|
this.imageLoadService = imageLoadService;
|
|
1894
2089
|
this.channelService = channelService;
|
|
1895
2090
|
/**
|
|
@@ -1935,6 +2130,13 @@ class AttachmentListComponent {
|
|
|
1935
2130
|
getFileSize(attachment) {
|
|
1936
2131
|
return prettybytes(Number(attachment.file_size));
|
|
1937
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
|
+
}
|
|
1938
2140
|
trimUrl(url) {
|
|
1939
2141
|
if (url !== undefined && url !== null) {
|
|
1940
2142
|
const [trimmedUrl] = url
|
|
@@ -1956,9 +2158,6 @@ class AttachmentListComponent {
|
|
|
1956
2158
|
this.imagesToView = attachments;
|
|
1957
2159
|
this.imagesToViewCurrentIndex = selectedIndex;
|
|
1958
2160
|
}
|
|
1959
|
-
closeImageModal() {
|
|
1960
|
-
this.imagesToView = [];
|
|
1961
|
-
}
|
|
1962
2161
|
stepImages(dir) {
|
|
1963
2162
|
this.imagesToViewCurrentIndex += dir * 1;
|
|
1964
2163
|
}
|
|
@@ -1979,9 +2178,12 @@ class AttachmentListComponent {
|
|
|
1979
2178
|
},
|
|
1980
2179
|
];
|
|
1981
2180
|
}
|
|
2181
|
+
closeImageModal() {
|
|
2182
|
+
this.imagesToView = [];
|
|
2183
|
+
}
|
|
1982
2184
|
}
|
|
1983
|
-
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 });
|
|
1984
|
-
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 } });
|
|
1985
2187
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: AttachmentListComponent, decorators: [{
|
|
1986
2188
|
type: Component,
|
|
1987
2189
|
args: [{
|
|
@@ -1989,36 +2191,41 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
1989
2191
|
templateUrl: './attachment-list.component.html',
|
|
1990
2192
|
styles: [],
|
|
1991
2193
|
}]
|
|
1992
|
-
}], ctorParameters: function () { return [{ type: ImageLoadService }, { type: ChannelService }]; }, propDecorators: { messageId: [{
|
|
2194
|
+
}], ctorParameters: function () { return [{ type: CustomTemplatesService }, { type: ImageLoadService }, { type: ChannelService }]; }, propDecorators: { messageId: [{
|
|
1993
2195
|
type: Input
|
|
1994
2196
|
}], attachments: [{
|
|
1995
2197
|
type: Input
|
|
2198
|
+
}], modalContent: [{
|
|
2199
|
+
type: ViewChild,
|
|
2200
|
+
args: ['modalContent', { static: true }]
|
|
1996
2201
|
}] } });
|
|
1997
2202
|
|
|
1998
2203
|
/**
|
|
1999
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.
|
|
2000
2205
|
*/
|
|
2001
2206
|
class AttachmentPreviewListComponent {
|
|
2002
|
-
constructor(
|
|
2003
|
-
|
|
2004
|
-
|
|
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();
|
|
2005
2216
|
}
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
yield this.attachmentService.retryAttachmentUpload(file);
|
|
2009
|
-
});
|
|
2217
|
+
attachmentUploadRetried(file) {
|
|
2218
|
+
this.retryAttachmentUpload.emit(file);
|
|
2010
2219
|
}
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
yield this.attachmentService.deleteAttachment(upload);
|
|
2014
|
-
});
|
|
2220
|
+
attachmentDeleted(upload) {
|
|
2221
|
+
this.deleteAttachment.emit(upload);
|
|
2015
2222
|
}
|
|
2016
2223
|
trackByFile(_, item) {
|
|
2017
2224
|
return item.file;
|
|
2018
2225
|
}
|
|
2019
2226
|
}
|
|
2020
|
-
AttachmentPreviewListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: AttachmentPreviewListComponent, deps: [
|
|
2021
|
-
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 } });
|
|
2022
2229
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: AttachmentPreviewListComponent, decorators: [{
|
|
2023
2230
|
type: Component,
|
|
2024
2231
|
args: [{
|
|
@@ -2026,13 +2233,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
2026
2233
|
templateUrl: './attachment-preview-list.component.html',
|
|
2027
2234
|
styles: [],
|
|
2028
2235
|
}]
|
|
2029
|
-
}], ctorParameters: function () { return [
|
|
2236
|
+
}], ctorParameters: function () { return []; }, propDecorators: { attachmentUploads$: [{
|
|
2237
|
+
type: Input
|
|
2238
|
+
}], retryAttachmentUpload: [{
|
|
2239
|
+
type: Output
|
|
2240
|
+
}], deleteAttachment: [{
|
|
2241
|
+
type: Output
|
|
2242
|
+
}] } });
|
|
2030
2243
|
|
|
2031
2244
|
/**
|
|
2032
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).
|
|
2033
2246
|
*/
|
|
2034
2247
|
class MessageInputComponent {
|
|
2035
|
-
constructor(channelService, notificationService, attachmentService, configService, textareaType, componentFactoryResolver, cdRef, chatClient, emojiInputService) {
|
|
2248
|
+
constructor(channelService, notificationService, attachmentService, configService, textareaType, componentFactoryResolver, cdRef, chatClient, emojiInputService, customTemplatesService) {
|
|
2036
2249
|
this.channelService = channelService;
|
|
2037
2250
|
this.notificationService = notificationService;
|
|
2038
2251
|
this.attachmentService = attachmentService;
|
|
@@ -2042,6 +2255,7 @@ class MessageInputComponent {
|
|
|
2042
2255
|
this.cdRef = cdRef;
|
|
2043
2256
|
this.chatClient = chatClient;
|
|
2044
2257
|
this.emojiInputService = emojiInputService;
|
|
2258
|
+
this.customTemplatesService = customTemplatesService;
|
|
2045
2259
|
/**
|
|
2046
2260
|
* Determines if the message is being dispalyed in a channel or in a [thread](https://getstream.io/chat/docs/javascript/threads/?language=javascript).
|
|
2047
2261
|
*/
|
|
@@ -2086,16 +2300,10 @@ class MessageInputComponent {
|
|
|
2086
2300
|
}));
|
|
2087
2301
|
this.attachmentUploads$ = this.attachmentService.attachmentUploads$;
|
|
2088
2302
|
this.isFileUploadEnabled = this.configService.isFileUploadEnabled;
|
|
2089
|
-
this.acceptedFileTypes = this.configService.acceptedFileTypes;
|
|
2090
2303
|
this.isMultipleFileUploadEnabled =
|
|
2091
2304
|
this.configService.isMultipleFileUploadEnabled;
|
|
2092
2305
|
this.areMentionsEnabled = this.configService.areMentionsEnabled;
|
|
2093
|
-
this.mentionAutocompleteItemTemplate =
|
|
2094
|
-
this.configService.mentionAutocompleteItemTemplate;
|
|
2095
2306
|
this.mentionScope = this.configService.mentionScope;
|
|
2096
|
-
this.commandAutocompleteItemTemplate =
|
|
2097
|
-
this.configService.commandAutocompleteItemTemplate;
|
|
2098
|
-
this.emojiPickerTemplate = this.configService.emojiPickerTemplate;
|
|
2099
2307
|
this.subscriptions.push(this.typingStart$.subscribe(() => void this.channelService.typingStarted(this.parentMessageId)));
|
|
2100
2308
|
this.subscriptions.push(combineLatest([
|
|
2101
2309
|
this.channelService.latestMessageDateByUserByChannels$,
|
|
@@ -2118,6 +2326,16 @@ class MessageInputComponent {
|
|
|
2118
2326
|
}
|
|
2119
2327
|
}));
|
|
2120
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
|
+
}
|
|
2121
2339
|
ngAfterViewInit() {
|
|
2122
2340
|
this.isViewInited = true;
|
|
2123
2341
|
this.initTextarea();
|
|
@@ -2133,9 +2351,6 @@ class MessageInputComponent {
|
|
|
2133
2351
|
if (changes.isFileUploadEnabled) {
|
|
2134
2352
|
this.configService.isFileUploadEnabled = this.isFileUploadEnabled;
|
|
2135
2353
|
}
|
|
2136
|
-
if (changes.acceptedFileTypes) {
|
|
2137
|
-
this.configService.acceptedFileTypes = this.acceptedFileTypes;
|
|
2138
|
-
}
|
|
2139
2354
|
if (changes.isMultipleFileUploadEnabled) {
|
|
2140
2355
|
this.configService.isMultipleFileUploadEnabled =
|
|
2141
2356
|
this.isMultipleFileUploadEnabled;
|
|
@@ -2143,25 +2358,25 @@ class MessageInputComponent {
|
|
|
2143
2358
|
if (changes.areMentionsEnabled) {
|
|
2144
2359
|
this.configService.areMentionsEnabled = this.areMentionsEnabled;
|
|
2145
2360
|
}
|
|
2146
|
-
if (changes.mentionAutocompleteItemTemplate) {
|
|
2147
|
-
this.configService.mentionAutocompleteItemTemplate =
|
|
2148
|
-
this.mentionAutocompleteItemTemplate;
|
|
2149
|
-
}
|
|
2150
|
-
if (changes.commandAutocompleteItemTemplate) {
|
|
2151
|
-
this.configService.commandAutocompleteItemTemplate =
|
|
2152
|
-
this.commandAutocompleteItemTemplate;
|
|
2153
|
-
}
|
|
2154
2361
|
if (changes.mentionScope) {
|
|
2155
2362
|
this.configService.mentionScope = this.mentionScope;
|
|
2156
2363
|
}
|
|
2157
|
-
if (changes.emojiPickerTemplate) {
|
|
2158
|
-
this.configService.emojiPickerTemplate = this.emojiPickerTemplate;
|
|
2159
|
-
}
|
|
2160
2364
|
if (changes.mode) {
|
|
2161
2365
|
this.setCanSendMessages();
|
|
2162
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
|
+
}
|
|
2163
2375
|
}
|
|
2164
2376
|
ngOnDestroy() {
|
|
2377
|
+
if (this.sendMessageSubcription) {
|
|
2378
|
+
this.sendMessageSubcription.unsubscribe();
|
|
2379
|
+
}
|
|
2165
2380
|
this.subscriptions.forEach((s) => s.unsubscribe());
|
|
2166
2381
|
}
|
|
2167
2382
|
messageSent() {
|
|
@@ -2213,10 +2428,6 @@ class MessageInputComponent {
|
|
|
2213
2428
|
get containsLinks() {
|
|
2214
2429
|
return /(?:(?:https?|ftp):\/\/)?[\w/\-?=%.]+\.[\w/\-&?=%.]+/.test(this.textareaValue);
|
|
2215
2430
|
}
|
|
2216
|
-
get accept() {
|
|
2217
|
-
var _a;
|
|
2218
|
-
return this.acceptedFileTypes ? (_a = this.acceptedFileTypes) === null || _a === void 0 ? void 0 : _a.join(',') : '';
|
|
2219
|
-
}
|
|
2220
2431
|
get quotedMessageAttachments() {
|
|
2221
2432
|
var _a;
|
|
2222
2433
|
const originalAttachments = (_a = this.quotedMessage) === null || _a === void 0 ? void 0 : _a.attachments;
|
|
@@ -2247,6 +2458,24 @@ class MessageInputComponent {
|
|
|
2247
2458
|
deselectMessageToQuote() {
|
|
2248
2459
|
this.channelService.selectMessageToQuote(undefined);
|
|
2249
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
|
+
}
|
|
2250
2479
|
clearFileInput() {
|
|
2251
2480
|
this.fileInput.nativeElement.value = '';
|
|
2252
2481
|
}
|
|
@@ -2264,7 +2493,7 @@ class MessageInputComponent {
|
|
|
2264
2493
|
}
|
|
2265
2494
|
areAttachemntsValid(fileList) {
|
|
2266
2495
|
return __awaiter(this, void 0, void 0, function* () {
|
|
2267
|
-
if (!fileList
|
|
2496
|
+
if (!fileList) {
|
|
2268
2497
|
return true;
|
|
2269
2498
|
}
|
|
2270
2499
|
if (!this.appSettings) {
|
|
@@ -2353,8 +2582,8 @@ class MessageInputComponent {
|
|
|
2353
2582
|
setTimeout(() => this.initTextarea());
|
|
2354
2583
|
}
|
|
2355
2584
|
}
|
|
2356
|
-
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 });
|
|
2357
|
-
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 } });
|
|
2358
2587
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: MessageInputComponent, decorators: [{
|
|
2359
2588
|
type: Component,
|
|
2360
2589
|
args: [{
|
|
@@ -2366,26 +2595,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
2366
2595
|
}], ctorParameters: function () { return [{ type: ChannelService }, { type: NotificationService }, { type: AttachmentService }, { type: MessageInputConfigService }, { type: i0.Type, decorators: [{
|
|
2367
2596
|
type: Inject,
|
|
2368
2597
|
args: [textareaInjectionToken]
|
|
2369
|
-
}] }, { 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: [{
|
|
2370
2599
|
type: Input
|
|
2371
2600
|
}], areMentionsEnabled: [{
|
|
2372
2601
|
type: Input
|
|
2373
2602
|
}], mentionScope: [{
|
|
2374
2603
|
type: Input
|
|
2375
|
-
}], mentionAutocompleteItemTemplate: [{
|
|
2376
|
-
type: Input
|
|
2377
|
-
}], commandAutocompleteItemTemplate: [{
|
|
2378
|
-
type: Input
|
|
2379
|
-
}], emojiPickerTemplate: [{
|
|
2380
|
-
type: Input
|
|
2381
2604
|
}], mode: [{
|
|
2382
2605
|
type: Input
|
|
2383
|
-
}], acceptedFileTypes: [{
|
|
2384
|
-
type: Input
|
|
2385
2606
|
}], isMultipleFileUploadEnabled: [{
|
|
2386
2607
|
type: Input
|
|
2387
2608
|
}], message: [{
|
|
2388
2609
|
type: Input
|
|
2610
|
+
}], sendMessage$: [{
|
|
2611
|
+
type: Input
|
|
2389
2612
|
}], messageUpdate: [{
|
|
2390
2613
|
type: Output
|
|
2391
2614
|
}], fileInput: [{
|
|
@@ -2403,7 +2626,7 @@ class NotificationComponent {
|
|
|
2403
2626
|
constructor() { }
|
|
2404
2627
|
}
|
|
2405
2628
|
NotificationComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: NotificationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2406
|
-
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"] }] });
|
|
2407
2630
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: NotificationComponent, decorators: [{
|
|
2408
2631
|
type: Component,
|
|
2409
2632
|
args: [{
|
|
@@ -2413,25 +2636,28 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
2413
2636
|
}]
|
|
2414
2637
|
}], ctorParameters: function () { return []; }, propDecorators: { type: [{
|
|
2415
2638
|
type: Input
|
|
2639
|
+
}], content: [{
|
|
2640
|
+
type: Input
|
|
2416
2641
|
}] } });
|
|
2417
2642
|
|
|
2418
2643
|
/**
|
|
2419
2644
|
* The `NotificationList` component displays the list of active notifications.
|
|
2420
2645
|
*/
|
|
2421
2646
|
class NotificationListComponent {
|
|
2422
|
-
constructor(notificationService) {
|
|
2647
|
+
constructor(customTemplatesService, notificationService) {
|
|
2648
|
+
this.customTemplatesService = customTemplatesService;
|
|
2423
2649
|
this.notificationService = notificationService;
|
|
2424
2650
|
this.notifications$ = this.notificationService.notifications$;
|
|
2425
2651
|
}
|
|
2426
2652
|
trackById(_, item) {
|
|
2427
2653
|
return item.id;
|
|
2428
2654
|
}
|
|
2429
|
-
|
|
2655
|
+
getNotificationContentContext(notification) {
|
|
2430
2656
|
return Object.assign(Object.assign({}, notification.templateContext), { dismissFn: notification.dismissFn });
|
|
2431
2657
|
}
|
|
2432
2658
|
}
|
|
2433
|
-
NotificationListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: NotificationListComponent, deps: [{ token: NotificationService }], target: i0.ɵɵFactoryTarget.Component });
|
|
2434
|
-
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 } });
|
|
2435
2661
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: NotificationListComponent, decorators: [{
|
|
2436
2662
|
type: Component,
|
|
2437
2663
|
args: [{
|
|
@@ -2439,16 +2665,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
2439
2665
|
templateUrl: './notification-list.component.html',
|
|
2440
2666
|
styles: [],
|
|
2441
2667
|
}]
|
|
2442
|
-
}], ctorParameters: function () { return [{ type: NotificationService }]; } });
|
|
2668
|
+
}], ctorParameters: function () { return [{ type: CustomTemplatesService }, { type: NotificationService }]; } });
|
|
2443
2669
|
|
|
2444
2670
|
/**
|
|
2445
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.
|
|
2446
2672
|
*/
|
|
2447
2673
|
class MessageActionsBoxComponent {
|
|
2448
|
-
constructor(chatClientService, notificationService, channelService) {
|
|
2674
|
+
constructor(chatClientService, notificationService, channelService, customTemplatesService) {
|
|
2449
2675
|
this.chatClientService = chatClientService;
|
|
2450
2676
|
this.notificationService = notificationService;
|
|
2451
2677
|
this.channelService = channelService;
|
|
2678
|
+
this.customTemplatesService = customTemplatesService;
|
|
2452
2679
|
/**
|
|
2453
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.
|
|
2454
2681
|
*/
|
|
@@ -2470,107 +2697,122 @@ class MessageActionsBoxComponent {
|
|
|
2470
2697
|
*/
|
|
2471
2698
|
this.isEditing = new EventEmitter();
|
|
2472
2699
|
this.isEditModalOpen = false;
|
|
2700
|
+
this.subscriptions = [];
|
|
2701
|
+
this.visibleMessageActionItems = [];
|
|
2702
|
+
this.sendMessageSubject = new Subject();
|
|
2473
2703
|
this.modalClosed = () => {
|
|
2474
2704
|
this.isEditModalOpen = false;
|
|
2475
2705
|
this.isEditing.emit(false);
|
|
2476
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();
|
|
2477
2767
|
}
|
|
2478
2768
|
ngOnChanges(changes) {
|
|
2479
|
-
if (changes.isMine || changes.enabledActions) {
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
}
|
|
2484
|
-
if (this.isEditVisible) {
|
|
2485
|
-
displayedActionsCount++;
|
|
2486
|
-
}
|
|
2487
|
-
if (this.isDeleteVisible) {
|
|
2488
|
-
displayedActionsCount++;
|
|
2489
|
-
}
|
|
2490
|
-
if (this.isMuteVisible) {
|
|
2491
|
-
displayedActionsCount++;
|
|
2492
|
-
}
|
|
2493
|
-
if (this.isFlagVisible) {
|
|
2494
|
-
displayedActionsCount++;
|
|
2495
|
-
}
|
|
2496
|
-
if (this.isPinVisible) {
|
|
2497
|
-
displayedActionsCount++;
|
|
2498
|
-
}
|
|
2499
|
-
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);
|
|
2500
2773
|
}
|
|
2501
2774
|
}
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
return ((this.enabledActions.indexOf('quote') !== -1 ||
|
|
2505
|
-
this.enabledActions.indexOf('quote-message') !== -1) &&
|
|
2506
|
-
!((_a = this.message) === null || _a === void 0 ? void 0 : _a.quoted_message));
|
|
2507
|
-
}
|
|
2508
|
-
get isEditVisible() {
|
|
2509
|
-
return (((this.enabledActions.indexOf('edit') !== -1 ||
|
|
2510
|
-
this.enabledActions.indexOf('update-own-message') !== -1) &&
|
|
2511
|
-
this.isMine) ||
|
|
2512
|
-
this.enabledActions.indexOf('edit-any') !== -1 ||
|
|
2513
|
-
this.enabledActions.indexOf('update-any-message') !== -1);
|
|
2514
|
-
}
|
|
2515
|
-
get isDeleteVisible() {
|
|
2516
|
-
return (((this.enabledActions.indexOf('delete') !== -1 ||
|
|
2517
|
-
this.enabledActions.indexOf('delete-own-message') !== -1) &&
|
|
2518
|
-
this.isMine) ||
|
|
2519
|
-
this.enabledActions.indexOf('delete-any') !== -1 ||
|
|
2520
|
-
this.enabledActions.indexOf('delete-any-message') !== -1);
|
|
2521
|
-
}
|
|
2522
|
-
get isMuteVisible() {
|
|
2523
|
-
return this.enabledActions.indexOf('mute') !== -1;
|
|
2524
|
-
}
|
|
2525
|
-
get isFlagVisible() {
|
|
2526
|
-
return ((this.enabledActions.indexOf('flag') !== -1 ||
|
|
2527
|
-
this.enabledActions.indexOf('flag-message') !== -1) &&
|
|
2528
|
-
!this.isMine);
|
|
2529
|
-
}
|
|
2530
|
-
get isPinVisible() {
|
|
2531
|
-
return this.enabledActions.indexOf('pin') !== -1;
|
|
2532
|
-
}
|
|
2533
|
-
pinClicked() {
|
|
2534
|
-
alert('Feature not yet implemented');
|
|
2535
|
-
}
|
|
2536
|
-
flagClicked() {
|
|
2537
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
2538
|
-
try {
|
|
2539
|
-
yield this.chatClientService.flagMessage(this.message.id);
|
|
2540
|
-
this.notificationService.addTemporaryNotification('streamChat.Message has been successfully flagged', 'success');
|
|
2541
|
-
}
|
|
2542
|
-
catch (err) {
|
|
2543
|
-
this.notificationService.addTemporaryNotification('streamChat.Error adding flag');
|
|
2544
|
-
}
|
|
2545
|
-
});
|
|
2775
|
+
ngOnDestroy() {
|
|
2776
|
+
this.subscriptions.forEach((s) => s.unsubscribe());
|
|
2546
2777
|
}
|
|
2547
|
-
|
|
2548
|
-
|
|
2778
|
+
getActionLabel(actionLabelOrTranslationKey) {
|
|
2779
|
+
return typeof actionLabelOrTranslationKey === 'string'
|
|
2780
|
+
? actionLabelOrTranslationKey
|
|
2781
|
+
: actionLabelOrTranslationKey();
|
|
2549
2782
|
}
|
|
2550
|
-
|
|
2551
|
-
this.
|
|
2783
|
+
sendClicked() {
|
|
2784
|
+
this.sendMessageSubject.next();
|
|
2552
2785
|
}
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
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
|
+
};
|
|
2556
2797
|
}
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
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
|
+
};
|
|
2560
2809
|
}
|
|
2561
|
-
|
|
2562
|
-
return
|
|
2563
|
-
try {
|
|
2564
|
-
yield this.channelService.deleteMessage(this.message);
|
|
2565
|
-
}
|
|
2566
|
-
catch (error) {
|
|
2567
|
-
this.notificationService.addTemporaryNotification('streamChat.Error deleting message');
|
|
2568
|
-
}
|
|
2569
|
-
});
|
|
2810
|
+
trackByActionName(_, item) {
|
|
2811
|
+
return item.actionName;
|
|
2570
2812
|
}
|
|
2571
2813
|
}
|
|
2572
|
-
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 });
|
|
2573
|
-
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 } });
|
|
2574
2816
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: MessageActionsBoxComponent, decorators: [{
|
|
2575
2817
|
type: Component,
|
|
2576
2818
|
args: [{
|
|
@@ -2578,9 +2820,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
2578
2820
|
templateUrl: './message-actions-box.component.html',
|
|
2579
2821
|
styles: [],
|
|
2580
2822
|
}]
|
|
2581
|
-
}], ctorParameters: function () { return [{ type: ChatClientService }, { type: NotificationService }, { type: ChannelService }]; }, propDecorators: {
|
|
2582
|
-
type: Input
|
|
2583
|
-
}], isOpen: [{
|
|
2823
|
+
}], ctorParameters: function () { return [{ type: ChatClientService }, { type: NotificationService }, { type: ChannelService }, { type: CustomTemplatesService }]; }, propDecorators: { isOpen: [{
|
|
2584
2824
|
type: Input
|
|
2585
2825
|
}], isMine: [{
|
|
2586
2826
|
type: Input
|
|
@@ -2592,9 +2832,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
2592
2832
|
type: Output
|
|
2593
2833
|
}], isEditing: [{
|
|
2594
2834
|
type: Output
|
|
2595
|
-
}],
|
|
2835
|
+
}], modalContent: [{
|
|
2596
2836
|
type: ViewChild,
|
|
2597
|
-
args: [
|
|
2837
|
+
args: ['modalContent', { static: true }]
|
|
2598
2838
|
}] } });
|
|
2599
2839
|
|
|
2600
2840
|
/**
|
|
@@ -2610,7 +2850,7 @@ class ChannelComponent {
|
|
|
2610
2850
|
}
|
|
2611
2851
|
}
|
|
2612
2852
|
ChannelComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ChannelComponent, deps: [{ token: ChannelService }], target: i0.ɵɵFactoryTarget.Component });
|
|
2613
|
-
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 } });
|
|
2614
2854
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ChannelComponent, decorators: [{
|
|
2615
2855
|
type: Component,
|
|
2616
2856
|
args: [{
|
|
@@ -2704,9 +2944,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
2704
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)
|
|
2705
2945
|
*/
|
|
2706
2946
|
class ChannelHeaderComponent {
|
|
2707
|
-
constructor(channelService, channelListToggleService) {
|
|
2947
|
+
constructor(channelService, channelListToggleService, customTemplatesService, cdRef) {
|
|
2708
2948
|
this.channelService = channelService;
|
|
2709
2949
|
this.channelListToggleService = channelListToggleService;
|
|
2950
|
+
this.customTemplatesService = customTemplatesService;
|
|
2951
|
+
this.cdRef = cdRef;
|
|
2952
|
+
this.subscriptions = [];
|
|
2710
2953
|
this.channelService.activeChannel$.subscribe((c) => {
|
|
2711
2954
|
var _a, _b;
|
|
2712
2955
|
this.activeChannel = c;
|
|
@@ -2718,10 +2961,22 @@ class ChannelHeaderComponent {
|
|
|
2718
2961
|
capabilities.indexOf('connect-events') !== -1;
|
|
2719
2962
|
});
|
|
2720
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
|
+
}
|
|
2721
2973
|
toggleMenu(event) {
|
|
2722
2974
|
event.stopPropagation();
|
|
2723
2975
|
this.channelListToggleService.toggle();
|
|
2724
2976
|
}
|
|
2977
|
+
getChannelActionsContext() {
|
|
2978
|
+
return { channel: this.activeChannel };
|
|
2979
|
+
}
|
|
2725
2980
|
get memberCountParam() {
|
|
2726
2981
|
var _a, _b;
|
|
2727
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 };
|
|
@@ -2731,8 +2986,8 @@ class ChannelHeaderComponent {
|
|
|
2731
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 };
|
|
2732
2987
|
}
|
|
2733
2988
|
}
|
|
2734
|
-
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 });
|
|
2735
|
-
ChannelHeaderComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: ChannelHeaderComponent, selector: "stream-channel-header",
|
|
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 } });
|
|
2736
2991
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ChannelHeaderComponent, decorators: [{
|
|
2737
2992
|
type: Component,
|
|
2738
2993
|
args: [{
|
|
@@ -2740,9 +2995,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
2740
2995
|
templateUrl: './channel-header.component.html',
|
|
2741
2996
|
styles: [],
|
|
2742
2997
|
}]
|
|
2743
|
-
}], ctorParameters: function () { return [{ type: ChannelService }, { type: ChannelListToggleService }
|
|
2744
|
-
type: Input
|
|
2745
|
-
}] } });
|
|
2998
|
+
}], ctorParameters: function () { return [{ type: ChannelService }, { type: ChannelListToggleService }, { type: CustomTemplatesService }, { type: i0.ChangeDetectorRef }]; } });
|
|
2746
2999
|
|
|
2747
3000
|
/**
|
|
2748
3001
|
* The `ChannelPreview` component displays a channel preview in the channel list, it consists of the image, name and latest message of the channel.
|
|
@@ -2822,7 +3075,7 @@ class ChannelPreviewComponent {
|
|
|
2822
3075
|
}
|
|
2823
3076
|
}
|
|
2824
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 });
|
|
2825
|
-
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 } });
|
|
2826
3079
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ChannelPreviewComponent, decorators: [{
|
|
2827
3080
|
type: Component,
|
|
2828
3081
|
args: [{
|
|
@@ -2838,19 +3091,25 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
2838
3091
|
* The `ChannelList` component renders the list of channels.
|
|
2839
3092
|
*/
|
|
2840
3093
|
class ChannelListComponent {
|
|
2841
|
-
constructor(channelService, channelListToggleService) {
|
|
3094
|
+
constructor(channelService, channelListToggleService, customTemplatesService) {
|
|
2842
3095
|
this.channelService = channelService;
|
|
2843
3096
|
this.channelListToggleService = channelListToggleService;
|
|
3097
|
+
this.customTemplatesService = customTemplatesService;
|
|
2844
3098
|
this.isLoadingMoreChannels = false;
|
|
3099
|
+
this.subscriptions = [];
|
|
2845
3100
|
this.isOpen$ = this.channelListToggleService.isOpen$;
|
|
2846
3101
|
this.channels$ = this.channelService.channels$;
|
|
2847
3102
|
this.hasMoreChannels$ = this.channelService.hasMoreChannels$;
|
|
2848
3103
|
this.isError$ = this.channels$.pipe(map(() => false), catchError(() => of(true)), startWith(false));
|
|
2849
3104
|
this.isInitializing$ = this.channels$.pipe(map((channels) => !channels), catchError(() => of(false)));
|
|
3105
|
+
this.subscriptions.push(this.customTemplatesService.channelPreviewTemplate$.subscribe((template) => (this.customChannelPreviewTemplate = template)));
|
|
2850
3106
|
}
|
|
2851
3107
|
ngAfterViewInit() {
|
|
2852
3108
|
this.channelListToggleService.setMenuElement(this.container.nativeElement);
|
|
2853
3109
|
}
|
|
3110
|
+
ngOnDestroy() {
|
|
3111
|
+
this.subscriptions.forEach((s) => s.unsubscribe());
|
|
3112
|
+
}
|
|
2854
3113
|
loadMoreChannels() {
|
|
2855
3114
|
return __awaiter(this, void 0, void 0, function* () {
|
|
2856
3115
|
this.isLoadingMoreChannels = true;
|
|
@@ -2864,9 +3123,14 @@ class ChannelListComponent {
|
|
|
2864
3123
|
channelSelected() {
|
|
2865
3124
|
this.channelListToggleService.channelSelected();
|
|
2866
3125
|
}
|
|
3126
|
+
getChannelPreviewContext(channel) {
|
|
3127
|
+
return {
|
|
3128
|
+
channel,
|
|
3129
|
+
};
|
|
3130
|
+
}
|
|
2867
3131
|
}
|
|
2868
|
-
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 });
|
|
2869
|
-
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 } });
|
|
2870
3134
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ChannelListComponent, decorators: [{
|
|
2871
3135
|
type: Component,
|
|
2872
3136
|
args: [{
|
|
@@ -2874,9 +3138,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
2874
3138
|
templateUrl: './channel-list.component.html',
|
|
2875
3139
|
styles: [],
|
|
2876
3140
|
}]
|
|
2877
|
-
}], ctorParameters: function () { return [{ type: ChannelService }, { type: ChannelListToggleService }]; }, propDecorators: {
|
|
2878
|
-
type: Input
|
|
2879
|
-
}], container: [{
|
|
3141
|
+
}], ctorParameters: function () { return [{ type: ChannelService }, { type: ChannelListToggleService }, { type: CustomTemplatesService }]; }, propDecorators: { container: [{
|
|
2880
3142
|
type: ViewChild,
|
|
2881
3143
|
args: ['container']
|
|
2882
3144
|
}] } });
|
|
@@ -3035,7 +3297,7 @@ class MessageReactionsComponent {
|
|
|
3035
3297
|
}
|
|
3036
3298
|
}
|
|
3037
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 });
|
|
3038
|
-
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"] }] });
|
|
3039
3301
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: MessageReactionsComponent, decorators: [{
|
|
3040
3302
|
type: Component,
|
|
3041
3303
|
args: [{
|
|
@@ -3067,9 +3329,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
3067
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).
|
|
3068
3330
|
*/
|
|
3069
3331
|
class MessageComponent {
|
|
3070
|
-
constructor(chatClientService, channelService) {
|
|
3332
|
+
constructor(chatClientService, channelService, customTemplatesService, cdRef) {
|
|
3071
3333
|
this.chatClientService = chatClientService;
|
|
3072
3334
|
this.channelService = channelService;
|
|
3335
|
+
this.customTemplatesService = customTemplatesService;
|
|
3336
|
+
this.cdRef = cdRef;
|
|
3073
3337
|
/**
|
|
3074
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).
|
|
3075
3339
|
*/
|
|
@@ -3083,12 +3347,28 @@ class MessageComponent {
|
|
|
3083
3347
|
this.isPressedOnMobile = false;
|
|
3084
3348
|
this.visibleMessageActionsCount = 0;
|
|
3085
3349
|
this.messageTextParts = [];
|
|
3350
|
+
this.subscriptions = [];
|
|
3086
3351
|
this.user = this.chatClientService.chatClient.user;
|
|
3087
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
|
+
}
|
|
3088
3359
|
ngOnChanges(changes) {
|
|
3089
3360
|
if (changes.message) {
|
|
3090
3361
|
this.createMessageParts();
|
|
3091
3362
|
}
|
|
3363
|
+
if (changes.enabledMessageActions) {
|
|
3364
|
+
this.canReactToMessage =
|
|
3365
|
+
this.enabledMessageActions.indexOf('send-reaction') !== -1;
|
|
3366
|
+
this.canReceiveReadEvents =
|
|
3367
|
+
this.enabledMessageActions.indexOf('read-events') !== -1;
|
|
3368
|
+
}
|
|
3369
|
+
}
|
|
3370
|
+
ngOnDestroy() {
|
|
3371
|
+
this.subscriptions.forEach((s) => s.unsubscribe());
|
|
3092
3372
|
}
|
|
3093
3373
|
get isSentByCurrentUser() {
|
|
3094
3374
|
var _a, _b, _c;
|
|
@@ -3156,6 +3436,24 @@ class MessageComponent {
|
|
|
3156
3436
|
? [originalAttachments[0]]
|
|
3157
3437
|
: [];
|
|
3158
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
|
+
}
|
|
3159
3457
|
resendMessage() {
|
|
3160
3458
|
void this.channelService.resendMessage(this.message);
|
|
3161
3459
|
}
|
|
@@ -3180,6 +3478,29 @@ class MessageComponent {
|
|
|
3180
3478
|
setAsActiveParentMessage() {
|
|
3181
3479
|
void this.channelService.setAsActiveParentMessage(this.message);
|
|
3182
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
|
+
}
|
|
3183
3504
|
createMessageParts() {
|
|
3184
3505
|
var _a, _b;
|
|
3185
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);
|
|
@@ -3198,12 +3519,7 @@ class MessageComponent {
|
|
|
3198
3519
|
this.message.mentioned_users.length === 0) {
|
|
3199
3520
|
// Wrap emojis in span to display emojis correctly in Chrome https://bugs.chromium.org/p/chromium/issues/detail?id=596223
|
|
3200
3521
|
const regex = new RegExp(emojiRegex(), 'g');
|
|
3201
|
-
|
|
3202
|
-
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
3203
|
-
const isChrome = !!window.chrome &&
|
|
3204
|
-
typeof window.opr === 'undefined';
|
|
3205
|
-
/* eslint-enable @typescript-eslint/no-unsafe-member-access */
|
|
3206
|
-
content = content.replace(regex, (match) => `<span ${isChrome ? 'class="str-chat__emoji-display-fix"' : ''}>${match}</span>`);
|
|
3522
|
+
content = content.replace(regex, (match) => `<span class="str-chat__emoji-display-fix">${match}</span>`);
|
|
3207
3523
|
this.messageTextParts = [{ content, type: 'text' }];
|
|
3208
3524
|
}
|
|
3209
3525
|
else {
|
|
@@ -3230,8 +3546,8 @@ class MessageComponent {
|
|
|
3230
3546
|
}
|
|
3231
3547
|
}
|
|
3232
3548
|
}
|
|
3233
|
-
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 });
|
|
3234
|
-
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", areReactionsEnabled: "areReactionsEnabled", canReactToMessage: "canReactToMessage", isLastSentMessage: "isLastSentMessage", canReceiveReadEvents: "canReceiveReadEvents", 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]=\"\n areReactionsEnabled !== false && hasReactions\n \"\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=\"\n areReactionsEnabled !== false &&\n canReactToMessage !== false &&\n enabledMessageActions.indexOf('send-reaction') !== -1\n \"\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 *ngIf=\"areReactionsEnabled !== false\"\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 } });
|
|
3235
3551
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: MessageComponent, decorators: [{
|
|
3236
3552
|
type: Component,
|
|
3237
3553
|
args: [{
|
|
@@ -3239,22 +3555,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
3239
3555
|
templateUrl: './message.component.html',
|
|
3240
3556
|
styles: [],
|
|
3241
3557
|
}]
|
|
3242
|
-
}], ctorParameters: function () { return [{ type: ChatClientService }, { type: ChannelService }]; }, propDecorators: {
|
|
3243
|
-
type: Input
|
|
3244
|
-
}], mentionTemplate: [{
|
|
3245
|
-
type: Input
|
|
3246
|
-
}], message: [{
|
|
3558
|
+
}], ctorParameters: function () { return [{ type: ChatClientService }, { type: ChannelService }, { type: CustomTemplatesService }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { message: [{
|
|
3247
3559
|
type: Input
|
|
3248
3560
|
}], enabledMessageActions: [{
|
|
3249
3561
|
type: Input
|
|
3250
|
-
}], areReactionsEnabled: [{
|
|
3251
|
-
type: Input
|
|
3252
|
-
}], canReactToMessage: [{
|
|
3253
|
-
type: Input
|
|
3254
3562
|
}], isLastSentMessage: [{
|
|
3255
3563
|
type: Input
|
|
3256
|
-
}], canReceiveReadEvents: [{
|
|
3257
|
-
type: Input
|
|
3258
3564
|
}], mode: [{
|
|
3259
3565
|
type: Input
|
|
3260
3566
|
}], container: [{
|
|
@@ -3353,11 +3659,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
3353
3659
|
* The `AutocompleteTextarea` component is used by the [`MessageInput`](./MessageInputComponent.mdx) component to display the input HTML element where users can type their message.
|
|
3354
3660
|
*/
|
|
3355
3661
|
class AutocompleteTextareaComponent {
|
|
3356
|
-
constructor(channelService, chatClientService, transliterationService, emojiInputService) {
|
|
3662
|
+
constructor(channelService, chatClientService, transliterationService, emojiInputService, customTemplatesService) {
|
|
3357
3663
|
this.channelService = channelService;
|
|
3358
3664
|
this.chatClientService = chatClientService;
|
|
3359
3665
|
this.transliterationService = transliterationService;
|
|
3360
3666
|
this.emojiInputService = emojiInputService;
|
|
3667
|
+
this.customTemplatesService = customTemplatesService;
|
|
3361
3668
|
this.class = 'str-chat__textarea';
|
|
3362
3669
|
/**
|
|
3363
3670
|
* The value of the input HTML element.
|
|
@@ -3433,6 +3740,8 @@ class AutocompleteTextareaComponent {
|
|
|
3433
3740
|
selectionStart + emoji.length;
|
|
3434
3741
|
this.inputChanged();
|
|
3435
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)));
|
|
3436
3745
|
this.autocompleteConfig.mentions = [
|
|
3437
3746
|
this.userMentionConfig,
|
|
3438
3747
|
this.slashCommandConfig,
|
|
@@ -3531,8 +3840,8 @@ class AutocompleteTextareaComponent {
|
|
|
3531
3840
|
}
|
|
3532
3841
|
}
|
|
3533
3842
|
}
|
|
3534
|
-
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 });
|
|
3535
|
-
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 } });
|
|
3536
3845
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: AutocompleteTextareaComponent, decorators: [{
|
|
3537
3846
|
type: Component,
|
|
3538
3847
|
args: [{
|
|
@@ -3540,16 +3849,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
3540
3849
|
templateUrl: './autocomplete-textarea.component.html',
|
|
3541
3850
|
styles: [],
|
|
3542
3851
|
}]
|
|
3543
|
-
}], 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: [{
|
|
3544
3853
|
type: HostBinding
|
|
3545
3854
|
}], value: [{
|
|
3546
3855
|
type: Input
|
|
3547
3856
|
}], areMentionsEnabled: [{
|
|
3548
3857
|
type: Input
|
|
3549
|
-
}], mentionAutocompleteItemTemplate: [{
|
|
3550
|
-
type: Input
|
|
3551
|
-
}], commandAutocompleteItemTemplate: [{
|
|
3552
|
-
type: Input
|
|
3553
3858
|
}], mentionScope: [{
|
|
3554
3859
|
type: Input
|
|
3555
3860
|
}], valueChange: [{
|
|
@@ -3607,19 +3912,11 @@ const isOnSameDay = (date1, date2) => {
|
|
|
3607
3912
|
* The `MessageList` component renders a scrollable list of messages.
|
|
3608
3913
|
*/
|
|
3609
3914
|
class MessageListComponent {
|
|
3610
|
-
constructor(channelService, chatClientService, imageLoadService) {
|
|
3915
|
+
constructor(channelService, chatClientService, imageLoadService, customTemplatesService) {
|
|
3611
3916
|
this.channelService = channelService;
|
|
3612
3917
|
this.chatClientService = chatClientService;
|
|
3613
3918
|
this.imageLoadService = imageLoadService;
|
|
3614
|
-
|
|
3615
|
-
* @deprecated use [channel capabilities](https://getstream.io/chat/docs/javascript/channel_capabilities/?language=javascript) instead. If true, the message reactions are displayed. Users can also react to messages if they have the necessary [channel capability](https://getstream.io/chat/docs/javascript/channel_capabilities/?language=javascript).
|
|
3616
|
-
*/
|
|
3617
|
-
this.areReactionsEnabled = undefined;
|
|
3618
|
-
/**
|
|
3619
|
-
* @deprecated use [channel capabilities](https://getstream.io/chat/docs/javascript/channel_capabilities/?language=javascript) instead. The list of [actions that are enabled](./MessageActionsBoxComponent.mdx), please note that the user also has to have the necessary [channel capabilities](https://getstream.io/chat/docs/javascript/channel_capabilities/?language=javascript) for actions to work. Unathorized actions won't be displayed on the UI. The `MessgaeList` component makes the necessary checks before passing the actions to the `Message` component.
|
|
3620
|
-
*/
|
|
3621
|
-
/* eslint-disable-next-line @angular-eslint/no-input-rename */
|
|
3622
|
-
this.enabledMessageActionsInput = undefined;
|
|
3919
|
+
this.customTemplatesService = customTemplatesService;
|
|
3623
3920
|
/**
|
|
3624
3921
|
* Determines if the message list should display channel messages or [thread messages](https://getstream.io/chat/docs/javascript/threads/?language=javascript).
|
|
3625
3922
|
*/
|
|
@@ -3628,7 +3925,6 @@ class MessageListComponent {
|
|
|
3628
3925
|
this.class = 'str-chat-angular__main-panel-inner str-chat-angular__message-list-host';
|
|
3629
3926
|
this.unreadMessageCount = 0;
|
|
3630
3927
|
this.groupStyles = [];
|
|
3631
|
-
this.authorizedMessageActions = ['flag'];
|
|
3632
3928
|
this.isUserScrolledUpThreshold = 300;
|
|
3633
3929
|
this.subscriptions = [];
|
|
3634
3930
|
this.subscriptions.push(this.channelService.activeChannel$.subscribe((channel) => {
|
|
@@ -3636,39 +3932,7 @@ class MessageListComponent {
|
|
|
3636
3932
|
this.resetScrollState();
|
|
3637
3933
|
const capabilites = (_a = channel === null || channel === void 0 ? void 0 : channel.data) === null || _a === void 0 ? void 0 : _a.own_capabilities;
|
|
3638
3934
|
if (capabilites) {
|
|
3639
|
-
this.
|
|
3640
|
-
this.canReceiveReadEvents = capabilites.indexOf('read-events') !== -1;
|
|
3641
|
-
this.authorizedMessageActions = [];
|
|
3642
|
-
if (this.canReactToMessage) {
|
|
3643
|
-
this.authorizedMessageActions.push('send-reaction');
|
|
3644
|
-
}
|
|
3645
|
-
if (this.canReceiveReadEvents) {
|
|
3646
|
-
this.authorizedMessageActions.push('read-events');
|
|
3647
|
-
}
|
|
3648
|
-
if (capabilites.indexOf('flag-message') !== -1) {
|
|
3649
|
-
this.authorizedMessageActions.push('flag');
|
|
3650
|
-
}
|
|
3651
|
-
if (capabilites.indexOf('update-own-message') !== -1) {
|
|
3652
|
-
this.authorizedMessageActions.push('edit');
|
|
3653
|
-
}
|
|
3654
|
-
if (capabilites.indexOf('update-any-message') !== -1) {
|
|
3655
|
-
this.authorizedMessageActions.push('edit');
|
|
3656
|
-
this.authorizedMessageActions.push('edit-any');
|
|
3657
|
-
}
|
|
3658
|
-
if (capabilites.indexOf('delete-own-message') !== -1) {
|
|
3659
|
-
this.authorizedMessageActions.push('delete');
|
|
3660
|
-
}
|
|
3661
|
-
if (capabilites.indexOf('delete-any-message') !== -1) {
|
|
3662
|
-
this.authorizedMessageActions.push('delete');
|
|
3663
|
-
this.authorizedMessageActions.push('delete-any');
|
|
3664
|
-
}
|
|
3665
|
-
if (capabilites.indexOf('send-reply') !== -1) {
|
|
3666
|
-
this.authorizedMessageActions.push('send-reply');
|
|
3667
|
-
}
|
|
3668
|
-
if (capabilites.indexOf('quote-message') !== -1) {
|
|
3669
|
-
this.authorizedMessageActions.push('quote-message');
|
|
3670
|
-
}
|
|
3671
|
-
this.setEnabledActions();
|
|
3935
|
+
this.enabledMessageActions = capabilites;
|
|
3672
3936
|
}
|
|
3673
3937
|
}));
|
|
3674
3938
|
this.subscriptions.push(this.imageLoadService.imageLoad$.subscribe(() => {
|
|
@@ -3689,6 +3953,8 @@ class MessageListComponent {
|
|
|
3689
3953
|
}
|
|
3690
3954
|
this.parentMessage = message;
|
|
3691
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)));
|
|
3692
3958
|
this.usersTypingInChannel$ = this.channelService.usersTypingInChannel$;
|
|
3693
3959
|
this.usersTypingInThread$ = this.channelService.usersTypingInThread$;
|
|
3694
3960
|
}
|
|
@@ -3696,9 +3962,6 @@ class MessageListComponent {
|
|
|
3696
3962
|
this.setMessages$();
|
|
3697
3963
|
}
|
|
3698
3964
|
ngOnChanges(changes) {
|
|
3699
|
-
if (changes.enabledMessageActionsInput) {
|
|
3700
|
-
this.setEnabledActions();
|
|
3701
|
-
}
|
|
3702
3965
|
if (changes.mode) {
|
|
3703
3966
|
this.setMessages$();
|
|
3704
3967
|
}
|
|
@@ -3730,11 +3993,6 @@ class MessageListComponent {
|
|
|
3730
3993
|
ngOnDestroy() {
|
|
3731
3994
|
this.subscriptions.forEach((s) => s.unsubscribe());
|
|
3732
3995
|
}
|
|
3733
|
-
get usersTyping$() {
|
|
3734
|
-
return this.mode === 'thread'
|
|
3735
|
-
? this.usersTypingInThread$
|
|
3736
|
-
: this.usersTypingInChannel$;
|
|
3737
|
-
}
|
|
3738
3996
|
trackByMessageId(index, item) {
|
|
3739
3997
|
return item.id;
|
|
3740
3998
|
}
|
|
@@ -3767,31 +4025,24 @@ class MessageListComponent {
|
|
|
3767
4025
|
}
|
|
3768
4026
|
this.prevScrollTop = this.scrollContainer.nativeElement.scrollTop;
|
|
3769
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
|
+
}
|
|
3770
4041
|
preserveScrollbarPosition() {
|
|
3771
4042
|
this.scrollContainer.nativeElement.scrollTop =
|
|
3772
4043
|
(this.prevScrollTop || 0) +
|
|
3773
4044
|
(this.scrollContainer.nativeElement.scrollHeight - this.containerHeight);
|
|
3774
4045
|
}
|
|
3775
|
-
setEnabledActions() {
|
|
3776
|
-
this.enabledMessageActions = [];
|
|
3777
|
-
if (!this.enabledMessageActionsInput) {
|
|
3778
|
-
this.enabledMessageActions = this.authorizedMessageActions;
|
|
3779
|
-
return;
|
|
3780
|
-
}
|
|
3781
|
-
this.enabledMessageActionsInput = [
|
|
3782
|
-
...this.enabledMessageActionsInput,
|
|
3783
|
-
'send-reaction',
|
|
3784
|
-
'read-events',
|
|
3785
|
-
'send-reply',
|
|
3786
|
-
'quote-message',
|
|
3787
|
-
];
|
|
3788
|
-
this.enabledMessageActionsInput.forEach((action) => {
|
|
3789
|
-
const isAuthorized = this.authorizedMessageActions.indexOf(action) !== -1;
|
|
3790
|
-
if (isAuthorized) {
|
|
3791
|
-
this.enabledMessageActions.push(action);
|
|
3792
|
-
}
|
|
3793
|
-
});
|
|
3794
|
-
}
|
|
3795
4046
|
setMessages$() {
|
|
3796
4047
|
this.messages$ = (this.mode === 'main'
|
|
3797
4048
|
? this.channelService.activeChannelMessages$
|
|
@@ -3844,9 +4095,14 @@ class MessageListComponent {
|
|
|
3844
4095
|
this.prevScrollTop = undefined;
|
|
3845
4096
|
this.isNewMessageSentByUser = undefined;
|
|
3846
4097
|
}
|
|
4098
|
+
get usersTyping$() {
|
|
4099
|
+
return this.mode === 'thread'
|
|
4100
|
+
? this.usersTypingInThread$
|
|
4101
|
+
: this.usersTypingInChannel$;
|
|
4102
|
+
}
|
|
3847
4103
|
}
|
|
3848
|
-
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 });
|
|
3849
|
-
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 } });
|
|
3850
4106
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: MessageListComponent, decorators: [{
|
|
3851
4107
|
type: Component,
|
|
3852
4108
|
args: [{
|
|
@@ -3854,20 +4110,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
3854
4110
|
templateUrl: './message-list.component.html',
|
|
3855
4111
|
styles: [],
|
|
3856
4112
|
}]
|
|
3857
|
-
}], ctorParameters: function () { return [{ type: ChannelService }, { type: ChatClientService }, { type: ImageLoadService }]; }, propDecorators: {
|
|
3858
|
-
type: Input
|
|
3859
|
-
}], messageInputTemplate: [{
|
|
3860
|
-
type: Input
|
|
3861
|
-
}], mentionTemplate: [{
|
|
3862
|
-
type: Input
|
|
3863
|
-
}], typingIndicatorTemplate: [{
|
|
3864
|
-
type: Input
|
|
3865
|
-
}], areReactionsEnabled: [{
|
|
3866
|
-
type: Input
|
|
3867
|
-
}], enabledMessageActionsInput: [{
|
|
3868
|
-
type: Input,
|
|
3869
|
-
args: ['enabledMessageActions']
|
|
3870
|
-
}], mode: [{
|
|
4113
|
+
}], ctorParameters: function () { return [{ type: ChannelService }, { type: ChatClientService }, { type: ImageLoadService }, { type: CustomTemplatesService }]; }, propDecorators: { mode: [{
|
|
3871
4114
|
type: Input
|
|
3872
4115
|
}], class: [{
|
|
3873
4116
|
type: HostBinding,
|
|
@@ -3884,7 +4127,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
3884
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.
|
|
3885
4128
|
*/
|
|
3886
4129
|
class ThreadComponent {
|
|
3887
|
-
constructor(channelService) {
|
|
4130
|
+
constructor(customTemplatesService, channelService) {
|
|
4131
|
+
this.customTemplatesService = customTemplatesService;
|
|
3888
4132
|
this.channelService = channelService;
|
|
3889
4133
|
this.class = 'str-chat__thread';
|
|
3890
4134
|
this.subscriptions = [];
|
|
@@ -3893,16 +4137,21 @@ class ThreadComponent {
|
|
|
3893
4137
|
ngOnDestroy() {
|
|
3894
4138
|
this.subscriptions.forEach((s) => s.unsubscribe());
|
|
3895
4139
|
}
|
|
3896
|
-
|
|
3897
|
-
|
|
3898
|
-
|
|
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 };
|
|
3899
4148
|
}
|
|
3900
4149
|
closeThread() {
|
|
3901
4150
|
void this.channelService.setAsActiveParentMessage(undefined);
|
|
3902
4151
|
}
|
|
3903
4152
|
}
|
|
3904
|
-
ThreadComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ThreadComponent, deps: [{ token: ChannelService }], target: i0.ɵɵFactoryTarget.Component });
|
|
3905
|
-
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 } });
|
|
3906
4155
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ThreadComponent, decorators: [{
|
|
3907
4156
|
type: Component,
|
|
3908
4157
|
args: [{
|
|
@@ -3910,7 +4159,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
3910
4159
|
templateUrl: './thread.component.html',
|
|
3911
4160
|
styles: [],
|
|
3912
4161
|
}]
|
|
3913
|
-
}], ctorParameters: function () { return [{ type: ChannelService }]; }, propDecorators: { class: [{
|
|
4162
|
+
}], ctorParameters: function () { return [{ type: CustomTemplatesService }, { type: ChannelService }]; }, propDecorators: { class: [{
|
|
3914
4163
|
type: HostBinding,
|
|
3915
4164
|
args: ['class']
|
|
3916
4165
|
}] } });
|
|
@@ -3918,14 +4167,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
3918
4167
|
class StreamAvatarModule {
|
|
3919
4168
|
}
|
|
3920
4169
|
StreamAvatarModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: StreamAvatarModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
3921
|
-
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] });
|
|
3922
4171
|
StreamAvatarModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: StreamAvatarModule, imports: [[CommonModule, TranslateModule]] });
|
|
3923
4172
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: StreamAvatarModule, decorators: [{
|
|
3924
4173
|
type: NgModule,
|
|
3925
4174
|
args: [{
|
|
3926
|
-
declarations: [AvatarComponent],
|
|
4175
|
+
declarations: [AvatarComponent, AvatarPlaceholderComponent],
|
|
3927
4176
|
imports: [CommonModule, TranslateModule],
|
|
3928
|
-
exports: [AvatarComponent],
|
|
4177
|
+
exports: [AvatarComponent, AvatarPlaceholderComponent],
|
|
3929
4178
|
}]
|
|
3930
4179
|
}] });
|
|
3931
4180
|
|
|
@@ -3949,7 +4198,9 @@ StreamChatModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", versio
|
|
|
3949
4198
|
AttachmentPreviewListComponent,
|
|
3950
4199
|
ModalComponent,
|
|
3951
4200
|
TextareaDirective,
|
|
3952
|
-
ThreadComponent
|
|
4201
|
+
ThreadComponent,
|
|
4202
|
+
IconPlaceholderComponent,
|
|
4203
|
+
LoadingIndicatorPlaceholderComponent], imports: [CommonModule, TranslateModule, StreamAvatarModule], exports: [ChannelComponent,
|
|
3953
4204
|
ChannelHeaderComponent,
|
|
3954
4205
|
ChannelListComponent,
|
|
3955
4206
|
ChannelPreviewComponent,
|
|
@@ -3966,7 +4217,9 @@ StreamChatModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", versio
|
|
|
3966
4217
|
AttachmentPreviewListComponent,
|
|
3967
4218
|
ModalComponent,
|
|
3968
4219
|
StreamAvatarModule,
|
|
3969
|
-
ThreadComponent
|
|
4220
|
+
ThreadComponent,
|
|
4221
|
+
IconPlaceholderComponent,
|
|
4222
|
+
LoadingIndicatorPlaceholderComponent] });
|
|
3970
4223
|
StreamChatModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: StreamChatModule, imports: [[CommonModule, TranslateModule, StreamAvatarModule], StreamAvatarModule] });
|
|
3971
4224
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: StreamChatModule, decorators: [{
|
|
3972
4225
|
type: NgModule,
|
|
@@ -3990,6 +4243,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
3990
4243
|
ModalComponent,
|
|
3991
4244
|
TextareaDirective,
|
|
3992
4245
|
ThreadComponent,
|
|
4246
|
+
IconPlaceholderComponent,
|
|
4247
|
+
LoadingIndicatorPlaceholderComponent,
|
|
3993
4248
|
],
|
|
3994
4249
|
imports: [CommonModule, TranslateModule, StreamAvatarModule],
|
|
3995
4250
|
exports: [
|
|
@@ -4011,6 +4266,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
4011
4266
|
ModalComponent,
|
|
4012
4267
|
StreamAvatarModule,
|
|
4013
4268
|
ThreadComponent,
|
|
4269
|
+
IconPlaceholderComponent,
|
|
4270
|
+
LoadingIndicatorPlaceholderComponent,
|
|
4014
4271
|
],
|
|
4015
4272
|
}]
|
|
4016
4273
|
}] });
|
|
@@ -4073,5 +4330,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
4073
4330
|
* Generated bundle index. Do not edit.
|
|
4074
4331
|
*/
|
|
4075
4332
|
|
|
4076
|
-
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 };
|
|
4077
4334
|
//# sourceMappingURL=stream-chat-angular.js.map
|