stream-chat-angular 2.9.0 → 2.12.1
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 +2 -0
- package/assets/version.d.ts +1 -1
- package/bundles/stream-chat-angular.umd.js +718 -343
- package/bundles/stream-chat-angular.umd.js.map +1 -1
- package/esm2015/assets/i18n/en.js +3 -1
- package/esm2015/assets/version.js +2 -2
- package/esm2015/lib/channel/channel.component.js +3 -2
- package/esm2015/lib/channel.service.js +175 -40
- package/esm2015/lib/chat-client.service.js +6 -1
- package/esm2015/lib/icon/icon.component.js +2 -2
- package/esm2015/lib/message/message.component.js +67 -42
- package/esm2015/lib/message-actions-box/message-actions-box.component.js +20 -9
- package/esm2015/lib/message-input/message-input.component.js +61 -13
- package/esm2015/lib/message-list/message-list.component.js +124 -55
- package/esm2015/lib/message-preview.js +4 -2
- package/esm2015/lib/stream-chat.module.js +8 -3
- package/esm2015/lib/thread/thread.component.js +37 -0
- package/esm2015/public-api.js +2 -1
- package/fesm2015/stream-chat-angular.js +583 -252
- package/fesm2015/stream-chat-angular.js.map +1 -1
- package/lib/channel/channel.component.d.ts +2 -1
- package/lib/channel.service.d.ts +22 -7
- package/lib/chat-client.service.d.ts +1 -0
- package/lib/icon/icon.component.d.ts +1 -1
- package/lib/message/message.component.d.ts +26 -8
- package/lib/message-actions-box/message-actions-box.component.d.ts +4 -1
- package/lib/message-input/message-input.component.d.ts +7 -1
- package/lib/message-list/message-list.component.d.ts +21 -7
- package/lib/message-preview.d.ts +1 -1
- package/lib/stream-chat.module.d.ts +5 -4
- package/lib/thread/thread.component.d.ts +18 -0
- package/package.json +2 -11
- package/public-api.d.ts +1 -0
- package/src/assets/i18n/en.ts +4 -0
- package/src/assets/version.ts +1 -1
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
import { __awaiter } from 'tslib';
|
|
2
2
|
import * as i0 from '@angular/core';
|
|
3
3
|
import { Injectable, Component, Input, InjectionToken, EventEmitter, Directive, Output, Inject, ViewChild, HostBinding, NgModule } from '@angular/core';
|
|
4
|
-
import { BehaviorSubject, ReplaySubject,
|
|
4
|
+
import { BehaviorSubject, ReplaySubject, combineLatest, Subject, of } from 'rxjs';
|
|
5
5
|
import { StreamChat } from 'stream-chat';
|
|
6
|
-
import { map, first, catchError, startWith, distinctUntilChanged,
|
|
6
|
+
import { map, shareReplay, filter, first, catchError, startWith, distinctUntilChanged, 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 i6 from '@angular/common';
|
|
11
11
|
import { CommonModule } from '@angular/common';
|
|
12
|
+
import prettybytes from 'pretty-bytes';
|
|
12
13
|
import Dayjs from 'dayjs';
|
|
13
14
|
import calendar from 'dayjs/plugin/calendar';
|
|
14
|
-
import prettybytes from 'pretty-bytes';
|
|
15
15
|
import transliterate from '@stream-io/transliterate';
|
|
16
16
|
import * as i5 from 'angular-mentions';
|
|
17
17
|
import { MentionModule } from 'angular-mentions';
|
|
18
18
|
|
|
19
|
-
const version = '2.
|
|
19
|
+
const version = '2.12.1';
|
|
20
20
|
|
|
21
21
|
class NotificationService {
|
|
22
22
|
constructor() {
|
|
@@ -105,6 +105,11 @@ class ChatClientService {
|
|
|
105
105
|
});
|
|
106
106
|
});
|
|
107
107
|
}
|
|
108
|
+
disconnectUser() {
|
|
109
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
110
|
+
yield this.chatClient.disconnectUser();
|
|
111
|
+
});
|
|
112
|
+
}
|
|
108
113
|
getAppSettings() {
|
|
109
114
|
return __awaiter(this, void 0, void 0, function* () {
|
|
110
115
|
if (this.appSettingsSubject.getValue()) {
|
|
@@ -144,7 +149,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
144
149
|
}]
|
|
145
150
|
}], ctorParameters: function () { return [{ type: i0.NgZone }, { type: NotificationService }]; } });
|
|
146
151
|
|
|
147
|
-
const createMessagePreview = (user, text, attachments, mentionedUsers) => {
|
|
152
|
+
const createMessagePreview = (user, text, attachments = [], mentionedUsers = [], parentId = undefined, quotedMessageId = undefined) => {
|
|
148
153
|
const clientSideId = `${user.id}-${v4()}`;
|
|
149
154
|
return {
|
|
150
155
|
__html: text,
|
|
@@ -158,6 +163,8 @@ const createMessagePreview = (user, text, attachments, mentionedUsers) => {
|
|
|
158
163
|
user,
|
|
159
164
|
attachments,
|
|
160
165
|
mentioned_users: mentionedUsers,
|
|
166
|
+
parent_id: parentId,
|
|
167
|
+
quoted_message_id: quotedMessageId,
|
|
161
168
|
};
|
|
162
169
|
};
|
|
163
170
|
|
|
@@ -183,31 +190,52 @@ class ChannelService {
|
|
|
183
190
|
this.activeChannelMessagesSubject = new BehaviorSubject([]);
|
|
184
191
|
this.hasMoreChannelsSubject = new ReplaySubject(1);
|
|
185
192
|
this.activeChannelSubscriptions = [];
|
|
193
|
+
this.activeParentMessageIdSubject = new BehaviorSubject(undefined);
|
|
194
|
+
this.activeThreadMessagesSubject = new BehaviorSubject([]);
|
|
195
|
+
this.messagePageSize = 25;
|
|
196
|
+
this.messageToQuoteSubject = new BehaviorSubject(undefined);
|
|
186
197
|
this.channelListSetter = (channels) => {
|
|
187
198
|
this.channelsSubject.next(channels);
|
|
188
199
|
};
|
|
189
200
|
this.messageListSetter = (messages) => {
|
|
190
201
|
this.activeChannelMessagesSubject.next(messages);
|
|
191
202
|
};
|
|
203
|
+
this.threadListSetter = (messages) => {
|
|
204
|
+
this.activeThreadMessagesSubject.next(messages);
|
|
205
|
+
};
|
|
206
|
+
this.parentMessageSetter = (message) => {
|
|
207
|
+
this.activeParentMessageIdSubject.next(message === null || message === void 0 ? void 0 : message.id);
|
|
208
|
+
};
|
|
192
209
|
this.channels$ = this.channelsSubject.asObservable();
|
|
193
210
|
this.activeChannel$ = this.activeChannelSubject.asObservable();
|
|
194
211
|
this.activeChannelMessages$ = this.activeChannelMessagesSubject.pipe(map((messages) => {
|
|
195
212
|
const channel = this.activeChannelSubject.getValue();
|
|
196
|
-
return messages.map((message) =>
|
|
197
|
-
if (this.isStreamMessage(message) &&
|
|
198
|
-
this.isFormatMessageResponse(message)) {
|
|
199
|
-
return message;
|
|
200
|
-
}
|
|
201
|
-
else if (this.isFormatMessageResponse(message)) {
|
|
202
|
-
return Object.assign(Object.assign({}, message), { readBy: getReadBy(message, channel) });
|
|
203
|
-
}
|
|
204
|
-
else {
|
|
205
|
-
const formatMessage = this.formatMessage(message);
|
|
206
|
-
return Object.assign(Object.assign({}, formatMessage), { readBy: getReadBy(formatMessage, channel) });
|
|
207
|
-
}
|
|
208
|
-
});
|
|
213
|
+
return messages.map((message) => this.transformToStreamMessage(message, channel));
|
|
209
214
|
}));
|
|
210
215
|
this.hasMoreChannels$ = this.hasMoreChannelsSubject.asObservable();
|
|
216
|
+
this.activeParentMessageId$ =
|
|
217
|
+
this.activeParentMessageIdSubject.asObservable();
|
|
218
|
+
this.activeThreadMessages$ = this.activeThreadMessagesSubject.pipe(map((messages) => {
|
|
219
|
+
const channel = this.activeChannelSubject.getValue();
|
|
220
|
+
return messages.map((message) => this.transformToStreamMessage(message, channel));
|
|
221
|
+
}));
|
|
222
|
+
this.activeParentMessage$ = combineLatest([
|
|
223
|
+
this.activeChannelMessages$,
|
|
224
|
+
this.activeParentMessageId$,
|
|
225
|
+
]).pipe(map(([messages, parentMessageId]) => {
|
|
226
|
+
if (!parentMessageId) {
|
|
227
|
+
return undefined;
|
|
228
|
+
}
|
|
229
|
+
else {
|
|
230
|
+
return messages.find((m) => m.id === parentMessageId);
|
|
231
|
+
}
|
|
232
|
+
}), shareReplay());
|
|
233
|
+
this.messageToQuote$ = this.messageToQuoteSubject.asObservable();
|
|
234
|
+
this.chatClientService.connectionState$
|
|
235
|
+
.pipe(filter((s) => s === 'online'))
|
|
236
|
+
.subscribe(() => {
|
|
237
|
+
void this.setAsActiveParentMessage(undefined);
|
|
238
|
+
});
|
|
211
239
|
}
|
|
212
240
|
setAsActiveChannel(channel) {
|
|
213
241
|
const prevActiveChannel = this.activeChannelSubject.getValue();
|
|
@@ -221,25 +249,66 @@ class ChannelService {
|
|
|
221
249
|
void channel.markRead();
|
|
222
250
|
}
|
|
223
251
|
this.activeChannelMessagesSubject.next([...channel.state.messages]);
|
|
252
|
+
this.activeParentMessageIdSubject.next(undefined);
|
|
253
|
+
this.activeThreadMessagesSubject.next([]);
|
|
254
|
+
this.messageToQuoteSubject.next(undefined);
|
|
255
|
+
}
|
|
256
|
+
setAsActiveParentMessage(message) {
|
|
257
|
+
var _a;
|
|
258
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
259
|
+
const messageToQuote = this.messageToQuoteSubject.getValue();
|
|
260
|
+
if (messageToQuote && !!messageToQuote.parent_id) {
|
|
261
|
+
this.messageToQuoteSubject.next(undefined);
|
|
262
|
+
}
|
|
263
|
+
if (!message) {
|
|
264
|
+
this.activeParentMessageIdSubject.next(undefined);
|
|
265
|
+
this.activeThreadMessagesSubject.next([]);
|
|
266
|
+
}
|
|
267
|
+
else {
|
|
268
|
+
this.activeParentMessageIdSubject.next(message.id);
|
|
269
|
+
const activeChannel = this.activeChannelSubject.getValue();
|
|
270
|
+
const result = yield (activeChannel === null || activeChannel === void 0 ? void 0 : activeChannel.getReplies(message.id, {
|
|
271
|
+
limit: (_a = this.options) === null || _a === void 0 ? void 0 : _a.message_limit,
|
|
272
|
+
}));
|
|
273
|
+
this.activeThreadMessagesSubject.next((result === null || result === void 0 ? void 0 : result.messages) || []);
|
|
274
|
+
}
|
|
275
|
+
});
|
|
224
276
|
}
|
|
277
|
+
// load more thread replies
|
|
225
278
|
loadMoreMessages() {
|
|
226
|
-
var _a, _b, _c, _d;
|
|
279
|
+
var _a, _b, _c, _d, _e;
|
|
227
280
|
return __awaiter(this, void 0, void 0, function* () {
|
|
228
281
|
const activeChnannel = this.activeChannelSubject.getValue();
|
|
229
282
|
const lastMessageId = (_a = this.activeChannelMessagesSubject.getValue()[0]) === null || _a === void 0 ? void 0 : _a.id;
|
|
230
283
|
yield (activeChnannel === null || activeChnannel === void 0 ? void 0 : activeChnannel.query({
|
|
231
|
-
messages: { limit:
|
|
284
|
+
messages: { limit: (_b = this.options) === null || _b === void 0 ? void 0 : _b.message_limit, id_lt: lastMessageId },
|
|
232
285
|
members: { limit: 0 },
|
|
233
286
|
watchers: { limit: 0 },
|
|
234
287
|
}));
|
|
235
|
-
if (((
|
|
236
|
-
((
|
|
288
|
+
if (((_c = activeChnannel === null || activeChnannel === void 0 ? void 0 : activeChnannel.data) === null || _c === void 0 ? void 0 : _c.id) ===
|
|
289
|
+
((_e = (_d = this.activeChannelSubject.getValue()) === null || _d === void 0 ? void 0 : _d.data) === null || _e === void 0 ? void 0 : _e.id)) {
|
|
237
290
|
this.activeChannelMessagesSubject.next([
|
|
238
291
|
...activeChnannel.state.messages,
|
|
239
292
|
]);
|
|
240
293
|
}
|
|
241
294
|
});
|
|
242
295
|
}
|
|
296
|
+
loadMoreThreadReplies() {
|
|
297
|
+
var _a, _b;
|
|
298
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
299
|
+
const activeChnannel = this.activeChannelSubject.getValue();
|
|
300
|
+
const parentMessageId = this.activeParentMessageIdSubject.getValue();
|
|
301
|
+
if (!parentMessageId) {
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
const lastMessageId = (_a = this.activeThreadMessagesSubject.getValue()[0]) === null || _a === void 0 ? void 0 : _a.id;
|
|
305
|
+
yield (activeChnannel === null || activeChnannel === void 0 ? void 0 : activeChnannel.getReplies(parentMessageId, {
|
|
306
|
+
limit: (_b = this.options) === null || _b === void 0 ? void 0 : _b.message_limit,
|
|
307
|
+
id_lt: lastMessageId,
|
|
308
|
+
}));
|
|
309
|
+
this.activeThreadMessagesSubject.next((activeChnannel === null || activeChnannel === void 0 ? void 0 : activeChnannel.state.threads[parentMessageId]) || []);
|
|
310
|
+
});
|
|
311
|
+
}
|
|
243
312
|
init(filters, sort, options) {
|
|
244
313
|
return __awaiter(this, void 0, void 0, function* () {
|
|
245
314
|
this.filters = filters;
|
|
@@ -249,13 +318,21 @@ class ChannelService {
|
|
|
249
318
|
state: true,
|
|
250
319
|
presence: true,
|
|
251
320
|
watch: true,
|
|
252
|
-
message_limit:
|
|
321
|
+
message_limit: this.messagePageSize,
|
|
253
322
|
};
|
|
254
323
|
this.sort = sort || { last_message_at: -1, updated_at: -1 };
|
|
255
324
|
yield this.queryChannels();
|
|
256
325
|
this.chatClientService.notification$.subscribe((notification) => void this.handleNotification(notification));
|
|
257
326
|
});
|
|
258
327
|
}
|
|
328
|
+
reset() {
|
|
329
|
+
this.activeChannelMessagesSubject.next([]);
|
|
330
|
+
this.activeChannelSubject.next(undefined);
|
|
331
|
+
this.activeParentMessageIdSubject.next(undefined);
|
|
332
|
+
this.activeThreadMessagesSubject.next([]);
|
|
333
|
+
this.channelsSubject.next(undefined);
|
|
334
|
+
this.selectMessageToQuote(undefined);
|
|
335
|
+
}
|
|
259
336
|
loadMoreChannels() {
|
|
260
337
|
return __awaiter(this, void 0, void 0, function* () {
|
|
261
338
|
this.options.offset = this.channels.length;
|
|
@@ -277,9 +354,9 @@ class ChannelService {
|
|
|
277
354
|
.getValue()) === null || _a === void 0 ? void 0 : _a.deleteReaction(messageId, reactionType));
|
|
278
355
|
});
|
|
279
356
|
}
|
|
280
|
-
sendMessage(text, attachments = [], mentionedUsers = []) {
|
|
357
|
+
sendMessage(text, attachments = [], mentionedUsers = [], parentId = undefined, quotedMessageId = undefined) {
|
|
281
358
|
return __awaiter(this, void 0, void 0, function* () {
|
|
282
|
-
const preview = createMessagePreview(this.chatClientService.chatClient.user, text, attachments, mentionedUsers);
|
|
359
|
+
const preview = createMessagePreview(this.chatClientService.chatClient.user, text, attachments, mentionedUsers, parentId, quotedMessageId);
|
|
283
360
|
const channel = this.activeChannelSubject.getValue();
|
|
284
361
|
preview.readBy = [];
|
|
285
362
|
channel.state.addMessageSorted(preview, true);
|
|
@@ -363,29 +440,57 @@ class ChannelService {
|
|
|
363
440
|
const response = yield channel.sendAction(messageId, formData);
|
|
364
441
|
if (response === null || response === void 0 ? void 0 : response.message) {
|
|
365
442
|
channel.state.addMessageSorted(Object.assign(Object.assign({}, response.message), { status: 'received' }));
|
|
366
|
-
|
|
443
|
+
const isThreadReply = !!response.message.parent_id;
|
|
444
|
+
isThreadReply
|
|
445
|
+
? this.activeThreadMessagesSubject.next([
|
|
446
|
+
...channel.state.threads[response.message.parent_id],
|
|
447
|
+
])
|
|
448
|
+
: this.activeChannelMessagesSubject.next([...channel.state.messages]);
|
|
367
449
|
}
|
|
368
450
|
else {
|
|
369
451
|
channel.state.removeMessage({ id: messageId });
|
|
370
|
-
this.activeChannelMessagesSubject
|
|
452
|
+
if (this.activeChannelMessagesSubject
|
|
453
|
+
.getValue()
|
|
454
|
+
.find((m) => m.id === messageId)) {
|
|
455
|
+
this.activeChannelMessagesSubject.next([...channel.state.messages]);
|
|
456
|
+
}
|
|
457
|
+
else if (this.activeThreadMessagesSubject
|
|
458
|
+
.getValue()
|
|
459
|
+
.find((m) => m.id === messageId)) {
|
|
460
|
+
this.activeThreadMessagesSubject.next(channel.state.threads[this.activeParentMessageIdSubject.getValue()]);
|
|
461
|
+
}
|
|
371
462
|
}
|
|
372
463
|
});
|
|
373
464
|
}
|
|
465
|
+
selectMessageToQuote(message) {
|
|
466
|
+
this.messageToQuoteSubject.next(message);
|
|
467
|
+
}
|
|
374
468
|
sendMessageRequest(preview) {
|
|
375
469
|
var _a;
|
|
376
470
|
return __awaiter(this, void 0, void 0, function* () {
|
|
377
471
|
const channel = this.activeChannelSubject.getValue();
|
|
378
|
-
|
|
472
|
+
const isThreadReply = !!preview.parent_id;
|
|
473
|
+
isThreadReply
|
|
474
|
+
? this.activeThreadMessagesSubject.next([
|
|
475
|
+
...channel.state.threads[preview.parent_id],
|
|
476
|
+
])
|
|
477
|
+
: this.activeChannelMessagesSubject.next([...channel.state.messages]);
|
|
379
478
|
try {
|
|
380
479
|
const response = yield channel.sendMessage({
|
|
381
480
|
text: preview.text,
|
|
382
481
|
attachments: preview.attachments,
|
|
383
482
|
mentioned_users: (_a = preview.mentioned_users) === null || _a === void 0 ? void 0 : _a.map((u) => u.id),
|
|
384
483
|
id: preview.id,
|
|
484
|
+
parent_id: preview.parent_id,
|
|
485
|
+
quoted_message_id: preview.quoted_message_id,
|
|
385
486
|
});
|
|
386
487
|
if (response === null || response === void 0 ? void 0 : response.message) {
|
|
387
488
|
channel.state.addMessageSorted(Object.assign(Object.assign({}, response.message), { status: 'received' }), true);
|
|
388
|
-
|
|
489
|
+
isThreadReply
|
|
490
|
+
? this.activeThreadMessagesSubject.next([
|
|
491
|
+
...channel.state.threads[preview.parent_id],
|
|
492
|
+
])
|
|
493
|
+
: this.activeChannelMessagesSubject.next([...channel.state.messages]);
|
|
389
494
|
}
|
|
390
495
|
}
|
|
391
496
|
catch (error) {
|
|
@@ -394,7 +499,11 @@ class ChannelService {
|
|
|
394
499
|
? JSON.parse(stringError)
|
|
395
500
|
: {};
|
|
396
501
|
channel.state.addMessageSorted(Object.assign(Object.assign({}, preview), { errorStatusCode: parsedError.status || undefined, status: 'failed' }), true);
|
|
397
|
-
|
|
502
|
+
isThreadReply
|
|
503
|
+
? this.activeThreadMessagesSubject.next([
|
|
504
|
+
...channel.state.threads[preview.parent_id],
|
|
505
|
+
])
|
|
506
|
+
: this.activeChannelMessagesSubject.next([...channel.state.messages]);
|
|
398
507
|
}
|
|
399
508
|
});
|
|
400
509
|
}
|
|
@@ -472,9 +581,15 @@ class ChannelService {
|
|
|
472
581
|
}
|
|
473
582
|
}
|
|
474
583
|
watchForActiveChannelEvents(channel) {
|
|
475
|
-
this.activeChannelSubscriptions.push(channel.on('message.new', () => {
|
|
584
|
+
this.activeChannelSubscriptions.push(channel.on('message.new', (event) => {
|
|
476
585
|
this.ngZone.run(() => {
|
|
477
|
-
|
|
586
|
+
event.message && event.message.parent_id
|
|
587
|
+
? this.activeThreadMessagesSubject.next([
|
|
588
|
+
...channel.state.threads[event.message.parent_id],
|
|
589
|
+
])
|
|
590
|
+
: this.activeChannelMessagesSubject.next([
|
|
591
|
+
...channel.state.messages,
|
|
592
|
+
]);
|
|
478
593
|
this.activeChannel$.pipe(first()).subscribe((c) => {
|
|
479
594
|
if (this.canSendReadEvents) {
|
|
480
595
|
void (c === null || c === void 0 ? void 0 : c.markRead());
|
|
@@ -503,19 +618,27 @@ class ChannelService {
|
|
|
503
618
|
}
|
|
504
619
|
messageUpdated(event) {
|
|
505
620
|
this.ngZone.run(() => {
|
|
506
|
-
const
|
|
621
|
+
const isThreadReply = event.message && event.message.parent_id;
|
|
622
|
+
const messages = isThreadReply
|
|
623
|
+
? this.activeThreadMessagesSubject.getValue()
|
|
624
|
+
: this.activeChannelMessagesSubject.getValue();
|
|
507
625
|
const messageIndex = messages.findIndex((m) => { var _a; return m.id === ((_a = event.message) === null || _a === void 0 ? void 0 : _a.id); });
|
|
508
626
|
if (messageIndex !== -1 && event.message) {
|
|
509
627
|
messages[messageIndex] = event.message;
|
|
510
|
-
|
|
628
|
+
isThreadReply
|
|
629
|
+
? this.activeThreadMessagesSubject.next([...messages])
|
|
630
|
+
: this.activeChannelMessagesSubject.next([...messages]);
|
|
511
631
|
}
|
|
512
632
|
});
|
|
513
633
|
}
|
|
514
634
|
messageReactionEventReceived(e) {
|
|
515
635
|
this.ngZone.run(() => {
|
|
516
636
|
var _a, _b, _c, _d;
|
|
637
|
+
const isThreadMessage = e.message && e.message.parent_id;
|
|
517
638
|
let messages;
|
|
518
|
-
|
|
639
|
+
(isThreadMessage
|
|
640
|
+
? this.activeThreadMessages$
|
|
641
|
+
: this.activeChannelMessages$)
|
|
519
642
|
.pipe(first())
|
|
520
643
|
.subscribe((m) => (messages = m));
|
|
521
644
|
const message = messages.find((m) => { var _a; return m.id === ((_a = e === null || e === void 0 ? void 0 : e.message) === null || _a === void 0 ? void 0 : _a.id); });
|
|
@@ -526,7 +649,9 @@ class ChannelService {
|
|
|
526
649
|
message.reaction_scores = Object.assign({}, (_b = e.message) === null || _b === void 0 ? void 0 : _b.reaction_scores);
|
|
527
650
|
message.latest_reactions = [...(((_c = e.message) === null || _c === void 0 ? void 0 : _c.latest_reactions) || [])];
|
|
528
651
|
message.own_reactions = [...(((_d = e.message) === null || _d === void 0 ? void 0 : _d.own_reactions) || [])];
|
|
529
|
-
|
|
652
|
+
isThreadMessage
|
|
653
|
+
? this.activeThreadMessagesSubject.next([...messages])
|
|
654
|
+
: this.activeChannelMessagesSubject.next([...messages]);
|
|
530
655
|
});
|
|
531
656
|
}
|
|
532
657
|
formatMessage(message) {
|
|
@@ -574,7 +699,7 @@ class ChannelService {
|
|
|
574
699
|
case 'message.new': {
|
|
575
700
|
this.ngZone.run(() => {
|
|
576
701
|
if (this.customNewMessageHandler) {
|
|
577
|
-
this.customNewMessageHandler(event, channel, this.channelListSetter, this.messageListSetter);
|
|
702
|
+
this.customNewMessageHandler(event, channel, this.channelListSetter, this.messageListSetter, this.threadListSetter, this.parentMessageSetter);
|
|
578
703
|
}
|
|
579
704
|
else {
|
|
580
705
|
this.handleNewMessage(event, channel);
|
|
@@ -585,7 +710,7 @@ class ChannelService {
|
|
|
585
710
|
case 'channel.hidden': {
|
|
586
711
|
this.ngZone.run(() => {
|
|
587
712
|
if (this.customChannelHiddenHandler) {
|
|
588
|
-
this.customChannelHiddenHandler(event, channel, this.channelListSetter, this.messageListSetter);
|
|
713
|
+
this.customChannelHiddenHandler(event, channel, this.channelListSetter, this.messageListSetter, this.threadListSetter, this.parentMessageSetter);
|
|
589
714
|
}
|
|
590
715
|
else {
|
|
591
716
|
this.handleChannelHidden(event);
|
|
@@ -596,7 +721,7 @@ class ChannelService {
|
|
|
596
721
|
case 'channel.deleted': {
|
|
597
722
|
this.ngZone.run(() => {
|
|
598
723
|
if (this.customChannelDeletedHandler) {
|
|
599
|
-
this.customChannelDeletedHandler(event, channel, this.channelListSetter, this.messageListSetter);
|
|
724
|
+
this.customChannelDeletedHandler(event, channel, this.channelListSetter, this.messageListSetter, this.threadListSetter, this.parentMessageSetter);
|
|
600
725
|
}
|
|
601
726
|
else {
|
|
602
727
|
this.handleChannelDeleted(event);
|
|
@@ -607,7 +732,7 @@ class ChannelService {
|
|
|
607
732
|
case 'channel.visible': {
|
|
608
733
|
this.ngZone.run(() => {
|
|
609
734
|
if (this.customChannelVisibleHandler) {
|
|
610
|
-
this.customChannelVisibleHandler(event, channel, this.channelListSetter, this.messageListSetter);
|
|
735
|
+
this.customChannelVisibleHandler(event, channel, this.channelListSetter, this.messageListSetter, this.threadListSetter, this.parentMessageSetter);
|
|
611
736
|
}
|
|
612
737
|
else {
|
|
613
738
|
this.handleChannelVisible(event, channel);
|
|
@@ -618,7 +743,7 @@ class ChannelService {
|
|
|
618
743
|
case 'channel.updated': {
|
|
619
744
|
this.ngZone.run(() => {
|
|
620
745
|
if (this.customChannelUpdatedHandler) {
|
|
621
|
-
this.customChannelUpdatedHandler(event, channel, this.channelListSetter, this.messageListSetter);
|
|
746
|
+
this.customChannelUpdatedHandler(event, channel, this.channelListSetter, this.messageListSetter, this.threadListSetter, this.parentMessageSetter);
|
|
622
747
|
}
|
|
623
748
|
else {
|
|
624
749
|
this.handleChannelUpdate(event);
|
|
@@ -629,7 +754,7 @@ class ChannelService {
|
|
|
629
754
|
case 'channel.truncated': {
|
|
630
755
|
this.ngZone.run(() => {
|
|
631
756
|
if (this.customChannelTruncatedHandler) {
|
|
632
|
-
this.customChannelTruncatedHandler(event, channel, this.channelListSetter, this.messageListSetter);
|
|
757
|
+
this.customChannelTruncatedHandler(event, channel, this.channelListSetter, this.messageListSetter, this.threadListSetter, this.parentMessageSetter);
|
|
633
758
|
}
|
|
634
759
|
else {
|
|
635
760
|
this.handleChannelTruncate(event);
|
|
@@ -669,6 +794,7 @@ class ChannelService {
|
|
|
669
794
|
}
|
|
670
795
|
}
|
|
671
796
|
}
|
|
797
|
+
// truncate active thread as well
|
|
672
798
|
handleChannelTruncate(event) {
|
|
673
799
|
var _a, _b;
|
|
674
800
|
const channelIndex = this.channels.findIndex((c) => c.cid === event.channel.cid);
|
|
@@ -680,6 +806,8 @@ class ChannelService {
|
|
|
680
806
|
channel.state.messages = [];
|
|
681
807
|
this.activeChannelSubject.next(channel);
|
|
682
808
|
this.activeChannelMessagesSubject.next([]);
|
|
809
|
+
this.activeParentMessageIdSubject.next(undefined);
|
|
810
|
+
this.activeThreadMessagesSubject.next([]);
|
|
683
811
|
}
|
|
684
812
|
}
|
|
685
813
|
}
|
|
@@ -695,6 +823,20 @@ class ChannelService {
|
|
|
695
823
|
const capabilites = (_a = channel.data) === null || _a === void 0 ? void 0 : _a.own_capabilities;
|
|
696
824
|
return capabilites.indexOf('read-events') !== -1;
|
|
697
825
|
}
|
|
826
|
+
transformToStreamMessage(message, channel) {
|
|
827
|
+
const isThreadMessage = !!message.parent_id;
|
|
828
|
+
if (this.isStreamMessage(message) &&
|
|
829
|
+
this.isFormatMessageResponse(message)) {
|
|
830
|
+
return message;
|
|
831
|
+
}
|
|
832
|
+
else if (this.isFormatMessageResponse(message)) {
|
|
833
|
+
return Object.assign(Object.assign({}, message), { readBy: isThreadMessage ? [] : getReadBy(message, channel) });
|
|
834
|
+
}
|
|
835
|
+
else {
|
|
836
|
+
const formatMessage = this.formatMessage(message);
|
|
837
|
+
return Object.assign(Object.assign({}, formatMessage), { readBy: isThreadMessage ? [] : getReadBy(formatMessage, channel) });
|
|
838
|
+
}
|
|
839
|
+
}
|
|
698
840
|
}
|
|
699
841
|
ChannelService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ChannelService, deps: [{ token: ChatClientService }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
700
842
|
ChannelService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ChannelService, providedIn: 'root' });
|
|
@@ -1007,6 +1149,7 @@ const en = {
|
|
|
1007
1149
|
Flag: 'Flag',
|
|
1008
1150
|
'Message Failed': 'Message Failed',
|
|
1009
1151
|
'Message Failed · Unauthorized': 'Message Failed · Unauthorized',
|
|
1152
|
+
'Message Failed · Click to try again': 'Message Failed · Click to try again',
|
|
1010
1153
|
'Message deleted': 'Message deleted',
|
|
1011
1154
|
'Message has been successfully flagged': 'Message has been successfully flagged',
|
|
1012
1155
|
'Message pinned': 'Message pinned',
|
|
@@ -1057,6 +1200,7 @@ const en = {
|
|
|
1057
1200
|
test: 'success',
|
|
1058
1201
|
'Sending links is not allowed in this conversation': 'Sending links is not allowed in this conversation',
|
|
1059
1202
|
"You can't send messages in this channel": "You can't send messages in this channel",
|
|
1203
|
+
"You can't send thread replies in this channel": "You can't send thread replies in this channel",
|
|
1060
1204
|
'Unsupported file type: {{type}}': 'Unsupported file type: {{type}}',
|
|
1061
1205
|
},
|
|
1062
1206
|
};
|
|
@@ -1072,14 +1216,14 @@ class StreamI18nService {
|
|
|
1072
1216
|
this.translteService.setTranslation(lang, { streamChat: Object.assign(Object.assign({}, en.streamChat), overrides) }, true);
|
|
1073
1217
|
}
|
|
1074
1218
|
}
|
|
1075
|
-
StreamI18nService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: StreamI18nService, deps: [{ token:
|
|
1219
|
+
StreamI18nService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: StreamI18nService, deps: [{ token: i1.TranslateService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1076
1220
|
StreamI18nService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: StreamI18nService, providedIn: 'root' });
|
|
1077
1221
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: StreamI18nService, decorators: [{
|
|
1078
1222
|
type: Injectable,
|
|
1079
1223
|
args: [{
|
|
1080
1224
|
providedIn: 'root',
|
|
1081
1225
|
}]
|
|
1082
|
-
}], ctorParameters: function () { return [{ type:
|
|
1226
|
+
}], ctorParameters: function () { return [{ type: i1.TranslateService }]; } });
|
|
1083
1227
|
|
|
1084
1228
|
class AvatarComponent {
|
|
1085
1229
|
constructor() {
|
|
@@ -1113,7 +1257,7 @@ class IconComponent {
|
|
|
1113
1257
|
constructor() { }
|
|
1114
1258
|
}
|
|
1115
1259
|
IconComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: IconComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1116
|
-
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: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type:
|
|
1260
|
+
IconComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: IconComponent, selector: "stream-icon", inputs: { icon: "icon", size: "size" }, ngImport: i0, template: "<svg\n data-testid=\"action-icon\"\n *ngIf=\"icon === 'action-icon'\"\n height=\"4\"\n viewBox=\"0 0 11 4\"\n width=\"11\"\n xmlns=\"http://www.w3.org/2000/svg\"\n>\n <path\n d=\"M1.5 3a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm4 0a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm4 0a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3z\"\n fillRule=\"nonzero\"\n />\n</svg>\n<svg\n *ngIf=\"icon === 'delivered-icon'\"\n height=\"16\"\n width=\"16\"\n xmlns=\"http://www.w3.org/2000/svg\"\n data-testid=\"delivered-icon\"\n>\n <path\n d=\"M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0zm3.72 6.633a.955.955 0 1 0-1.352-1.352L6.986 8.663 5.633 7.31A.956.956 0 1 0 4.28 8.663l2.029 2.028a.956.956 0 0 0 1.353 0l4.058-4.058z\"\n fill=\"#006CFF\"\n fillRule=\"evenodd\"\n />\n</svg>\n<svg\n *ngIf=\"icon === 'reaction-icon'\"\n height=\"12\"\n viewBox=\"0 0 12 12\"\n width=\"12\"\n xmlns=\"http://www.w3.org/2000/svg\"\n data-testid=\"reaction-icon\"\n>\n <g clipRule=\"evenodd\" fillRule=\"evenodd\">\n <path\n d=\"M6 1.2C3.3 1.2 1.2 3.3 1.2 6c0 2.7 2.1 4.8 4.8 4.8 2.7 0 4.8-2.1 4.8-4.8 0-2.7-2.1-4.8-4.8-4.8zM0 6c0-3.3 2.7-6 6-6s6 2.7 6 6-2.7 6-6 6-6-2.7-6-6z\"\n ></path>\n <path\n d=\"M5.4 4.5c0 .5-.4.9-.9.9s-.9-.4-.9-.9.4-.9.9-.9.9.4.9.9zM8.4 4.5c0 .5-.4.9-.9.9s-.9-.4-.9-.9.4-.9.9-.9.9.4.9.9zM3.3 6.7c.3-.2.6-.1.8.1.3.4.8.9 1.5 1 .6.2 1.4.1 2.4-1 .2-.2.6-.3.8 0 .2.2.3.6 0 .8-1.1 1.3-2.4 1.7-3.5 1.5-1-.2-1.8-.9-2.2-1.5-.2-.3-.1-.7.2-.9z\"\n ></path>\n </g>\n</svg>\n<svg\n data-testid=\"connection-error\"\n *ngIf=\"icon === 'connection-error'\"\n width=\"78px\"\n height=\"78px\"\n viewBox=\"0 0 78 78\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n>\n <!-- Generator: Sketch 52.6 (67491) - http://www.bohemiancoding.com/sketch -->\n <title>Combined Shape</title>\n <desc>Created with Sketch.</desc>\n <g\n id=\"Interactions\"\n stroke=\"none\"\n stroke-width=\"1\"\n fill=\"none\"\n fill-rule=\"evenodd\"\n >\n <g\n id=\"Connection-Error-_-Connectivity\"\n transform=\"translate(-270.000000, -30.000000)\"\n fill=\"#CF1F25\"\n >\n <g\n id=\"109-network-connection\"\n transform=\"translate(270.000000, 30.000000)\"\n >\n <path\n d=\"M66.4609744,11.414231 C81.6225232,26.5757798 81.6225232,51.157545 66.4609744,66.3188467 C51.2994256,81.4803954 26.7176604,81.4803954 11.5563587,66.3188467 C-3.60519004,51.1572979 -3.60519004,26.5755327 11.5563587,11.414231 C26.7179075,-3.74731776 51.2996727,-3.74731776 66.4609744,11.414231 Z M54.7853215,45.8823776 L54.7853215,40.5882574 C54.7853215,39.613638 53.9952341,38.8235506 53.0206147,38.8235506 L44.9576695,38.8235506 L41.428256,42.3529641 L51.255555,42.3529641 L51.255555,45.8823776 L54.7853215,45.8823776 Z M40.6659027,43.1153174 L37.8988425,45.8823776 L40.6659027,45.8823776 L40.6659027,43.1153174 Z M51.1764962,56.4702653 L58.2353232,56.4702653 C59.2099355,56.4702653 60.00003,55.6801708 60.00003,54.7055585 L60.00003,51.176145 C60.00003,50.2015327 59.2099355,49.4114382 58.2353232,49.4114382 L51.1764962,49.4114382 C50.2018839,49.4114382 49.4117894,50.2015327 49.4117894,51.176145 L49.4117894,54.7055585 C49.4117894,55.6801708 50.2018839,56.4702653 51.1764962,56.4702653 Z M35.2941353,56.4702653 L42.3529624,56.4702653 C43.3275746,56.4702653 44.1176691,55.6801708 44.1176691,54.7055585 L44.1176691,51.176145 C44.1176691,50.2015327 43.3275746,49.4114382 42.3529624,49.4114382 L35.2941353,49.4114382 C34.319523,49.4114382 33.5294285,50.2015327 33.5294285,51.176145 L33.5294285,54.7055585 C33.5294285,55.6801708 34.319523,56.4702653 35.2941353,56.4702653 Z M56.6964989,19.0874231 C56.007381,18.3985134 54.8903216,18.3985134 54.2012036,19.087423 L45.882376,27.4062507 L45.882376,19.4117761 C45.882376,18.4371568 45.0922885,17.6470693 44.1176692,17.6470693 L33.5294286,17.6470693 C32.5548092,17.6470694 31.7647218,18.4371568 31.7647218,19.4117761 L31.7647218,30.0000167 C31.7647219,30.9746363 32.5548092,31.7647237 33.5294285,31.7647237 L41.5239031,31.7647237 L34.4650761,38.8235508 L24.7058947,38.8235508 C23.7312753,38.8235508 22.9411879,39.6136382 22.9411879,40.5882575 L22.9411879,45.8823778 L26.4706014,45.8823778 L26.4706014,42.3529643 L30.9356624,42.3529643 L23.8768354,49.4117914 L19.4117743,49.4117914 C18.4371549,49.4117914 17.6470675,50.2018788 17.6470675,51.1764981 L17.6470675,54.7059117 C17.6504049,54.9674302 17.7129076,55.2248042 17.8298886,55.4587302 L16.4456526,56.8429662 C15.7446193,57.5200453 15.7252005,58.6372282 16.4022825,59.3382615 C17.0793616,60.0392948 18.1965445,60.0587136 18.8975778,59.3816316 C18.9122847,59.3674273 18.9267436,59.3529684 18.940948,59.3382615 L56.6964963,21.5830662 C57.3856425,20.8939094 57.3856425,19.7765747 56.6964963,19.0874179 Z\"\n id=\"Combined-Shape\"\n ></path>\n </g>\n </g>\n </g>\n</svg>\n<svg\n *ngIf=\"icon === 'send'\"\n data-testid=\"send\"\n height=\"17\"\n viewBox=\"0 0 18 17\"\n width=\"18\"\n xmlns=\"http://www.w3.org/2000/svg\"\n>\n <title translate>streamChat.Send</title>\n <path\n d=\"M0 17.015l17.333-8.508L0 0v6.617l12.417 1.89L0 10.397z\"\n fill=\"#006cff\"\n fillRule=\"evenodd\"\n />\n</svg>\n<svg\n *ngIf=\"icon === 'file-upload'\"\n data-testid=\"file-upload\"\n height=\"14\"\n width=\"14\"\n xmlns=\"http://www.w3.org/2000/svg\"\n>\n <title translate>streamChat.Attach files</title>\n <path\n d=\"M1.667.333h10.666c.737 0 1.334.597 1.334 1.334v10.666c0 .737-.597 1.334-1.334 1.334H1.667a1.333 1.333 0 0 1-1.334-1.334V1.667C.333.93.93.333 1.667.333zm2 1.334a1.667 1.667 0 1 0 0 3.333 1.667 1.667 0 0 0 0-3.333zm-2 9.333v1.333h10.666v-4l-2-2-4 4-2-2L1.667 11z\"\n fillRule=\"nonzero\"\n />\n</svg>\n<svg\n data-testid=\"retry\"\n *ngIf=\"icon === 'retry'\"\n width=\"22\"\n height=\"20\"\n viewBox=\"0 0 22 20\"\n xmlns=\"http://www.w3.org/2000/svg\"\n>\n <path\n d=\"M20 5.535V2a1 1 0 0 1 2 0v6a1 1 0 0 1-1 1h-6a1 1 0 0 1 0-2h3.638l-2.975-2.653a8 8 0 1 0 1.884 8.32 1 1 0 1 1 1.886.666A10 10 0 1 1 5.175 1.245c3.901-2.15 8.754-1.462 11.88 1.667L20 5.535z\"\n fill=\"#FFF\"\n fill-rule=\"nonzero\"\n />\n</svg>\n<svg\n *ngIf=\"icon === 'close'\"\n data-testid=\"close\"\n width=\"28\"\n height=\"28\"\n viewBox=\"0 0 28 28\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n>\n <defs>\n <path\n d=\"M465 5c5.53 0 10 4.47 10 10s-4.47 10-10 10-10-4.47-10-10 4.47-10 10-10zm3.59 5L465 13.59 461.41 10 460 11.41l3.59 3.59-3.59 3.59 1.41 1.41 3.59-3.59 3.59 3.59 1.41-1.41-3.59-3.59 3.59-3.59-1.41-1.41z\"\n id=\"b\"\n />\n <filter\n x=\"-30%\"\n y=\"-30%\"\n width=\"160%\"\n height=\"160%\"\n filterUnits=\"objectBoundingBox\"\n id=\"a\"\n >\n <feOffset in=\"SourceAlpha\" result=\"shadowOffsetOuter1\" />\n <feGaussianBlur\n stdDeviation=\"2\"\n in=\"shadowOffsetOuter1\"\n result=\"shadowBlurOuter1\"\n />\n <feColorMatrix\n values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.5 0\"\n in=\"shadowBlurOuter1\"\n />\n </filter>\n </defs>\n <g transform=\"translate(-451 -1)\" fill-rule=\"nonzero\" fill=\"none\">\n <use fill=\"#000\" filter=\"url(#a)\" xlink:href=\"#b\" />\n <use fill=\"#FFF\" fill-rule=\"evenodd\" xlink:href=\"#b\" />\n </g>\n</svg>\n<svg\n *ngIf=\"icon === 'file'\"\n data-testid=\"file\"\n className=\"rfu-file-icon--small fa-file-fallback\"\n [attr.height]=\"size || 20\"\n [attr.width]=\"size || 20\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 384 512\"\n>\n <path\n d=\"M369.9 97.9L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM332.1 128H256V51.9l76.1 76.1zM48 464V48h160v104c0 13.3 10.7 24 24 24h104v288H48z\"\n fill=\"#414D54\"\n />\n</svg>\n<svg\n *ngIf=\"icon === 'reply'\"\n data-testid=\"reply\"\n height=\"15\"\n width=\"18\"\n xmlns=\"http://www.w3.org/2000/svg\"\n>\n <path\n d=\"M.56 10.946H.06l-.002-.498L.025.92a.5.5 0 1 1 1-.004l.032 9.029H9.06v-4l9 4.5-9 4.5v-4H.56z\"\n fillRule=\"nonzero\"\n />\n</svg>\n<svg\n height=\"10\"\n width=\"10\"\n xmlns=\"http://www.w3.org/2000/svg\"\n data-testid=\"close-no-outline\"\n *ngIf=\"icon === 'close-no-outline'\"\n>\n <path\n d=\"M9.916 1.027L8.973.084 5 4.058 1.027.084l-.943.943L4.058 5 .084 8.973l.943.943L5 5.942l3.973 3.974.943-.943L5.942 5z\"\n fillRule=\"evenodd\"\n />\n</svg>\n<svg\n height=\"10\"\n width=\"14\"\n xmlns=\"http://www.w3.org/2000/svg\"\n data-testid=\"reply-in-thread\"\n *ngIf=\"icon === 'reply-in-thread'\"\n>\n <path\n d=\"M8.516 3c4.78 0 4.972 6.5 4.972 6.5-1.6-2.906-2.847-3.184-4.972-3.184v2.872L3.772 4.994 8.516.5V3zM.484 5l4.5-4.237v1.78L2.416 5l2.568 2.125v1.828L.484 5z\"\n fillRule=\"evenodd\"\n />\n</svg>\n", directives: [{ type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }] });
|
|
1117
1261
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: IconComponent, decorators: [{
|
|
1118
1262
|
type: Component,
|
|
1119
1263
|
args: [{
|
|
@@ -1251,6 +1395,90 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
1251
1395
|
}]
|
|
1252
1396
|
}], ctorParameters: function () { return []; } });
|
|
1253
1397
|
|
|
1398
|
+
class ImageLoadService {
|
|
1399
|
+
constructor() {
|
|
1400
|
+
this.imageLoad$ = new Subject();
|
|
1401
|
+
}
|
|
1402
|
+
}
|
|
1403
|
+
ImageLoadService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ImageLoadService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1404
|
+
ImageLoadService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ImageLoadService, providedIn: 'root' });
|
|
1405
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ImageLoadService, decorators: [{
|
|
1406
|
+
type: Injectable,
|
|
1407
|
+
args: [{
|
|
1408
|
+
providedIn: 'root',
|
|
1409
|
+
}]
|
|
1410
|
+
}], ctorParameters: function () { return []; } });
|
|
1411
|
+
|
|
1412
|
+
class AttachmentListComponent {
|
|
1413
|
+
constructor(imageLoadService, channelService) {
|
|
1414
|
+
this.imageLoadService = imageLoadService;
|
|
1415
|
+
this.channelService = channelService;
|
|
1416
|
+
this.attachments = [];
|
|
1417
|
+
this.orderedAttachments = [];
|
|
1418
|
+
}
|
|
1419
|
+
ngOnChanges() {
|
|
1420
|
+
this.orderedAttachments = [
|
|
1421
|
+
...this.attachments.filter((a) => this.isImage(a)),
|
|
1422
|
+
...this.attachments.filter((a) => this.isFile(a)),
|
|
1423
|
+
...this.attachments.filter((a) => this.isCard(a)),
|
|
1424
|
+
];
|
|
1425
|
+
}
|
|
1426
|
+
trackById(index) {
|
|
1427
|
+
return index;
|
|
1428
|
+
}
|
|
1429
|
+
isImage(attachment) {
|
|
1430
|
+
return isImageAttachment(attachment);
|
|
1431
|
+
}
|
|
1432
|
+
isFile(attachment) {
|
|
1433
|
+
return attachment.type === 'file';
|
|
1434
|
+
}
|
|
1435
|
+
isCard(attachment) {
|
|
1436
|
+
return (!attachment.type ||
|
|
1437
|
+
(attachment.type === 'image' && !this.isImage(attachment)) ||
|
|
1438
|
+
attachment.type === 'giphy');
|
|
1439
|
+
}
|
|
1440
|
+
imageLoaded() {
|
|
1441
|
+
this.imageLoadService.imageLoad$.next();
|
|
1442
|
+
}
|
|
1443
|
+
hasFileSize(attachment) {
|
|
1444
|
+
return (attachment.file_size && Number.isFinite(Number(attachment.file_size)));
|
|
1445
|
+
}
|
|
1446
|
+
getFileSize(attachment) {
|
|
1447
|
+
return prettybytes(attachment.file_size);
|
|
1448
|
+
}
|
|
1449
|
+
trimUrl(url) {
|
|
1450
|
+
if (url !== undefined && url !== null) {
|
|
1451
|
+
const [trimmedUrl] = url
|
|
1452
|
+
.replace(/^(?:https?:\/\/)?(?:www\.)?/i, '')
|
|
1453
|
+
.split('/');
|
|
1454
|
+
return trimmedUrl;
|
|
1455
|
+
}
|
|
1456
|
+
return null;
|
|
1457
|
+
}
|
|
1458
|
+
sendAction(action) {
|
|
1459
|
+
void this.channelService.sendAction(this.messageId, {
|
|
1460
|
+
[action.name]: action.value,
|
|
1461
|
+
});
|
|
1462
|
+
}
|
|
1463
|
+
trackByActionValue(_, item) {
|
|
1464
|
+
return item.value;
|
|
1465
|
+
}
|
|
1466
|
+
}
|
|
1467
|
+
AttachmentListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: AttachmentListComponent, deps: [{ token: ImageLoadService }, { token: ChannelService }], target: i0.ɵɵFactoryTarget.Component });
|
|
1468
|
+
AttachmentListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: AttachmentListComponent, selector: "stream-attachment-list", inputs: { messageId: "messageId", attachments: "attachments" }, usesOnChanges: true, ngImport: i0, template: "<ng-container *ngFor=\"let attachment of orderedAttachments; trackBy: trackById\">\n <div\n data-testclass=\"attachment-container\"\n class=\"str-chat__message-attachment str-chat__message-attachment--{{\n attachment.type\n }}\"\n [class.str-chat__message-attachment--card]=\"isCard(attachment)\"\n [class.str-chat-angular__message-attachment-file-single]=\"\n isFile(attachment)\n \"\n >\n <img\n *ngIf=\"isImage(attachment)\"\n class=\"str-chat__message-attachment--img\"\n data-testclass=\"image\"\n [src]=\"attachment.img_url || attachment.thumb_url || attachment.image_url\"\n [alt]=\"attachment?.fallback\"\n (load)=\"imageLoaded()\"\n />\n <div\n *ngIf=\"isFile(attachment)\"\n class=\"\n str-chat__message-attachment-file--item\n str-chat-angular__message-attachment-file-single\n \"\n >\n <stream-icon icon=\"file\" [size]=\"30\"></stream-icon>\n <div class=\"str-chat__message-attachment-file--item-text\">\n <a\n data-testclass=\"file-link\"\n download\n href=\"{{ attachment.asset_url }}\"\n target=\"_blank\"\n >\n {{ attachment.title }}\n </a>\n <span data-testclass=\"size\" *ngIf=\"hasFileSize(attachment)\">{{\n getFileSize(attachment)\n }}</span>\n </div>\n </div>\n <div\n *ngIf=\"isCard(attachment)\"\n class=\"str-chat__message-attachment-card str-chat__message-attachment-card--{{\n attachment.type\n }}\"\n >\n <div\n *ngIf=\"attachment.image_url || attachment.thumb_url\"\n class=\"str-chat__message-attachment-card--header\"\n >\n <img\n data-testclass=\"card-img\"\n alt=\"{{ attachment.image_url || attachment.thumb_url }}\"\n src=\"{{ attachment.image_url || attachment.thumb_url }}\"\n />\n </div>\n <div class=\"str-chat__message-attachment-card--content\">\n <div class=\"str-chat__message-attachment-card--flex\">\n <div\n *ngIf=\"attachment.title\"\n data-testclass=\"card-title\"\n class=\"str-chat__message-attachment-card--title\"\n >\n {{ attachment.title }}\n </div>\n <div\n *ngIf=\"attachment.text\"\n class=\"str-chat__message-attachment-card--text\"\n data-testclass=\"card-text\"\n >\n {{ attachment.text }}\n </div>\n <a\n class=\"str-chat__message-attachment-card--url\"\n *ngIf=\"attachment.title_link || attachment.og_scrape_url\"\n data-testclass=\"url-link\"\n noopener\n noreferrer\n href=\"{{ attachment.title_link || attachment.og_scrape_url }}\"\n target=\"_blank\"\n >\n {{ trimUrl(attachment.title_link || attachment.og_scrape_url) }}\n </a>\n </div>\n </div>\n </div>\n <div\n class=\"str-chat__message-attachment-actions\"\n *ngIf=\"attachment.actions && attachment.actions.length > 0\"\n >\n <div class=\"str-chat__message-attachment-actions-form\">\n <button\n *ngFor=\"let action of attachment.actions; trackBy: trackByActionValue\"\n class=\"str-chat__message-attachment-actions-button str-chat__message-attachment-actions-button--{{\n action.style\n }}\"\n data-testclass=\"attachment-action\"\n (click)=\"sendAction(action)\"\n (keyup.enter)=\"sendAction(action)\"\n >\n {{ action.text }}\n </button>\n </div>\n </div>\n </div>\n</ng-container>\n", components: [{ type: IconComponent, selector: "stream-icon", inputs: ["icon", "size"] }], directives: [{ type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
|
|
1469
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: AttachmentListComponent, decorators: [{
|
|
1470
|
+
type: Component,
|
|
1471
|
+
args: [{
|
|
1472
|
+
selector: 'stream-attachment-list',
|
|
1473
|
+
templateUrl: './attachment-list.component.html',
|
|
1474
|
+
styles: [],
|
|
1475
|
+
}]
|
|
1476
|
+
}], ctorParameters: function () { return [{ type: ImageLoadService }, { type: ChannelService }]; }, propDecorators: { messageId: [{
|
|
1477
|
+
type: Input
|
|
1478
|
+
}], attachments: [{
|
|
1479
|
+
type: Input
|
|
1480
|
+
}] } });
|
|
1481
|
+
|
|
1254
1482
|
class AttachmentPreviewListComponent {
|
|
1255
1483
|
constructor(attachmentService) {
|
|
1256
1484
|
this.attachmentService = attachmentService;
|
|
@@ -1271,7 +1499,7 @@ class AttachmentPreviewListComponent {
|
|
|
1271
1499
|
}
|
|
1272
1500
|
}
|
|
1273
1501
|
AttachmentPreviewListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: AttachmentPreviewListComponent, deps: [{ token: AttachmentService }], target: i0.ɵɵFactoryTarget.Component });
|
|
1274
|
-
AttachmentPreviewListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: AttachmentPreviewListComponent, selector: "stream-attachment-preview-list", ngImport: i0, template: "<div class=\"rfu-image-previewer\" *ngIf=\"(attachmentUploads$ | async)?.length\">\n <ng-container\n *ngFor=\"\n let attachmentUpload of attachmentUploads$ | async;\n trackBy: trackByFile\n \"\n >\n <div\n *ngIf=\"attachmentUpload.type === 'image'\"\n class=\"rfu-image-previewer__image\"\n [class.rfu-image-previewer__image--loaded]=\"\n attachmentUpload.state === 'success'\n \"\n data-testclass=\"attachment-image-preview\"\n >\n <div\n *ngIf=\"attachmentUpload.state === 'error'\"\n class=\"rfu-image-previewer__retry\"\n (click)=\"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: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type:
|
|
1502
|
+
AttachmentPreviewListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: AttachmentPreviewListComponent, selector: "stream-attachment-preview-list", ngImport: i0, template: "<div class=\"rfu-image-previewer\" *ngIf=\"(attachmentUploads$ | async)?.length\">\n <ng-container\n *ngFor=\"\n let attachmentUpload of attachmentUploads$ | async;\n trackBy: trackByFile\n \"\n >\n <div\n *ngIf=\"attachmentUpload.type === 'image'\"\n class=\"rfu-image-previewer__image\"\n [class.rfu-image-previewer__image--loaded]=\"\n attachmentUpload.state === 'success'\n \"\n data-testclass=\"attachment-image-preview\"\n >\n <div\n *ngIf=\"attachmentUpload.state === 'error'\"\n class=\"rfu-image-previewer__retry\"\n (click)=\"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: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }], pipes: { "async": i6.AsyncPipe } });
|
|
1275
1503
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: AttachmentPreviewListComponent, decorators: [{
|
|
1276
1504
|
type: Component,
|
|
1277
1505
|
args: [{
|
|
@@ -1291,6 +1519,7 @@ class MessageInputComponent {
|
|
|
1291
1519
|
this.componentFactoryResolver = componentFactoryResolver;
|
|
1292
1520
|
this.cdRef = cdRef;
|
|
1293
1521
|
this.chatClient = chatClient;
|
|
1522
|
+
this.mode = 'main';
|
|
1294
1523
|
this.messageUpdate = new EventEmitter();
|
|
1295
1524
|
this.textareaValue = '';
|
|
1296
1525
|
this.mentionedUsers = [];
|
|
@@ -1311,14 +1540,19 @@ class MessageInputComponent {
|
|
|
1311
1540
|
this.isFileUploadAuthorized =
|
|
1312
1541
|
capabilities.indexOf('upload-file') !== -1;
|
|
1313
1542
|
this.canSendLinks = capabilities.indexOf('send-links') !== -1;
|
|
1314
|
-
this.
|
|
1315
|
-
|
|
1316
|
-
this.cdRef.detectChanges();
|
|
1317
|
-
this.initTextarea();
|
|
1318
|
-
}
|
|
1543
|
+
this.channel = channel;
|
|
1544
|
+
this.setCanSendMessages();
|
|
1319
1545
|
}
|
|
1320
1546
|
}));
|
|
1321
1547
|
this.subscriptions.push(this.chatClient.appSettings$.subscribe((appSettings) => (this.appSettings = appSettings)));
|
|
1548
|
+
this.subscriptions.push(this.channelService.messageToQuote$.subscribe((m) => {
|
|
1549
|
+
const isThreadReply = m && m.parent_id;
|
|
1550
|
+
if ((this.mode === 'thread' && isThreadReply) ||
|
|
1551
|
+
(this.mode === 'thread' && this.quotedMessage && !m) ||
|
|
1552
|
+
(this.mode === 'main' && !isThreadReply)) {
|
|
1553
|
+
this.quotedMessage = m;
|
|
1554
|
+
}
|
|
1555
|
+
}));
|
|
1322
1556
|
this.attachmentUploads$ = this.attachmentService.attachmentUploads$;
|
|
1323
1557
|
this.isFileUploadEnabled = this.configService.isFileUploadEnabled;
|
|
1324
1558
|
this.acceptedFileTypes = this.configService.acceptedFileTypes;
|
|
@@ -1367,11 +1601,15 @@ class MessageInputComponent {
|
|
|
1367
1601
|
if (changes.mentionScope) {
|
|
1368
1602
|
this.configService.mentionScope = this.mentionScope;
|
|
1369
1603
|
}
|
|
1604
|
+
if (changes.mode) {
|
|
1605
|
+
this.setCanSendMessages();
|
|
1606
|
+
}
|
|
1370
1607
|
}
|
|
1371
1608
|
ngOnDestroy() {
|
|
1372
1609
|
this.subscriptions.forEach((s) => s.unsubscribe());
|
|
1373
1610
|
}
|
|
1374
1611
|
messageSent() {
|
|
1612
|
+
var _a;
|
|
1375
1613
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1376
1614
|
let attachmentUploadInProgressCounter;
|
|
1377
1615
|
this.attachmentService.attachmentUploadInProgressCounter$
|
|
@@ -1396,10 +1634,16 @@ class MessageInputComponent {
|
|
|
1396
1634
|
if (!this.isUpdate) {
|
|
1397
1635
|
this.textareaValue = '';
|
|
1398
1636
|
}
|
|
1637
|
+
let parentMessageId = undefined;
|
|
1638
|
+
if (this.mode === 'thread') {
|
|
1639
|
+
this.channelService.activeParentMessageId$
|
|
1640
|
+
.pipe(first())
|
|
1641
|
+
.subscribe((id) => (parentMessageId = id));
|
|
1642
|
+
}
|
|
1399
1643
|
try {
|
|
1400
1644
|
yield (this.isUpdate
|
|
1401
1645
|
? this.channelService.updateMessage(Object.assign(Object.assign({}, this.message), { text: text, attachments: attachments }))
|
|
1402
|
-
: this.channelService.sendMessage(text, attachments, this.mentionedUsers));
|
|
1646
|
+
: this.channelService.sendMessage(text, attachments, this.mentionedUsers, parentMessageId, (_a = this.quotedMessage) === null || _a === void 0 ? void 0 : _a.id));
|
|
1403
1647
|
this.messageUpdate.emit();
|
|
1404
1648
|
if (!this.isUpdate) {
|
|
1405
1649
|
this.attachmentService.resetAttachmentUploads();
|
|
@@ -1410,6 +1654,9 @@ class MessageInputComponent {
|
|
|
1410
1654
|
this.notificationService.addTemporaryNotification('streamChat.Edit message request failed');
|
|
1411
1655
|
}
|
|
1412
1656
|
}
|
|
1657
|
+
if (this.quotedMessage) {
|
|
1658
|
+
this.deselectMessageToQuote();
|
|
1659
|
+
}
|
|
1413
1660
|
});
|
|
1414
1661
|
}
|
|
1415
1662
|
get containsLinks() {
|
|
@@ -1419,6 +1666,13 @@ class MessageInputComponent {
|
|
|
1419
1666
|
var _a;
|
|
1420
1667
|
return this.acceptedFileTypes ? (_a = this.acceptedFileTypes) === null || _a === void 0 ? void 0 : _a.join(',') : '';
|
|
1421
1668
|
}
|
|
1669
|
+
get quotedMessageAttachments() {
|
|
1670
|
+
var _a;
|
|
1671
|
+
const originalAttachments = (_a = this.quotedMessage) === null || _a === void 0 ? void 0 : _a.attachments;
|
|
1672
|
+
return originalAttachments && originalAttachments.length
|
|
1673
|
+
? [originalAttachments[0]]
|
|
1674
|
+
: [];
|
|
1675
|
+
}
|
|
1422
1676
|
filesSelected(fileList) {
|
|
1423
1677
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1424
1678
|
if (!(yield this.areAttachemntsValid(fileList))) {
|
|
@@ -1428,6 +1682,9 @@ class MessageInputComponent {
|
|
|
1428
1682
|
this.clearFileInput();
|
|
1429
1683
|
});
|
|
1430
1684
|
}
|
|
1685
|
+
deselectMessageToQuote() {
|
|
1686
|
+
this.channelService.selectMessageToQuote(undefined);
|
|
1687
|
+
}
|
|
1431
1688
|
clearFileInput() {
|
|
1432
1689
|
this.fileInput.nativeElement.value = '';
|
|
1433
1690
|
}
|
|
@@ -1493,9 +1750,24 @@ class MessageInputComponent {
|
|
|
1493
1750
|
return isValid;
|
|
1494
1751
|
});
|
|
1495
1752
|
}
|
|
1753
|
+
setCanSendMessages() {
|
|
1754
|
+
var _a, _b;
|
|
1755
|
+
const capabilities = (_b = (_a = this.channel) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.own_capabilities;
|
|
1756
|
+
if (!capabilities) {
|
|
1757
|
+
this.canSendMessages = false;
|
|
1758
|
+
}
|
|
1759
|
+
else {
|
|
1760
|
+
this.canSendMessages =
|
|
1761
|
+
capabilities.indexOf(this.mode === 'main' ? 'send-message' : 'send-reply') !== -1;
|
|
1762
|
+
}
|
|
1763
|
+
if (this.isViewInited) {
|
|
1764
|
+
this.cdRef.detectChanges();
|
|
1765
|
+
this.initTextarea();
|
|
1766
|
+
}
|
|
1767
|
+
}
|
|
1496
1768
|
}
|
|
1497
1769
|
MessageInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: MessageInputComponent, deps: [{ token: ChannelService }, { token: NotificationService }, { token: AttachmentService }, { token: MessageInputConfigService }, { token: textareaInjectionToken }, { token: i0.ComponentFactoryResolver }, { token: i0.ChangeDetectorRef }, { token: ChatClientService }], target: i0.ɵɵFactoryTarget.Component });
|
|
1498
|
-
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", commandAutocompleteItemTemplate: "commandAutocompleteItemTemplate", 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 }], 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
|
|
1770
|
+
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", commandAutocompleteItemTemplate: "commandAutocompleteItemTemplate", mode: "mode", 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 }], usesOnChanges: true, ngImport: i0, template: "<div\n class=\"{{\n mode === 'main' ? 'str-chat__input-flat' : 'str-chat__small-message-input'\n }}\"\n [class.str-chat__input-flat-has-attachments]=\"\n (attachmentUploads$ | async)!.length > 0\n \"\n [class.str-chat__input-flat-quoted]=\"!!quotedMessage\"\n>\n <div\n data-testid=\"quoted-message-container\"\n class=\"quoted-message-preview\"\n *ngIf=\"quotedMessage\"\n >\n <div class=\"quoted-message-preview-header\">\n <div>{{ \"streamChat.Reply to Message\" | translate }}</div>\n <button\n class=\"str-chat__square-button\"\n data-testid=\"remove-quote\"\n (click)=\"deselectMessageToQuote()\"\n (keyup.enter)=\"deselectMessageToQuote()\"\n >\n <stream-icon\n icon=\"close-no-outline\"\n style=\"font-size: 10px; line-height: 10px\"\n ></stream-icon>\n </button>\n </div>\n <div class=\"quoted-message-preview-content\">\n <stream-avatar\n data-testid=\"qouted-message-avatar\"\n class=\"str-chat-angular__avatar-host\"\n [imageUrl]=\"quotedMessage?.user?.image\"\n [name]=\"quotedMessage?.user?.name || quotedMessage?.user?.id\"\n [size]=\"20\"\n ></stream-avatar>\n <div class=\"quoted-message-preview-content-inner\">\n <stream-attachment-list\n *ngIf=\"\n quotedMessage?.attachments && quotedMessage?.attachments?.length\n \"\n [attachments]=\"quotedMessageAttachments\"\n [messageId]=\"quotedMessage?.id\"\n ></stream-attachment-list>\n <div\n data-testid=\"quoted-message-text\"\n [innerHTML]=\"quotedMessage?.html || quotedMessage?.text\"\n ></div>\n </div>\n </div>\n </div>\n <div class=\"str-chat__input-flat-wrapper\" style=\"width: 100%\">\n <div\n class=\"{{\n mode === 'main'\n ? 'str-chat__input-flat--textarea-wrapper'\n : 'str-chat__small-message-input--textarea-wrapper'\n }}\"\n >\n <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 *ngIf=\"canSendMessages; else notAllowed\"\n streamTextarea\n [(value)]=\"textareaValue\"\n (send)=\"messageSent()\"\n [componentRef]=\"textareaRef\"\n (userMentions)=\"mentionedUsers = $event\"\n [areMentionsEnabled]=\"areMentionsEnabled\"\n [mentionAutocompleteItemTemplate]=\"mentionAutocompleteItemTemplate\"\n [commandAutocompleteItemTemplate]=\"commandAutocompleteItemTemplate\"\n [mentionScope]=\"mentionScope\"\n ></ng-template>\n <ng-template #notAllowed>\n <textarea\n disabled\n rows=\"1\"\n [value]=\"\n (mode === 'thread'\n ? 'You can\\'t send thread replies in this channel'\n : 'streamChat.You can\\'t send messages in this channel'\n ) | translate\n \"\n class=\"rta__textarea str-chat__textarea__textarea\"\n ></textarea>\n </ng-template>\n </div>\n <div\n *ngIf=\"isFileUploadEnabled && isFileUploadAuthorized && canSendMessages\"\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 *ngIf=\"canSendMessages\"\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: IconComponent, selector: "stream-icon", inputs: ["icon", "size"] }, { type: AvatarComponent, selector: "stream-avatar", inputs: ["name", "imageUrl", "size"] }, { type: AttachmentListComponent, selector: "stream-attachment-list", inputs: ["messageId", "attachments"] }, { type: AttachmentPreviewListComponent, selector: "stream-attachment-preview-list" }], directives: [{ type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: TextareaDirective, selector: "[streamTextarea]", inputs: ["componentRef", "areMentionsEnabled", "mentionAutocompleteItemTemplate", "mentionScope", "commandAutocompleteItemTemplate", "value"], outputs: ["valueChange", "send", "userMentions"] }], pipes: { "async": i6.AsyncPipe, "translate": i1.TranslatePipe } });
|
|
1499
1771
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: MessageInputComponent, decorators: [{
|
|
1500
1772
|
type: Component,
|
|
1501
1773
|
args: [{
|
|
@@ -1517,6 +1789,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
1517
1789
|
type: Input
|
|
1518
1790
|
}], commandAutocompleteItemTemplate: [{
|
|
1519
1791
|
type: Input
|
|
1792
|
+
}], mode: [{
|
|
1793
|
+
type: Input
|
|
1520
1794
|
}], acceptedFileTypes: [{
|
|
1521
1795
|
type: Input
|
|
1522
1796
|
}], isMultipleFileUploadEnabled: [{
|
|
@@ -1575,7 +1849,7 @@ class ModalComponent {
|
|
|
1575
1849
|
}
|
|
1576
1850
|
}
|
|
1577
1851
|
ModalComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1578
|
-
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:
|
|
1852
|
+
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"] }] });
|
|
1579
1853
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ModalComponent, decorators: [{
|
|
1580
1854
|
type: Component,
|
|
1581
1855
|
args: [{
|
|
@@ -1618,7 +1892,7 @@ class NotificationListComponent {
|
|
|
1618
1892
|
}
|
|
1619
1893
|
}
|
|
1620
1894
|
NotificationListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: NotificationListComponent, deps: [{ token: NotificationService }], target: i0.ɵɵFactoryTarget.Component });
|
|
1621
|
-
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\">\n {{ notification.text | translate: notification.translateParams }}\n </div></stream-notification\n >\n</div>\n", components: [{ type: NotificationComponent, selector: "stream-notification", inputs: ["type"] }], directives: [{ type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], pipes: { "async": i6.AsyncPipe, "translate":
|
|
1895
|
+
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\">\n {{ notification.text | translate: notification.translateParams }}\n </div></stream-notification\n >\n</div>\n", components: [{ type: NotificationComponent, selector: "stream-notification", inputs: ["type"] }], directives: [{ type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], pipes: { "async": i6.AsyncPipe, "translate": i1.TranslatePipe } });
|
|
1622
1896
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: NotificationListComponent, decorators: [{
|
|
1623
1897
|
type: Component,
|
|
1624
1898
|
args: [{
|
|
@@ -1669,21 +1943,32 @@ class MessageActionsBoxComponent {
|
|
|
1669
1943
|
}
|
|
1670
1944
|
}
|
|
1671
1945
|
get isQuoteVisible() {
|
|
1672
|
-
|
|
1946
|
+
var _a;
|
|
1947
|
+
return ((this.enabledActions.indexOf('quote') !== -1 ||
|
|
1948
|
+
this.enabledActions.indexOf('quote-message') !== -1) &&
|
|
1949
|
+
!((_a = this.message) === null || _a === void 0 ? void 0 : _a.quoted_message));
|
|
1673
1950
|
}
|
|
1674
1951
|
get isEditVisible() {
|
|
1675
|
-
return ((this.enabledActions.indexOf('edit') !== -1
|
|
1676
|
-
this.enabledActions.indexOf('
|
|
1952
|
+
return (((this.enabledActions.indexOf('edit') !== -1 ||
|
|
1953
|
+
this.enabledActions.indexOf('update-own-message') !== -1) &&
|
|
1954
|
+
this.isMine) ||
|
|
1955
|
+
this.enabledActions.indexOf('edit-any') !== -1 ||
|
|
1956
|
+
this.enabledActions.indexOf('update-any-message') !== -1);
|
|
1677
1957
|
}
|
|
1678
1958
|
get isDeleteVisible() {
|
|
1679
|
-
return ((this.enabledActions.indexOf('delete') !== -1
|
|
1680
|
-
this.enabledActions.indexOf('delete-
|
|
1959
|
+
return (((this.enabledActions.indexOf('delete') !== -1 ||
|
|
1960
|
+
this.enabledActions.indexOf('delete-own-message') !== -1) &&
|
|
1961
|
+
this.isMine) ||
|
|
1962
|
+
this.enabledActions.indexOf('delete-any') !== -1 ||
|
|
1963
|
+
this.enabledActions.indexOf('delete-any-message') !== -1);
|
|
1681
1964
|
}
|
|
1682
1965
|
get isMuteVisible() {
|
|
1683
1966
|
return this.enabledActions.indexOf('mute') !== -1;
|
|
1684
1967
|
}
|
|
1685
1968
|
get isFlagVisible() {
|
|
1686
|
-
return this.enabledActions.indexOf('flag') !== -1
|
|
1969
|
+
return ((this.enabledActions.indexOf('flag') !== -1 ||
|
|
1970
|
+
this.enabledActions.indexOf('flag-message') !== -1) &&
|
|
1971
|
+
!this.isMine);
|
|
1687
1972
|
}
|
|
1688
1973
|
get isPinVisible() {
|
|
1689
1974
|
return this.enabledActions.indexOf('pin') !== -1;
|
|
@@ -1706,7 +1991,7 @@ class MessageActionsBoxComponent {
|
|
|
1706
1991
|
alert('Feature not yet implemented');
|
|
1707
1992
|
}
|
|
1708
1993
|
quoteClicked() {
|
|
1709
|
-
|
|
1994
|
+
this.channelService.selectMessageToQuote(this.message);
|
|
1710
1995
|
}
|
|
1711
1996
|
editClicked() {
|
|
1712
1997
|
this.isEditing.emit(true);
|
|
@@ -1728,7 +2013,7 @@ class MessageActionsBoxComponent {
|
|
|
1728
2013
|
}
|
|
1729
2014
|
}
|
|
1730
2015
|
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 });
|
|
1731
|
-
MessageActionsBoxComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: MessageActionsBoxComponent, selector: "stream-message-actions-box", inputs: { messageInputTemplate: "messageInputTemplate", 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 <ng-container *ngIf=\"messageInputTemplate; else defaultInput\">\n <ng-container\n *ngTemplateOutlet=\"\n messageInputTemplate;\n context: {\n message: message,\n messageUpdateHandler: modalClosed\n }\n \"\n ></ng-container>\n </ng-container>\n <ng-template #defaultInput>\n <stream-message-input\n [message]=\"message\"\n (messageUpdate)=\"modalClosed()\"\n ></stream-message-input>\n </ng-template>\n <stream-notification-list></stream-notification-list>\n <div\n class=\"\n str-chat__message-team-form-footer\n str-chat__message-team-form-footer-angular\n \"\n >\n <div class=\"str-chat__edit-message-form-options\">\n <button translate data-testid=\"cancel-button\" (click)=\"modalClosed()\">\n streamChat.Cancel\n </button>\n <button\n type=\"submit\"\n translate\n data-testid=\"send-button\"\n (click)=\"sendClicked()\"\n (keyup.enter)=\"sendClicked()\"\n >\n streamChat.Send\n </button>\n </div>\n </div>\n </div>\n</stream-modal>\n", components: [{ type: ModalComponent, selector: "stream-modal", inputs: ["isOpen"], outputs: ["isOpenChange"] }, { type: MessageInputComponent, selector: "stream-message-input", inputs: ["isFileUploadEnabled", "areMentionsEnabled", "mentionScope", "mentionAutocompleteItemTemplate", "commandAutocompleteItemTemplate", "acceptedFileTypes", "isMultipleFileUploadEnabled", "message"], outputs: ["messageUpdate"] }, { type: NotificationListComponent, selector: "stream-notification-list" }], directives: [{ type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i6.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type:
|
|
2016
|
+
MessageActionsBoxComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: MessageActionsBoxComponent, selector: "stream-message-actions-box", inputs: { messageInputTemplate: "messageInputTemplate", 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 <ng-container *ngIf=\"messageInputTemplate; else defaultInput\">\n <ng-container\n *ngTemplateOutlet=\"\n messageInputTemplate;\n context: {\n message: message,\n messageUpdateHandler: modalClosed\n }\n \"\n ></ng-container>\n </ng-container>\n <ng-template #defaultInput>\n <stream-message-input\n [message]=\"message\"\n (messageUpdate)=\"modalClosed()\"\n ></stream-message-input>\n </ng-template>\n <stream-notification-list></stream-notification-list>\n <div\n class=\"\n str-chat__message-team-form-footer\n str-chat__message-team-form-footer-angular\n \"\n >\n <div class=\"str-chat__edit-message-form-options\">\n <button translate data-testid=\"cancel-button\" (click)=\"modalClosed()\">\n streamChat.Cancel\n </button>\n <button\n type=\"submit\"\n translate\n data-testid=\"send-button\"\n (click)=\"sendClicked()\"\n (keyup.enter)=\"sendClicked()\"\n >\n streamChat.Send\n </button>\n </div>\n </div>\n </div>\n</stream-modal>\n", components: [{ type: ModalComponent, selector: "stream-modal", inputs: ["isOpen"], outputs: ["isOpenChange"] }, { type: MessageInputComponent, selector: "stream-message-input", inputs: ["isFileUploadEnabled", "areMentionsEnabled", "mentionScope", "mentionAutocompleteItemTemplate", "commandAutocompleteItemTemplate", "mode", "acceptedFileTypes", "isMultipleFileUploadEnabled", "message"], outputs: ["messageUpdate"] }, { type: NotificationListComponent, selector: "stream-notification-list" }], directives: [{ type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i6.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }], pipes: { "translate": i1.TranslatePipe } });
|
|
1732
2017
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: MessageActionsBoxComponent, decorators: [{
|
|
1733
2018
|
type: Component,
|
|
1734
2019
|
args: [{
|
|
@@ -1761,10 +2046,11 @@ class ChannelComponent {
|
|
|
1761
2046
|
this.subscriptions = [];
|
|
1762
2047
|
this.isError$ = this.channelService.channels$.pipe(map(() => false), catchError(() => of(true)), startWith(false));
|
|
1763
2048
|
this.isInitializing$ = this.channelService.channels$.pipe(map((channels) => !channels), catchError(() => of(false)));
|
|
2049
|
+
this.isActiveThread$ = this.channelService.activeParentMessageId$.pipe(map((id) => !!id));
|
|
1764
2050
|
}
|
|
1765
2051
|
}
|
|
1766
2052
|
ChannelComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ChannelComponent, deps: [{ token: ChannelService }], target: i0.ɵɵFactoryTarget.Component });
|
|
1767
|
-
ChannelComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: ChannelComponent, selector: "stream-channel", ngImport: i0, template: "<div\n *ngIf=\"(isError$ | async) === false && (isInitializing$ | async) === false\"\n class=\"str-chat str-chat-channel messaging\"\n>\n <div class=\"str-chat__container\">\n <div class=\"str-chat__main-panel\">\n <ng-content></ng-content>\n </div>\n </div>\n</div>\n", directives: [{ type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], pipes: { "async": i6.AsyncPipe } });
|
|
2053
|
+
ChannelComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: ChannelComponent, selector: "stream-channel", ngImport: i0, template: "<div\n *ngIf=\"(isError$ | async) === false && (isInitializing$ | async) === false\"\n class=\"str-chat str-chat-channel messaging\"\n>\n <div class=\"str-chat__container\">\n <div class=\"str-chat__main-panel\">\n <ng-content></ng-content>\n </div>\n <ng-content\n *ngIf=\"isActiveThread$ | async\"\n select='[name=\"thread\"]'\n ></ng-content>\n </div>\n</div>\n", directives: [{ type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], pipes: { "async": i6.AsyncPipe } });
|
|
1768
2054
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ChannelComponent, decorators: [{
|
|
1769
2055
|
type: Component,
|
|
1770
2056
|
args: [{
|
|
@@ -1864,7 +2150,7 @@ class ChannelHeaderComponent {
|
|
|
1864
2150
|
}
|
|
1865
2151
|
}
|
|
1866
2152
|
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 });
|
|
1867
|
-
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 data-testid=\"name\" class=\"str-chat__header-livestream-left--title\">\n {{ activeChannel?.data?.name }}\n </p>\n <p data-testid=\"info\" class=\"str-chat__header-livestream-left--members\">\n {{'streamChat.{{ memberCount }} members' | translate:memberCountParam}}\n {{canReceiveConnectEvents ? ('streamChat.{{ watcherCount }} online' |\n translate:watcherCountParam) : ''}}\n </p>\n </div>\n</div>\n", components: [{ type: AvatarComponent, selector: "stream-avatar", inputs: ["name", "imageUrl", "size"] }], pipes: { "translate":
|
|
2153
|
+
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 data-testid=\"name\" class=\"str-chat__header-livestream-left--title\">\n {{ activeChannel?.data?.name }}\n </p>\n <p data-testid=\"info\" class=\"str-chat__header-livestream-left--members\">\n {{'streamChat.{{ memberCount }} members' | translate:memberCountParam}}\n {{canReceiveConnectEvents ? ('streamChat.{{ watcherCount }} online' |\n translate:watcherCountParam) : ''}}\n </p>\n </div>\n</div>\n", components: [{ type: AvatarComponent, selector: "stream-avatar", inputs: ["name", "imageUrl", "size"] }], pipes: { "translate": i1.TranslatePipe } });
|
|
1868
2154
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ChannelHeaderComponent, decorators: [{
|
|
1869
2155
|
type: Component,
|
|
1870
2156
|
args: [{
|
|
@@ -1949,7 +2235,7 @@ class ChannelPreviewComponent {
|
|
|
1949
2235
|
}
|
|
1950
2236
|
}
|
|
1951
2237
|
ChannelPreviewComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ChannelPreviewComponent, deps: [{ token: ChannelService }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
|
|
1952
|
-
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":
|
|
2238
|
+
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 } });
|
|
1953
2239
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ChannelPreviewComponent, decorators: [{
|
|
1954
2240
|
type: Component,
|
|
1955
2241
|
args: [{
|
|
@@ -1990,7 +2276,7 @@ class ChannelListComponent {
|
|
|
1990
2276
|
}
|
|
1991
2277
|
}
|
|
1992
2278
|
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 });
|
|
1993
|
-
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: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i6.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], pipes: { "async": i6.AsyncPipe, "translate":
|
|
2279
|
+
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: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i6.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], pipes: { "async": i6.AsyncPipe, "translate": i1.TranslatePipe } });
|
|
1994
2280
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ChannelListComponent, decorators: [{
|
|
1995
2281
|
type: Component,
|
|
1996
2282
|
args: [{
|
|
@@ -2169,95 +2455,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
2169
2455
|
args: ['selectorTooltip']
|
|
2170
2456
|
}] } });
|
|
2171
2457
|
|
|
2172
|
-
class ImageLoadService {
|
|
2173
|
-
constructor() {
|
|
2174
|
-
this.imageLoad$ = new Subject();
|
|
2175
|
-
}
|
|
2176
|
-
}
|
|
2177
|
-
ImageLoadService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ImageLoadService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2178
|
-
ImageLoadService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ImageLoadService, providedIn: 'root' });
|
|
2179
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ImageLoadService, decorators: [{
|
|
2180
|
-
type: Injectable,
|
|
2181
|
-
args: [{
|
|
2182
|
-
providedIn: 'root',
|
|
2183
|
-
}]
|
|
2184
|
-
}], ctorParameters: function () { return []; } });
|
|
2185
|
-
|
|
2186
|
-
class AttachmentListComponent {
|
|
2187
|
-
constructor(imageLoadService, channelService) {
|
|
2188
|
-
this.imageLoadService = imageLoadService;
|
|
2189
|
-
this.channelService = channelService;
|
|
2190
|
-
this.attachments = [];
|
|
2191
|
-
this.orderedAttachments = [];
|
|
2192
|
-
}
|
|
2193
|
-
ngOnChanges() {
|
|
2194
|
-
this.orderedAttachments = [
|
|
2195
|
-
...this.attachments.filter((a) => this.isImage(a)),
|
|
2196
|
-
...this.attachments.filter((a) => this.isFile(a)),
|
|
2197
|
-
...this.attachments.filter((a) => this.isCard(a)),
|
|
2198
|
-
];
|
|
2199
|
-
}
|
|
2200
|
-
trackById(index) {
|
|
2201
|
-
return index;
|
|
2202
|
-
}
|
|
2203
|
-
isImage(attachment) {
|
|
2204
|
-
return isImageAttachment(attachment);
|
|
2205
|
-
}
|
|
2206
|
-
isFile(attachment) {
|
|
2207
|
-
return attachment.type === 'file';
|
|
2208
|
-
}
|
|
2209
|
-
isCard(attachment) {
|
|
2210
|
-
return (!attachment.type ||
|
|
2211
|
-
(attachment.type === 'image' && !this.isImage(attachment)) ||
|
|
2212
|
-
attachment.type === 'giphy');
|
|
2213
|
-
}
|
|
2214
|
-
imageLoaded() {
|
|
2215
|
-
this.imageLoadService.imageLoad$.next();
|
|
2216
|
-
}
|
|
2217
|
-
hasFileSize(attachment) {
|
|
2218
|
-
return (attachment.file_size && Number.isFinite(Number(attachment.file_size)));
|
|
2219
|
-
}
|
|
2220
|
-
getFileSize(attachment) {
|
|
2221
|
-
return prettybytes(attachment.file_size);
|
|
2222
|
-
}
|
|
2223
|
-
trimUrl(url) {
|
|
2224
|
-
if (url !== undefined && url !== null) {
|
|
2225
|
-
const [trimmedUrl] = url
|
|
2226
|
-
.replace(/^(?:https?:\/\/)?(?:www\.)?/i, '')
|
|
2227
|
-
.split('/');
|
|
2228
|
-
return trimmedUrl;
|
|
2229
|
-
}
|
|
2230
|
-
return null;
|
|
2231
|
-
}
|
|
2232
|
-
sendAction(action) {
|
|
2233
|
-
void this.channelService.sendAction(this.messageId, {
|
|
2234
|
-
[action.name]: action.value,
|
|
2235
|
-
});
|
|
2236
|
-
}
|
|
2237
|
-
trackByActionValue(_, item) {
|
|
2238
|
-
return item.value;
|
|
2239
|
-
}
|
|
2240
|
-
}
|
|
2241
|
-
AttachmentListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: AttachmentListComponent, deps: [{ token: ImageLoadService }, { token: ChannelService }], target: i0.ɵɵFactoryTarget.Component });
|
|
2242
|
-
AttachmentListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: AttachmentListComponent, selector: "stream-attachment-list", inputs: { messageId: "messageId", attachments: "attachments" }, usesOnChanges: true, ngImport: i0, template: "<ng-container *ngFor=\"let attachment of orderedAttachments; trackBy: trackById\">\n <div\n data-testclass=\"attachment-container\"\n class=\"str-chat__message-attachment str-chat__message-attachment--{{\n attachment.type\n }}\"\n [class.str-chat__message-attachment--card]=\"isCard(attachment)\"\n [class.str-chat-angular__message-attachment-file-single]=\"\n isFile(attachment)\n \"\n >\n <img\n *ngIf=\"isImage(attachment)\"\n class=\"str-chat__message-attachment--img\"\n data-testclass=\"image\"\n [src]=\"attachment.img_url || attachment.thumb_url || attachment.image_url\"\n [alt]=\"attachment?.fallback\"\n (load)=\"imageLoaded()\"\n />\n <div\n *ngIf=\"isFile(attachment)\"\n class=\"\n str-chat__message-attachment-file--item\n str-chat-angular__message-attachment-file-single\n \"\n >\n <stream-icon icon=\"file\" [size]=\"30\"></stream-icon>\n <div class=\"str-chat__message-attachment-file--item-text\">\n <a\n data-testclass=\"file-link\"\n download\n href=\"{{ attachment.asset_url }}\"\n target=\"_blank\"\n >\n {{ attachment.title }}\n </a>\n <span data-testclass=\"size\" *ngIf=\"hasFileSize(attachment)\">{{\n getFileSize(attachment)\n }}</span>\n </div>\n </div>\n <div\n *ngIf=\"isCard(attachment)\"\n class=\"str-chat__message-attachment-card str-chat__message-attachment-card--{{\n attachment.type\n }}\"\n >\n <div\n *ngIf=\"attachment.image_url || attachment.thumb_url\"\n class=\"str-chat__message-attachment-card--header\"\n >\n <img\n data-testclass=\"card-img\"\n alt=\"{{ attachment.image_url || attachment.thumb_url }}\"\n src=\"{{ attachment.image_url || attachment.thumb_url }}\"\n />\n </div>\n <div class=\"str-chat__message-attachment-card--content\">\n <div class=\"str-chat__message-attachment-card--flex\">\n <div\n *ngIf=\"attachment.title\"\n data-testclass=\"card-title\"\n class=\"str-chat__message-attachment-card--title\"\n >\n {{ attachment.title }}\n </div>\n <div\n *ngIf=\"attachment.text\"\n class=\"str-chat__message-attachment-card--text\"\n data-testclass=\"card-text\"\n >\n {{ attachment.text }}\n </div>\n <a\n class=\"str-chat__message-attachment-card--url\"\n *ngIf=\"attachment.title_link || attachment.og_scrape_url\"\n data-testclass=\"url-link\"\n noopener\n noreferrer\n href=\"{{ attachment.title_link || attachment.og_scrape_url }}\"\n target=\"_blank\"\n >\n {{ trimUrl(attachment.title_link || attachment.og_scrape_url) }}\n </a>\n </div>\n </div>\n </div>\n <div\n class=\"str-chat__message-attachment-actions\"\n *ngIf=\"attachment.actions && attachment.actions.length > 0\"\n >\n <div class=\"str-chat__message-attachment-actions-form\">\n <button\n *ngFor=\"let action of attachment.actions; trackBy: trackByActionValue\"\n class=\"str-chat__message-attachment-actions-button str-chat__message-attachment-actions-button--{{\n action.style\n }}\"\n data-testclass=\"attachment-action\"\n (click)=\"sendAction(action)\"\n (keyup.enter)=\"sendAction(action)\"\n >\n {{ action.text }}\n </button>\n </div>\n </div>\n </div>\n</ng-container>\n", components: [{ type: IconComponent, selector: "stream-icon", inputs: ["icon", "size"] }], directives: [{ type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
|
|
2243
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: AttachmentListComponent, decorators: [{
|
|
2244
|
-
type: Component,
|
|
2245
|
-
args: [{
|
|
2246
|
-
selector: 'stream-attachment-list',
|
|
2247
|
-
templateUrl: './attachment-list.component.html',
|
|
2248
|
-
styles: [],
|
|
2249
|
-
}]
|
|
2250
|
-
}], ctorParameters: function () { return [{ type: ImageLoadService }, { type: ChannelService }]; }, propDecorators: { messageId: [{
|
|
2251
|
-
type: Input
|
|
2252
|
-
}], attachments: [{
|
|
2253
|
-
type: Input
|
|
2254
|
-
}] } });
|
|
2255
|
-
|
|
2256
2458
|
class MessageComponent {
|
|
2257
2459
|
constructor(chatClientService, channelService) {
|
|
2258
2460
|
this.chatClientService = chatClientService;
|
|
2259
2461
|
this.channelService = channelService;
|
|
2260
2462
|
this.enabledMessageActions = [];
|
|
2463
|
+
this.mode = 'main';
|
|
2261
2464
|
this.isActionBoxOpen = false;
|
|
2262
2465
|
this.isReactionSelectorOpen = false;
|
|
2263
2466
|
this.isPressedOnMobile = false;
|
|
@@ -2266,46 +2469,8 @@ class MessageComponent {
|
|
|
2266
2469
|
this.user = this.chatClientService.chatClient.user;
|
|
2267
2470
|
}
|
|
2268
2471
|
ngOnChanges(changes) {
|
|
2269
|
-
var _a, _b;
|
|
2270
2472
|
if (changes.message) {
|
|
2271
|
-
|
|
2272
|
-
if (!content) {
|
|
2273
|
-
this.messageTextParts = [];
|
|
2274
|
-
}
|
|
2275
|
-
else {
|
|
2276
|
-
// Backend will wrap HTML content with <p></p>\n
|
|
2277
|
-
if (content.startsWith('<p>')) {
|
|
2278
|
-
content = content.replace('<p>', '');
|
|
2279
|
-
}
|
|
2280
|
-
if (content.endsWith('</p>\n')) {
|
|
2281
|
-
content = content.replace('</p>\n', '');
|
|
2282
|
-
}
|
|
2283
|
-
if (!this.message.mentioned_users ||
|
|
2284
|
-
this.message.mentioned_users.length === 0) {
|
|
2285
|
-
this.messageTextParts = [{ content, type: 'text' }];
|
|
2286
|
-
}
|
|
2287
|
-
else {
|
|
2288
|
-
this.messageTextParts = [];
|
|
2289
|
-
let text = content;
|
|
2290
|
-
this.message.mentioned_users.forEach((user) => {
|
|
2291
|
-
const mention = `@${user.name || user.id}`;
|
|
2292
|
-
const precedingText = text.substring(0, text.indexOf(mention));
|
|
2293
|
-
this.messageTextParts.push({
|
|
2294
|
-
content: precedingText,
|
|
2295
|
-
type: 'text',
|
|
2296
|
-
});
|
|
2297
|
-
this.messageTextParts.push({
|
|
2298
|
-
content: mention,
|
|
2299
|
-
type: 'mention',
|
|
2300
|
-
user,
|
|
2301
|
-
});
|
|
2302
|
-
text = text.replace(precedingText + mention, '');
|
|
2303
|
-
});
|
|
2304
|
-
if (text) {
|
|
2305
|
-
this.messageTextParts.push({ content: text, type: 'text' });
|
|
2306
|
-
}
|
|
2307
|
-
}
|
|
2308
|
-
}
|
|
2473
|
+
this.createMessageParts();
|
|
2309
2474
|
}
|
|
2310
2475
|
}
|
|
2311
2476
|
get isSentByCurrentUser() {
|
|
@@ -2347,7 +2512,8 @@ class MessageComponent {
|
|
|
2347
2512
|
this.message.type === 'system' ||
|
|
2348
2513
|
this.message.type === 'ephemeral' ||
|
|
2349
2514
|
this.message.status === 'failed' ||
|
|
2350
|
-
this.message.status === 'sending'
|
|
2515
|
+
this.message.status === 'sending' ||
|
|
2516
|
+
(this.mode === 'thread' && !this.message.parent_id));
|
|
2351
2517
|
}
|
|
2352
2518
|
get hasAttachment() {
|
|
2353
2519
|
var _a;
|
|
@@ -2358,6 +2524,21 @@ class MessageComponent {
|
|
|
2358
2524
|
return (!!((_a = this.message) === null || _a === void 0 ? void 0 : _a.reaction_counts) &&
|
|
2359
2525
|
Object.keys(this.message.reaction_counts).length > 0);
|
|
2360
2526
|
}
|
|
2527
|
+
get replyCountParam() {
|
|
2528
|
+
var _a;
|
|
2529
|
+
return { replyCount: (_a = this.message) === null || _a === void 0 ? void 0 : _a.reply_count };
|
|
2530
|
+
}
|
|
2531
|
+
get canDisplayReadStatus() {
|
|
2532
|
+
return (this.canReceiveReadEvents !== false &&
|
|
2533
|
+
this.enabledMessageActions.indexOf('read-events') !== -1);
|
|
2534
|
+
}
|
|
2535
|
+
get quotedMessageAttachments() {
|
|
2536
|
+
var _a, _b;
|
|
2537
|
+
const originalAttachments = (_b = (_a = this.message) === null || _a === void 0 ? void 0 : _a.quoted_message) === null || _b === void 0 ? void 0 : _b.attachments;
|
|
2538
|
+
return originalAttachments && originalAttachments.length
|
|
2539
|
+
? [originalAttachments[0]]
|
|
2540
|
+
: [];
|
|
2541
|
+
}
|
|
2361
2542
|
resendMessage() {
|
|
2362
2543
|
void this.channelService.resendMessage(this.message);
|
|
2363
2544
|
}
|
|
@@ -2379,9 +2560,53 @@ class MessageComponent {
|
|
|
2379
2560
|
};
|
|
2380
2561
|
window.addEventListener('click', eventHandler);
|
|
2381
2562
|
}
|
|
2563
|
+
setAsActiveParentMessage() {
|
|
2564
|
+
void this.channelService.setAsActiveParentMessage(this.message);
|
|
2565
|
+
}
|
|
2566
|
+
createMessageParts() {
|
|
2567
|
+
var _a, _b;
|
|
2568
|
+
let content = ((_a = this.message) === null || _a === void 0 ? void 0 : _a.html) || ((_b = this.message) === null || _b === void 0 ? void 0 : _b.text);
|
|
2569
|
+
if (!content) {
|
|
2570
|
+
this.messageTextParts = [];
|
|
2571
|
+
}
|
|
2572
|
+
else {
|
|
2573
|
+
// Backend will wrap HTML content with <p></p>\n
|
|
2574
|
+
if (content.startsWith('<p>')) {
|
|
2575
|
+
content = content.replace('<p>', '');
|
|
2576
|
+
}
|
|
2577
|
+
if (content.endsWith('</p>\n')) {
|
|
2578
|
+
content = content.replace('</p>\n', '');
|
|
2579
|
+
}
|
|
2580
|
+
if (!this.message.mentioned_users ||
|
|
2581
|
+
this.message.mentioned_users.length === 0) {
|
|
2582
|
+
this.messageTextParts = [{ content, type: 'text' }];
|
|
2583
|
+
}
|
|
2584
|
+
else {
|
|
2585
|
+
this.messageTextParts = [];
|
|
2586
|
+
let text = content;
|
|
2587
|
+
this.message.mentioned_users.forEach((user) => {
|
|
2588
|
+
const mention = `@${user.name || user.id}`;
|
|
2589
|
+
const precedingText = text.substring(0, text.indexOf(mention));
|
|
2590
|
+
this.messageTextParts.push({
|
|
2591
|
+
content: precedingText,
|
|
2592
|
+
type: 'text',
|
|
2593
|
+
});
|
|
2594
|
+
this.messageTextParts.push({
|
|
2595
|
+
content: mention,
|
|
2596
|
+
type: 'mention',
|
|
2597
|
+
user,
|
|
2598
|
+
});
|
|
2599
|
+
text = text.replace(precedingText + mention, '');
|
|
2600
|
+
});
|
|
2601
|
+
if (text) {
|
|
2602
|
+
this.messageTextParts.push({ content: text, type: 'text' });
|
|
2603
|
+
}
|
|
2604
|
+
}
|
|
2605
|
+
}
|
|
2606
|
+
}
|
|
2382
2607
|
}
|
|
2383
2608
|
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 });
|
|
2384
|
-
MessageComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: MessageComponent, selector: "stream-message", inputs: { messageInputTemplate: "messageInputTemplate", mentionTemplate: "mentionTemplate", message: "message", enabledMessageActions: "enabledMessageActions", areReactionsEnabled: "areReactionsEnabled", canReactToMessage: "canReactToMessage", isLastSentMessage: "isLastSentMessage", canReceiveReadEvents: "canReceiveReadEvents" }, viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div\n #container\n class=\"str-chat__message-simple str-chat__message str-chat__message--{{\n message?.type\n }} str-chat__message--{{ message?.status }} {{\n message?.text ? 'str-chat__message--has-text' : 'has-no-text'\n }}\"\n [class.str-chat__message--me]=\"isSentByCurrentUser\"\n [class.str-chat__message-simple--me]=\"isSentByCurrentUser\"\n [class.mobile-press]=\"isPressedOnMobile\"\n [class.str-chat__message--has-attachment]=\"hasAttachment\"\n [class.str-chat__message--with-reactions]=\"\n areReactionsEnabled && 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\n *ngIf=\"\n isMessageDeliveredAndRead && canReceiveReadEvents;\n else deliveredStatus\n \"\n >\n <ng-container *ngTemplateOutlet=\"readStatus\"></ng-container>\n </ng-container>\n </ng-template>\n </ng-container>\n <stream-avatar\n data-testid=\"avatar\"\n class=\"str-chat-angular__avatar-host\"\n [imageUrl]=\"message?.user?.image\"\n [name]=\"message?.user?.name || message?.user?.id\"\n ></stream-avatar>\n <div class=\"str-chat__message-inner\">\n <div\n class=\"str-chat__message-simple__actions\"\n data-testid=\"message-options\"\n *ngIf=\"areOptionsVisible\"\n >\n <div\n data-testid=\"message-actions-container\"\n class=\"\n str-chat__message-simple__actions__action\n str-chat__message-simple__actions__action--options\n \"\n [class.str-chat-angular__message-simple__actions__action--options--editing]=\"\n isEditing\n \"\n >\n <stream-message-actions-box\n [isOpen]=\"isActionBoxOpen\"\n [isMine]=\"isSentByCurrentUser\"\n [enabledActions]=\"enabledMessageActions\"\n [message]=\"message\"\n (displayedActionsCount)=\"visibleMessageActionsCount = $event\"\n (isEditing)=\"isEditing = $event; isActionBoxOpen = !isEditing\"\n [messageInputTemplate]=\"messageInputTemplate\"\n ></stream-message-actions-box>\n <stream-icon\n *ngIf=\"visibleMessageActionsCount > 0\"\n data-testid=\"action-icon\"\n icon=\"action-icon\"\n (keyup.enter)=\"isActionBoxOpen = !isActionBoxOpen\"\n (click)=\"isActionBoxOpen = !isActionBoxOpen\"\n ></stream-icon>\n </div>\n <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 [messageId]=\"message!.id\"\n ></stream-attachment-list>\n <div class=\"str-chat__message-text\" *ngIf=\"message?.text\">\n <div\n data-testid=\"inner-message\"\n class=\"\n str-chat__message-text-inner str-chat__message-simple-text-inner\n \"\n [class.str-chat__message-light-text-inner--has-attachment]=\"\n hasAttachment\n \"\n (click)=\"\n message?.status === 'failed' && message?.errorStatusCode !== 403\n ? resendMessage()\n : undefined\n \"\n (keyup.enter)=\"\n message?.status === 'failed' && message?.errorStatusCode !== 403\n ? resendMessage()\n : undefined\n \"\n >\n <div\n data-testid=\"client-error-message\"\n *ngIf=\"message?.type === 'error'\"\n class=\"str-chat__simple-message--error-message\"\n >\n {{ \"streamChat.Error \u00B7 Unsent\" | translate }}\n </div>\n <div\n data-testid=\"error-message\"\n *ngIf=\"message?.status === 'failed'\"\n class=\"str-chat__simple-message--error-message\"\n >\n {{\n (message?.errorStatusCode === 403\n ? \"streamChat.Message Failed \u00B7 Unauthorized\"\n : \"streamChat.Message Failed \u00B7 Click to try again\"\n ) | translate\n }}\n </div>\n <div\n (click)=\"textClicked()\"\n (keyup.enter)=\"textClicked()\"\n data-testid=\"text\"\n >\n <p>\n <!-- eslint-disable-next-line @angular-eslint/template/use-track-by-function -->\n <ng-container *ngFor=\"let part of messageTextParts\">\n <span\n *ngIf=\"part.type === 'text'; else mention\"\n [innerHTML]=\"part.content\"\n ></span>\n <ng-template #mention>\n <ng-container *ngIf=\"mentionTemplate; else defaultMention\">\n <ng-container\n *ngTemplateOutlet=\"\n mentionTemplate;\n context: { user: part.user! }\n \"\n ></ng-container>\n </ng-container>\n <ng-template #defaultMention>\n <b>{{ part.content }}</b>\n </ng-template>\n </ng-template>\n </ng-container>\n </p>\n </div>\n </div>\n </div>\n <div class=\"str-chat__message-data str-chat__message-simple-data\">\n <span\n data-testid=\"sender\"\n *ngIf=\"!isSentByCurrentUser\"\n class=\"str-chat__message-simple-name\"\n >\n {{ message?.user?.name ? message?.user?.name : message?.user?.id }}\n </span>\n <span data-testid=\"date\" class=\"str-chat__message-simple-timestamp\">\n {{ parsedDate }}\n </span>\n </div>\n </div>\n </ng-container>\n </ng-container>\n</div>\n\n<ng-template #sendingStatus>\n <span\n class=\"\n str-chat__message-simple-status str-chat__message-simple-status-angular\n \"\n data-testid=\"sending-indicator\"\n >\n <div class=\"str-chat__tooltip\">\n {{ \"streamChat.Sending...\" | translate }}\n </div>\n <stream-loading-indicator\n data-testid=\"loading-indicator\"\n ></stream-loading-indicator>\n </span>\n</ng-template>\n<ng-template #readStatus>\n <span\n class=\"\n str-chat__message-simple-status str-chat__message-simple-status-angular\n \"\n data-testid=\"read-indicator\"\n >\n <div class=\"str-chat__tooltip\" data-testid=\"read-by-tooltip\">\n {{ readByText }}\n </div>\n <stream-avatar\n class=\"str-chat-angular__avatar-host\"\n data-test-id=\"last-read-user-avatar\"\n [size]=\"15\"\n [imageUrl]=\"lastReadUser?.image\"\n [name]=\"lastReadUser?.name || lastReadUser?.id\"\n ></stream-avatar>\n <span\n data-test-id=\"read-by-length\"\n *ngIf=\"isReadByMultipleUsers\"\n class=\"str-chat__message-simple-status-number\"\n >\n {{ (message?.readBy)!.length }}\n </span>\n </span>\n</ng-template>\n<ng-template #deliveredStatus>\n <span\n class=\"\n str-chat__message-simple-status str-chat__message-simple-status-angular\n \"\n data-testid=\"delivered-indicator\"\n >\n <div class=\"str-chat__tooltip\">\n {{ \"streamChat.Delivered\" | translate }}\n </div>\n <stream-icon\n data-testid=\"delivered-icon\"\n icon=\"delivered-icon\"\n ></stream-icon>\n </span>\n</ng-template>\n\n<ng-template #deletedMessage>\n <div data-testid=\"message-deleted-component\">\n <div class=\"str-chat__message--deleted-inner\" translate>\n streamChat.This message was deleted...\n </div>\n </div>\n</ng-template>\n\n<ng-template #systemMessage>\n <div data-testid=\"system-message\" class=\"str-chat__message--system\">\n <div class=\"str-chat__message--system__text\">\n <div class=\"str-chat__message--system__line\"></div>\n <p>{{ message?.text }}</p>\n <div class=\"str-chat__message--system__line\"></div>\n </div>\n <div class=\"str-chat__message--system__date\">\n {{ parsedDate }}\n </div>\n </div>\n</ng-template>\n", components: [{ type: AvatarComponent, selector: "stream-avatar", inputs: ["name", "imageUrl", "size"] }, { type: MessageActionsBoxComponent, selector: "stream-message-actions-box", inputs: ["messageInputTemplate", "isOpen", "isMine", "message", "enabledActions"], outputs: ["displayedActionsCount", "isEditing"] }, { type: IconComponent, selector: "stream-icon", inputs: ["icon", "size"] }, { type: MessageReactionsComponent, selector: "stream-message-reactions", inputs: ["messageId", "messageReactionCounts", "isSelectorOpen", "latestReactions", "ownReactions"], outputs: ["isSelectorOpenChange"] }, { type: AttachmentListComponent, selector: "stream-attachment-list", inputs: ["messageId", "attachments"] }, { type: LoadingIndicatorComponent, selector: "stream-loading-indicator", inputs: ["size", "color"] }], directives: [{ type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i6.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i10.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }], pipes: { "translate": i10.TranslatePipe } });
|
|
2609
|
+
MessageComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: MessageComponent, selector: "stream-message", inputs: { messageInputTemplate: "messageInputTemplate", mentionTemplate: "mentionTemplate", message: "message", enabledMessageActions: "enabledMessageActions", areReactionsEnabled: "areReactionsEnabled", canReactToMessage: "canReactToMessage", isLastSentMessage: "isLastSentMessage", canReceiveReadEvents: "canReceiveReadEvents", mode: "mode" }, viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div\n #container\n class=\"str-chat__message-simple str-chat__message str-chat__message--{{\n message?.type\n }} str-chat__message--{{ message?.status }} {{\n message?.text ? 'str-chat__message--has-text' : 'has-no-text'\n }}\"\n [class.str-chat__message--me]=\"isSentByCurrentUser\"\n [class.str-chat__message-simple--me]=\"isSentByCurrentUser\"\n [class.mobile-press]=\"isPressedOnMobile\"\n [class.str-chat__message--has-attachment]=\"hasAttachment\"\n [class.str-chat__message--with-reactions]=\"\n areReactionsEnabled !== false && hasReactions\n \"\n data-testid=\"message-container\"\n (mouseleave)=\"isActionBoxOpen = false\"\n>\n <ng-container *ngIf=\"!message?.deleted_at; else deletedMessage\">\n <ng-container *ngIf=\"message?.type !== 'system'; else systemMessage\">\n <ng-container\n *ngIf=\"\n isSentByCurrentUser &&\n ((isLastSentMessage && message?.status === 'received') ||\n message?.status === 'sending')\n \"\n >\n <ng-container *ngIf=\"message?.status === 'sending'; else sentStatus\">\n <ng-container *ngTemplateOutlet=\"sendingStatus\"></ng-container>\n </ng-container>\n <ng-template #sentStatus>\n <ng-container\n *ngIf=\"\n mode === 'main' &&\n isMessageDeliveredAndRead &&\n canDisplayReadStatus;\n else deliveredStatus\n \"\n >\n <ng-container *ngTemplateOutlet=\"readStatus\"></ng-container>\n </ng-container>\n </ng-template>\n </ng-container>\n <stream-avatar\n data-testid=\"avatar\"\n class=\"str-chat-angular__avatar-host\"\n [imageUrl]=\"message?.user?.image\"\n [name]=\"message?.user?.name || message?.user?.id\"\n ></stream-avatar>\n <div class=\"str-chat__message-inner\">\n <div\n class=\"str-chat__message-simple__actions\"\n data-testid=\"message-options\"\n *ngIf=\"areOptionsVisible\"\n >\n <div\n data-testid=\"message-actions-container\"\n class=\"\n str-chat__message-simple__actions__action\n str-chat__message-simple__actions__action--options\n \"\n [class.str-chat-angular__message-simple__actions__action--options--editing]=\"\n isEditing\n \"\n >\n <stream-message-actions-box\n [isOpen]=\"isActionBoxOpen\"\n [isMine]=\"isSentByCurrentUser\"\n [enabledActions]=\"enabledMessageActions\"\n [message]=\"message\"\n (displayedActionsCount)=\"visibleMessageActionsCount = $event\"\n (isEditing)=\"isEditing = $event; isActionBoxOpen = !isEditing\"\n [messageInputTemplate]=\"messageInputTemplate\"\n ></stream-message-actions-box>\n <stream-icon\n *ngIf=\"visibleMessageActionsCount > 0\"\n data-testid=\"action-icon\"\n icon=\"action-icon\"\n (keyup.enter)=\"isActionBoxOpen = !isActionBoxOpen\"\n (click)=\"isActionBoxOpen = !isActionBoxOpen\"\n ></stream-icon>\n </div>\n <!-- eslint-disable @angular-eslint/template/conditional-complexity -->\n <div\n *ngIf=\"\n enabledMessageActions.indexOf('send-reply') !== -1 &&\n mode === 'main'\n \"\n class=\"\n str-chat__message-simple__actions__action\n str-chat__message-simple__actions__action--thread\n \"\n data-testid=\"reply-in-thread\"\n (click)=\"setAsActiveParentMessage()\"\n (keyup.enter)=\"setAsActiveParentMessage()\"\n >\n <stream-icon icon=\"reply-in-thread\"></stream-icon>\n </div>\n <div\n *ngIf=\"\n areReactionsEnabled !== false &&\n canReactToMessage !== false &&\n enabledMessageActions.indexOf('send-reaction') !== -1\n \"\n class=\"\n str-chat__message-simple__actions__action\n str-chat__message-simple__actions__action--reactions\n \"\n data-testid=\"reaction-icon\"\n (click)=\"isReactionSelectorOpen = !isReactionSelectorOpen\"\n (keyup.enter)=\"isReactionSelectorOpen = !isReactionSelectorOpen\"\n >\n <stream-icon icon=\"reaction-icon\"></stream-icon>\n </div>\n </div>\n <!-- eslint-enable @angular-eslint/template/conditional-complexity -->\n <stream-message-reactions\n *ngIf=\"areReactionsEnabled !== false\"\n [messageReactionCounts]=\"message?.reaction_counts || {}\"\n [latestReactions]=\"message?.latest_reactions || []\"\n [(isSelectorOpen)]=\"isReactionSelectorOpen\"\n [messageId]=\"message?.id\"\n [ownReactions]=\"message?.own_reactions || []\"\n ></stream-message-reactions>\n <stream-attachment-list\n *ngIf=\"hasAttachment && !message?.quoted_message\"\n [attachments]=\"message!.attachments!\"\n [messageId]=\"message!.id\"\n ></stream-attachment-list>\n <div class=\"str-chat__message-text\" *ngIf=\"message?.text\">\n <div\n data-testid=\"inner-message\"\n class=\"\n str-chat__message-text-inner str-chat__message-simple-text-inner\n \"\n [class.str-chat__message-light-text-inner--has-attachment]=\"\n hasAttachment\n \"\n (click)=\"\n message?.status === 'failed' && message?.errorStatusCode !== 403\n ? resendMessage()\n : undefined\n \"\n (keyup.enter)=\"\n message?.status === 'failed' && message?.errorStatusCode !== 403\n ? resendMessage()\n : undefined\n \"\n >\n <ng-container *ngTemplateOutlet=\"quotedMessage\"></ng-container>\n <stream-attachment-list\n *ngIf=\"hasAttachment && message?.quoted_message\"\n [attachments]=\"message!.attachments!\"\n [messageId]=\"message!.id\"\n ></stream-attachment-list>\n <div\n data-testid=\"client-error-message\"\n *ngIf=\"message?.type === 'error'\"\n class=\"str-chat__simple-message--error-message\"\n >\n {{ \"streamChat.Error \u00B7 Unsent\" | translate }}\n </div>\n <div\n data-testid=\"error-message\"\n *ngIf=\"message?.status === 'failed'\"\n class=\"str-chat__simple-message--error-message\"\n >\n {{\n (message?.errorStatusCode === 403\n ? \"streamChat.Message Failed \u00B7 Unauthorized\"\n : \"streamChat.Message Failed \u00B7 Click to try again\"\n ) | translate\n }}\n </div>\n <div\n (click)=\"textClicked()\"\n (keyup.enter)=\"textClicked()\"\n data-testid=\"text\"\n >\n <p>\n <!-- eslint-disable-next-line @angular-eslint/template/use-track-by-function -->\n <ng-container *ngFor=\"let part of messageTextParts\">\n <span\n *ngIf=\"part.type === 'text'; else mention\"\n [innerHTML]=\"part.content\"\n ></span>\n <ng-template #mention>\n <ng-container *ngIf=\"mentionTemplate; else defaultMention\">\n <ng-container\n *ngTemplateOutlet=\"\n mentionTemplate;\n context: { user: part.user! }\n \"\n ></ng-container>\n </ng-container>\n <ng-template #defaultMention>\n <b>{{ part.content }}</b>\n </ng-template>\n </ng-template>\n </ng-container>\n </p>\n </div>\n </div>\n </div>\n <div class=\"str-chat__message-simple-reply-button\">\n <button\n *ngIf=\"\n !!message?.reply_count &&\n mode !== 'thread' &&\n enabledMessageActions.indexOf('send-reply') !== -1\n \"\n class=\"str-chat__message-replies-count-button\"\n data-testid=\"reply-count-button\"\n (click)=\"setAsActiveParentMessage()\"\n >\n <stream-icon icon=\"reply\"></stream-icon>\n {{message?.reply_count === 1 ? ('streamChat.1 reply' | translate) : ('streamChat.{{ replyCount }}\n replies' | translate:replyCountParam)}}\n </button>\n </div>\n <div class=\"str-chat__message-data str-chat__message-simple-data\">\n <span\n data-testid=\"sender\"\n *ngIf=\"!isSentByCurrentUser\"\n class=\"str-chat__message-simple-name\"\n >\n {{ message?.user?.name ? message?.user?.name : message?.user?.id }}\n </span>\n <span data-testid=\"date\" class=\"str-chat__message-simple-timestamp\">\n {{ parsedDate }}\n </span>\n </div>\n </div>\n </ng-container>\n </ng-container>\n</div>\n\n<ng-template #sendingStatus>\n <span\n class=\"\n str-chat__message-simple-status str-chat__message-simple-status-angular\n \"\n data-testid=\"sending-indicator\"\n >\n <div class=\"str-chat__tooltip\">\n {{ \"streamChat.Sending...\" | translate }}\n </div>\n <stream-loading-indicator\n data-testid=\"loading-indicator\"\n ></stream-loading-indicator>\n </span>\n</ng-template>\n<ng-template #readStatus>\n <span\n class=\"\n str-chat__message-simple-status str-chat__message-simple-status-angular\n \"\n data-testid=\"read-indicator\"\n >\n <div class=\"str-chat__tooltip\" data-testid=\"read-by-tooltip\">\n {{ readByText }}\n </div>\n <stream-avatar\n class=\"str-chat-angular__avatar-host\"\n data-test-id=\"last-read-user-avatar\"\n [size]=\"15\"\n [imageUrl]=\"lastReadUser?.image\"\n [name]=\"lastReadUser?.name || lastReadUser?.id\"\n ></stream-avatar>\n <span\n data-test-id=\"read-by-length\"\n *ngIf=\"isReadByMultipleUsers\"\n class=\"str-chat__message-simple-status-number\"\n >\n {{ (message?.readBy)!.length }}\n </span>\n </span>\n</ng-template>\n<ng-template #deliveredStatus>\n <span\n *ngIf=\"mode === 'main'\"\n class=\"\n str-chat__message-simple-status str-chat__message-simple-status-angular\n \"\n data-testid=\"delivered-indicator\"\n >\n <div class=\"str-chat__tooltip\">\n {{ \"streamChat.Delivered\" | translate }}\n </div>\n <stream-icon\n data-testid=\"delivered-icon\"\n icon=\"delivered-icon\"\n ></stream-icon>\n </span>\n</ng-template>\n\n<ng-template #deletedMessage>\n <div data-testid=\"message-deleted-component\">\n <div class=\"str-chat__message--deleted-inner\" translate>\n streamChat.This message was deleted...\n </div>\n </div>\n</ng-template>\n\n<ng-template #systemMessage>\n <div data-testid=\"system-message\" class=\"str-chat__message--system\">\n <div class=\"str-chat__message--system__text\">\n <div class=\"str-chat__message--system__line\"></div>\n <p>{{ message?.text }}</p>\n <div class=\"str-chat__message--system__line\"></div>\n </div>\n <div class=\"str-chat__message--system__date\">\n {{ parsedDate }}\n </div>\n </div>\n</ng-template>\n\n<ng-template #quotedMessage>\n <div\n *ngIf=\"message?.quoted_message\"\n class=\"quoted-message\"\n data-testid=\"quoted-message-container\"\n [class.mine]=\"isSentByCurrentUser\"\n >\n <stream-avatar\n data-testid=\"qouted-message-avatar\"\n class=\"str-chat-angular__avatar-host\"\n [imageUrl]=\"message?.quoted_message?.user?.image\"\n [name]=\"\n message?.quoted_message?.user?.name || message?.quoted_message?.user?.id\n \"\n [size]=\"20\"\n ></stream-avatar>\n <div class=\"quoted-message-inner\">\n <stream-attachment-list\n *ngIf=\"\n message?.quoted_message?.attachments &&\n message?.quoted_message?.attachments?.length\n \"\n [attachments]=\"quotedMessageAttachments\"\n [messageId]=\"message?.quoted_message?.id\"\n ></stream-attachment-list>\n <div\n data-testid=\"quoted-message-text\"\n [innerHTML]=\"\n message?.quoted_message?.html || message?.quoted_message?.text\n \"\n ></div>\n </div>\n </div>\n</ng-template>\n", components: [{ type: AvatarComponent, selector: "stream-avatar", inputs: ["name", "imageUrl", "size"] }, { type: MessageActionsBoxComponent, selector: "stream-message-actions-box", inputs: ["messageInputTemplate", "isOpen", "isMine", "message", "enabledActions"], outputs: ["displayedActionsCount", "isEditing"] }, { type: IconComponent, selector: "stream-icon", inputs: ["icon", "size"] }, { type: MessageReactionsComponent, selector: "stream-message-reactions", inputs: ["messageId", "messageReactionCounts", "isSelectorOpen", "latestReactions", "ownReactions"], outputs: ["isSelectorOpenChange"] }, { type: AttachmentListComponent, selector: "stream-attachment-list", inputs: ["messageId", "attachments"] }, { type: LoadingIndicatorComponent, selector: "stream-loading-indicator", inputs: ["size", "color"] }], directives: [{ type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i6.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }], pipes: { "translate": i1.TranslatePipe } });
|
|
2385
2610
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: MessageComponent, decorators: [{
|
|
2386
2611
|
type: Component,
|
|
2387
2612
|
args: [{
|
|
@@ -2405,6 +2630,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
2405
2630
|
type: Input
|
|
2406
2631
|
}], canReceiveReadEvents: [{
|
|
2407
2632
|
type: Input
|
|
2633
|
+
}], mode: [{
|
|
2634
|
+
type: Input
|
|
2408
2635
|
}], container: [{
|
|
2409
2636
|
type: ViewChild,
|
|
2410
2637
|
args: ['container']
|
|
@@ -2428,7 +2655,7 @@ class TextareaComponent {
|
|
|
2428
2655
|
}
|
|
2429
2656
|
}
|
|
2430
2657
|
TextareaComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: TextareaComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2431
|
-
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":
|
|
2658
|
+
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 } });
|
|
2432
2659
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: TextareaComponent, decorators: [{
|
|
2433
2660
|
type: Component,
|
|
2434
2661
|
args: [{
|
|
@@ -2613,7 +2840,7 @@ class AutocompleteTextareaComponent {
|
|
|
2613
2840
|
}
|
|
2614
2841
|
}
|
|
2615
2842
|
AutocompleteTextareaComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: AutocompleteTextareaComponent, deps: [{ token: ChannelService }, { token: ChatClientService }, { token: TransliterationService }], target: i0.ɵɵFactoryTarget.Component });
|
|
2616
|
-
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", commandAutocompleteItemTemplate: "commandAutocompleteItemTemplate", 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 class=\"rta__entity\" *ngSwitchCase=\"'command'\">\n <ng-container\n *ngTemplateOutlet=\"\n commandAutocompleteItemTemplate || defaultCommandTemplate;\n context: { item: item }\n \"\n ></ng-container>\n </div>\n </div>\n</ng-template>\n\n<ng-template #defaultCommandTemplate let-item=\"item\">\n <div class=\"str-chat__slash-command\">\n <span class=\"str-chat__slash-command-header\">\n <strong data-testclass=\"command-name\">{{ item.name }}</strong>\n {{ item.args }}\n </span>\n <br />\n <span class=\"str-chat__slash-command-description\">{{\n item.description\n }}</span>\n </div>\n</ng-template>\n\n<ng-template #defaultMentionTemplate let-item=\"item\">\n <div class=\"str-chat__user-item\">\n <stream-avatar\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: i5.MentionDirective, selector: "[mention], [mentionConfig]", inputs: ["mentionConfig", "mention", "mentionListTemplate"], outputs: ["searchTerm", "itemSelected", "opened", "closed"] }, { type: i6.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { type: i6.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { type: i6.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], pipes: { "translate":
|
|
2843
|
+
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", commandAutocompleteItemTemplate: "commandAutocompleteItemTemplate", 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 class=\"rta__entity\" *ngSwitchCase=\"'command'\">\n <ng-container\n *ngTemplateOutlet=\"\n commandAutocompleteItemTemplate || defaultCommandTemplate;\n context: { item: item }\n \"\n ></ng-container>\n </div>\n </div>\n</ng-template>\n\n<ng-template #defaultCommandTemplate let-item=\"item\">\n <div class=\"str-chat__slash-command\">\n <span class=\"str-chat__slash-command-header\">\n <strong data-testclass=\"command-name\">{{ item.name }}</strong>\n {{ item.args }}\n </span>\n <br />\n <span class=\"str-chat__slash-command-description\">{{\n item.description\n }}</span>\n </div>\n</ng-template>\n\n<ng-template #defaultMentionTemplate let-item=\"item\">\n <div class=\"str-chat__user-item\">\n <stream-avatar\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: i5.MentionDirective, selector: "[mention], [mentionConfig]", inputs: ["mentionConfig", "mention", "mentionListTemplate"], outputs: ["searchTerm", "itemSelected", "opened", "closed"] }, { type: i6.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { type: i6.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { type: i6.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], pipes: { "translate": i1.TranslatePipe } });
|
|
2617
2844
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: AutocompleteTextareaComponent, decorators: [{
|
|
2618
2845
|
type: Component,
|
|
2619
2846
|
args: [{
|
|
@@ -2689,30 +2916,37 @@ class MessageListComponent {
|
|
|
2689
2916
|
this.channelService = channelService;
|
|
2690
2917
|
this.chatClientService = chatClientService;
|
|
2691
2918
|
this.imageLoadService = imageLoadService;
|
|
2692
|
-
|
|
2919
|
+
/**
|
|
2920
|
+
* @deprecated https://getstream.io/chat/docs/sdk/angular/components/message_list/#caution-arereactionsenabled-deprecated
|
|
2921
|
+
*/
|
|
2922
|
+
this.areReactionsEnabled = undefined;
|
|
2923
|
+
/**
|
|
2924
|
+
* @deprecated https://getstream.io/chat/docs/sdk/angular/components/message_list/#caution-enabledmessageactions-deprecated
|
|
2925
|
+
*/
|
|
2693
2926
|
/* eslint-disable-next-line @angular-eslint/no-input-rename */
|
|
2694
|
-
this.enabledMessageActionsInput =
|
|
2927
|
+
this.enabledMessageActionsInput = undefined;
|
|
2928
|
+
this.mode = 'main';
|
|
2695
2929
|
this.enabledMessageActions = [];
|
|
2696
2930
|
this.class = 'str-chat-angular__main-panel-inner str-chat-angular__message-list-host';
|
|
2697
2931
|
this.unreadMessageCount = 0;
|
|
2698
2932
|
this.groupStyles = [];
|
|
2699
2933
|
this.authorizedMessageActions = ['flag'];
|
|
2700
2934
|
this.isUserScrolledUpThreshold = 300;
|
|
2701
|
-
this.
|
|
2935
|
+
this.subscriptions = [];
|
|
2936
|
+
this.subscriptions.push(this.channelService.activeChannel$.subscribe((channel) => {
|
|
2702
2937
|
var _a;
|
|
2703
|
-
this.
|
|
2704
|
-
this.hasNewMessages = true;
|
|
2705
|
-
this.isUserScrolledUp = false;
|
|
2706
|
-
this.containerHeight = undefined;
|
|
2707
|
-
this.olderMassagesLoaded = false;
|
|
2708
|
-
this.oldestMessageDate = undefined;
|
|
2709
|
-
this.unreadMessageCount = 0;
|
|
2710
|
-
this.isNewMessageSentByUser = undefined;
|
|
2938
|
+
this.resetScrollState();
|
|
2711
2939
|
const capabilites = (_a = channel === null || channel === void 0 ? void 0 : channel.data) === null || _a === void 0 ? void 0 : _a.own_capabilities;
|
|
2712
2940
|
if (capabilites) {
|
|
2713
2941
|
this.canReactToMessage = capabilites.indexOf('send-reaction') !== -1;
|
|
2714
2942
|
this.canReceiveReadEvents = capabilites.indexOf('read-events') !== -1;
|
|
2715
2943
|
this.authorizedMessageActions = [];
|
|
2944
|
+
if (this.canReactToMessage) {
|
|
2945
|
+
this.authorizedMessageActions.push('send-reaction');
|
|
2946
|
+
}
|
|
2947
|
+
if (this.canReceiveReadEvents) {
|
|
2948
|
+
this.authorizedMessageActions.push('read-events');
|
|
2949
|
+
}
|
|
2716
2950
|
if (capabilites.indexOf('flag-message') !== -1) {
|
|
2717
2951
|
this.authorizedMessageActions.push('flag');
|
|
2718
2952
|
}
|
|
@@ -2730,47 +2964,16 @@ class MessageListComponent {
|
|
|
2730
2964
|
this.authorizedMessageActions.push('delete');
|
|
2731
2965
|
this.authorizedMessageActions.push('delete-any');
|
|
2732
2966
|
}
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
});
|
|
2736
|
-
this.messages$ = this.channelService.activeChannelMessages$.pipe(tap((messages) => {
|
|
2737
|
-
var _a, _b, _c, _d, _e;
|
|
2738
|
-
if (messages.length === 0) {
|
|
2739
|
-
return;
|
|
2740
|
-
}
|
|
2741
|
-
const currentLatestMessageDate = messages[messages.length - 1].created_at;
|
|
2742
|
-
if (!this.latestMessageDate ||
|
|
2743
|
-
((_a = this.latestMessageDate) === null || _a === void 0 ? void 0 : _a.getTime()) < currentLatestMessageDate.getTime()) {
|
|
2744
|
-
this.latestMessageDate = currentLatestMessageDate;
|
|
2745
|
-
this.hasNewMessages = true;
|
|
2746
|
-
this.isNewMessageSentByUser =
|
|
2747
|
-
((_b = messages[messages.length - 1].user) === null || _b === void 0 ? void 0 : _b.id) ===
|
|
2748
|
-
((_d = (_c = this.chatClientService.chatClient) === null || _c === void 0 ? void 0 : _c.user) === null || _d === void 0 ? void 0 : _d.id);
|
|
2749
|
-
if (this.isUserScrolledUp) {
|
|
2750
|
-
this.unreadMessageCount++;
|
|
2967
|
+
if (capabilites.indexOf('send-reply') !== -1) {
|
|
2968
|
+
this.authorizedMessageActions.push('send-reply');
|
|
2751
2969
|
}
|
|
2970
|
+
if (capabilites.indexOf('quote-message') !== -1) {
|
|
2971
|
+
this.authorizedMessageActions.push('quote-message');
|
|
2972
|
+
}
|
|
2973
|
+
this.setEnabledActions();
|
|
2752
2974
|
}
|
|
2753
|
-
const currentOldestMessageDate = messages[0].created_at;
|
|
2754
|
-
if (!this.oldestMessageDate) {
|
|
2755
|
-
this.oldestMessageDate = currentOldestMessageDate;
|
|
2756
|
-
}
|
|
2757
|
-
else if (((_e = this.oldestMessageDate) === null || _e === void 0 ? void 0 : _e.getTime()) > currentOldestMessageDate.getTime()) {
|
|
2758
|
-
this.oldestMessageDate = currentOldestMessageDate;
|
|
2759
|
-
this.olderMassagesLoaded = true;
|
|
2760
|
-
}
|
|
2761
|
-
}), tap((messages) => {
|
|
2762
|
-
this.groupStyles = messages.map((m, i) => getGroupStyles(m, messages[i - 1], messages[i + 1]));
|
|
2763
|
-
}), tap((messages) => {
|
|
2764
|
-
var _a;
|
|
2765
|
-
return (this.lastSentMessageId = (_a = [...messages]
|
|
2766
|
-
.reverse()
|
|
2767
|
-
.find((m) => {
|
|
2768
|
-
var _a, _b, _c;
|
|
2769
|
-
return ((_a = m.user) === null || _a === void 0 ? void 0 : _a.id) === ((_c = (_b = this.chatClientService.chatClient) === null || _b === void 0 ? void 0 : _b.user) === null || _c === void 0 ? void 0 : _c.id) &&
|
|
2770
|
-
m.status !== 'sending';
|
|
2771
|
-
})) === null || _a === void 0 ? void 0 : _a.id);
|
|
2772
2975
|
}));
|
|
2773
|
-
this.imageLoadService.imageLoad$.subscribe(() => {
|
|
2976
|
+
this.subscriptions.push(this.imageLoadService.imageLoad$.subscribe(() => {
|
|
2774
2977
|
if (!this.isUserScrolledUp) {
|
|
2775
2978
|
this.scrollToBottom();
|
|
2776
2979
|
// Hacky and unreliable workaround to scroll down after loaded images move the scrollbar
|
|
@@ -2778,12 +2981,27 @@ class MessageListComponent {
|
|
|
2778
2981
|
this.scrollToBottom();
|
|
2779
2982
|
}, 300);
|
|
2780
2983
|
}
|
|
2781
|
-
});
|
|
2984
|
+
}));
|
|
2985
|
+
this.subscriptions.push(this.channelService.activeParentMessage$.subscribe((message) => {
|
|
2986
|
+
if (message &&
|
|
2987
|
+
this.parentMessage &&
|
|
2988
|
+
message.id !== this.parentMessage.id &&
|
|
2989
|
+
this.mode === 'thread') {
|
|
2990
|
+
this.resetScrollState();
|
|
2991
|
+
}
|
|
2992
|
+
this.parentMessage = message;
|
|
2993
|
+
}));
|
|
2994
|
+
}
|
|
2995
|
+
ngOnInit() {
|
|
2996
|
+
this.setMessages$();
|
|
2782
2997
|
}
|
|
2783
2998
|
ngOnChanges(changes) {
|
|
2784
2999
|
if (changes.enabledMessageActionsInput) {
|
|
2785
3000
|
this.setEnabledActions();
|
|
2786
3001
|
}
|
|
3002
|
+
if (changes.mode) {
|
|
3003
|
+
this.setMessages$();
|
|
3004
|
+
}
|
|
2787
3005
|
}
|
|
2788
3006
|
ngAfterViewChecked() {
|
|
2789
3007
|
if (this.hasNewMessages) {
|
|
@@ -2809,6 +3027,9 @@ class MessageListComponent {
|
|
|
2809
3027
|
this.containerHeight = this.scrollContainer.nativeElement.scrollHeight;
|
|
2810
3028
|
}
|
|
2811
3029
|
}
|
|
3030
|
+
ngOnDestroy() {
|
|
3031
|
+
this.subscriptions.forEach((s) => s.unsubscribe());
|
|
3032
|
+
}
|
|
2812
3033
|
trackByMessageId(index, item) {
|
|
2813
3034
|
return item.id;
|
|
2814
3035
|
}
|
|
@@ -2817,6 +3038,7 @@ class MessageListComponent {
|
|
|
2817
3038
|
this.scrollContainer.nativeElement.scrollHeight;
|
|
2818
3039
|
}
|
|
2819
3040
|
scrolled() {
|
|
3041
|
+
var _a, _b;
|
|
2820
3042
|
this.isUserScrolledUp =
|
|
2821
3043
|
this.scrollContainer.nativeElement.scrollHeight -
|
|
2822
3044
|
(this.scrollContainer.nativeElement.scrollTop +
|
|
@@ -2825,20 +3047,36 @@ class MessageListComponent {
|
|
|
2825
3047
|
if (!this.isUserScrolledUp) {
|
|
2826
3048
|
this.unreadMessageCount = 0;
|
|
2827
3049
|
}
|
|
2828
|
-
if (this.scrollContainer.nativeElement.scrollTop
|
|
3050
|
+
if (this.scrollContainer.nativeElement.scrollTop <=
|
|
3051
|
+
(((_a = this.parentMessageElement) === null || _a === void 0 ? void 0 : _a.nativeElement.clientHeight) || 0) &&
|
|
3052
|
+
(this.prevScrollTop === undefined ||
|
|
3053
|
+
this.prevScrollTop >
|
|
3054
|
+
(((_b = this.parentMessageElement) === null || _b === void 0 ? void 0 : _b.nativeElement.clientHeight) || 0))) {
|
|
2829
3055
|
this.containerHeight = this.scrollContainer.nativeElement.scrollHeight;
|
|
2830
|
-
|
|
3056
|
+
this.mode === 'main'
|
|
3057
|
+
? void this.channelService.loadMoreMessages()
|
|
3058
|
+
: void this.channelService.loadMoreThreadReplies();
|
|
2831
3059
|
}
|
|
3060
|
+
this.prevScrollTop = this.scrollContainer.nativeElement.scrollTop;
|
|
2832
3061
|
}
|
|
2833
3062
|
preserveScrollbarPosition() {
|
|
2834
3063
|
this.scrollContainer.nativeElement.scrollTop =
|
|
2835
|
-
this.
|
|
3064
|
+
(this.prevScrollTop || 0) +
|
|
3065
|
+
(this.scrollContainer.nativeElement.scrollHeight - this.containerHeight);
|
|
2836
3066
|
}
|
|
2837
3067
|
setEnabledActions() {
|
|
2838
3068
|
this.enabledMessageActions = [];
|
|
2839
3069
|
if (!this.enabledMessageActionsInput) {
|
|
3070
|
+
this.enabledMessageActions = this.authorizedMessageActions;
|
|
2840
3071
|
return;
|
|
2841
3072
|
}
|
|
3073
|
+
this.enabledMessageActionsInput = [
|
|
3074
|
+
...this.enabledMessageActionsInput,
|
|
3075
|
+
'send-reaction',
|
|
3076
|
+
'read-events',
|
|
3077
|
+
'send-reply',
|
|
3078
|
+
'quote-message',
|
|
3079
|
+
];
|
|
2842
3080
|
this.enabledMessageActionsInput.forEach((action) => {
|
|
2843
3081
|
const isAuthorized = this.authorizedMessageActions.indexOf(action) !== -1;
|
|
2844
3082
|
if (isAuthorized) {
|
|
@@ -2846,9 +3084,61 @@ class MessageListComponent {
|
|
|
2846
3084
|
}
|
|
2847
3085
|
});
|
|
2848
3086
|
}
|
|
3087
|
+
setMessages$() {
|
|
3088
|
+
this.messages$ = (this.mode === 'main'
|
|
3089
|
+
? this.channelService.activeChannelMessages$
|
|
3090
|
+
: this.channelService.activeThreadMessages$).pipe(tap((messages) => {
|
|
3091
|
+
var _a, _b, _c, _d, _e;
|
|
3092
|
+
if (messages.length === 0) {
|
|
3093
|
+
return;
|
|
3094
|
+
}
|
|
3095
|
+
const currentLatestMessageDate = messages[messages.length - 1].created_at;
|
|
3096
|
+
if (!this.latestMessageDate ||
|
|
3097
|
+
((_a = this.latestMessageDate) === null || _a === void 0 ? void 0 : _a.getTime()) < currentLatestMessageDate.getTime()) {
|
|
3098
|
+
this.latestMessageDate = currentLatestMessageDate;
|
|
3099
|
+
this.hasNewMessages = true;
|
|
3100
|
+
this.isNewMessageSentByUser =
|
|
3101
|
+
((_b = messages[messages.length - 1].user) === null || _b === void 0 ? void 0 : _b.id) ===
|
|
3102
|
+
((_d = (_c = this.chatClientService.chatClient) === null || _c === void 0 ? void 0 : _c.user) === null || _d === void 0 ? void 0 : _d.id);
|
|
3103
|
+
if (this.isUserScrolledUp) {
|
|
3104
|
+
this.unreadMessageCount++;
|
|
3105
|
+
}
|
|
3106
|
+
}
|
|
3107
|
+
const currentOldestMessageDate = messages[0].created_at;
|
|
3108
|
+
if (!this.oldestMessageDate) {
|
|
3109
|
+
this.oldestMessageDate = currentOldestMessageDate;
|
|
3110
|
+
}
|
|
3111
|
+
else if (((_e = this.oldestMessageDate) === null || _e === void 0 ? void 0 : _e.getTime()) > currentOldestMessageDate.getTime()) {
|
|
3112
|
+
this.oldestMessageDate = currentOldestMessageDate;
|
|
3113
|
+
this.olderMassagesLoaded = true;
|
|
3114
|
+
}
|
|
3115
|
+
}), tap((messages) => {
|
|
3116
|
+
this.groupStyles = messages.map((m, i) => getGroupStyles(m, messages[i - 1], messages[i + 1]));
|
|
3117
|
+
}), tap((messages) => {
|
|
3118
|
+
var _a;
|
|
3119
|
+
return (this.lastSentMessageId = (_a = [...messages]
|
|
3120
|
+
.reverse()
|
|
3121
|
+
.find((m) => {
|
|
3122
|
+
var _a, _b, _c;
|
|
3123
|
+
return ((_a = m.user) === null || _a === void 0 ? void 0 : _a.id) === ((_c = (_b = this.chatClientService.chatClient) === null || _b === void 0 ? void 0 : _b.user) === null || _c === void 0 ? void 0 : _c.id) &&
|
|
3124
|
+
m.status !== 'sending';
|
|
3125
|
+
})) === null || _a === void 0 ? void 0 : _a.id);
|
|
3126
|
+
}));
|
|
3127
|
+
}
|
|
3128
|
+
resetScrollState() {
|
|
3129
|
+
this.latestMessageDate = undefined;
|
|
3130
|
+
this.hasNewMessages = true;
|
|
3131
|
+
this.isUserScrolledUp = false;
|
|
3132
|
+
this.containerHeight = undefined;
|
|
3133
|
+
this.olderMassagesLoaded = false;
|
|
3134
|
+
this.oldestMessageDate = undefined;
|
|
3135
|
+
this.unreadMessageCount = 0;
|
|
3136
|
+
this.prevScrollTop = undefined;
|
|
3137
|
+
this.isNewMessageSentByUser = undefined;
|
|
3138
|
+
}
|
|
2849
3139
|
}
|
|
2850
3140
|
MessageListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: MessageListComponent, deps: [{ token: ChannelService }, { token: ChatClientService }, { token: ImageLoadService }], target: i0.ɵɵFactoryTarget.Component });
|
|
2851
|
-
MessageListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: MessageListComponent, selector: "stream-message-list", inputs: { messageTemplate: "messageTemplate", messageInputTemplate: "messageInputTemplate", mentionTemplate: "mentionTemplate", areReactionsEnabled: "areReactionsEnabled", enabledMessageActionsInput: ["enabledMessageActions", "enabledMessageActionsInput"] }, host: { properties: { "class": "this.class" } }, viewQueries: [{ propertyName: "scrollContainer", first: true, predicate: ["scrollContainer"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div\n #scrollContainer\n data-testid=\"scroll-container\"\n class=\"str-chat__list\"\n (scroll)=\"scrolled()\"\n>\n <div class=\"str-chat__reverse-infinite-scroll\">\n <ul class=\"str-chat__ul\">\n <li\n data-testclass=\"message\"\n *ngFor=\"\n let message of messages$ | async;\n let i = index;\n trackBy: trackByMessageId\n \"\n class=\"str-chat__li str-chat__li--{{ groupStyles[i] }}\"\n >\n <ng-container
|
|
3141
|
+
MessageListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: MessageListComponent, selector: "stream-message-list", inputs: { messageTemplate: "messageTemplate", messageInputTemplate: "messageInputTemplate", mentionTemplate: "mentionTemplate", areReactionsEnabled: "areReactionsEnabled", enabledMessageActionsInput: ["enabledMessageActions", "enabledMessageActionsInput"], mode: "mode" }, host: { properties: { "class": "this.class" } }, viewQueries: [{ propertyName: "scrollContainer", first: true, predicate: ["scrollContainer"], descendants: true }, { propertyName: "parentMessageElement", first: true, predicate: ["parentMessageElement"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div\n #scrollContainer\n data-testid=\"scroll-container\"\n class=\"str-chat__list\"\n (scroll)=\"scrolled()\"\n>\n <div class=\"str-chat__reverse-infinite-scroll\">\n <ul class=\"str-chat__ul\">\n <li\n #parentMessageElement\n *ngIf=\"mode === 'thread'\"\n data-testid=\"parent-message\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n messageTemplateContainer;\n context: { message: parentMessage }\n \"\n ></ng-container>\n <div class=\"str-chat__thread-start\" translate>\n streamChat.Start of a new thread\n </div>\n </li>\n <li\n data-testclass=\"message\"\n *ngFor=\"\n let message of messages$ | async;\n let i = index;\n trackBy: trackByMessageId\n \"\n class=\"str-chat__li str-chat__li--{{ groupStyles[i] }}\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n messageTemplateContainer;\n context: { message: message }\n \"\n ></ng-container>\n </li>\n </ul>\n </div>\n</div>\n<div class=\"str-chat__list-notifications\">\n <button\n data-testid=\"scroll-to-bottom\"\n *ngIf=\"isUserScrolledUp\"\n class=\"\n str-chat__message-notification\n str-chat__message-notification-right\n str-chat__message-notification-scroll-down\n \"\n (keyup.enter)=\"scrollToBottom()\"\n (click)=\"scrollToBottom()\"\n >\n <div\n *ngIf=\"unreadMessageCount > 0\"\n class=\"\n str-chat__message-notification\n str-chat__message-notification-scroll-down-unread-count\n \"\n >\n {{ unreadMessageCount }}\n </div>\n </button>\n</div>\n\n<ng-template #messageTemplateContainer let-message=\"message\">\n <ng-container *ngIf=\"messageTemplate; else defaultMessageTemplate\">\n <ng-container\n *ngTemplateOutlet=\"\n messageTemplate;\n context: {\n message: message,\n areReactionsEnabled: areReactionsEnabled,\n canReactToMessage: canReactToMessage,\n lastSentMessageId: !!(\n lastSentMessageId && message?.id === lastSentMessageId\n ),\n canReceiveReadEvents: canReceiveReadEvents,\n messageInputTemplate: messageInputTemplate,\n mentionTemplate: mentionTemplate,\n mode: mode\n }\n \"\n ></ng-container>\n </ng-container>\n <ng-template #defaultMessageTemplate>\n <stream-message\n [message]=\"message\"\n [areReactionsEnabled]=\"areReactionsEnabled\"\n [canReactToMessage]=\"canReactToMessage\"\n [isLastSentMessage]=\"\n !!(lastSentMessageId && message?.id === lastSentMessageId)\n \"\n [enabledMessageActions]=\"enabledMessageActions\"\n [canReceiveReadEvents]=\"canReceiveReadEvents\"\n [messageInputTemplate]=\"messageInputTemplate\"\n [mentionTemplate]=\"mentionTemplate\"\n [mode]=\"mode\"\n ></stream-message>\n </ng-template>\n</ng-template>\n", components: [{ type: MessageComponent, selector: "stream-message", inputs: ["messageInputTemplate", "mentionTemplate", "message", "enabledMessageActions", "areReactionsEnabled", "canReactToMessage", "isLastSentMessage", "canReceiveReadEvents", "mode"] }], directives: [{ type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i6.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], pipes: { "async": i6.AsyncPipe } });
|
|
2852
3142
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: MessageListComponent, decorators: [{
|
|
2853
3143
|
type: Component,
|
|
2854
3144
|
args: [{
|
|
@@ -2867,12 +3157,49 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
2867
3157
|
}], enabledMessageActionsInput: [{
|
|
2868
3158
|
type: Input,
|
|
2869
3159
|
args: ['enabledMessageActions']
|
|
3160
|
+
}], mode: [{
|
|
3161
|
+
type: Input
|
|
2870
3162
|
}], class: [{
|
|
2871
3163
|
type: HostBinding,
|
|
2872
3164
|
args: ['class']
|
|
2873
3165
|
}], scrollContainer: [{
|
|
2874
3166
|
type: ViewChild,
|
|
2875
3167
|
args: ['scrollContainer']
|
|
3168
|
+
}], parentMessageElement: [{
|
|
3169
|
+
type: ViewChild,
|
|
3170
|
+
args: ['parentMessageElement']
|
|
3171
|
+
}] } });
|
|
3172
|
+
|
|
3173
|
+
class ThreadComponent {
|
|
3174
|
+
constructor(channelService) {
|
|
3175
|
+
this.channelService = channelService;
|
|
3176
|
+
this.class = 'str-chat__thread';
|
|
3177
|
+
this.subscriptions = [];
|
|
3178
|
+
this.subscriptions.push(this.channelService.activeParentMessage$.subscribe((parentMessage) => (this.parentMessage = parentMessage)));
|
|
3179
|
+
}
|
|
3180
|
+
ngOnDestroy() {
|
|
3181
|
+
this.subscriptions.forEach((s) => s.unsubscribe());
|
|
3182
|
+
}
|
|
3183
|
+
get replyCountParam() {
|
|
3184
|
+
var _a;
|
|
3185
|
+
return { replyCount: (_a = this.parentMessage) === null || _a === void 0 ? void 0 : _a.reply_count };
|
|
3186
|
+
}
|
|
3187
|
+
closeThread() {
|
|
3188
|
+
void this.channelService.setAsActiveParentMessage(undefined);
|
|
3189
|
+
}
|
|
3190
|
+
}
|
|
3191
|
+
ThreadComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ThreadComponent, deps: [{ token: ChannelService }], target: i0.ɵɵFactoryTarget.Component });
|
|
3192
|
+
ThreadComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: ThreadComponent, selector: "stream-thread", host: { properties: { "class": "this.class" } }, ngImport: i0, template: "<div class=\"str-chat__thread-header\">\n <div class=\"str-chat__thread-header-details\">\n <strong translate>streamChat.Thread</strong>\n <small data-testid=\"reply-count\">\n {{parentMessage?.reply_count === 1 ? ('streamChat.1 reply' | translate) : ('streamChat.{{ replyCount }}\n replies' | translate:replyCountParam)}}\n </small>\n </div>\n <button\n class=\"str-chat__square-button\"\n data-testid=\"close-button\"\n (click)=\"closeThread()\"\n >\n <stream-icon icon=\"close-no-outline\"></stream-icon>\n </button>\n</div>\n<ng-content select='[name=\"thread-message-list\"]'></ng-content>\n<div class=\"str-chat__small-message-input__wrapper\">\n <ng-content select='[name=\"thread-message-input\"]'></ng-content>\n</div>\n", components: [{ type: IconComponent, selector: "stream-icon", inputs: ["icon", "size"] }], directives: [{ type: i1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }], pipes: { "translate": i1.TranslatePipe } });
|
|
3193
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ThreadComponent, decorators: [{
|
|
3194
|
+
type: Component,
|
|
3195
|
+
args: [{
|
|
3196
|
+
selector: 'stream-thread',
|
|
3197
|
+
templateUrl: './thread.component.html',
|
|
3198
|
+
styles: [],
|
|
3199
|
+
}]
|
|
3200
|
+
}], ctorParameters: function () { return [{ type: ChannelService }]; }, propDecorators: { class: [{
|
|
3201
|
+
type: HostBinding,
|
|
3202
|
+
args: ['class']
|
|
2876
3203
|
}] } });
|
|
2877
3204
|
|
|
2878
3205
|
class StreamAvatarModule {
|
|
@@ -2908,7 +3235,8 @@ StreamChatModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", versio
|
|
|
2908
3235
|
NotificationListComponent,
|
|
2909
3236
|
AttachmentPreviewListComponent,
|
|
2910
3237
|
ModalComponent,
|
|
2911
|
-
TextareaDirective
|
|
3238
|
+
TextareaDirective,
|
|
3239
|
+
ThreadComponent], imports: [CommonModule, TranslateModule, StreamAvatarModule], exports: [ChannelComponent,
|
|
2912
3240
|
ChannelHeaderComponent,
|
|
2913
3241
|
ChannelListComponent,
|
|
2914
3242
|
ChannelPreviewComponent,
|
|
@@ -2924,7 +3252,8 @@ StreamChatModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", versio
|
|
|
2924
3252
|
NotificationListComponent,
|
|
2925
3253
|
AttachmentPreviewListComponent,
|
|
2926
3254
|
ModalComponent,
|
|
2927
|
-
StreamAvatarModule
|
|
3255
|
+
StreamAvatarModule,
|
|
3256
|
+
ThreadComponent] });
|
|
2928
3257
|
StreamChatModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: StreamChatModule, imports: [[CommonModule, TranslateModule, StreamAvatarModule], StreamAvatarModule] });
|
|
2929
3258
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: StreamChatModule, decorators: [{
|
|
2930
3259
|
type: NgModule,
|
|
@@ -2947,6 +3276,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
2947
3276
|
AttachmentPreviewListComponent,
|
|
2948
3277
|
ModalComponent,
|
|
2949
3278
|
TextareaDirective,
|
|
3279
|
+
ThreadComponent,
|
|
2950
3280
|
],
|
|
2951
3281
|
imports: [CommonModule, TranslateModule, StreamAvatarModule],
|
|
2952
3282
|
exports: [
|
|
@@ -2967,6 +3297,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
2967
3297
|
AttachmentPreviewListComponent,
|
|
2968
3298
|
ModalComponent,
|
|
2969
3299
|
StreamAvatarModule,
|
|
3300
|
+
ThreadComponent,
|
|
2970
3301
|
],
|
|
2971
3302
|
}]
|
|
2972
3303
|
}] });
|
|
@@ -3029,5 +3360,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
3029
3360
|
* Generated bundle index. Do not edit.
|
|
3030
3361
|
*/
|
|
3031
3362
|
|
|
3032
|
-
export { AttachmentListComponent, AttachmentPreviewListComponent, AttachmentService, AutocompleteTextareaComponent, AvatarComponent, ChannelComponent, ChannelHeaderComponent, ChannelListComponent, ChannelListToggleService, ChannelPreviewComponent, ChannelService, ChatClientService, IconComponent, ImageLoadService, LoadingIndicatorComponent, MessageActionsBoxComponent, MessageComponent, MessageInputComponent, MessageInputConfigService, MessageListComponent, MessageReactionsComponent, ModalComponent, NotificationComponent, NotificationListComponent, NotificationService, StreamAutocompleteTextareaModule, StreamAvatarModule, StreamChatModule, StreamI18nService, StreamTextareaModule, TextareaComponent, TextareaDirective, ThemeService, TransliterationService, createMessagePreview, getDeviceWidth, getGroupStyles, getReadBy, getReadByText, isImageAttachment, isImageFile, parseDate, textareaInjectionToken };
|
|
3363
|
+
export { AttachmentListComponent, AttachmentPreviewListComponent, AttachmentService, AutocompleteTextareaComponent, AvatarComponent, ChannelComponent, ChannelHeaderComponent, ChannelListComponent, ChannelListToggleService, ChannelPreviewComponent, ChannelService, ChatClientService, IconComponent, ImageLoadService, LoadingIndicatorComponent, MessageActionsBoxComponent, MessageComponent, MessageInputComponent, MessageInputConfigService, MessageListComponent, MessageReactionsComponent, ModalComponent, NotificationComponent, NotificationListComponent, NotificationService, StreamAutocompleteTextareaModule, StreamAvatarModule, StreamChatModule, StreamI18nService, StreamTextareaModule, TextareaComponent, TextareaDirective, ThemeService, ThreadComponent, TransliterationService, createMessagePreview, getDeviceWidth, getGroupStyles, getReadBy, getReadByText, isImageAttachment, isImageFile, parseDate, textareaInjectionToken };
|
|
3033
3364
|
//# sourceMappingURL=stream-chat-angular.js.map
|