stream-chat-angular 1.3.0 → 2.0.0
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/assets/i18n/en.d.ts +1 -0
- package/assets/version.d.ts +1 -1
- package/bundles/stream-chat-angular.umd.js +1196 -365
- package/bundles/stream-chat-angular.umd.js.map +1 -1
- package/esm2015/assets/i18n/en.js +2 -1
- package/esm2015/assets/version.js +2 -2
- package/esm2015/lib/attachment-list/attachment-list.component.js +3 -4
- package/esm2015/lib/attachment-preview-list/attachment-preview-list.component.js +38 -0
- package/esm2015/lib/attachment.service.js +190 -0
- package/esm2015/lib/channel.service.js +53 -4
- package/esm2015/lib/chat-client.service.js +16 -1
- package/esm2015/lib/injection-tokens.js +3 -0
- package/esm2015/lib/is-image-attachment.js +6 -0
- package/esm2015/lib/message/highlight-mentions.pipe.js +23 -0
- package/esm2015/lib/message/message.component.js +3 -2
- package/esm2015/lib/message-actions-box/message-actions-box.component.js +43 -12
- package/esm2015/lib/message-input/autocomplete-textarea/autocomplete-textarea.component.js +145 -0
- package/esm2015/lib/message-input/message-input-config.service.js +19 -0
- package/esm2015/lib/message-input/message-input.component.js +122 -140
- package/esm2015/lib/message-input/textarea/textarea.component.js +42 -0
- package/esm2015/lib/message-input/textarea.directive.js +69 -0
- package/esm2015/lib/message-input/textarea.interface.js +2 -0
- package/esm2015/lib/message-list/message-list.component.js +19 -3
- package/esm2015/lib/message-preview.js +3 -2
- package/esm2015/lib/modal/modal.component.js +63 -0
- package/esm2015/lib/notification-list/notification-list.component.js +1 -1
- package/esm2015/lib/notification.service.js +1 -1
- package/esm2015/lib/stream-autocomplete-textarea.module.js +33 -0
- package/esm2015/lib/stream-avatar.module.js +19 -0
- package/esm2015/lib/stream-chat.module.js +25 -11
- package/esm2015/lib/stream-textarea.module.js +31 -0
- package/esm2015/lib/types.js +1 -1
- package/esm2015/public-api.js +19 -1
- package/fesm2015/stream-chat-angular.js +955 -241
- package/fesm2015/stream-chat-angular.js.map +1 -1
- package/lib/attachment-preview-list/attachment-preview-list.component.d.ts +14 -0
- package/lib/attachment.service.d.ts +25 -0
- package/lib/channel.service.d.ts +6 -2
- package/lib/chat-client.service.d.ts +1 -0
- package/lib/injection-tokens.d.ts +3 -0
- package/lib/is-image-attachment.d.ts +2 -0
- package/lib/message/highlight-mentions.pipe.d.ts +8 -0
- package/lib/message/message.component.d.ts +1 -0
- package/lib/message-actions-box/message-actions-box.component.d.ts +11 -4
- package/lib/message-input/autocomplete-textarea/autocomplete-textarea.component.d.ts +42 -0
- package/lib/message-input/message-input-config.service.d.ts +14 -0
- package/lib/message-input/message-input.component.d.ts +30 -20
- package/lib/message-input/textarea/textarea.component.d.ts +16 -0
- package/lib/message-input/textarea.directive.d.ts +21 -0
- package/lib/message-input/textarea.interface.d.ts +12 -0
- package/lib/message-list/message-list.component.d.ts +1 -1
- package/lib/message-preview.d.ts +1 -1
- package/lib/modal/modal.component.d.ts +16 -0
- package/lib/notification-list/notification-list.component.d.ts +3 -3
- package/lib/notification.service.d.ts +2 -2
- package/lib/stream-autocomplete-textarea.module.d.ts +11 -0
- package/lib/stream-avatar.module.d.ts +9 -0
- package/lib/stream-chat.module.d.ts +23 -19
- package/lib/stream-textarea.module.d.ts +9 -0
- package/lib/types.d.ts +7 -1
- package/package.json +3 -2
- package/public-api.d.ts +18 -0
- package/src/assets/i18n/en.ts +1 -0
- package/src/assets/version.ts +1 -1
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { __awaiter } from 'tslib';
|
|
2
2
|
import * as i0 from '@angular/core';
|
|
3
|
-
import { Injectable, Component, Input, EventEmitter, Output, ViewChild, HostBinding, NgModule } from '@angular/core';
|
|
3
|
+
import { Injectable, Component, Input, InjectionToken, EventEmitter, Directive, Output, Inject, ViewChild, Pipe, HostBinding, NgModule } from '@angular/core';
|
|
4
4
|
import { BehaviorSubject, ReplaySubject, of, Subject } from 'rxjs';
|
|
5
5
|
import { StreamChat } from 'stream-chat';
|
|
6
|
-
import { map, first, catchError, startWith, distinctUntilChanged, filter, tap } from 'rxjs/operators';
|
|
6
|
+
import { map, first, catchError, startWith, distinctUntilChanged, filter, debounceTime, tap } from 'rxjs/operators';
|
|
7
7
|
import { v4 } from 'uuid';
|
|
8
|
-
import * as
|
|
8
|
+
import * as i1 from '@ngx-translate/core';
|
|
9
9
|
import { TranslateModule } from '@ngx-translate/core';
|
|
10
10
|
import * as i5 from '@angular/common';
|
|
11
11
|
import { CommonModule } from '@angular/common';
|
|
@@ -14,8 +14,10 @@ import calendar from 'dayjs/plugin/calendar';
|
|
|
14
14
|
import * as i2 from '@ctrl/ngx-emoji-mart/ngx-emoji';
|
|
15
15
|
import { EmojiModule } from '@ctrl/ngx-emoji-mart/ngx-emoji';
|
|
16
16
|
import prettybytes from 'pretty-bytes';
|
|
17
|
+
import * as i4 from 'angular-mentions';
|
|
18
|
+
import { MentionModule } from 'angular-mentions';
|
|
17
19
|
|
|
18
|
-
const version = '
|
|
20
|
+
const version = '2.0.0';
|
|
19
21
|
|
|
20
22
|
class NotificationService {
|
|
21
23
|
constructor() {
|
|
@@ -118,6 +120,21 @@ class ChatClientService {
|
|
|
118
120
|
yield this.chatClient.flagMessage(messageId);
|
|
119
121
|
});
|
|
120
122
|
}
|
|
123
|
+
autocompleteUsers(searchTerm) {
|
|
124
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
125
|
+
if (!searchTerm) {
|
|
126
|
+
return [];
|
|
127
|
+
}
|
|
128
|
+
const result = yield this.chatClient.queryUsers({
|
|
129
|
+
$or: [
|
|
130
|
+
{ id: { $autocomplete: searchTerm } },
|
|
131
|
+
{ name: { $autocomplete: searchTerm } },
|
|
132
|
+
],
|
|
133
|
+
id: { $ne: this.chatClient.userID },
|
|
134
|
+
});
|
|
135
|
+
return result.users;
|
|
136
|
+
});
|
|
137
|
+
}
|
|
121
138
|
}
|
|
122
139
|
ChatClientService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ChatClientService, deps: [{ token: i0.NgZone }, { token: i0.ApplicationRef }, { token: NotificationService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
123
140
|
ChatClientService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ChatClientService, providedIn: 'root' });
|
|
@@ -128,7 +145,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
128
145
|
}]
|
|
129
146
|
}], ctorParameters: function () { return [{ type: i0.NgZone }, { type: i0.ApplicationRef }, { type: NotificationService }]; } });
|
|
130
147
|
|
|
131
|
-
const createMessagePreview = (user, text, attachments) => {
|
|
148
|
+
const createMessagePreview = (user, text, attachments, mentionedUsers) => {
|
|
132
149
|
const clientSideId = `${user.id}-${v4()}`;
|
|
133
150
|
return {
|
|
134
151
|
__html: text,
|
|
@@ -141,6 +158,7 @@ const createMessagePreview = (user, text, attachments) => {
|
|
|
141
158
|
type: 'regular',
|
|
142
159
|
user,
|
|
143
160
|
attachments,
|
|
161
|
+
mentioned_users: mentionedUsers,
|
|
144
162
|
};
|
|
145
163
|
};
|
|
146
164
|
|
|
@@ -178,7 +196,8 @@ class ChannelService {
|
|
|
178
196
|
this.activeChannelMessages$ = this.activeChannelMessagesSubject.pipe(map((messages) => {
|
|
179
197
|
const channel = this.activeChannelSubject.getValue();
|
|
180
198
|
return messages.map((message) => {
|
|
181
|
-
if (this.isStreamMessage(message)
|
|
199
|
+
if (this.isStreamMessage(message) &&
|
|
200
|
+
this.isFormatMessageResponse(message)) {
|
|
182
201
|
return message;
|
|
183
202
|
}
|
|
184
203
|
else if (this.isFormatMessageResponse(message)) {
|
|
@@ -258,9 +277,9 @@ class ChannelService {
|
|
|
258
277
|
.getValue()) === null || _a === void 0 ? void 0 : _a.deleteReaction(messageId, reactionType));
|
|
259
278
|
});
|
|
260
279
|
}
|
|
261
|
-
sendMessage(text, attachments = []) {
|
|
280
|
+
sendMessage(text, attachments = [], mentionedUsers = []) {
|
|
262
281
|
return __awaiter(this, void 0, void 0, function* () {
|
|
263
|
-
const preview = createMessagePreview(this.chatClientService.chatClient.user, text, attachments);
|
|
282
|
+
const preview = createMessagePreview(this.chatClientService.chatClient.user, text, attachments, mentionedUsers);
|
|
264
283
|
const channel = this.activeChannelSubject.getValue();
|
|
265
284
|
preview.readBy = [];
|
|
266
285
|
channel.state.addMessageSorted(preview, true);
|
|
@@ -274,6 +293,16 @@ class ChannelService {
|
|
|
274
293
|
yield this.sendMessageRequest(message);
|
|
275
294
|
});
|
|
276
295
|
}
|
|
296
|
+
updateMessage(message) {
|
|
297
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
298
|
+
yield this.chatClientService.chatClient.updateMessage(message);
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
deleteMessage(message) {
|
|
302
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
303
|
+
yield this.chatClientService.chatClient.deleteMessage(message.id);
|
|
304
|
+
});
|
|
305
|
+
}
|
|
277
306
|
uploadAttachments(uploads) {
|
|
278
307
|
return __awaiter(this, void 0, void 0, function* () {
|
|
279
308
|
const result = [];
|
|
@@ -307,7 +336,32 @@ class ChannelService {
|
|
|
307
336
|
: channel.deleteFile(attachmentUpload.url));
|
|
308
337
|
});
|
|
309
338
|
}
|
|
339
|
+
autocompleteMembers(searchTerm) {
|
|
340
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
341
|
+
const activeChannel = this.activeChannelSubject.getValue();
|
|
342
|
+
if (!activeChannel) {
|
|
343
|
+
return [];
|
|
344
|
+
}
|
|
345
|
+
if (Object.keys(activeChannel.state.members).length <= 100) {
|
|
346
|
+
return Object.values(activeChannel.state.members).filter((m) => { var _a; return ((_a = m.user) === null || _a === void 0 ? void 0 : _a.id) !== this.chatClientService.chatClient.userID; });
|
|
347
|
+
}
|
|
348
|
+
else {
|
|
349
|
+
if (!searchTerm) {
|
|
350
|
+
return [];
|
|
351
|
+
}
|
|
352
|
+
const result = yield activeChannel.queryMembers({
|
|
353
|
+
$or: [
|
|
354
|
+
{ id: { $autocomplete: searchTerm } },
|
|
355
|
+
{ name: { $autocomplete: searchTerm } },
|
|
356
|
+
],
|
|
357
|
+
id: { $ne: this.chatClientService.chatClient.userID },
|
|
358
|
+
});
|
|
359
|
+
return Object.values(result.members);
|
|
360
|
+
}
|
|
361
|
+
});
|
|
362
|
+
}
|
|
310
363
|
sendMessageRequest(preview) {
|
|
364
|
+
var _a;
|
|
311
365
|
return __awaiter(this, void 0, void 0, function* () {
|
|
312
366
|
const channel = this.activeChannelSubject.getValue();
|
|
313
367
|
this.activeChannelMessagesSubject.next([...channel.state.messages]);
|
|
@@ -315,6 +369,7 @@ class ChannelService {
|
|
|
315
369
|
yield channel.sendMessage({
|
|
316
370
|
text: preview.text,
|
|
317
371
|
attachments: preview.attachments,
|
|
372
|
+
mentioned_users: (_a = preview.mentioned_users) === null || _a === void 0 ? void 0 : _a.map((u) => u.id),
|
|
318
373
|
id: preview.id,
|
|
319
374
|
});
|
|
320
375
|
}
|
|
@@ -408,6 +463,8 @@ class ChannelService {
|
|
|
408
463
|
.subscribe((c) => void (c === null || c === void 0 ? void 0 : c.markRead()));
|
|
409
464
|
});
|
|
410
465
|
}));
|
|
466
|
+
this.activeChannelSubscriptions.push(channel.on('message.updated', (event) => this.messageUpdated(event)));
|
|
467
|
+
this.activeChannelSubscriptions.push(channel.on('message.deleted', (event) => this.messageUpdated(event)));
|
|
411
468
|
this.activeChannelSubscriptions.push(channel.on('reaction.new', (e) => this.messageReactionEventReceived(e)));
|
|
412
469
|
this.activeChannelSubscriptions.push(channel.on('reaction.deleted', (e) => this.messageReactionEventReceived(e)));
|
|
413
470
|
this.activeChannelSubscriptions.push(channel.on('reaction.updated', (e) => this.messageReactionEventReceived(e)));
|
|
@@ -423,6 +480,16 @@ class ChannelService {
|
|
|
423
480
|
this.activeChannelMessagesSubject.next(this.activeChannelMessagesSubject.getValue());
|
|
424
481
|
}));
|
|
425
482
|
}
|
|
483
|
+
messageUpdated(event) {
|
|
484
|
+
this.ngZone.run(() => {
|
|
485
|
+
const messages = this.activeChannelMessagesSubject.getValue();
|
|
486
|
+
const messageIndex = messages.findIndex((m) => { var _a; return m.id === ((_a = event.message) === null || _a === void 0 ? void 0 : _a.id); });
|
|
487
|
+
if (messageIndex !== -1 && event.message) {
|
|
488
|
+
messages[messageIndex] = event.message;
|
|
489
|
+
this.activeChannelMessagesSubject.next([...messages]);
|
|
490
|
+
}
|
|
491
|
+
});
|
|
492
|
+
}
|
|
426
493
|
messageReactionEventReceived(e) {
|
|
427
494
|
this.ngZone.run(() => {
|
|
428
495
|
var _a, _b, _c, _d;
|
|
@@ -680,6 +747,195 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
680
747
|
}]
|
|
681
748
|
}], ctorParameters: function () { return []; } });
|
|
682
749
|
|
|
750
|
+
const isImageAttachment = (attachment) => {
|
|
751
|
+
return (attachment.type === 'image' &&
|
|
752
|
+
!attachment.title_link &&
|
|
753
|
+
!attachment.og_scrape_url);
|
|
754
|
+
};
|
|
755
|
+
|
|
756
|
+
class AttachmentService {
|
|
757
|
+
constructor(channelService, notificationService) {
|
|
758
|
+
this.channelService = channelService;
|
|
759
|
+
this.notificationService = notificationService;
|
|
760
|
+
this.attachmentUploadInProgressCounterSubject = new BehaviorSubject(0);
|
|
761
|
+
this.attachmentUploadsSubject = new BehaviorSubject([]);
|
|
762
|
+
this.attachmentUploadInProgressCounter$ =
|
|
763
|
+
this.attachmentUploadInProgressCounterSubject.asObservable();
|
|
764
|
+
this.attachmentUploads$ = this.attachmentUploadsSubject.asObservable();
|
|
765
|
+
}
|
|
766
|
+
resetAttachmentUploads() {
|
|
767
|
+
this.attachmentUploadsSubject.next([]);
|
|
768
|
+
}
|
|
769
|
+
filesSelected(fileList) {
|
|
770
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
771
|
+
if (!fileList) {
|
|
772
|
+
return;
|
|
773
|
+
}
|
|
774
|
+
const imageFiles = [];
|
|
775
|
+
const dataFiles = [];
|
|
776
|
+
Array.from(fileList).forEach((file) => {
|
|
777
|
+
if (file.type.startsWith('image/') && !file.type.endsWith('.photoshop')) {
|
|
778
|
+
// photoshop files begin with 'image/'
|
|
779
|
+
imageFiles.push(file);
|
|
780
|
+
}
|
|
781
|
+
else {
|
|
782
|
+
dataFiles.push(file);
|
|
783
|
+
}
|
|
784
|
+
});
|
|
785
|
+
imageFiles.forEach((f) => this.createPreview(f));
|
|
786
|
+
const newUploads = [
|
|
787
|
+
...imageFiles.map((file) => ({
|
|
788
|
+
file,
|
|
789
|
+
state: 'uploading',
|
|
790
|
+
type: 'image',
|
|
791
|
+
})),
|
|
792
|
+
...dataFiles.map((file) => ({
|
|
793
|
+
file,
|
|
794
|
+
state: 'uploading',
|
|
795
|
+
type: 'file',
|
|
796
|
+
})),
|
|
797
|
+
];
|
|
798
|
+
this.attachmentUploadsSubject.next([
|
|
799
|
+
...this.attachmentUploadsSubject.getValue(),
|
|
800
|
+
...newUploads,
|
|
801
|
+
]);
|
|
802
|
+
yield this.uploadAttachments(newUploads);
|
|
803
|
+
});
|
|
804
|
+
}
|
|
805
|
+
retryAttachmentUpload(file) {
|
|
806
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
807
|
+
const attachmentUploads = this.attachmentUploadsSubject.getValue();
|
|
808
|
+
const upload = attachmentUploads.find((u) => u.file === file);
|
|
809
|
+
if (!upload) {
|
|
810
|
+
return;
|
|
811
|
+
}
|
|
812
|
+
upload.state = 'uploading';
|
|
813
|
+
this.attachmentUploadsSubject.next([...attachmentUploads]);
|
|
814
|
+
yield this.uploadAttachments([upload]);
|
|
815
|
+
});
|
|
816
|
+
}
|
|
817
|
+
deleteAttachment(upload) {
|
|
818
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
819
|
+
const attachmentUploads = this.attachmentUploadsSubject.getValue();
|
|
820
|
+
if (upload.state === 'success') {
|
|
821
|
+
try {
|
|
822
|
+
yield this.channelService.deleteAttachment(upload);
|
|
823
|
+
attachmentUploads.splice(attachmentUploads.indexOf(upload), 1);
|
|
824
|
+
}
|
|
825
|
+
catch (error) {
|
|
826
|
+
this.notificationService.addTemporaryNotification('streamChat.Error deleting attachment');
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
else {
|
|
830
|
+
attachmentUploads.splice(attachmentUploads.indexOf(upload), 1);
|
|
831
|
+
}
|
|
832
|
+
this.attachmentUploadsSubject.next([...attachmentUploads]);
|
|
833
|
+
});
|
|
834
|
+
}
|
|
835
|
+
mapToAttachments() {
|
|
836
|
+
const attachmentUploads = this.attachmentUploadsSubject.getValue();
|
|
837
|
+
return attachmentUploads
|
|
838
|
+
.filter((r) => r.state === 'success')
|
|
839
|
+
.map((r) => {
|
|
840
|
+
var _a, _b, _c;
|
|
841
|
+
const attachment = {
|
|
842
|
+
type: r.type,
|
|
843
|
+
};
|
|
844
|
+
if (r.type === 'image') {
|
|
845
|
+
attachment.fallback = (_a = r.file) === null || _a === void 0 ? void 0 : _a.name;
|
|
846
|
+
attachment.image_url = r.url;
|
|
847
|
+
}
|
|
848
|
+
else {
|
|
849
|
+
attachment.asset_url = r.url;
|
|
850
|
+
attachment.title = (_b = r.file) === null || _b === void 0 ? void 0 : _b.name;
|
|
851
|
+
attachment.file_size = (_c = r.file) === null || _c === void 0 ? void 0 : _c.size;
|
|
852
|
+
}
|
|
853
|
+
return attachment;
|
|
854
|
+
});
|
|
855
|
+
}
|
|
856
|
+
createFromAttachments(attachments) {
|
|
857
|
+
const attachmentUploads = [];
|
|
858
|
+
attachments.forEach((attachment) => {
|
|
859
|
+
if (isImageAttachment(attachment)) {
|
|
860
|
+
attachmentUploads.push({
|
|
861
|
+
url: (attachment.img_url ||
|
|
862
|
+
attachment.thumb_url ||
|
|
863
|
+
attachment.image_url),
|
|
864
|
+
state: 'success',
|
|
865
|
+
type: 'image',
|
|
866
|
+
file: {
|
|
867
|
+
name: attachment.fallback,
|
|
868
|
+
},
|
|
869
|
+
});
|
|
870
|
+
}
|
|
871
|
+
else if (attachment.type === 'file') {
|
|
872
|
+
attachmentUploads.push({
|
|
873
|
+
url: attachment.asset_url,
|
|
874
|
+
state: 'success',
|
|
875
|
+
file: {
|
|
876
|
+
name: attachment.title,
|
|
877
|
+
size: attachment.file_size,
|
|
878
|
+
},
|
|
879
|
+
type: 'file',
|
|
880
|
+
});
|
|
881
|
+
}
|
|
882
|
+
});
|
|
883
|
+
if (attachmentUploads.length > 0) {
|
|
884
|
+
this.attachmentUploadsSubject.next([
|
|
885
|
+
...this.attachmentUploadsSubject.getValue(),
|
|
886
|
+
...attachmentUploads,
|
|
887
|
+
]);
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
createPreview(file) {
|
|
891
|
+
const reader = new FileReader();
|
|
892
|
+
reader.onload = (event) => {
|
|
893
|
+
var _a;
|
|
894
|
+
const attachmentUploads = this.attachmentUploadsSubject.getValue();
|
|
895
|
+
const upload = attachmentUploads.find((upload) => upload.file === file);
|
|
896
|
+
if (!upload) {
|
|
897
|
+
return;
|
|
898
|
+
}
|
|
899
|
+
upload.previewUri = ((_a = event.target) === null || _a === void 0 ? void 0 : _a.result) || undefined;
|
|
900
|
+
this.attachmentUploadsSubject.next([...attachmentUploads]);
|
|
901
|
+
};
|
|
902
|
+
reader.readAsDataURL(file);
|
|
903
|
+
}
|
|
904
|
+
uploadAttachments(uploads) {
|
|
905
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
906
|
+
const attachmentUploads = this.attachmentUploadsSubject.getValue();
|
|
907
|
+
this.attachmentUploadInProgressCounterSubject.next(this.attachmentUploadInProgressCounterSubject.getValue() + 1);
|
|
908
|
+
const result = yield this.channelService.uploadAttachments(uploads);
|
|
909
|
+
result.forEach((r) => {
|
|
910
|
+
const upload = attachmentUploads.find((upload) => upload.file === r.file);
|
|
911
|
+
if (!upload) {
|
|
912
|
+
if (r.url) {
|
|
913
|
+
void this.channelService.deleteAttachment(r);
|
|
914
|
+
}
|
|
915
|
+
return;
|
|
916
|
+
}
|
|
917
|
+
upload.state = r.state;
|
|
918
|
+
upload.url = r.url;
|
|
919
|
+
if (upload.state === 'error') {
|
|
920
|
+
this.notificationService.addTemporaryNotification(upload.type === 'image'
|
|
921
|
+
? 'streamChat.Error uploading image'
|
|
922
|
+
: 'streamChat.Error uploading file');
|
|
923
|
+
}
|
|
924
|
+
});
|
|
925
|
+
this.attachmentUploadInProgressCounterSubject.next(this.attachmentUploadInProgressCounterSubject.getValue() - 1);
|
|
926
|
+
this.attachmentUploadsSubject.next([...attachmentUploads]);
|
|
927
|
+
});
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
AttachmentService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: AttachmentService, deps: [{ token: ChannelService }, { token: NotificationService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
931
|
+
AttachmentService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: AttachmentService, providedIn: 'root' });
|
|
932
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: AttachmentService, decorators: [{
|
|
933
|
+
type: Injectable,
|
|
934
|
+
args: [{
|
|
935
|
+
providedIn: 'root',
|
|
936
|
+
}]
|
|
937
|
+
}], ctorParameters: function () { return [{ type: ChannelService }, { type: NotificationService }]; } });
|
|
938
|
+
|
|
683
939
|
const en = {
|
|
684
940
|
streamChat: {
|
|
685
941
|
'1 reply': '1 reply',
|
|
@@ -705,6 +961,7 @@ const en = {
|
|
|
705
961
|
'Error unmuting a user ...': 'Error unmuting a user ...',
|
|
706
962
|
'Error uploading file': 'Error uploading file',
|
|
707
963
|
'Error uploading image': 'Error uploading image',
|
|
964
|
+
'Error deleting attachment': 'Error deleting attachment',
|
|
708
965
|
'Error · Unsent': 'Error · Unsent',
|
|
709
966
|
'Error: {{ errorMessage }}': 'Error: {{ errorMessage }}',
|
|
710
967
|
Flag: 'Flag',
|
|
@@ -772,14 +1029,14 @@ class StreamI18nService {
|
|
|
772
1029
|
this.translteService.setTranslation(lang, { streamChat: Object.assign(Object.assign({}, en.streamChat), overrides) }, true);
|
|
773
1030
|
}
|
|
774
1031
|
}
|
|
775
|
-
StreamI18nService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: StreamI18nService, deps: [{ token:
|
|
1032
|
+
StreamI18nService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: StreamI18nService, deps: [{ token: i1.TranslateService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
776
1033
|
StreamI18nService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: StreamI18nService, providedIn: 'root' });
|
|
777
1034
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: StreamI18nService, decorators: [{
|
|
778
1035
|
type: Injectable,
|
|
779
1036
|
args: [{
|
|
780
1037
|
providedIn: 'root',
|
|
781
1038
|
}]
|
|
782
|
-
}], ctorParameters: function () { return [{ type:
|
|
1039
|
+
}], ctorParameters: function () { return [{ type: i1.TranslateService }]; } });
|
|
783
1040
|
|
|
784
1041
|
class AvatarComponent {
|
|
785
1042
|
constructor() {
|
|
@@ -813,7 +1070,7 @@ class IconComponent {
|
|
|
813
1070
|
constructor() { }
|
|
814
1071
|
}
|
|
815
1072
|
IconComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: IconComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
816
|
-
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", directives: [{ type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type:
|
|
1073
|
+
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", directives: [{ type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }] });
|
|
817
1074
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: IconComponent, decorators: [{
|
|
818
1075
|
type: Component,
|
|
819
1076
|
args: [{
|
|
@@ -833,29 +1090,408 @@ class LoadingIndicatorComponent {
|
|
|
833
1090
|
this.color = '#006CFF';
|
|
834
1091
|
}
|
|
835
1092
|
}
|
|
836
|
-
LoadingIndicatorComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: LoadingIndicatorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
837
|
-
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: i5.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] });
|
|
838
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: LoadingIndicatorComponent, decorators: [{
|
|
1093
|
+
LoadingIndicatorComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: LoadingIndicatorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1094
|
+
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: i5.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] });
|
|
1095
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: LoadingIndicatorComponent, decorators: [{
|
|
1096
|
+
type: Component,
|
|
1097
|
+
args: [{
|
|
1098
|
+
selector: 'stream-loading-indicator',
|
|
1099
|
+
templateUrl: './loading-indicator.component.html',
|
|
1100
|
+
styles: [],
|
|
1101
|
+
}]
|
|
1102
|
+
}], ctorParameters: function () { return []; }, propDecorators: { size: [{
|
|
1103
|
+
type: Input
|
|
1104
|
+
}], color: [{
|
|
1105
|
+
type: Input
|
|
1106
|
+
}] } });
|
|
1107
|
+
|
|
1108
|
+
const textareaInjectionToken = new InjectionToken('textareaInjectionToken');
|
|
1109
|
+
|
|
1110
|
+
class TextareaDirective {
|
|
1111
|
+
constructor(viewContainerRef) {
|
|
1112
|
+
this.viewContainerRef = viewContainerRef;
|
|
1113
|
+
this.value = '';
|
|
1114
|
+
this.valueChange = new EventEmitter();
|
|
1115
|
+
this.send = new EventEmitter();
|
|
1116
|
+
this.userMentions = new EventEmitter();
|
|
1117
|
+
this.subscriptions = [];
|
|
1118
|
+
}
|
|
1119
|
+
ngOnChanges(changes) {
|
|
1120
|
+
if (!this.componentRef) {
|
|
1121
|
+
return;
|
|
1122
|
+
}
|
|
1123
|
+
if (changes.componentRef) {
|
|
1124
|
+
this.subscriptions.forEach((s) => s.unsubscribe());
|
|
1125
|
+
if (this.componentRef) {
|
|
1126
|
+
this.subscriptions.push(this.componentRef.instance.valueChange.subscribe((value) => this.valueChange.next(value)));
|
|
1127
|
+
this.subscriptions.push(this.componentRef.instance.send.subscribe((value) => this.send.next(value)));
|
|
1128
|
+
if (this.componentRef.instance.userMentions) {
|
|
1129
|
+
this.subscriptions.push(this.componentRef.instance.userMentions.subscribe((value) => this.userMentions.next(value)));
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
}
|
|
1133
|
+
if (changes.areMentionsEnabled) {
|
|
1134
|
+
this.componentRef.instance.areMentionsEnabled = this.areMentionsEnabled;
|
|
1135
|
+
}
|
|
1136
|
+
if (changes.mentionAutocompleteItemTemplate) {
|
|
1137
|
+
this.componentRef.instance.mentionAutocompleteItemTemplate =
|
|
1138
|
+
this.mentionAutocompleteItemTemplate;
|
|
1139
|
+
}
|
|
1140
|
+
if (changes.mentionScope) {
|
|
1141
|
+
this.componentRef.instance.mentionScope = this.mentionScope;
|
|
1142
|
+
}
|
|
1143
|
+
if (changes.value) {
|
|
1144
|
+
this.componentRef.instance.value = this.value;
|
|
1145
|
+
}
|
|
1146
|
+
// ngOnChanges not called for dynamic components since we don't use template binding
|
|
1147
|
+
// eslint-disable-next-line @angular-eslint/no-lifecycle-call
|
|
1148
|
+
this.componentRef.instance.ngOnChanges(changes);
|
|
1149
|
+
}
|
|
1150
|
+
}
|
|
1151
|
+
TextareaDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: TextareaDirective, deps: [{ token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Directive });
|
|
1152
|
+
TextareaDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "12.2.5", type: TextareaDirective, selector: "[streamTextarea]", inputs: { componentRef: "componentRef", areMentionsEnabled: "areMentionsEnabled", mentionAutocompleteItemTemplate: "mentionAutocompleteItemTemplate", mentionScope: "mentionScope", value: "value" }, outputs: { valueChange: "valueChange", send: "send", userMentions: "userMentions" }, usesOnChanges: true, ngImport: i0 });
|
|
1153
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: TextareaDirective, decorators: [{
|
|
1154
|
+
type: Directive,
|
|
1155
|
+
args: [{
|
|
1156
|
+
selector: '[streamTextarea]',
|
|
1157
|
+
}]
|
|
1158
|
+
}], ctorParameters: function () { return [{ type: i0.ViewContainerRef }]; }, propDecorators: { componentRef: [{
|
|
1159
|
+
type: Input
|
|
1160
|
+
}], areMentionsEnabled: [{
|
|
1161
|
+
type: Input
|
|
1162
|
+
}], mentionAutocompleteItemTemplate: [{
|
|
1163
|
+
type: Input
|
|
1164
|
+
}], mentionScope: [{
|
|
1165
|
+
type: Input
|
|
1166
|
+
}], value: [{
|
|
1167
|
+
type: Input
|
|
1168
|
+
}], valueChange: [{
|
|
1169
|
+
type: Output
|
|
1170
|
+
}], send: [{
|
|
1171
|
+
type: Output
|
|
1172
|
+
}], userMentions: [{
|
|
1173
|
+
type: Output
|
|
1174
|
+
}] } });
|
|
1175
|
+
|
|
1176
|
+
class MessageInputConfigService {
|
|
1177
|
+
constructor() {
|
|
1178
|
+
this.isFileUploadEnabled = true;
|
|
1179
|
+
this.areMentionsEnabled = true;
|
|
1180
|
+
this.isMultipleFileUploadEnabled = true;
|
|
1181
|
+
this.mentionScope = 'channel';
|
|
1182
|
+
}
|
|
1183
|
+
}
|
|
1184
|
+
MessageInputConfigService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: MessageInputConfigService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1185
|
+
MessageInputConfigService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: MessageInputConfigService, providedIn: 'root' });
|
|
1186
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: MessageInputConfigService, decorators: [{
|
|
1187
|
+
type: Injectable,
|
|
1188
|
+
args: [{
|
|
1189
|
+
providedIn: 'root',
|
|
1190
|
+
}]
|
|
1191
|
+
}], ctorParameters: function () { return []; } });
|
|
1192
|
+
|
|
1193
|
+
class AttachmentPreviewListComponent {
|
|
1194
|
+
constructor(attachmentService) {
|
|
1195
|
+
this.attachmentService = attachmentService;
|
|
1196
|
+
this.attachmentUploads$ = this.attachmentService.attachmentUploads$;
|
|
1197
|
+
}
|
|
1198
|
+
retryAttachmentUpload(file) {
|
|
1199
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1200
|
+
yield this.attachmentService.retryAttachmentUpload(file);
|
|
1201
|
+
});
|
|
1202
|
+
}
|
|
1203
|
+
deleteAttachment(upload) {
|
|
1204
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1205
|
+
yield this.attachmentService.deleteAttachment(upload);
|
|
1206
|
+
});
|
|
1207
|
+
}
|
|
1208
|
+
trackByFile(_, item) {
|
|
1209
|
+
return item.file;
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1212
|
+
AttachmentPreviewListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: AttachmentPreviewListComponent, deps: [{ token: AttachmentService }], target: i0.ɵɵFactoryTarget.Component });
|
|
1213
|
+
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\">\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)=\"retryAttachmentUpload(attachmentUpload.file)\"\n (keyup.enter)=\"retryAttachmentUpload(attachmentUpload.file)\"\n data-testclass=\"upload-error\"\n >\n <stream-icon icon=\"retry\"></stream-icon>\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)=\"deleteAttachment(attachmentUpload)\"\n (keyup.enter)=\"deleteAttachment(attachmentUpload)\"\n >\n <stream-icon icon=\"close\"></stream-icon>\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\n data-testclass=\"loading-indicator\"\n color=\"rgba(255,255,255,0.7)\"\n *ngIf=\"attachmentUpload.state === 'uploading'\"\n ></stream-loading-indicator>\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 icon=\"file\"></stream-icon>\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)=\"retryAttachmentUpload(attachmentUpload.file)\"\n (keyup.enter)=\"retryAttachmentUpload(attachmentUpload.file)\"\n translate\n >\n streamChat.failed\n </div>\n <div\n class=\"rfu-file-previewer__retry\"\n (click)=\"retryAttachmentUpload(attachmentUpload.file)\"\n (keyup.enter)=\"retryAttachmentUpload(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)=\"deleteAttachment(attachmentUpload)\"\n (keyup.enter)=\"deleteAttachment(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></stream-loading-indicator>\n </div>\n </li>\n </ol>\n </div>\n </ng-container>\n</div>\n", components: [{ type: IconComponent, selector: "stream-icon", inputs: ["icon", "size"] }, { type: LoadingIndicatorComponent, selector: "stream-loading-indicator", inputs: ["size", "color"] }], directives: [{ type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }], pipes: { "async": i5.AsyncPipe } });
|
|
1214
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: AttachmentPreviewListComponent, decorators: [{
|
|
1215
|
+
type: Component,
|
|
1216
|
+
args: [{
|
|
1217
|
+
selector: 'stream-attachment-preview-list',
|
|
1218
|
+
templateUrl: './attachment-preview-list.component.html',
|
|
1219
|
+
styles: [],
|
|
1220
|
+
}]
|
|
1221
|
+
}], ctorParameters: function () { return [{ type: AttachmentService }]; } });
|
|
1222
|
+
|
|
1223
|
+
class MessageInputComponent {
|
|
1224
|
+
constructor(channelService, notificationService, attachmentService, configService, textareaType, componentFactoryResolver) {
|
|
1225
|
+
this.channelService = channelService;
|
|
1226
|
+
this.notificationService = notificationService;
|
|
1227
|
+
this.attachmentService = attachmentService;
|
|
1228
|
+
this.configService = configService;
|
|
1229
|
+
this.textareaType = textareaType;
|
|
1230
|
+
this.componentFactoryResolver = componentFactoryResolver;
|
|
1231
|
+
this.messageUpdate = new EventEmitter();
|
|
1232
|
+
this.textareaValue = '';
|
|
1233
|
+
this.mentionedUsers = [];
|
|
1234
|
+
this.subscriptions = [];
|
|
1235
|
+
this.subscriptions.push(this.channelService.activeChannel$.subscribe((channel) => {
|
|
1236
|
+
var _a;
|
|
1237
|
+
this.textareaValue = '';
|
|
1238
|
+
this.attachmentService.resetAttachmentUploads();
|
|
1239
|
+
const capabilities = (_a = channel === null || channel === void 0 ? void 0 : channel.data) === null || _a === void 0 ? void 0 : _a.own_capabilities;
|
|
1240
|
+
if (capabilities) {
|
|
1241
|
+
this.isFileUploadAuthorized =
|
|
1242
|
+
capabilities.indexOf('upload-file') !== -1;
|
|
1243
|
+
}
|
|
1244
|
+
}));
|
|
1245
|
+
this.subscriptions.push(this.attachmentService.attachmentUploadInProgressCounter$.subscribe((counter) => {
|
|
1246
|
+
if (counter === 0 && this.hideNotification) {
|
|
1247
|
+
this.hideNotification();
|
|
1248
|
+
this.hideNotification = undefined;
|
|
1249
|
+
}
|
|
1250
|
+
}));
|
|
1251
|
+
this.attachmentUploads$ = this.attachmentService.attachmentUploads$;
|
|
1252
|
+
this.isFileUploadEnabled = this.configService.isFileUploadEnabled;
|
|
1253
|
+
this.acceptedFileTypes = this.configService.acceptedFileTypes;
|
|
1254
|
+
this.isMultipleFileUploadEnabled =
|
|
1255
|
+
this.configService.isMultipleFileUploadEnabled;
|
|
1256
|
+
this.areMentionsEnabled = this.configService.areMentionsEnabled;
|
|
1257
|
+
this.mentionAutocompleteItemTemplate =
|
|
1258
|
+
this.configService.mentionAutocompleteItemTemplate;
|
|
1259
|
+
this.mentionScope = this.configService.mentionScope;
|
|
1260
|
+
}
|
|
1261
|
+
ngOnInit() {
|
|
1262
|
+
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(this.textareaType);
|
|
1263
|
+
this.textareaRef =
|
|
1264
|
+
this.textareaAnchor.viewContainerRef.createComponent(componentFactory);
|
|
1265
|
+
}
|
|
1266
|
+
ngOnChanges(changes) {
|
|
1267
|
+
if (changes.message) {
|
|
1268
|
+
this.attachmentService.resetAttachmentUploads();
|
|
1269
|
+
if (this.isUpdate) {
|
|
1270
|
+
this.attachmentService.createFromAttachments(this.message.attachments || []);
|
|
1271
|
+
this.textareaValue = this.message.text || '';
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
1274
|
+
if (changes.isFileUploadEnabled) {
|
|
1275
|
+
this.configService.isFileUploadEnabled = this.isFileUploadEnabled;
|
|
1276
|
+
}
|
|
1277
|
+
if (changes.acceptedFileTypes) {
|
|
1278
|
+
this.configService.acceptedFileTypes = this.acceptedFileTypes;
|
|
1279
|
+
}
|
|
1280
|
+
if (changes.isMultipleFileUploadEnabled) {
|
|
1281
|
+
this.configService.isMultipleFileUploadEnabled =
|
|
1282
|
+
this.isMultipleFileUploadEnabled;
|
|
1283
|
+
}
|
|
1284
|
+
if (changes.areMentionsEnabled) {
|
|
1285
|
+
this.configService.areMentionsEnabled = this.areMentionsEnabled;
|
|
1286
|
+
}
|
|
1287
|
+
if (changes.mentionAutocompleteItemTemplate) {
|
|
1288
|
+
this.configService.mentionAutocompleteItemTemplate =
|
|
1289
|
+
this.mentionAutocompleteItemTemplate;
|
|
1290
|
+
}
|
|
1291
|
+
if (changes.mentionScope) {
|
|
1292
|
+
this.configService.mentionScope = this.mentionScope;
|
|
1293
|
+
}
|
|
1294
|
+
}
|
|
1295
|
+
ngOnDestroy() {
|
|
1296
|
+
this.subscriptions.forEach((s) => s.unsubscribe());
|
|
1297
|
+
}
|
|
1298
|
+
messageSent() {
|
|
1299
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1300
|
+
let attachmentUploadInProgressCounter;
|
|
1301
|
+
this.attachmentService.attachmentUploadInProgressCounter$
|
|
1302
|
+
.pipe(first())
|
|
1303
|
+
.subscribe((counter) => (attachmentUploadInProgressCounter = counter));
|
|
1304
|
+
if (attachmentUploadInProgressCounter > 0) {
|
|
1305
|
+
if (!this.hideNotification) {
|
|
1306
|
+
this.hideNotification =
|
|
1307
|
+
this.notificationService.addPermanentNotification('streamChat.Wait until all attachments have uploaded');
|
|
1308
|
+
}
|
|
1309
|
+
return;
|
|
1310
|
+
}
|
|
1311
|
+
const attachments = this.attachmentService.mapToAttachments();
|
|
1312
|
+
const text = this.textareaValue;
|
|
1313
|
+
if (!text && (!attachments || attachments.length === 0)) {
|
|
1314
|
+
return;
|
|
1315
|
+
}
|
|
1316
|
+
if (!this.isUpdate) {
|
|
1317
|
+
this.textareaValue = '';
|
|
1318
|
+
}
|
|
1319
|
+
try {
|
|
1320
|
+
yield (this.isUpdate
|
|
1321
|
+
? this.channelService.updateMessage(Object.assign(Object.assign({}, this.message), { text: text, attachments: attachments }))
|
|
1322
|
+
: this.channelService.sendMessage(text, attachments, this.mentionedUsers));
|
|
1323
|
+
this.messageUpdate.emit();
|
|
1324
|
+
if (!this.isUpdate) {
|
|
1325
|
+
this.attachmentService.resetAttachmentUploads();
|
|
1326
|
+
}
|
|
1327
|
+
}
|
|
1328
|
+
catch (error) {
|
|
1329
|
+
if (this.isUpdate) {
|
|
1330
|
+
this.notificationService.addTemporaryNotification('streamChat.Edit message request failed');
|
|
1331
|
+
}
|
|
1332
|
+
}
|
|
1333
|
+
});
|
|
1334
|
+
}
|
|
1335
|
+
get accept() {
|
|
1336
|
+
var _a;
|
|
1337
|
+
return this.acceptedFileTypes ? (_a = this.acceptedFileTypes) === null || _a === void 0 ? void 0 : _a.join(',') : '';
|
|
1338
|
+
}
|
|
1339
|
+
filesSelected(fileList) {
|
|
1340
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1341
|
+
yield this.attachmentService.filesSelected(fileList);
|
|
1342
|
+
this.clearFileInput();
|
|
1343
|
+
});
|
|
1344
|
+
}
|
|
1345
|
+
clearFileInput() {
|
|
1346
|
+
this.fileInput.nativeElement.value = '';
|
|
1347
|
+
}
|
|
1348
|
+
get isUpdate() {
|
|
1349
|
+
return !!this.message;
|
|
1350
|
+
}
|
|
1351
|
+
}
|
|
1352
|
+
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 }], target: i0.ɵɵFactoryTarget.Component });
|
|
1353
|
+
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", mentionAutocompleteItemTemplate: "mentionAutocompleteItemTemplate", acceptedFileTypes: "acceptedFileTypes", isMultipleFileUploadEnabled: "isMultipleFileUploadEnabled", message: "message" }, outputs: { messageUpdate: "messageUpdate" }, providers: [AttachmentService], viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true }, { propertyName: "textareaAnchor", first: true, predicate: TextareaDirective, descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<div\n class=\"str-chat__input-flat\"\n [class.str-chat__input-flat-has-attachments]=\"\n (attachmentUploads$ | async)!.length > 0\n \"\n>\n <div class=\"str-chat__input-flat-wrapper\">\n <div class=\"str-chat__input-flat--textarea-wrapper\">\n <stream-attachment-preview-list\n class=\"rfu-image-previewer-angular-host\"\n ></stream-attachment-preview-list>\n <div class=\"rta str-chat__textarea\">\n <ng-template\n streamTextarea\n [(value)]=\"textareaValue\"\n (send)=\"messageSent()\"\n [componentRef]=\"textareaRef\"\n (userMentions)=\"mentionedUsers = $event\"\n [areMentionsEnabled]=\"areMentionsEnabled\"\n [mentionAutocompleteItemTemplate]=\"mentionAutocompleteItemTemplate\"\n [mentionScope]=\"mentionScope\"\n ></ng-template>\n </div>\n <div\n *ngIf=\"isFileUploadEnabled && isFileUploadAuthorized\"\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 [accept]=\"accept\"\n [multiple]=\"isMultipleFileUploadEnabled\"\n (change)=\"filesSelected(fileInput.files)\"\n />\n <span class=\"str-chat__input-flat-fileupload\">\n <stream-icon icon=\"file-upload\"></stream-icon>\n </span>\n </label>\n </div>\n </div>\n </div>\n <button\n data-testid=\"send-button\"\n class=\"str-chat__send-button\"\n (click)=\"messageSent()\"\n (keyup.enter)=\"messageSent()\"\n >\n <stream-icon icon=\"send\"></stream-icon>\n </button>\n </div>\n</div>\n", components: [{ type: AttachmentPreviewListComponent, selector: "stream-attachment-preview-list" }, { type: IconComponent, selector: "stream-icon", inputs: ["icon", "size"] }], directives: [{ type: TextareaDirective, selector: "[streamTextarea]", inputs: ["componentRef", "areMentionsEnabled", "mentionAutocompleteItemTemplate", "mentionScope", "value"], outputs: ["valueChange", "send", "userMentions"] }, { type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], pipes: { "async": i5.AsyncPipe, "translate": i1.TranslatePipe } });
|
|
1354
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: MessageInputComponent, decorators: [{
|
|
1355
|
+
type: Component,
|
|
1356
|
+
args: [{
|
|
1357
|
+
selector: 'stream-message-input',
|
|
1358
|
+
templateUrl: './message-input.component.html',
|
|
1359
|
+
styles: [],
|
|
1360
|
+
providers: [AttachmentService],
|
|
1361
|
+
}]
|
|
1362
|
+
}], ctorParameters: function () { return [{ type: ChannelService }, { type: NotificationService }, { type: AttachmentService }, { type: MessageInputConfigService }, { type: i0.Type, decorators: [{
|
|
1363
|
+
type: Inject,
|
|
1364
|
+
args: [textareaInjectionToken]
|
|
1365
|
+
}] }, { type: i0.ComponentFactoryResolver }]; }, propDecorators: { isFileUploadEnabled: [{
|
|
1366
|
+
type: Input
|
|
1367
|
+
}], areMentionsEnabled: [{
|
|
1368
|
+
type: Input
|
|
1369
|
+
}], mentionScope: [{
|
|
1370
|
+
type: Input
|
|
1371
|
+
}], mentionAutocompleteItemTemplate: [{
|
|
1372
|
+
type: Input
|
|
1373
|
+
}], acceptedFileTypes: [{
|
|
1374
|
+
type: Input
|
|
1375
|
+
}], isMultipleFileUploadEnabled: [{
|
|
1376
|
+
type: Input
|
|
1377
|
+
}], message: [{
|
|
1378
|
+
type: Input
|
|
1379
|
+
}], messageUpdate: [{
|
|
1380
|
+
type: Output
|
|
1381
|
+
}], fileInput: [{
|
|
1382
|
+
type: ViewChild,
|
|
1383
|
+
args: ['fileInput']
|
|
1384
|
+
}], textareaAnchor: [{
|
|
1385
|
+
type: ViewChild,
|
|
1386
|
+
args: [TextareaDirective, { static: true }]
|
|
1387
|
+
}] } });
|
|
1388
|
+
|
|
1389
|
+
class ModalComponent {
|
|
1390
|
+
constructor() {
|
|
1391
|
+
this.isOpen = false;
|
|
1392
|
+
this.isOpenChange = new EventEmitter();
|
|
1393
|
+
this.watchForEscPress = (event) => {
|
|
1394
|
+
if (event.key === 'Escape') {
|
|
1395
|
+
this.close();
|
|
1396
|
+
}
|
|
1397
|
+
};
|
|
1398
|
+
this.stopWatchForEscPress = () => {
|
|
1399
|
+
window.removeEventListener('keyup', this.watchForEscPress);
|
|
1400
|
+
};
|
|
1401
|
+
this.watchForOutsideClicks = (event) => {
|
|
1402
|
+
var _a;
|
|
1403
|
+
if (!((_a = this.content) === null || _a === void 0 ? void 0 : _a.nativeElement.contains(event.target))) {
|
|
1404
|
+
this.close();
|
|
1405
|
+
}
|
|
1406
|
+
};
|
|
1407
|
+
}
|
|
1408
|
+
ngOnChanges(changes) {
|
|
1409
|
+
if (changes.isOpen) {
|
|
1410
|
+
if (this.isOpen) {
|
|
1411
|
+
window.addEventListener('keyup', this.watchForEscPress);
|
|
1412
|
+
setTimeout(() => window.addEventListener('click', this.watchForOutsideClicks), 0);
|
|
1413
|
+
}
|
|
1414
|
+
else {
|
|
1415
|
+
this.stopWatchForOutsideClicks();
|
|
1416
|
+
this.stopWatchForEscPress();
|
|
1417
|
+
}
|
|
1418
|
+
}
|
|
1419
|
+
}
|
|
1420
|
+
close() {
|
|
1421
|
+
this.isOpen = false;
|
|
1422
|
+
this.isOpenChange.emit(false);
|
|
1423
|
+
this.stopWatchForOutsideClicks();
|
|
1424
|
+
this.stopWatchForEscPress();
|
|
1425
|
+
}
|
|
1426
|
+
stopWatchForOutsideClicks() {
|
|
1427
|
+
window.removeEventListener('click', this.watchForOutsideClicks);
|
|
1428
|
+
}
|
|
1429
|
+
}
|
|
1430
|
+
ModalComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1431
|
+
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: i1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }] });
|
|
1432
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ModalComponent, decorators: [{
|
|
1433
|
+
type: Component,
|
|
1434
|
+
args: [{
|
|
1435
|
+
selector: 'stream-modal',
|
|
1436
|
+
templateUrl: './modal.component.html',
|
|
1437
|
+
styles: [],
|
|
1438
|
+
}]
|
|
1439
|
+
}], ctorParameters: function () { return []; }, propDecorators: { isOpen: [{
|
|
1440
|
+
type: Input
|
|
1441
|
+
}], isOpenChange: [{
|
|
1442
|
+
type: Output
|
|
1443
|
+
}], content: [{
|
|
1444
|
+
type: ViewChild,
|
|
1445
|
+
args: ['content']
|
|
1446
|
+
}] } });
|
|
1447
|
+
|
|
1448
|
+
class NotificationComponent {
|
|
1449
|
+
constructor() { }
|
|
1450
|
+
}
|
|
1451
|
+
NotificationComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: NotificationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1452
|
+
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" });
|
|
1453
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: NotificationComponent, decorators: [{
|
|
1454
|
+
type: Component,
|
|
1455
|
+
args: [{
|
|
1456
|
+
selector: 'stream-notification',
|
|
1457
|
+
templateUrl: './notification.component.html',
|
|
1458
|
+
styles: [],
|
|
1459
|
+
}]
|
|
1460
|
+
}], ctorParameters: function () { return []; }, propDecorators: { type: [{
|
|
1461
|
+
type: Input
|
|
1462
|
+
}] } });
|
|
1463
|
+
|
|
1464
|
+
class NotificationListComponent {
|
|
1465
|
+
constructor(notificationService) {
|
|
1466
|
+
this.notificationService = notificationService;
|
|
1467
|
+
this.notifications$ = this.notificationService.notifications$;
|
|
1468
|
+
}
|
|
1469
|
+
trackByItem(_, item) {
|
|
1470
|
+
return item;
|
|
1471
|
+
}
|
|
1472
|
+
}
|
|
1473
|
+
NotificationListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: NotificationListComponent, deps: [{ token: NotificationService }], target: i0.ɵɵFactoryTarget.Component });
|
|
1474
|
+
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 <stream-notification\n *ngFor=\"let notification of notifications$ | async; trackBy: trackByItem\"\n [type]=\"notification.type\"\n ><div data-testclass=\"notification-content\" translate>\n {{ notification.text }}\n </div></stream-notification\n >\n</div>\n", components: [{ type: NotificationComponent, selector: "stream-notification", inputs: ["type"] }], directives: [{ type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }], pipes: { "async": i5.AsyncPipe } });
|
|
1475
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: NotificationListComponent, decorators: [{
|
|
839
1476
|
type: Component,
|
|
840
1477
|
args: [{
|
|
841
|
-
selector: 'stream-
|
|
842
|
-
templateUrl: './
|
|
1478
|
+
selector: 'stream-notification-list',
|
|
1479
|
+
templateUrl: './notification-list.component.html',
|
|
843
1480
|
styles: [],
|
|
844
1481
|
}]
|
|
845
|
-
}], ctorParameters: function () { return []; }
|
|
846
|
-
type: Input
|
|
847
|
-
}], color: [{
|
|
848
|
-
type: Input
|
|
849
|
-
}] } });
|
|
1482
|
+
}], ctorParameters: function () { return [{ type: NotificationService }]; } });
|
|
850
1483
|
|
|
851
1484
|
class MessageActionsBoxComponent {
|
|
852
|
-
constructor(chatClientService, notificationService) {
|
|
1485
|
+
constructor(chatClientService, notificationService, channelService) {
|
|
853
1486
|
this.chatClientService = chatClientService;
|
|
854
1487
|
this.notificationService = notificationService;
|
|
1488
|
+
this.channelService = channelService;
|
|
855
1489
|
this.isOpen = false;
|
|
856
1490
|
this.isMine = false;
|
|
857
1491
|
this.enabledActions = [];
|
|
858
1492
|
this.displayedActionsCount = new EventEmitter();
|
|
1493
|
+
this.isEditing = new EventEmitter();
|
|
1494
|
+
this.isEditModalOpen = false;
|
|
859
1495
|
}
|
|
860
1496
|
ngOnChanges(changes) {
|
|
861
1497
|
if (changes.isMine || changes.enabledActions) {
|
|
@@ -885,10 +1521,12 @@ class MessageActionsBoxComponent {
|
|
|
885
1521
|
return this.enabledActions.indexOf('quote') !== -1;
|
|
886
1522
|
}
|
|
887
1523
|
get isEditVisible() {
|
|
888
|
-
return this.enabledActions.indexOf('edit') !== -1
|
|
1524
|
+
return ((this.enabledActions.indexOf('edit') !== -1 && this.isMine) ||
|
|
1525
|
+
this.enabledActions.indexOf('edit-any') !== -1);
|
|
889
1526
|
}
|
|
890
1527
|
get isDeleteVisible() {
|
|
891
|
-
return this.enabledActions.indexOf('delete') !== -1
|
|
1528
|
+
return ((this.enabledActions.indexOf('delete') !== -1 && this.isMine) ||
|
|
1529
|
+
this.enabledActions.indexOf('delete-any') !== -1);
|
|
892
1530
|
}
|
|
893
1531
|
get isMuteVisible() {
|
|
894
1532
|
return this.enabledActions.indexOf('mute') !== -1;
|
|
@@ -920,14 +1558,30 @@ class MessageActionsBoxComponent {
|
|
|
920
1558
|
alert('Feature not yet implemented');
|
|
921
1559
|
}
|
|
922
1560
|
editClicked() {
|
|
923
|
-
|
|
1561
|
+
this.isEditing.emit(true);
|
|
1562
|
+
this.isEditModalOpen = true;
|
|
1563
|
+
}
|
|
1564
|
+
sendClicked() {
|
|
1565
|
+
var _a;
|
|
1566
|
+
(_a = this.messageInput) === null || _a === void 0 ? void 0 : _a.messageSent();
|
|
1567
|
+
}
|
|
1568
|
+
modalClosed() {
|
|
1569
|
+
this.isEditModalOpen = false;
|
|
1570
|
+
this.isEditing.emit(false);
|
|
924
1571
|
}
|
|
925
1572
|
deleteClicked() {
|
|
926
|
-
|
|
1573
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1574
|
+
try {
|
|
1575
|
+
yield this.channelService.deleteMessage(this.message);
|
|
1576
|
+
}
|
|
1577
|
+
catch (error) {
|
|
1578
|
+
this.notificationService.addTemporaryNotification('streamChat.Error deleting message');
|
|
1579
|
+
}
|
|
1580
|
+
});
|
|
927
1581
|
}
|
|
928
1582
|
}
|
|
929
|
-
MessageActionsBoxComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: MessageActionsBoxComponent, deps: [{ token: ChatClientService }, { token: NotificationService }], target: i0.ɵɵFactoryTarget.Component });
|
|
930
|
-
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" }, 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 <button\n data-testid=\"quote-action\"\n *ngIf=\"isQuoteVisible\"\n (click)=\"quoteClicked()\"\n >\n <li class=\"str-chat__message-actions-list-item\">\n {{ \"streamChat.Reply\" | translate }}\n </li>\n </button>\n <button\n data-testid=\"pin-action\"\n *ngIf=\"isPinVisible\"\n (click)=\"pinClicked()\"\n >\n <li class=\"str-chat__message-actions-list-item\">\n {{\n (message?.pinned ? \"streamChat.Unpin\" : \"streamChat.Pin\") | translate\n }}\n </li>\n </button>\n <button\n data-testid=\"flag-action\"\n *ngIf=\"isFlagVisible\"\n (click)=\"flagClicked()\"\n >\n <li class=\"str-chat__message-actions-list-item\">\n {{ \"streamChat.Flag\" | translate }}\n </li>\n </button>\n <button\n data-testid=\"mute-action\"\n *ngIf=\"isMuteVisible\"\n (click)=\"muteClicked()\"\n >\n <li class=\"str-chat__message-actions-list-item\">\n {{ \"streamChat.Mute\" | translate }}\n </li>\n </button>\n <button\n data-testid=\"edit-action\"\n *ngIf=\"isEditVisible\"\n (click)=\"editClicked()\"\n >\n <li class=\"str-chat__message-actions-list-item\">\n {{ \"streamChat.Edit Message\" | translate }}\n </li>\n </button>\n <button\n data-testid=\"delete-action\"\n *ngIf=\"isDeleteVisible\"\n (click)=\"deleteClicked()\"\n >\n <li class=\"str-chat__message-actions-list-item\">\n {{ \"streamChat.Delete\" | translate }}\n </li>\n </button>\n </ul>\n</div>\n", directives: [{ type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], pipes: { "translate":
|
|
1583
|
+
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 });
|
|
1584
|
+
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: "messageInput", first: true, predicate: MessageInputComponent, descendants: 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 <button\n data-testid=\"quote-action\"\n *ngIf=\"isQuoteVisible\"\n (click)=\"quoteClicked()\"\n >\n <li class=\"str-chat__message-actions-list-item\">\n {{ \"streamChat.Reply\" | translate }}\n </li>\n </button>\n <button\n data-testid=\"pin-action\"\n *ngIf=\"isPinVisible\"\n (click)=\"pinClicked()\"\n >\n <li class=\"str-chat__message-actions-list-item\">\n {{\n (message?.pinned ? \"streamChat.Unpin\" : \"streamChat.Pin\") | translate\n }}\n </li>\n </button>\n <button\n data-testid=\"flag-action\"\n *ngIf=\"isFlagVisible\"\n (click)=\"flagClicked()\"\n >\n <li class=\"str-chat__message-actions-list-item\">\n {{ \"streamChat.Flag\" | translate }}\n </li>\n </button>\n <button\n data-testid=\"mute-action\"\n *ngIf=\"isMuteVisible\"\n (click)=\"muteClicked()\"\n >\n <li class=\"str-chat__message-actions-list-item\">\n {{ \"streamChat.Mute\" | translate }}\n </li>\n </button>\n <button\n data-testid=\"edit-action\"\n *ngIf=\"isEditVisible\"\n (click)=\"editClicked()\"\n >\n <li class=\"str-chat__message-actions-list-item\">\n {{ \"streamChat.Edit Message\" | translate }}\n </li>\n </button>\n <button\n data-testid=\"delete-action\"\n *ngIf=\"isDeleteVisible\"\n (click)=\"deleteClicked()\"\n >\n <li class=\"str-chat__message-actions-list-item\">\n {{ \"streamChat.Delete\" | translate }}\n </li>\n </button>\n </ul>\n</div>\n\n<stream-modal\n [isOpen]=\"isEditModalOpen\"\n (isOpenChange)=\"\n isEditModalOpen = $event; isEditModalOpen ? '' : modalClosed()\n \"\n>\n <div class=\"str-chat__edit-message-form\" *ngIf=\"isEditModalOpen\">\n <stream-message-input\n [message]=\"message\"\n (messageUpdate)=\"modalClosed()\"\n ></stream-message-input>\n <stream-notification-list></stream-notification-list>\n <div class=\"str-chat__message-team-form-footer\">\n <div></div>\n <div>\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</stream-modal>\n", components: [{ type: ModalComponent, selector: "stream-modal", inputs: ["isOpen"], outputs: ["isOpenChange"] }, { type: MessageInputComponent, selector: "stream-message-input", inputs: ["isFileUploadEnabled", "areMentionsEnabled", "mentionScope", "mentionAutocompleteItemTemplate", "acceptedFileTypes", "isMultipleFileUploadEnabled", "message"], outputs: ["messageUpdate"] }, { type: NotificationListComponent, selector: "stream-notification-list" }], directives: [{ type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }], pipes: { "translate": i1.TranslatePipe } });
|
|
931
1585
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: MessageActionsBoxComponent, decorators: [{
|
|
932
1586
|
type: Component,
|
|
933
1587
|
args: [{
|
|
@@ -935,7 +1589,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
935
1589
|
templateUrl: './message-actions-box.component.html',
|
|
936
1590
|
styles: [],
|
|
937
1591
|
}]
|
|
938
|
-
}], ctorParameters: function () { return [{ type: ChatClientService }, { type: NotificationService }]; }, propDecorators: { isOpen: [{
|
|
1592
|
+
}], ctorParameters: function () { return [{ type: ChatClientService }, { type: NotificationService }, { type: ChannelService }]; }, propDecorators: { isOpen: [{
|
|
939
1593
|
type: Input
|
|
940
1594
|
}], isMine: [{
|
|
941
1595
|
type: Input
|
|
@@ -945,6 +1599,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
945
1599
|
type: Input
|
|
946
1600
|
}], displayedActionsCount: [{
|
|
947
1601
|
type: Output
|
|
1602
|
+
}], isEditing: [{
|
|
1603
|
+
type: Output
|
|
1604
|
+
}], messageInput: [{
|
|
1605
|
+
type: ViewChild,
|
|
1606
|
+
args: [MessageInputComponent]
|
|
948
1607
|
}] } });
|
|
949
1608
|
|
|
950
1609
|
class ChannelComponent {
|
|
@@ -1047,7 +1706,7 @@ class ChannelHeaderComponent {
|
|
|
1047
1706
|
}
|
|
1048
1707
|
}
|
|
1049
1708
|
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 });
|
|
1050
|
-
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 <span class=\"str-chat__header-hamburger--line\"></span>\n <span class=\"str-chat__header-hamburger--line\"></span>\n <span class=\"str-chat__header-hamburger--line\"></span>\n </div>\n <stream-avatar\n imageUrl=\"{{ activeChannel?.data?.image }}\"\n name=\"{{ activeChannel?.data?.name }}\"\n ></stream-avatar>\n <div class=\"str-chat__header-livestream-left\">\n <p class=\"str-chat__header-livestream-left--title\">\n {{ activeChannel?.data?.name }}\n </p>\n <p class=\"str-chat__header-livestream-left--members\">\n {{'streamChat.{{ memberCount }} members' | translate:memberCountParam}}\n {{'streamChat.{{ watcherCount }} online' | translate:watcherCountParam}}\n </p>\n </div>\n</div>\n", components: [{ type: AvatarComponent, selector: "stream-avatar", inputs: ["name", "imageUrl", "size"] }], pipes: { "translate":
|
|
1709
|
+
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 <span class=\"str-chat__header-hamburger--line\"></span>\n <span class=\"str-chat__header-hamburger--line\"></span>\n <span class=\"str-chat__header-hamburger--line\"></span>\n </div>\n <stream-avatar\n imageUrl=\"{{ activeChannel?.data?.image }}\"\n name=\"{{ activeChannel?.data?.name }}\"\n ></stream-avatar>\n <div class=\"str-chat__header-livestream-left\">\n <p class=\"str-chat__header-livestream-left--title\">\n {{ activeChannel?.data?.name }}\n </p>\n <p class=\"str-chat__header-livestream-left--members\">\n {{'streamChat.{{ memberCount }} members' | translate:memberCountParam}}\n {{'streamChat.{{ watcherCount }} online' | translate:watcherCountParam}}\n </p>\n </div>\n</div>\n", components: [{ type: AvatarComponent, selector: "stream-avatar", inputs: ["name", "imageUrl", "size"] }], pipes: { "translate": i1.TranslatePipe } });
|
|
1051
1710
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ChannelHeaderComponent, decorators: [{
|
|
1052
1711
|
type: Component,
|
|
1053
1712
|
args: [{
|
|
@@ -1123,7 +1782,7 @@ class ChannelPreviewComponent {
|
|
|
1123
1782
|
}
|
|
1124
1783
|
}
|
|
1125
1784
|
ChannelPreviewComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ChannelPreviewComponent, deps: [{ token: ChannelService }], target: i0.ɵɵFactoryTarget.Component });
|
|
1126
|
-
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: AvatarComponent, selector: "stream-avatar", inputs: ["name", "imageUrl", "size"] }], pipes: { "translate":
|
|
1785
|
+
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: AvatarComponent, selector: "stream-avatar", inputs: ["name", "imageUrl", "size"] }], pipes: { "translate": i1.TranslatePipe } });
|
|
1127
1786
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ChannelPreviewComponent, decorators: [{
|
|
1128
1787
|
type: Component,
|
|
1129
1788
|
args: [{
|
|
@@ -1164,7 +1823,7 @@ class ChannelListComponent {
|
|
|
1164
1823
|
}
|
|
1165
1824
|
}
|
|
1166
1825
|
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 });
|
|
1167
|
-
ChannelListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: ChannelListComponent, selector: "stream-channel-list", inputs: { customChannelPreviewTemplate: "customChannelPreviewTemplate" }, 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-container\n *ngIf=\"customChannelPreviewTemplate; else defaultTemplate\"\n >\n <div (click)=\"channelSelected()\" (keyup.enter)=\"channelSelected()\">\n <ng-container\n *ngTemplateOutlet=\"\n customChannelPreviewTemplate;\n context: { channel: channel }\n \"\n ></ng-container>\n </div>\n </ng-container>\n <ng-template #defaultTemplate>\n <stream-channel-preview\n data-testclass=\"channel-preview\"\n [channel]=\"channel\"\n (click)=\"channelSelected()\"\n (keyup.enter)=\"channelSelected()\"\n ></stream-channel-preview>\n </ng-template>\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></stream-loading-indicator\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 icon=\"connection-error\"></stream-icon>\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: LoadingIndicatorComponent, selector: "stream-loading-indicator", inputs: ["size", "color"] }, { type: IconComponent, selector: "stream-icon", inputs: ["icon", "size"] }], directives: [{ type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i5.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], pipes: { "async": i5.AsyncPipe, "translate":
|
|
1826
|
+
ChannelListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: ChannelListComponent, selector: "stream-channel-list", inputs: { customChannelPreviewTemplate: "customChannelPreviewTemplate" }, 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-container\n *ngIf=\"customChannelPreviewTemplate; else defaultTemplate\"\n >\n <div (click)=\"channelSelected()\" (keyup.enter)=\"channelSelected()\">\n <ng-container\n *ngTemplateOutlet=\"\n customChannelPreviewTemplate;\n context: { channel: channel }\n \"\n ></ng-container>\n </div>\n </ng-container>\n <ng-template #defaultTemplate>\n <stream-channel-preview\n data-testclass=\"channel-preview\"\n [channel]=\"channel\"\n (click)=\"channelSelected()\"\n (keyup.enter)=\"channelSelected()\"\n ></stream-channel-preview>\n </ng-template>\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></stream-loading-indicator\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 icon=\"connection-error\"></stream-icon>\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: LoadingIndicatorComponent, selector: "stream-loading-indicator", inputs: ["size", "color"] }, { type: IconComponent, selector: "stream-icon", inputs: ["icon", "size"] }], directives: [{ type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i5.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], pipes: { "async": i5.AsyncPipe, "translate": i1.TranslatePipe } });
|
|
1168
1827
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ChannelListComponent, decorators: [{
|
|
1169
1828
|
type: Component,
|
|
1170
1829
|
args: [{
|
|
@@ -1374,9 +2033,7 @@ class AttachmentListComponent {
|
|
|
1374
2033
|
return index;
|
|
1375
2034
|
}
|
|
1376
2035
|
isImage(attachment) {
|
|
1377
|
-
return (attachment
|
|
1378
|
-
!attachment.title_link &&
|
|
1379
|
-
!attachment.og_scrape_url);
|
|
2036
|
+
return isImageAttachment(attachment);
|
|
1380
2037
|
}
|
|
1381
2038
|
isFile(attachment) {
|
|
1382
2039
|
return attachment.type === 'file';
|
|
@@ -1417,6 +2074,27 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
1417
2074
|
type: Input
|
|
1418
2075
|
}] } });
|
|
1419
2076
|
|
|
2077
|
+
class HighlightMentionsPipe {
|
|
2078
|
+
transform(value, mentionedUsers) {
|
|
2079
|
+
if (!value || !mentionedUsers) {
|
|
2080
|
+
return value || '';
|
|
2081
|
+
}
|
|
2082
|
+
let result = value;
|
|
2083
|
+
mentionedUsers.forEach((u) => {
|
|
2084
|
+
result = result.replace(new RegExp(`@${u.name || u.id}`, 'g'), `<b>@${u.name || u.id}</b>`);
|
|
2085
|
+
});
|
|
2086
|
+
return result;
|
|
2087
|
+
}
|
|
2088
|
+
}
|
|
2089
|
+
HighlightMentionsPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: HighlightMentionsPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
2090
|
+
HighlightMentionsPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: HighlightMentionsPipe, name: "highlightMentions" });
|
|
2091
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: HighlightMentionsPipe, decorators: [{
|
|
2092
|
+
type: Pipe,
|
|
2093
|
+
args: [{
|
|
2094
|
+
name: 'highlightMentions',
|
|
2095
|
+
}]
|
|
2096
|
+
}] });
|
|
2097
|
+
|
|
1420
2098
|
class MessageComponent {
|
|
1421
2099
|
constructor(chatClientService, channelService) {
|
|
1422
2100
|
this.chatClientService = chatClientService;
|
|
@@ -1501,7 +2179,7 @@ class MessageComponent {
|
|
|
1501
2179
|
}
|
|
1502
2180
|
}
|
|
1503
2181
|
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 });
|
|
1504
|
-
MessageComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: MessageComponent, selector: "stream-message", inputs: { message: "message", enabledMessageActions: "enabledMessageActions", areReactionsEnabled: "areReactionsEnabled", canReactToMessage: "canReactToMessage", isLastSentMessage: "isLastSentMessage" }, viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: 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 && hasReactions\n \"\n data-testid=\"message-container\"\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 *ngIf=\"isMessageDeliveredAndRead; else deliveredStatus\">\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 class=\"\n str-chat__message-simple__actions__action\n str-chat__message-simple__actions__action--options\n \"\n >\n <stream-message-actions-box\n [isOpen]=\"isActionBoxOpen\"\n [isMine]=\"isSentByCurrentUser\"\n [enabledActions]=\"enabledMessageActions\"\n [message]=\"message\"\n (displayedActionsCount)=\"visibleMessageActionsCount = $event\"\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 <div\n *ngIf=\"areReactionsEnabled && canReactToMessage\"\n class=\"\n str-chat__message-simple__actions__action\n str-chat__message-simple__actions__action--reactions\n \"\n data-testid=\"reaction-icon\"\n (click)=\"isReactionSelectorOpen = !isReactionSelectorOpen\"\n (keyup.enter)=\"isReactionSelectorOpen = !isReactionSelectorOpen\"\n >\n <stream-icon icon=\"reaction-icon\"></stream-icon>\n </div>\n </div>\n <stream-message-reactions\n *ngIf=\"areReactionsEnabled\"\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\"\n [attachments]=\"message!.attachments!\"\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 <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 [innerHTML]=\"message?.html || message?.text\"\n ></div>\n </div>\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 class=\"str-chat__message-simple-status\" data-testid=\"sending-indicator\">\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 class=\"str-chat__message-simple-status\" data-testid=\"read-indicator\">\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 class=\"str-chat__message-simple-status\"\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", components: [{ type: AvatarComponent, selector: "stream-avatar", inputs: ["name", "imageUrl", "size"] }, { type: MessageActionsBoxComponent, selector: "stream-message-actions-box", inputs: ["isOpen", "isMine", "message", "enabledActions"], outputs: ["displayedActionsCount"] }, { 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: ["attachments"] }, { type: LoadingIndicatorComponent, selector: "stream-loading-indicator", inputs: ["size", "color"] }], directives: [{ type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i5.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i4.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }], pipes: { "translate": i4.TranslatePipe } });
|
|
2182
|
+
MessageComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: MessageComponent, selector: "stream-message", inputs: { message: "message", enabledMessageActions: "enabledMessageActions", areReactionsEnabled: "areReactionsEnabled", canReactToMessage: "canReactToMessage", isLastSentMessage: "isLastSentMessage" }, viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: 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 && hasReactions\n \"\n data-testid=\"message-container\"\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 *ngIf=\"isMessageDeliveredAndRead; else deliveredStatus\">\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 ></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 <div\n *ngIf=\"areReactionsEnabled && canReactToMessage\"\n class=\"\n str-chat__message-simple__actions__action\n str-chat__message-simple__actions__action--reactions\n \"\n data-testid=\"reaction-icon\"\n (click)=\"isReactionSelectorOpen = !isReactionSelectorOpen\"\n (keyup.enter)=\"isReactionSelectorOpen = !isReactionSelectorOpen\"\n >\n <stream-icon icon=\"reaction-icon\"></stream-icon>\n </div>\n </div>\n <stream-message-reactions\n *ngIf=\"areReactionsEnabled\"\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\"\n [attachments]=\"message!.attachments!\"\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 <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 [innerHTML]=\"\n message?.html || message?.text\n | highlightMentions: message?.mentioned_users\n \"\n ></div>\n </div>\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 class=\"str-chat__message-simple-status\" data-testid=\"sending-indicator\">\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 class=\"str-chat__message-simple-status\" data-testid=\"read-indicator\">\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 class=\"str-chat__message-simple-status\"\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", components: [{ type: AvatarComponent, selector: "stream-avatar", inputs: ["name", "imageUrl", "size"] }, { type: MessageActionsBoxComponent, selector: "stream-message-actions-box", inputs: ["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: ["attachments"] }, { type: LoadingIndicatorComponent, selector: "stream-loading-indicator", inputs: ["size", "color"] }], directives: [{ type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i5.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }], pipes: { "translate": i1.TranslatePipe, "highlightMentions": HighlightMentionsPipe } });
|
|
1505
2183
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: MessageComponent, decorators: [{
|
|
1506
2184
|
type: Component,
|
|
1507
2185
|
args: [{
|
|
@@ -1524,195 +2202,177 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
1524
2202
|
args: ['container']
|
|
1525
2203
|
}] } });
|
|
1526
2204
|
|
|
1527
|
-
class
|
|
1528
|
-
constructor(
|
|
2205
|
+
class TextareaComponent {
|
|
2206
|
+
constructor() {
|
|
2207
|
+
this.class = 'str-chat__textarea';
|
|
2208
|
+
this.value = '';
|
|
2209
|
+
this.valueChange = new EventEmitter();
|
|
2210
|
+
this.send = new EventEmitter();
|
|
2211
|
+
}
|
|
2212
|
+
// eslint-disable-next-line @angular-eslint/no-empty-lifecycle-method
|
|
2213
|
+
ngOnChanges() { }
|
|
2214
|
+
inputChanged() {
|
|
2215
|
+
this.valueChange.emit(this.messageInput.nativeElement.value);
|
|
2216
|
+
}
|
|
2217
|
+
sent(event) {
|
|
2218
|
+
event.preventDefault();
|
|
2219
|
+
this.send.next();
|
|
2220
|
+
}
|
|
2221
|
+
}
|
|
2222
|
+
TextareaComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: TextareaComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2223
|
+
TextareaComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: TextareaComponent, selector: "stream-textarea", inputs: { value: "value" }, outputs: { valueChange: "valueChange", send: "send" }, 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\"\n rows=\"1\"\n (input)=\"inputChanged()\"\n (keydown.enter)=\"sent($event)\"\n></textarea>\n", pipes: { "translate": i1.TranslatePipe } });
|
|
2224
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: TextareaComponent, decorators: [{
|
|
2225
|
+
type: Component,
|
|
2226
|
+
args: [{
|
|
2227
|
+
selector: 'stream-textarea',
|
|
2228
|
+
templateUrl: './textarea.component.html',
|
|
2229
|
+
styles: [],
|
|
2230
|
+
}]
|
|
2231
|
+
}], ctorParameters: function () { return []; }, propDecorators: { class: [{
|
|
2232
|
+
type: HostBinding
|
|
2233
|
+
}], value: [{
|
|
2234
|
+
type: Input
|
|
2235
|
+
}], valueChange: [{
|
|
2236
|
+
type: Output
|
|
2237
|
+
}], send: [{
|
|
2238
|
+
type: Output
|
|
2239
|
+
}], messageInput: [{
|
|
2240
|
+
type: ViewChild,
|
|
2241
|
+
args: ['input']
|
|
2242
|
+
}] } });
|
|
2243
|
+
|
|
2244
|
+
class AutocompleteTextareaComponent {
|
|
2245
|
+
constructor(channelService, chatClientService) {
|
|
1529
2246
|
this.channelService = channelService;
|
|
1530
|
-
this.
|
|
1531
|
-
this.
|
|
1532
|
-
this.
|
|
1533
|
-
this.
|
|
1534
|
-
this.
|
|
2247
|
+
this.chatClientService = chatClientService;
|
|
2248
|
+
this.class = 'str-chat__textarea';
|
|
2249
|
+
this.value = '';
|
|
2250
|
+
this.areMentionsEnabled = true;
|
|
2251
|
+
this.mentionScope = 'channel';
|
|
2252
|
+
this.valueChange = new EventEmitter();
|
|
2253
|
+
this.send = new EventEmitter();
|
|
2254
|
+
this.userMentions = new EventEmitter();
|
|
2255
|
+
this.labelKey = 'autocompleteLabel';
|
|
2256
|
+
this.triggerChar = '@';
|
|
2257
|
+
this.autocompleteConfig = {
|
|
2258
|
+
mentions: [],
|
|
2259
|
+
};
|
|
1535
2260
|
this.subscriptions = [];
|
|
1536
|
-
this.
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
this.
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
2261
|
+
this.mentionedUsers = [];
|
|
2262
|
+
this.userMentionConfig = {
|
|
2263
|
+
triggerChar: this.triggerChar,
|
|
2264
|
+
dropUp: true,
|
|
2265
|
+
labelKey: this.labelKey,
|
|
2266
|
+
mentionFilter: this.filter,
|
|
2267
|
+
mentionSelect: (item, triggerChar) => this.mentioned(item, triggerChar),
|
|
2268
|
+
};
|
|
2269
|
+
this.searchTerm$ = new BehaviorSubject('');
|
|
2270
|
+
this.searchTerm$
|
|
2271
|
+
.pipe(debounceTime(300), distinctUntilChanged())
|
|
2272
|
+
.subscribe((searchTerm) => void this.updateMentionOptions(searchTerm));
|
|
2273
|
+
this.subscriptions.push(this.channelService.activeChannel$.subscribe(() => {
|
|
2274
|
+
this.mentionedUsers = [];
|
|
2275
|
+
this.userMentions.next([...this.mentionedUsers]);
|
|
2276
|
+
void this.updateMentionOptions(this.searchTerm$.getValue());
|
|
1547
2277
|
}));
|
|
1548
2278
|
}
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
event === null || event === void 0 ? void 0 : event.preventDefault();
|
|
1555
|
-
if (this.attachmentUploadInProgressCounter > 0) {
|
|
1556
|
-
if (!this.hideNotification) {
|
|
1557
|
-
this.hideNotification =
|
|
1558
|
-
this.notificationService.addPermanentNotification('streamChat.Wait until all attachments have uploaded');
|
|
1559
|
-
}
|
|
1560
|
-
return;
|
|
2279
|
+
ngOnChanges(changes) {
|
|
2280
|
+
if (changes.areMentionsEnabled) {
|
|
2281
|
+
if (this.areMentionsEnabled) {
|
|
2282
|
+
this.autocompleteConfig.mentions = [this.userMentionConfig];
|
|
2283
|
+
this.autocompleteConfig = Object.assign({}, this.autocompleteConfig);
|
|
1561
2284
|
}
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
.
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
attachment.fallback = r.file.name;
|
|
1571
|
-
attachment.image_url = r.url;
|
|
1572
|
-
}
|
|
1573
|
-
else {
|
|
1574
|
-
attachment.asset_url = r.url;
|
|
1575
|
-
attachment.title = r.file.name;
|
|
1576
|
-
attachment.file_size = r.file.size;
|
|
1577
|
-
}
|
|
1578
|
-
return attachment;
|
|
1579
|
-
});
|
|
1580
|
-
this.messageInput.nativeElement.value = '';
|
|
1581
|
-
yield this.channelService.sendMessage(text, attachments);
|
|
1582
|
-
this.attachmentUploads = [];
|
|
1583
|
-
});
|
|
2285
|
+
else {
|
|
2286
|
+
this.autocompleteConfig.mentions = [];
|
|
2287
|
+
this.autocompleteConfig = Object.assign({}, this.autocompleteConfig);
|
|
2288
|
+
}
|
|
2289
|
+
}
|
|
2290
|
+
if (changes.mentionScope) {
|
|
2291
|
+
void this.updateMentionOptions(this.searchTerm$.getValue());
|
|
2292
|
+
}
|
|
1584
2293
|
}
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
return this.acceptedFileTypes ? (_a = this.acceptedFileTypes) === null || _a === void 0 ? void 0 : _a.join(',') : '';
|
|
2294
|
+
filter(searchString, items) {
|
|
2295
|
+
return items.filter((item) => item.autocompleteLabel.toLowerCase().includes(searchString.toLowerCase()));
|
|
1588
2296
|
}
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
}
|
|
1594
|
-
const imageFiles = [];
|
|
1595
|
-
const dataFiles = [];
|
|
1596
|
-
Array.from(fileList).forEach((file) => {
|
|
1597
|
-
if (file.type.startsWith('image/') && !file.type.endsWith('.photoshop')) {
|
|
1598
|
-
// photoshop files begin with 'image/'
|
|
1599
|
-
imageFiles.push(file);
|
|
1600
|
-
}
|
|
1601
|
-
else {
|
|
1602
|
-
dataFiles.push(file);
|
|
1603
|
-
}
|
|
1604
|
-
});
|
|
1605
|
-
imageFiles.forEach((f) => this.createPreview(f));
|
|
1606
|
-
const newUploads = [
|
|
1607
|
-
...imageFiles.map((file) => ({
|
|
1608
|
-
file,
|
|
1609
|
-
state: 'uploading',
|
|
1610
|
-
type: 'image',
|
|
1611
|
-
})),
|
|
1612
|
-
...dataFiles.map((file) => ({
|
|
1613
|
-
file,
|
|
1614
|
-
state: 'uploading',
|
|
1615
|
-
type: 'file',
|
|
1616
|
-
})),
|
|
1617
|
-
];
|
|
1618
|
-
this.attachmentUploads = [...this.attachmentUploads, ...newUploads];
|
|
1619
|
-
this.clearFileInput();
|
|
1620
|
-
yield this.uploadAttachments(newUploads);
|
|
1621
|
-
});
|
|
2297
|
+
mentioned(item, triggerChar = '') {
|
|
2298
|
+
this.mentionedUsers.push((item.user ? item.user : item));
|
|
2299
|
+
this.userMentions.next([...this.mentionedUsers]);
|
|
2300
|
+
return triggerChar + item.autocompleteLabel;
|
|
1622
2301
|
}
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
const upload = this.attachmentUploads.find((u) => u.file === file);
|
|
1626
|
-
if (!upload) {
|
|
1627
|
-
return;
|
|
1628
|
-
}
|
|
1629
|
-
upload.state = 'uploading';
|
|
1630
|
-
yield this.uploadAttachments([upload]);
|
|
1631
|
-
});
|
|
2302
|
+
autcompleteSearchTermChanged(searchTerm) {
|
|
2303
|
+
this.searchTerm$.next(searchTerm);
|
|
1632
2304
|
}
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
if (upload.state === 'success') {
|
|
1636
|
-
try {
|
|
1637
|
-
yield this.channelService.deleteAttachment(upload);
|
|
1638
|
-
this.attachmentUploads.splice(this.attachmentUploads.indexOf(upload), 1);
|
|
1639
|
-
}
|
|
1640
|
-
catch (error) {
|
|
1641
|
-
// TODO error handling
|
|
1642
|
-
}
|
|
1643
|
-
}
|
|
1644
|
-
else {
|
|
1645
|
-
this.attachmentUploads.splice(this.attachmentUploads.indexOf(upload), 1);
|
|
1646
|
-
}
|
|
1647
|
-
});
|
|
2305
|
+
inputChanged() {
|
|
2306
|
+
this.valueChange.emit(this.messageInput.nativeElement.value);
|
|
1648
2307
|
}
|
|
1649
|
-
|
|
1650
|
-
|
|
2308
|
+
inputLeft() {
|
|
2309
|
+
this.updateMentionedUsersFromText();
|
|
1651
2310
|
}
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
const upload = this.attachmentUploads.find((upload) => upload.file === file);
|
|
1657
|
-
if (!upload) {
|
|
1658
|
-
return;
|
|
1659
|
-
}
|
|
1660
|
-
upload.previewUri = ((_a = event.target) === null || _a === void 0 ? void 0 : _a.result) || undefined;
|
|
1661
|
-
};
|
|
1662
|
-
reader.readAsDataURL(file);
|
|
2311
|
+
sent(event) {
|
|
2312
|
+
event.preventDefault();
|
|
2313
|
+
this.updateMentionedUsersFromText();
|
|
2314
|
+
this.send.next();
|
|
1663
2315
|
}
|
|
1664
|
-
|
|
2316
|
+
updateMentionOptions(searchTerm) {
|
|
1665
2317
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1666
|
-
this.
|
|
1667
|
-
|
|
1668
|
-
result.forEach((r) => {
|
|
1669
|
-
const upload = this.attachmentUploads.find((upload) => upload.file === r.file);
|
|
1670
|
-
if (!upload) {
|
|
1671
|
-
if (r.url) {
|
|
1672
|
-
void this.channelService.deleteAttachment(r);
|
|
1673
|
-
}
|
|
1674
|
-
return;
|
|
1675
|
-
}
|
|
1676
|
-
upload.state = r.state;
|
|
1677
|
-
upload.url = r.url;
|
|
1678
|
-
if (upload.state === 'error') {
|
|
1679
|
-
this.notificationService.addTemporaryNotification(upload.type === 'image'
|
|
1680
|
-
? 'streamChat.Error uploading image'
|
|
1681
|
-
: 'streamChat.Error uploading file');
|
|
1682
|
-
}
|
|
1683
|
-
});
|
|
1684
|
-
this.attachmentUploadInProgressCounter--;
|
|
1685
|
-
if (this.attachmentUploadInProgressCounter === 0 && this.hideNotification) {
|
|
1686
|
-
this.hideNotification();
|
|
1687
|
-
this.hideNotification = undefined;
|
|
2318
|
+
if (!this.areMentionsEnabled) {
|
|
2319
|
+
return;
|
|
1688
2320
|
}
|
|
2321
|
+
const request = this.mentionScope === 'application'
|
|
2322
|
+
? (s) => this.chatClientService.autocompleteUsers(s)
|
|
2323
|
+
: (s) => this.channelService.autocompleteMembers(s);
|
|
2324
|
+
const result = yield request(searchTerm || '');
|
|
2325
|
+
const items = this.filter(searchTerm || '', result.map((i) => {
|
|
2326
|
+
const user = (i.user ? i.user : i);
|
|
2327
|
+
return Object.assign(Object.assign({}, i), { autocompleteLabel: user.name || user.id, type: 'mention' });
|
|
2328
|
+
}));
|
|
2329
|
+
this.userMentionConfig.items = items;
|
|
2330
|
+
this.autocompleteConfig.mentions = [this.userMentionConfig];
|
|
2331
|
+
this.autocompleteConfig = Object.assign({}, this.autocompleteConfig);
|
|
1689
2332
|
});
|
|
1690
2333
|
}
|
|
1691
|
-
|
|
1692
|
-
|
|
2334
|
+
updateMentionedUsersFromText() {
|
|
2335
|
+
const updatedMentionedUsers = [];
|
|
2336
|
+
this.mentionedUsers.forEach((u) => {
|
|
2337
|
+
const key = u.name || u.id;
|
|
2338
|
+
if (this.value.includes(`${this.triggerChar}${key}`)) {
|
|
2339
|
+
updatedMentionedUsers.push(u);
|
|
2340
|
+
}
|
|
2341
|
+
});
|
|
2342
|
+
if (updatedMentionedUsers.length !== this.mentionedUsers.length) {
|
|
2343
|
+
this.userMentions.next([...updatedMentionedUsers]);
|
|
2344
|
+
this.mentionedUsers = updatedMentionedUsers;
|
|
2345
|
+
}
|
|
1693
2346
|
}
|
|
1694
2347
|
}
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type:
|
|
2348
|
+
AutocompleteTextareaComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: AutocompleteTextareaComponent, deps: [{ token: ChannelService }, { token: ChatClientService }], target: i0.ɵɵFactoryTarget.Component });
|
|
2349
|
+
AutocompleteTextareaComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: AutocompleteTextareaComponent, selector: "stream-autocomplete-textarea", inputs: { value: "value", areMentionsEnabled: "areMentionsEnabled", mentionAutocompleteItemTemplate: "mentionAutocompleteItemTemplate", 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\"\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>\n</ng-template>\n\n<ng-template #defaultMentionTemplate let-item=\"item\">\n <div class=\"str-chat__user-item\">\n <stream-avatar\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>\n <span data-testclass=\"username\" class=\"str-chat__user-item--name\">{{\n item.autocompleteLabel\n }}</span>\n </div>\n</ng-template>\n", components: [{ type: AvatarComponent, selector: "stream-avatar", inputs: ["name", "imageUrl", "size"] }], directives: [{ type: i4.MentionDirective, selector: "[mention], [mentionConfig]", inputs: ["mentionConfig", "mention", "mentionListTemplate"], outputs: ["searchTerm", "itemSelected", "opened", "closed"] }, { type: i5.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { type: i5.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { type: i5.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], pipes: { "translate": i1.TranslatePipe } });
|
|
2350
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: AutocompleteTextareaComponent, decorators: [{
|
|
1698
2351
|
type: Component,
|
|
1699
2352
|
args: [{
|
|
1700
|
-
selector: 'stream-
|
|
1701
|
-
templateUrl: './
|
|
2353
|
+
selector: 'stream-autocomplete-textarea',
|
|
2354
|
+
templateUrl: './autocomplete-textarea.component.html',
|
|
1702
2355
|
styles: [],
|
|
1703
2356
|
}]
|
|
1704
|
-
}], ctorParameters: function () { return [{ type: ChannelService }, { type:
|
|
2357
|
+
}], ctorParameters: function () { return [{ type: ChannelService }, { type: ChatClientService }]; }, propDecorators: { class: [{
|
|
2358
|
+
type: HostBinding
|
|
2359
|
+
}], value: [{
|
|
1705
2360
|
type: Input
|
|
1706
|
-
}],
|
|
2361
|
+
}], areMentionsEnabled: [{
|
|
1707
2362
|
type: Input
|
|
1708
|
-
}],
|
|
2363
|
+
}], mentionAutocompleteItemTemplate: [{
|
|
2364
|
+
type: Input
|
|
2365
|
+
}], mentionScope: [{
|
|
1709
2366
|
type: Input
|
|
2367
|
+
}], valueChange: [{
|
|
2368
|
+
type: Output
|
|
2369
|
+
}], send: [{
|
|
2370
|
+
type: Output
|
|
2371
|
+
}], userMentions: [{
|
|
2372
|
+
type: Output
|
|
1710
2373
|
}], messageInput: [{
|
|
1711
2374
|
type: ViewChild,
|
|
1712
2375
|
args: ['input']
|
|
1713
|
-
}], fileInput: [{
|
|
1714
|
-
type: ViewChild,
|
|
1715
|
-
args: ['fileInput']
|
|
1716
2376
|
}] } });
|
|
1717
2377
|
|
|
1718
2378
|
const getGroupStyles = (message, previousMessage, nextMessage, noGroupByUser = false) => {
|
|
@@ -1761,7 +2421,9 @@ class MessageListComponent {
|
|
|
1761
2421
|
this.chatClientService = chatClientService;
|
|
1762
2422
|
this.imageLoadService = imageLoadService;
|
|
1763
2423
|
this.areReactionsEnabled = true;
|
|
1764
|
-
|
|
2424
|
+
/* eslint-disable-next-line @angular-eslint/no-input-rename */
|
|
2425
|
+
this.enabledMessageActionsInput = ['flag', 'edit', 'edit-any', 'delete', 'delete-any'];
|
|
2426
|
+
this.enabledMessageActions = [];
|
|
1765
2427
|
this.class = 'str-chat-angular__main-panel-inner str-chat-angular__message-list-host';
|
|
1766
2428
|
this.unreadMessageCount = 0;
|
|
1767
2429
|
this.groupStyles = [];
|
|
@@ -1784,6 +2446,20 @@ class MessageListComponent {
|
|
|
1784
2446
|
if (capabilites.indexOf('flag-message') !== -1) {
|
|
1785
2447
|
this.authorizedMessageActions.push('flag');
|
|
1786
2448
|
}
|
|
2449
|
+
if (capabilites.indexOf('update-own-message') !== -1) {
|
|
2450
|
+
this.authorizedMessageActions.push('edit');
|
|
2451
|
+
}
|
|
2452
|
+
if (capabilites.indexOf('update-any-message') !== -1) {
|
|
2453
|
+
this.authorizedMessageActions.push('edit');
|
|
2454
|
+
this.authorizedMessageActions.push('edit-any');
|
|
2455
|
+
}
|
|
2456
|
+
if (capabilites.indexOf('delete-own-message') !== -1) {
|
|
2457
|
+
this.authorizedMessageActions.push('delete');
|
|
2458
|
+
}
|
|
2459
|
+
if (capabilites.indexOf('delete-any-message') !== -1) {
|
|
2460
|
+
this.authorizedMessageActions.push('delete');
|
|
2461
|
+
this.authorizedMessageActions.push('delete-any');
|
|
2462
|
+
}
|
|
1787
2463
|
this.setEnabledActions();
|
|
1788
2464
|
}
|
|
1789
2465
|
});
|
|
@@ -1883,10 +2559,10 @@ class MessageListComponent {
|
|
|
1883
2559
|
this.scrollContainer.nativeElement.scrollHeight - this.containerHeight;
|
|
1884
2560
|
}
|
|
1885
2561
|
setEnabledActions() {
|
|
2562
|
+
this.enabledMessageActions = [];
|
|
1886
2563
|
if (!this.enabledMessageActionsInput) {
|
|
1887
2564
|
return;
|
|
1888
2565
|
}
|
|
1889
|
-
this.enabledMessageActions = [];
|
|
1890
2566
|
this.enabledMessageActionsInput.forEach((action) => {
|
|
1891
2567
|
const isAuthorized = this.authorizedMessageActions.indexOf(action) !== -1;
|
|
1892
2568
|
if (isAuthorized) {
|
|
@@ -1919,47 +2595,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
1919
2595
|
args: ['scrollContainer']
|
|
1920
2596
|
}] } });
|
|
1921
2597
|
|
|
1922
|
-
class
|
|
1923
|
-
constructor() { }
|
|
1924
|
-
}
|
|
1925
|
-
NotificationComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: NotificationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1926
|
-
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" });
|
|
1927
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: NotificationComponent, decorators: [{
|
|
1928
|
-
type: Component,
|
|
1929
|
-
args: [{
|
|
1930
|
-
selector: 'stream-notification',
|
|
1931
|
-
templateUrl: './notification.component.html',
|
|
1932
|
-
styles: [],
|
|
1933
|
-
}]
|
|
1934
|
-
}], ctorParameters: function () { return []; }, propDecorators: { type: [{
|
|
1935
|
-
type: Input
|
|
1936
|
-
}] } });
|
|
1937
|
-
|
|
1938
|
-
class NotificationListComponent {
|
|
1939
|
-
constructor(notificationService) {
|
|
1940
|
-
this.notificationService = notificationService;
|
|
1941
|
-
this.notifications$ = this.notificationService.notifications$;
|
|
1942
|
-
}
|
|
1943
|
-
trackByItem(_, item) {
|
|
1944
|
-
return item;
|
|
1945
|
-
}
|
|
2598
|
+
class StreamAvatarModule {
|
|
1946
2599
|
}
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
i0.ɵɵ
|
|
1950
|
-
|
|
2600
|
+
StreamAvatarModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: StreamAvatarModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
2601
|
+
StreamAvatarModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: StreamAvatarModule, declarations: [AvatarComponent], imports: [CommonModule, TranslateModule], exports: [AvatarComponent] });
|
|
2602
|
+
StreamAvatarModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: StreamAvatarModule, imports: [[CommonModule, TranslateModule]] });
|
|
2603
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: StreamAvatarModule, decorators: [{
|
|
2604
|
+
type: NgModule,
|
|
1951
2605
|
args: [{
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
2606
|
+
declarations: [AvatarComponent],
|
|
2607
|
+
imports: [CommonModule, TranslateModule],
|
|
2608
|
+
exports: [AvatarComponent],
|
|
1955
2609
|
}]
|
|
1956
|
-
}]
|
|
2610
|
+
}] });
|
|
1957
2611
|
|
|
1958
2612
|
class StreamChatModule {
|
|
1959
2613
|
}
|
|
1960
2614
|
StreamChatModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: StreamChatModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
1961
|
-
StreamChatModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: StreamChatModule, declarations: [
|
|
1962
|
-
ChannelComponent,
|
|
2615
|
+
StreamChatModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: StreamChatModule, declarations: [ChannelComponent,
|
|
1963
2616
|
ChannelHeaderComponent,
|
|
1964
2617
|
ChannelListComponent,
|
|
1965
2618
|
ChannelPreviewComponent,
|
|
@@ -1972,8 +2625,11 @@ StreamChatModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", versio
|
|
|
1972
2625
|
AttachmentListComponent,
|
|
1973
2626
|
MessageReactionsComponent,
|
|
1974
2627
|
NotificationComponent,
|
|
1975
|
-
NotificationListComponent
|
|
1976
|
-
|
|
2628
|
+
NotificationListComponent,
|
|
2629
|
+
AttachmentPreviewListComponent,
|
|
2630
|
+
ModalComponent,
|
|
2631
|
+
TextareaDirective,
|
|
2632
|
+
HighlightMentionsPipe], imports: [CommonModule, EmojiModule, TranslateModule, StreamAvatarModule], exports: [ChannelComponent,
|
|
1977
2633
|
ChannelHeaderComponent,
|
|
1978
2634
|
ChannelListComponent,
|
|
1979
2635
|
ChannelPreviewComponent,
|
|
@@ -1986,13 +2642,15 @@ StreamChatModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", versio
|
|
|
1986
2642
|
AttachmentListComponent,
|
|
1987
2643
|
MessageReactionsComponent,
|
|
1988
2644
|
NotificationComponent,
|
|
1989
|
-
NotificationListComponent
|
|
1990
|
-
|
|
2645
|
+
NotificationListComponent,
|
|
2646
|
+
AttachmentPreviewListComponent,
|
|
2647
|
+
ModalComponent,
|
|
2648
|
+
HighlightMentionsPipe] });
|
|
2649
|
+
StreamChatModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: StreamChatModule, imports: [[CommonModule, EmojiModule, TranslateModule, StreamAvatarModule]] });
|
|
1991
2650
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: StreamChatModule, decorators: [{
|
|
1992
2651
|
type: NgModule,
|
|
1993
2652
|
args: [{
|
|
1994
2653
|
declarations: [
|
|
1995
|
-
AvatarComponent,
|
|
1996
2654
|
ChannelComponent,
|
|
1997
2655
|
ChannelHeaderComponent,
|
|
1998
2656
|
ChannelListComponent,
|
|
@@ -2007,10 +2665,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
2007
2665
|
MessageReactionsComponent,
|
|
2008
2666
|
NotificationComponent,
|
|
2009
2667
|
NotificationListComponent,
|
|
2668
|
+
AttachmentPreviewListComponent,
|
|
2669
|
+
ModalComponent,
|
|
2670
|
+
TextareaDirective,
|
|
2671
|
+
HighlightMentionsPipe,
|
|
2010
2672
|
],
|
|
2011
|
-
imports: [CommonModule, EmojiModule, TranslateModule],
|
|
2673
|
+
imports: [CommonModule, EmojiModule, TranslateModule, StreamAvatarModule],
|
|
2012
2674
|
exports: [
|
|
2013
|
-
AvatarComponent,
|
|
2014
2675
|
ChannelComponent,
|
|
2015
2676
|
ChannelHeaderComponent,
|
|
2016
2677
|
ChannelListComponent,
|
|
@@ -2025,6 +2686,59 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
2025
2686
|
MessageReactionsComponent,
|
|
2026
2687
|
NotificationComponent,
|
|
2027
2688
|
NotificationListComponent,
|
|
2689
|
+
AttachmentPreviewListComponent,
|
|
2690
|
+
ModalComponent,
|
|
2691
|
+
HighlightMentionsPipe,
|
|
2692
|
+
],
|
|
2693
|
+
}]
|
|
2694
|
+
}] });
|
|
2695
|
+
|
|
2696
|
+
class StreamAutocompleteTextareaModule {
|
|
2697
|
+
}
|
|
2698
|
+
StreamAutocompleteTextareaModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: StreamAutocompleteTextareaModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
2699
|
+
StreamAutocompleteTextareaModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: StreamAutocompleteTextareaModule, declarations: [AutocompleteTextareaComponent], imports: [CommonModule, TranslateModule, MentionModule, StreamAvatarModule], exports: [AutocompleteTextareaComponent] });
|
|
2700
|
+
StreamAutocompleteTextareaModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: StreamAutocompleteTextareaModule, providers: [
|
|
2701
|
+
{
|
|
2702
|
+
provide: textareaInjectionToken,
|
|
2703
|
+
useValue: AutocompleteTextareaComponent,
|
|
2704
|
+
},
|
|
2705
|
+
], imports: [[CommonModule, TranslateModule, MentionModule, StreamAvatarModule]] });
|
|
2706
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: StreamAutocompleteTextareaModule, decorators: [{
|
|
2707
|
+
type: NgModule,
|
|
2708
|
+
args: [{
|
|
2709
|
+
declarations: [AutocompleteTextareaComponent],
|
|
2710
|
+
imports: [CommonModule, TranslateModule, MentionModule, StreamAvatarModule],
|
|
2711
|
+
exports: [AutocompleteTextareaComponent],
|
|
2712
|
+
providers: [
|
|
2713
|
+
{
|
|
2714
|
+
provide: textareaInjectionToken,
|
|
2715
|
+
useValue: AutocompleteTextareaComponent,
|
|
2716
|
+
},
|
|
2717
|
+
],
|
|
2718
|
+
}]
|
|
2719
|
+
}] });
|
|
2720
|
+
|
|
2721
|
+
class StreamTextareaModule {
|
|
2722
|
+
}
|
|
2723
|
+
StreamTextareaModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: StreamTextareaModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
2724
|
+
StreamTextareaModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: StreamTextareaModule, declarations: [TextareaComponent], imports: [CommonModule, TranslateModule], exports: [TextareaComponent] });
|
|
2725
|
+
StreamTextareaModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: StreamTextareaModule, providers: [
|
|
2726
|
+
{
|
|
2727
|
+
provide: textareaInjectionToken,
|
|
2728
|
+
useValue: TextareaComponent,
|
|
2729
|
+
},
|
|
2730
|
+
], imports: [[CommonModule, TranslateModule]] });
|
|
2731
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: StreamTextareaModule, decorators: [{
|
|
2732
|
+
type: NgModule,
|
|
2733
|
+
args: [{
|
|
2734
|
+
declarations: [TextareaComponent],
|
|
2735
|
+
imports: [CommonModule, TranslateModule],
|
|
2736
|
+
exports: [TextareaComponent],
|
|
2737
|
+
providers: [
|
|
2738
|
+
{
|
|
2739
|
+
provide: textareaInjectionToken,
|
|
2740
|
+
useValue: TextareaComponent,
|
|
2741
|
+
},
|
|
2028
2742
|
],
|
|
2029
2743
|
}]
|
|
2030
2744
|
}] });
|
|
@@ -2037,5 +2751,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
2037
2751
|
* Generated bundle index. Do not edit.
|
|
2038
2752
|
*/
|
|
2039
2753
|
|
|
2040
|
-
export { AttachmentListComponent, AvatarComponent, ChannelComponent, ChannelHeaderComponent, ChannelListComponent, ChannelListToggleService, ChannelPreviewComponent, ChannelService, ChatClientService, IconComponent, ImageLoadService, LoadingIndicatorComponent, MessageActionsBoxComponent, MessageComponent, MessageInputComponent, MessageListComponent, MessageReactionsComponent, NotificationComponent, NotificationListComponent, StreamChatModule, StreamI18nService, ThemeService, getReadByText, parseDate };
|
|
2754
|
+
export { AttachmentListComponent, AttachmentPreviewListComponent, AttachmentService, AutocompleteTextareaComponent, AvatarComponent, ChannelComponent, ChannelHeaderComponent, ChannelListComponent, ChannelListToggleService, ChannelPreviewComponent, ChannelService, ChatClientService, HighlightMentionsPipe, IconComponent, ImageLoadService, LoadingIndicatorComponent, MessageActionsBoxComponent, MessageComponent, MessageInputComponent, MessageInputConfigService, MessageListComponent, MessageReactionsComponent, ModalComponent, NotificationComponent, NotificationListComponent, NotificationService, StreamAutocompleteTextareaModule, StreamChatModule, StreamI18nService, StreamTextareaModule, TextareaComponent, TextareaDirective, ThemeService, createMessagePreview, getDeviceWidth, getGroupStyles, getReadBy, getReadByText, isImageAttachment, parseDate, textareaInjectionToken };
|
|
2041
2755
|
//# sourceMappingURL=stream-chat-angular.js.map
|