stream-chat-angular 5.4.3 → 5.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/version.d.ts +1 -1
- package/esm2020/assets/version.mjs +2 -2
- package/esm2020/lib/attachment-list/attachment-list.component.mjs +37 -16
- package/esm2020/lib/attachment-preview-list/attachment-preview-list.component.mjs +23 -10
- package/esm2020/lib/attachment.service.mjs +38 -10
- package/esm2020/lib/custom-templates.service.mjs +9 -1
- package/esm2020/lib/message-input/message-input.component.mjs +5 -3
- package/esm2020/lib/message.service.mjs +18 -1
- package/esm2020/lib/types.mjs +1 -1
- package/fesm2015/stream-chat-angular.mjs +136 -51
- package/fesm2015/stream-chat-angular.mjs.map +1 -1
- package/fesm2020/stream-chat-angular.mjs +136 -51
- package/fesm2020/stream-chat-angular.mjs.map +1 -1
- package/lib/attachment-list/attachment-list.component.d.ts +11 -4
- package/lib/attachment-preview-list/attachment-preview-list.component.d.ts +14 -4
- package/lib/attachment.service.d.ts +15 -4
- package/lib/custom-templates.service.d.ts +9 -1
- package/lib/message-input/message-input.component.d.ts +4 -3
- package/lib/message.service.d.ts +19 -3
- package/lib/types.d.ts +8 -2
- package/package.json +1 -1
- package/src/assets/version.ts +1 -1
|
@@ -22,7 +22,7 @@ import transliterate from '@stream-io/transliterate';
|
|
|
22
22
|
import * as i8$1 from 'angular-mentions';
|
|
23
23
|
import { MentionModule } from 'angular-mentions';
|
|
24
24
|
|
|
25
|
-
const version = '5.
|
|
25
|
+
const version = '5.5.0';
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
28
|
* The `NotificationService` can be used to add or remove notifications. By default the [`NotificationList`](../components/NotificationListComponent.mdx) component displays the currently active notifications.
|
|
@@ -2040,20 +2040,73 @@ const isImageAttachment = (attachment) => {
|
|
|
2040
2040
|
!attachment.og_scrape_url);
|
|
2041
2041
|
};
|
|
2042
2042
|
|
|
2043
|
+
/**
|
|
2044
|
+
* The message service contains configuration options related to displaying the message content
|
|
2045
|
+
*/
|
|
2046
|
+
class MessageService {
|
|
2047
|
+
constructor() {
|
|
2048
|
+
/**
|
|
2049
|
+
* Decides if the message content should be formatted as text or HTML
|
|
2050
|
+
*
|
|
2051
|
+
* If you display messages as text the following parts are still be displayed as HTML:
|
|
2052
|
+
* - user mentions -> you can customize this with your own template using the [`customTemplatesService.mentionTemplate$`](https://getstream.io/chat/docs/sdk/angular/services/CustomTemplatesService/#mentiontemplate)
|
|
2053
|
+
* - links -> you can customize this by providing you own [`customLinkRenderer`](#customlinkrenderer) method
|
|
2054
|
+
*/
|
|
2055
|
+
this.displayAs = 'text';
|
|
2056
|
+
}
|
|
2057
|
+
/**
|
|
2058
|
+
* Tells if an attachment is custom (you need to provide your own template to display them) or built-in (the SDK supports it out-of-the-box)
|
|
2059
|
+
* @param attachment
|
|
2060
|
+
* @returns `true` if the attachment is custom
|
|
2061
|
+
*/
|
|
2062
|
+
isCustomAttachment(attachment) {
|
|
2063
|
+
if (this.filterCustomAttachment) {
|
|
2064
|
+
return this.filterCustomAttachment(attachment);
|
|
2065
|
+
}
|
|
2066
|
+
else {
|
|
2067
|
+
return (attachment.type !== 'image' &&
|
|
2068
|
+
attachment.type !== 'file' &&
|
|
2069
|
+
attachment.type !== 'video' &&
|
|
2070
|
+
attachment.type !== 'voiceRecording' &&
|
|
2071
|
+
attachment.type !== 'giphy');
|
|
2072
|
+
}
|
|
2073
|
+
}
|
|
2074
|
+
}
|
|
2075
|
+
MessageService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: MessageService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2076
|
+
MessageService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: MessageService, providedIn: 'root' });
|
|
2077
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: MessageService, decorators: [{
|
|
2078
|
+
type: Injectable,
|
|
2079
|
+
args: [{
|
|
2080
|
+
providedIn: 'root',
|
|
2081
|
+
}]
|
|
2082
|
+
}], ctorParameters: function () { return []; } });
|
|
2083
|
+
|
|
2043
2084
|
/**
|
|
2044
2085
|
* The `AttachmentService` manages the uploads of a message input.
|
|
2045
2086
|
*
|
|
2046
2087
|
* You can read more about [uploads](https://getstream.io/chat/docs/javascript/file_uploads/?language=javascript&q=size) in the Stream API documentation. You can use Stream's API or the dashboard to customize the [file](https://getstream.io/chat/docs/javascript/app_setting_overview/?language=javascript&q=size#file-uploads) and [image upload](https://getstream.io/chat/docs/javascript/app_setting_overview/?language=javascript&q=size#image-uploads) configuration.
|
|
2047
2088
|
*/
|
|
2048
2089
|
class AttachmentService {
|
|
2049
|
-
constructor(channelService, notificationService, chatClientService) {
|
|
2090
|
+
constructor(channelService, notificationService, chatClientService, messageService) {
|
|
2050
2091
|
this.channelService = channelService;
|
|
2051
2092
|
this.notificationService = notificationService;
|
|
2052
2093
|
this.chatClientService = chatClientService;
|
|
2053
|
-
this.
|
|
2094
|
+
this.messageService = messageService;
|
|
2095
|
+
/**
|
|
2096
|
+
* Emits the number of uploads in progress.
|
|
2097
|
+
*
|
|
2098
|
+
* You can increment and decrement this counter if you're using custom attachments and want to disable message sending until all attachments are uploaded.
|
|
2099
|
+
*
|
|
2100
|
+
* The SDK will handle updating this counter for built-in attachments, but for custom attachments you should take care of this.
|
|
2101
|
+
*/
|
|
2102
|
+
this.attachmentUploadInProgressCounter$ = new BehaviorSubject(0);
|
|
2103
|
+
/**
|
|
2104
|
+
* You can get and set the list if uploaded custom attachments
|
|
2105
|
+
*
|
|
2106
|
+
* By default the SDK components won't display these, but you can provide your own `customAttachmentPreviewListTemplate$` and `customAttachmentListTemplate$` for the [`CustomTemplatesService`](../../services/CustomTemplatesService).
|
|
2107
|
+
*/
|
|
2108
|
+
this.customAttachments$ = new BehaviorSubject([]);
|
|
2054
2109
|
this.attachmentUploadsSubject = new BehaviorSubject([]);
|
|
2055
|
-
this.attachmentUploadInProgressCounter$ =
|
|
2056
|
-
this.attachmentUploadInProgressCounterSubject.asObservable();
|
|
2057
2110
|
this.attachmentUploads$ = this.attachmentUploadsSubject.asObservable();
|
|
2058
2111
|
this.chatClientService.appSettings$.subscribe((appSettings) => (this.appSettings = appSettings));
|
|
2059
2112
|
}
|
|
@@ -2062,6 +2115,7 @@ class AttachmentService {
|
|
|
2062
2115
|
*/
|
|
2063
2116
|
resetAttachmentUploads() {
|
|
2064
2117
|
this.attachmentUploadsSubject.next([]);
|
|
2118
|
+
this.customAttachments$.next([]);
|
|
2065
2119
|
}
|
|
2066
2120
|
/**
|
|
2067
2121
|
* Upload a voice recording
|
|
@@ -2214,7 +2268,7 @@ class AttachmentService {
|
|
|
2214
2268
|
*/
|
|
2215
2269
|
mapToAttachments() {
|
|
2216
2270
|
const attachmentUploads = this.attachmentUploadsSubject.getValue();
|
|
2217
|
-
|
|
2271
|
+
const builtInAttachments = attachmentUploads
|
|
2218
2272
|
.filter((r) => r.state === 'success')
|
|
2219
2273
|
.map((r) => {
|
|
2220
2274
|
var _a, _b, _c, _d;
|
|
@@ -2242,6 +2296,7 @@ class AttachmentService {
|
|
|
2242
2296
|
}
|
|
2243
2297
|
return attachment;
|
|
2244
2298
|
});
|
|
2299
|
+
return [...builtInAttachments, ...this.customAttachments$.value];
|
|
2245
2300
|
}
|
|
2246
2301
|
/**
|
|
2247
2302
|
* Maps attachments received from the Stream API to uploads. This is useful when editing a message.
|
|
@@ -2249,7 +2304,17 @@ class AttachmentService {
|
|
|
2249
2304
|
*/
|
|
2250
2305
|
createFromAttachments(attachments) {
|
|
2251
2306
|
const attachmentUploads = [];
|
|
2307
|
+
const builtInAttachments = [];
|
|
2308
|
+
const customAttachments = [];
|
|
2252
2309
|
attachments.forEach((attachment) => {
|
|
2310
|
+
if (this.messageService.isCustomAttachment(attachment)) {
|
|
2311
|
+
customAttachments.push(attachment);
|
|
2312
|
+
}
|
|
2313
|
+
else {
|
|
2314
|
+
builtInAttachments.push(attachment);
|
|
2315
|
+
}
|
|
2316
|
+
});
|
|
2317
|
+
builtInAttachments.forEach((attachment) => {
|
|
2253
2318
|
if (isImageAttachment(attachment)) {
|
|
2254
2319
|
attachmentUploads.push({
|
|
2255
2320
|
url: (attachment.img_url ||
|
|
@@ -2301,6 +2366,9 @@ class AttachmentService {
|
|
|
2301
2366
|
...attachmentUploads,
|
|
2302
2367
|
]);
|
|
2303
2368
|
}
|
|
2369
|
+
if (customAttachments.length > 0) {
|
|
2370
|
+
this.customAttachments$.next(customAttachments);
|
|
2371
|
+
}
|
|
2304
2372
|
}
|
|
2305
2373
|
createPreview(file) {
|
|
2306
2374
|
var _a, _b;
|
|
@@ -2322,7 +2390,7 @@ class AttachmentService {
|
|
|
2322
2390
|
}
|
|
2323
2391
|
uploadAttachments(uploads) {
|
|
2324
2392
|
return __awaiter(this, void 0, void 0, function* () {
|
|
2325
|
-
this.
|
|
2393
|
+
this.attachmentUploadInProgressCounter$.next(this.attachmentUploadInProgressCounter$.value + 1);
|
|
2326
2394
|
const result = yield this.channelService.uploadAttachments(uploads);
|
|
2327
2395
|
const attachmentUploads = this.attachmentUploadsSubject.getValue();
|
|
2328
2396
|
result.forEach((r) => {
|
|
@@ -2359,7 +2427,7 @@ class AttachmentService {
|
|
|
2359
2427
|
this.notificationService.addTemporaryNotification(errorKey, 'error', undefined, translateParams);
|
|
2360
2428
|
}
|
|
2361
2429
|
});
|
|
2362
|
-
this.
|
|
2430
|
+
this.attachmentUploadInProgressCounter$.next(this.attachmentUploadInProgressCounter$.value - 1);
|
|
2363
2431
|
this.attachmentUploadsSubject.next([...attachmentUploads]);
|
|
2364
2432
|
});
|
|
2365
2433
|
}
|
|
@@ -2451,14 +2519,14 @@ class AttachmentService {
|
|
|
2451
2519
|
});
|
|
2452
2520
|
}
|
|
2453
2521
|
}
|
|
2454
|
-
AttachmentService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: AttachmentService, deps: [{ token: ChannelService }, { token: NotificationService }, { token: ChatClientService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2522
|
+
AttachmentService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: AttachmentService, deps: [{ token: ChannelService }, { token: NotificationService }, { token: ChatClientService }, { token: MessageService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2455
2523
|
AttachmentService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: AttachmentService, providedIn: 'root' });
|
|
2456
2524
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: AttachmentService, decorators: [{
|
|
2457
2525
|
type: Injectable,
|
|
2458
2526
|
args: [{
|
|
2459
2527
|
providedIn: 'root',
|
|
2460
2528
|
}]
|
|
2461
|
-
}], ctorParameters: function () { return [{ type: ChannelService }, { type: NotificationService }, { type: ChatClientService }]; } });
|
|
2529
|
+
}], ctorParameters: function () { return [{ type: ChannelService }, { type: NotificationService }, { type: ChatClientService }, { type: MessageService }]; } });
|
|
2462
2530
|
|
|
2463
2531
|
/**
|
|
2464
2532
|
* The `AttachmentConfigurationService` provides customization for certain attributes of attachments displayed inside the message component. If you're using your own CDN, you can integrate resizing features of it by providing your own handlers.
|
|
@@ -3151,6 +3219,14 @@ class CustomTemplatesService {
|
|
|
3151
3219
|
*
|
|
3152
3220
|
*/
|
|
3153
3221
|
this.channelPreviewInfoTemplate$ = new BehaviorSubject(undefined);
|
|
3222
|
+
/**
|
|
3223
|
+
* The template used to display custom attachment previews in the [message input component](../../components/MessageInputComponent.mdx)
|
|
3224
|
+
*/
|
|
3225
|
+
this.customAttachmentPreviewListTemplate$ = new BehaviorSubject(undefined);
|
|
3226
|
+
/**
|
|
3227
|
+
* The template used to display custom attachments in the [message component](../../components/MessageComponent.mdx)
|
|
3228
|
+
*/
|
|
3229
|
+
this.customAttachmentListTemplate$ = new BehaviorSubject(undefined);
|
|
3154
3230
|
}
|
|
3155
3231
|
}
|
|
3156
3232
|
CustomTemplatesService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: CustomTemplatesService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
@@ -4023,30 +4099,6 @@ const isOnSeparateDate = (date1, date2) => {
|
|
|
4023
4099
|
return false;
|
|
4024
4100
|
};
|
|
4025
4101
|
|
|
4026
|
-
/**
|
|
4027
|
-
* The message service contains configuration options related to displaying the message content
|
|
4028
|
-
*/
|
|
4029
|
-
class MessageService {
|
|
4030
|
-
constructor() {
|
|
4031
|
-
/**
|
|
4032
|
-
* Decides if the message content should be formatted as text or HTML
|
|
4033
|
-
*
|
|
4034
|
-
* If you display messages as text the following parts are still be displayed as HTML:
|
|
4035
|
-
* - user mentions -> you can customize this with your own template using the [`customTemplatesService.mentionTemplate$`](https://getstream.io/chat/docs/sdk/angular/services/CustomTemplatesService/#mentiontemplate)
|
|
4036
|
-
* - links -> you can customize this by providing you own [`customLinkRenderer`](#customlinkrenderer) method
|
|
4037
|
-
*/
|
|
4038
|
-
this.displayAs = 'text';
|
|
4039
|
-
}
|
|
4040
|
-
}
|
|
4041
|
-
MessageService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: MessageService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
4042
|
-
MessageService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: MessageService, providedIn: 'root' });
|
|
4043
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: MessageService, decorators: [{
|
|
4044
|
-
type: Injectable,
|
|
4045
|
-
args: [{
|
|
4046
|
-
providedIn: 'root',
|
|
4047
|
-
}]
|
|
4048
|
-
}], ctorParameters: function () { return []; } });
|
|
4049
|
-
|
|
4050
4102
|
Dayjs.extend(calendar);
|
|
4051
4103
|
Dayjs.extend(relativeTime);
|
|
4052
4104
|
const parseDate = (date, format = 'date-time') => {
|
|
@@ -4690,10 +4742,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImpor
|
|
|
4690
4742
|
* The `AttachmentList` component displays the attachments of a message
|
|
4691
4743
|
*/
|
|
4692
4744
|
class AttachmentListComponent {
|
|
4693
|
-
constructor(customTemplatesService, channelService, attachmentConfigurationService) {
|
|
4745
|
+
constructor(customTemplatesService, channelService, attachmentConfigurationService, messageService) {
|
|
4694
4746
|
this.customTemplatesService = customTemplatesService;
|
|
4695
4747
|
this.channelService = channelService;
|
|
4696
4748
|
this.attachmentConfigurationService = attachmentConfigurationService;
|
|
4749
|
+
this.messageService = messageService;
|
|
4697
4750
|
/**
|
|
4698
4751
|
* The attachments to display
|
|
4699
4752
|
*/
|
|
@@ -4704,28 +4757,47 @@ class AttachmentListComponent {
|
|
|
4704
4757
|
this.imageModalStateChange = new EventEmitter();
|
|
4705
4758
|
this.class = 'str-chat__attachment-list-angular-host';
|
|
4706
4759
|
this.orderedAttachments = [];
|
|
4760
|
+
this.customAttachments = [];
|
|
4707
4761
|
this.imagesToView = [];
|
|
4708
4762
|
this.imagesToViewCurrentIndex = 0;
|
|
4709
4763
|
this.attachmentConfigurations = new Map();
|
|
4764
|
+
this.subscriptions = [];
|
|
4765
|
+
}
|
|
4766
|
+
ngOnInit() {
|
|
4767
|
+
this.subscriptions.push(this.customTemplatesService.customAttachmentListTemplate$.subscribe((t) => (this.customAttachmentsTemplate = t)));
|
|
4710
4768
|
}
|
|
4711
4769
|
ngOnChanges(changes) {
|
|
4712
4770
|
if (changes.attachments) {
|
|
4713
|
-
const
|
|
4771
|
+
const builtInAttachments = [];
|
|
4772
|
+
const customAttachments = [];
|
|
4773
|
+
this.attachments.forEach((a) => {
|
|
4774
|
+
if (this.messageService.isCustomAttachment(a)) {
|
|
4775
|
+
customAttachments.push(a);
|
|
4776
|
+
}
|
|
4777
|
+
else {
|
|
4778
|
+
builtInAttachments.push(a);
|
|
4779
|
+
}
|
|
4780
|
+
});
|
|
4781
|
+
const images = builtInAttachments.filter(this.isImage);
|
|
4714
4782
|
const containsGallery = images.length >= 2;
|
|
4715
4783
|
this.orderedAttachments = [
|
|
4716
4784
|
...(containsGallery ? this.createGallery(images) : images),
|
|
4717
|
-
...
|
|
4718
|
-
...
|
|
4719
|
-
...
|
|
4785
|
+
...builtInAttachments.filter((a) => this.isVideo(a)),
|
|
4786
|
+
...builtInAttachments.filter((a) => this.isVoiceMessage(a)),
|
|
4787
|
+
...builtInAttachments.filter((a) => this.isFile(a)),
|
|
4720
4788
|
];
|
|
4721
4789
|
this.attachmentConfigurations = new Map();
|
|
4722
4790
|
// Display link attachments only if there are no other attachments
|
|
4723
4791
|
// Giphy-s always sent without other attachments
|
|
4724
4792
|
if (this.orderedAttachments.length === 0) {
|
|
4725
|
-
this.orderedAttachments.push(...
|
|
4793
|
+
this.orderedAttachments.push(...builtInAttachments.filter((a) => this.isCard(a)));
|
|
4726
4794
|
}
|
|
4795
|
+
this.customAttachments = customAttachments;
|
|
4727
4796
|
}
|
|
4728
4797
|
}
|
|
4798
|
+
ngOnDestroy() {
|
|
4799
|
+
this.subscriptions.forEach((s) => s.unsubscribe());
|
|
4800
|
+
}
|
|
4729
4801
|
trackByUrl(_, attachment) {
|
|
4730
4802
|
return (attachment.image_url ||
|
|
4731
4803
|
attachment.img_url ||
|
|
@@ -4857,12 +4929,12 @@ class AttachmentListComponent {
|
|
|
4857
4929
|
this.imagesToView = [];
|
|
4858
4930
|
}
|
|
4859
4931
|
}
|
|
4860
|
-
AttachmentListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: AttachmentListComponent, deps: [{ token: CustomTemplatesService }, { token: ChannelService }, { token: AttachmentConfigurationService }], target: i0.ɵɵFactoryTarget.Component });
|
|
4861
|
-
AttachmentListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: AttachmentListComponent, selector: "stream-attachment-list", inputs: { messageId: "messageId", parentMessageId: "parentMessageId", attachments: "attachments" }, outputs: { imageModalStateChange: "imageModalStateChange" }, host: { properties: { "class": "this.class" } }, viewQueries: [{ propertyName: "modalContent", first: true, predicate: ["modalContent"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<div *ngIf=\"orderedAttachments.length > 0\" class=\"str-chat__attachment-list\">\n <ng-container\n *ngFor=\"let attachment of orderedAttachments; trackBy: trackByUrl\"\n >\n <div\n data-testclass=\"attachment-container\"\n class=\"str-chat__message-attachment str-chat__message-attachment--{{\n attachment.type\n }} str-chat__message-attachment-dynamic-size\"\n [class.str-chat__message-attachment--card]=\"isCard(attachment)\"\n [class.str-chat-angular__message-attachment-file-single]=\"\n isFile(attachment)\n \"\n [class.str-chat__message-attachment--voice-recording]=\"\n isVoiceMessage(attachment)\n \"\n [class.str-chat__message-attachment-with-actions]=\"\n attachment.actions && attachment.actions.length > 0\n \"\n [class.str-chat__message-attachment--svg-image]=\"isSvg(attachment)\"\n >\n <ng-container *ngIf=\"isImage(attachment)\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.imageAttachmentTemplate$ | async) ||\n defaultImage;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultImage let-attachmentContext=\"attachment\">\n <img\n #imgElement\n class=\"str-chat__message-attachment--img\"\n data-testclass=\"image\"\n [src]=\"\n getImageAttachmentConfiguration(\n attachmentContext,\n 'single',\n imgElement\n ).url\n \"\n [alt]=\"attachmentContext?.fallback\"\n [ngStyle]=\"{\n height: getImageAttachmentConfiguration(\n attachmentContext,\n 'single',\n imgElement\n ).height,\n width: getImageAttachmentConfiguration(\n attachmentContext,\n 'single',\n imgElement\n ).width,\n '--original-height': getImageAttachmentConfiguration(\n attachmentContext,\n 'single',\n imgElement\n ).originalHeight,\n '--original-width': getImageAttachmentConfiguration(\n attachmentContext,\n 'single',\n imgElement\n ).originalWidth\n }\"\n (click)=\"openImageModal([attachmentContext])\"\n (keyup.enter)=\"openImageModal([attachmentContext])\"\n />\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"isGallery(attachment)\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.galleryAttachmentTemplate$ | async) ||\n defaultGallery;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultGallery let-attachmentContext=\"attachment\">\n <div\n class=\"str-chat__gallery\"\n data-testid=\"image-gallery\"\n [class.str-chat__gallery--square]=\"\n (attachmentContext?.images)!.length > 3\n \"\n [class.str-chat__gallery-two-rows]=\"\n (attachmentContext?.images)!.length > 2\n \"\n >\n <ng-container\n *ngFor=\"\n let galleryImage of attachmentContext.images;\n let index = index;\n let isLast = last;\n trackBy: trackByImageUrl\n \"\n >\n <button\n *ngIf=\"index < 3 || (index === 3 && isLast)\"\n class=\"str-chat__gallery-image\"\n data-testclass=\"gallery-image\"\n [class.str-chat__message-attachment--svg-image]=\"\n isSvg(galleryImage)\n \"\n (click)=\"openImageModal(attachmentContext.images!, index)\"\n (keyup.enter)=\"openImageModal(attachmentContext.images!, index)\"\n >\n <img\n #imgElement\n fetchpriority=\"low\"\n loading=\"lazy\"\n [src]=\"\n getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n imgElement\n ).url\n \"\n [alt]=\"galleryImage.fallback\"\n [style.--original-height]=\"\n getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n imgElement\n ).originalHeight\n \"\n [style.--original-width]=\"\n getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n imgElement\n ).originalWidth\n \"\n [ngStyle]=\"{\n height: getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n imgElement\n ).height,\n width: getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n imgElement\n ).width\n }\"\n />\n </button>\n <button\n *ngIf=\"index === 3 && !isLast\"\n #element\n class=\"str-chat__gallery-placeholder\"\n data-testclass=\"gallery-image\"\n data-testid=\"more-image-button\"\n [class.str-chat__message-attachment--svg-image]=\"\n isSvg(galleryImage)\n \"\n [ngStyle]=\"{\n 'background-image':\n 'url(' +\n getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n element\n ).url +\n ')',\n height: getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n element\n ).height,\n width: getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n element\n ).width,\n '--original-height': getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n element\n ).originalHeight,\n '--original-width': getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n element\n ).originalWidth\n }\"\n (click)=\"openImageModal(attachmentContext.images!, index)\"\n (keyup.enter)=\"openImageModal(attachmentContext.images!, index)\"\n >\n <p\n [innerHTML]=\"\n 'streamChat.{{ imageCount }} more'\n | translate\n : { imageCount: attachmentContext!.images!.length - 4 }\n \"\n ></p>\n </button>\n </ng-container>\n </div>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"isVideo(attachment)\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.videoAttachmentTemplate$ | async) ||\n defaultVideo;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultVideo let-attachmentContext=\"attachment\">\n <div\n class=\"str-chat__player-wrapper\"\n data-testclass=\"video-attachment-parent\"\n [style.--original-height]=\"\n getVideoAttachmentConfiguration(attachmentContext, videoElement)\n .originalHeight\n \"\n [style.--original-width]=\"\n getVideoAttachmentConfiguration(attachmentContext, videoElement)\n .originalWidth\n \"\n [ngStyle]=\"{\n height: getVideoAttachmentConfiguration(\n attachmentContext,\n videoElement\n ).height,\n width: getVideoAttachmentConfiguration(\n attachmentContext,\n videoElement\n ).width\n }\"\n >\n <video\n #videoElement\n class=\"str-chat__video-angular\"\n controls\n data-testclass=\"video-attachment\"\n [src]=\"\n getVideoAttachmentConfiguration(attachmentContext, videoElement)\n .url\n \"\n [poster]=\"\n getVideoAttachmentConfiguration(attachmentContext, videoElement)\n .thumbUrl\n \"\n ></video>\n </div>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"isFile(attachment)\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.fileAttachmentTemplate$ | async) ||\n defaultFile;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultFile let-attachmentContext=\"attachment\">\n <div\n class=\"str-chat__message-attachment-file--item str-chat-angular__message-attachment-file-single\"\n >\n <stream-icon-placeholder\n class=\"str-chat__attachment-type-icon\"\n icon=\"unspecified-filetype\"\n ></stream-icon-placeholder>\n <div class=\"str-chat__message-attachment-file--item-text\">\n <a\n class=\"str-chat__message-attachment-file--item-first-row\"\n data-testclass=\"file-link\"\n target=\"_blank\"\n href=\"{{ attachmentContext.asset_url }}\"\n >\n <div\n data-testclass=\"file-title\"\n class=\"str-chat__message-attachment-file--item-name\"\n >\n {{ attachmentContext.title }}\n </div>\n <stream-icon-placeholder\n class=\"str-chat__message-attachment-download-icon\"\n icon=\"download\"\n ></stream-icon-placeholder>\n </a>\n <span\n *ngIf=\"hasFileSize(attachmentContext)\"\n class=\"str-chat__message-attachment-file--item-size\"\n data-testclass=\"size\"\n >{{ getFileSize(attachmentContext) }}</span\n >\n </div>\n </div>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"isVoiceMessage(attachment)\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.voiceRecordingAttachmentTemplate$\n | async) || defaultRecording;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultRecording>\n <stream-voice-recording\n data-testclass=\"voice-recording\"\n [attachment]=\"attachment\"\n ></stream-voice-recording>\n </ng-template>\n </ng-container>\n <ng-container\n *ngIf=\"\n isCard(attachment) &&\n getCardAttachmentConfiguration(attachment) as attachmentConfiguration\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.cardAttachmentTemplate$ | async) ||\n defaultCard;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultCard let-attachmentContext=\"attachment\">\n <div\n class=\"str-chat__message-attachment-card str-chat__message-attachment-card--{{\n attachmentContext.type\n }}\"\n >\n <div\n *ngIf=\"attachmentConfiguration.url\"\n class=\"str-chat__message-attachment-card--header\"\n >\n <img\n fetchpriority=\"low\"\n loading=\"lazy\"\n data-testclass=\"card-img\"\n alt=\"{{ attachmentConfiguration.url }}\"\n src=\"{{ attachmentConfiguration.url }}\"\n [ngStyle]=\"{\n height: attachmentConfiguration.height,\n width: attachmentConfiguration.width\n }\"\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=\"attachmentContext.title\"\n data-testclass=\"card-title\"\n class=\"str-chat__message-attachment-card--title\"\n >\n {{ attachmentContext.title }}\n </div>\n <div\n *ngIf=\"attachmentContext.text\"\n class=\"str-chat__message-attachment-card--text\"\n data-testclass=\"card-text\"\n >\n {{ attachmentContext.text }}\n </div>\n <a\n *ngIf=\"\n attachmentContext.title_link ||\n attachmentContext.og_scrape_url\n \"\n class=\"str-chat__message-attachment-card--url\"\n data-testclass=\"url-link\"\n noopener\n noreferrer\n target=\"_blank\"\n href=\"{{\n attachmentContext.title_link ||\n attachmentContext.og_scrape_url\n }}\"\n >\n {{\n trimUrl(\n attachmentContext.title_link ||\n attachmentContext.og_scrape_url\n )\n }}\n </a>\n </div>\n </div>\n </div>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"attachment.actions && attachment.actions.length > 0\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.attachmentActionsTemplate$ | async) ||\n defaultActions;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultActions let-attachmentContext=\"attachment\">\n <div class=\"str-chat__message-attachment-actions\">\n <div class=\"str-chat__message-attachment-actions-form\">\n <button\n *ngFor=\"\n let action of attachmentContext.actions;\n trackBy: trackByActionValue\n \"\n data-testclass=\"attachment-action\"\n class=\"str-chat__message-attachment-actions-button str-chat__message-attachment-actions-button--{{\n action.style\n }}\"\n (click)=\"sendAction(action)\"\n (keyup.enter)=\"sendAction(action)\"\n >\n {{ action.text }}\n </button>\n </div>\n </div>\n </ng-template>\n </ng-container>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"imagesToView && imagesToView.length > 0\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.modalTemplate$ | async) || defaultModal;\n context: getModalContext()\n \"\n ></ng-container>\n </ng-container>\n</div>\n\n<ng-template\n #defaultModal\n let-isOpen=\"isOpen\"\n let-isOpenChangeHandler=\"isOpenChangeHandler\"\n let-content=\"content\"\n>\n <stream-modal\n class=\"stream-chat-angular__image-modal-host\"\n [isOpen]=\"isOpen\"\n [content]=\"content\"\n (isOpenChange)=\"isOpenChangeHandler($event)\"\n >\n </stream-modal>\n</ng-template>\n\n<ng-template #modalContent>\n <div class=\"stream-chat-angular__image-modal str-chat__image-carousel\">\n <img\n #imgElement\n class=\"stream-chat-angular__image-modal-image str-chat__image-carousel-image\"\n data-testid=\"modal-image\"\n [src]=\"\n getCarouselImageAttachmentConfiguration(\n imagesToView[imagesToViewCurrentIndex],\n imgElement\n ).url\n \"\n [style.--original-height]=\"\n getCarouselImageAttachmentConfiguration(\n imagesToView[imagesToViewCurrentIndex],\n imgElement\n ).originalHeight\n \"\n [style.--original-width]=\"\n getCarouselImageAttachmentConfiguration(\n imagesToView[imagesToViewCurrentIndex],\n imgElement\n ).originalWidth\n \"\n [alt]=\"imagesToView[imagesToViewCurrentIndex].fallback\"\n [ngStyle]=\"{\n width: getCarouselImageAttachmentConfiguration(\n imagesToView[imagesToViewCurrentIndex],\n imgElement\n ).width,\n height: getCarouselImageAttachmentConfiguration(\n imagesToView[imagesToViewCurrentIndex],\n imgElement\n ).height\n }\"\n />\n <div>\n <button\n class=\"stream-chat-angular__image-modal-stepper str-chat__image-carousel-stepper str-chat__image-carousel-stepper-prev\"\n data-testid=\"image-modal-prev\"\n type=\"button\"\n [ngStyle]=\"{\n visibility: isImageModalPrevButtonVisible ? 'visible' : 'hidden'\n }\"\n (click)=\"stepImages(-1)\"\n (keyup.enter)=\"stepImages(-1)\"\n >\n <stream-icon-placeholder icon=\"arrow-left\"></stream-icon-placeholder>\n </button>\n <button\n class=\"stream-chat-angular__image-modal-stepper str-chat__image-carousel-stepper str-chat__image-carousel-stepper-next\"\n type=\"button\"\n data-testid=\"image-modal-next\"\n [ngStyle]=\"{\n visibility: isImageModalNextButtonVisible ? 'visible' : 'hidden'\n }\"\n (click)=\"stepImages(1)\"\n (keyup.enter)=\"stepImages(1)\"\n >\n <stream-icon-placeholder icon=\"arrow-right\"></stream-icon-placeholder>\n </button>\n </div>\n </div>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i4.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: VoiceRecordingComponent, selector: "stream-voice-recording", inputs: ["attachment"] }, { kind: "component", type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon"] }, { kind: "component", type: ModalComponent, selector: "stream-modal", inputs: ["isOpen", "content"], outputs: ["isOpenChange"] }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }, { kind: "pipe", type: i10.TranslatePipe, name: "translate" }] });
|
|
4932
|
+
AttachmentListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: AttachmentListComponent, deps: [{ token: CustomTemplatesService }, { token: ChannelService }, { token: AttachmentConfigurationService }, { token: MessageService }], target: i0.ɵɵFactoryTarget.Component });
|
|
4933
|
+
AttachmentListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: AttachmentListComponent, selector: "stream-attachment-list", inputs: { messageId: "messageId", parentMessageId: "parentMessageId", attachments: "attachments" }, outputs: { imageModalStateChange: "imageModalStateChange" }, host: { properties: { "class": "this.class" } }, viewQueries: [{ propertyName: "modalContent", first: true, predicate: ["modalContent"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<div\n *ngIf=\"\n orderedAttachments.length > 0 ||\n (customAttachments.length > 0 && customAttachmentsTemplate)\n \"\n class=\"str-chat__attachment-list\"\n>\n <ng-container\n *ngFor=\"let attachment of orderedAttachments; trackBy: trackByUrl\"\n >\n <div\n data-testclass=\"attachment-container\"\n class=\"str-chat__message-attachment str-chat__message-attachment--{{\n attachment.type\n }} str-chat__message-attachment-dynamic-size\"\n [class.str-chat__message-attachment--card]=\"isCard(attachment)\"\n [class.str-chat-angular__message-attachment-file-single]=\"\n isFile(attachment)\n \"\n [class.str-chat__message-attachment--voice-recording]=\"\n isVoiceMessage(attachment)\n \"\n [class.str-chat__message-attachment-with-actions]=\"\n attachment.actions && attachment.actions.length > 0\n \"\n [class.str-chat__message-attachment--svg-image]=\"isSvg(attachment)\"\n >\n <ng-container *ngIf=\"isImage(attachment)\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.imageAttachmentTemplate$ | async) ||\n defaultImage;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultImage let-attachmentContext=\"attachment\">\n <img\n #imgElement\n class=\"str-chat__message-attachment--img\"\n data-testclass=\"image\"\n [src]=\"\n getImageAttachmentConfiguration(\n attachmentContext,\n 'single',\n imgElement\n ).url\n \"\n [alt]=\"attachmentContext?.fallback\"\n [ngStyle]=\"{\n height: getImageAttachmentConfiguration(\n attachmentContext,\n 'single',\n imgElement\n ).height,\n width: getImageAttachmentConfiguration(\n attachmentContext,\n 'single',\n imgElement\n ).width,\n '--original-height': getImageAttachmentConfiguration(\n attachmentContext,\n 'single',\n imgElement\n ).originalHeight,\n '--original-width': getImageAttachmentConfiguration(\n attachmentContext,\n 'single',\n imgElement\n ).originalWidth\n }\"\n (click)=\"openImageModal([attachmentContext])\"\n (keyup.enter)=\"openImageModal([attachmentContext])\"\n />\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"isGallery(attachment)\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.galleryAttachmentTemplate$ | async) ||\n defaultGallery;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultGallery let-attachmentContext=\"attachment\">\n <div\n class=\"str-chat__gallery\"\n data-testid=\"image-gallery\"\n [class.str-chat__gallery--square]=\"\n (attachmentContext?.images)!.length > 3\n \"\n [class.str-chat__gallery-two-rows]=\"\n (attachmentContext?.images)!.length > 2\n \"\n >\n <ng-container\n *ngFor=\"\n let galleryImage of attachmentContext.images;\n let index = index;\n let isLast = last;\n trackBy: trackByImageUrl\n \"\n >\n <button\n *ngIf=\"index < 3 || (index === 3 && isLast)\"\n class=\"str-chat__gallery-image\"\n data-testclass=\"gallery-image\"\n [class.str-chat__message-attachment--svg-image]=\"\n isSvg(galleryImage)\n \"\n (click)=\"openImageModal(attachmentContext.images!, index)\"\n (keyup.enter)=\"openImageModal(attachmentContext.images!, index)\"\n >\n <img\n #imgElement\n fetchpriority=\"low\"\n loading=\"lazy\"\n [src]=\"\n getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n imgElement\n ).url\n \"\n [alt]=\"galleryImage.fallback\"\n [style.--original-height]=\"\n getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n imgElement\n ).originalHeight\n \"\n [style.--original-width]=\"\n getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n imgElement\n ).originalWidth\n \"\n [ngStyle]=\"{\n height: getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n imgElement\n ).height,\n width: getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n imgElement\n ).width\n }\"\n />\n </button>\n <button\n *ngIf=\"index === 3 && !isLast\"\n #element\n class=\"str-chat__gallery-placeholder\"\n data-testclass=\"gallery-image\"\n data-testid=\"more-image-button\"\n [class.str-chat__message-attachment--svg-image]=\"\n isSvg(galleryImage)\n \"\n [ngStyle]=\"{\n 'background-image':\n 'url(' +\n getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n element\n ).url +\n ')',\n height: getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n element\n ).height,\n width: getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n element\n ).width,\n '--original-height': getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n element\n ).originalHeight,\n '--original-width': getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n element\n ).originalWidth\n }\"\n (click)=\"openImageModal(attachmentContext.images!, index)\"\n (keyup.enter)=\"openImageModal(attachmentContext.images!, index)\"\n >\n <p\n [innerHTML]=\"\n 'streamChat.{{ imageCount }} more'\n | translate\n : { imageCount: attachmentContext!.images!.length - 4 }\n \"\n ></p>\n </button>\n </ng-container>\n </div>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"isVideo(attachment)\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.videoAttachmentTemplate$ | async) ||\n defaultVideo;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultVideo let-attachmentContext=\"attachment\">\n <div\n class=\"str-chat__player-wrapper\"\n data-testclass=\"video-attachment-parent\"\n [style.--original-height]=\"\n getVideoAttachmentConfiguration(attachmentContext, videoElement)\n .originalHeight\n \"\n [style.--original-width]=\"\n getVideoAttachmentConfiguration(attachmentContext, videoElement)\n .originalWidth\n \"\n [ngStyle]=\"{\n height: getVideoAttachmentConfiguration(\n attachmentContext,\n videoElement\n ).height,\n width: getVideoAttachmentConfiguration(\n attachmentContext,\n videoElement\n ).width\n }\"\n >\n <video\n #videoElement\n class=\"str-chat__video-angular\"\n controls\n data-testclass=\"video-attachment\"\n [src]=\"\n getVideoAttachmentConfiguration(attachmentContext, videoElement)\n .url\n \"\n [poster]=\"\n getVideoAttachmentConfiguration(attachmentContext, videoElement)\n .thumbUrl\n \"\n ></video>\n </div>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"isFile(attachment)\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.fileAttachmentTemplate$ | async) ||\n defaultFile;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultFile let-attachmentContext=\"attachment\">\n <div\n class=\"str-chat__message-attachment-file--item str-chat-angular__message-attachment-file-single\"\n >\n <stream-icon-placeholder\n class=\"str-chat__attachment-type-icon\"\n icon=\"unspecified-filetype\"\n ></stream-icon-placeholder>\n <div class=\"str-chat__message-attachment-file--item-text\">\n <a\n class=\"str-chat__message-attachment-file--item-first-row\"\n data-testclass=\"file-link\"\n target=\"_blank\"\n href=\"{{ attachmentContext.asset_url }}\"\n >\n <div\n data-testclass=\"file-title\"\n class=\"str-chat__message-attachment-file--item-name\"\n >\n {{ attachmentContext.title }}\n </div>\n <stream-icon-placeholder\n class=\"str-chat__message-attachment-download-icon\"\n icon=\"download\"\n ></stream-icon-placeholder>\n </a>\n <span\n *ngIf=\"hasFileSize(attachmentContext)\"\n class=\"str-chat__message-attachment-file--item-size\"\n data-testclass=\"size\"\n >{{ getFileSize(attachmentContext) }}</span\n >\n </div>\n </div>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"isVoiceMessage(attachment)\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.voiceRecordingAttachmentTemplate$\n | async) || defaultRecording;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultRecording>\n <stream-voice-recording\n data-testclass=\"voice-recording\"\n [attachment]=\"attachment\"\n ></stream-voice-recording>\n </ng-template>\n </ng-container>\n <ng-container\n *ngIf=\"\n isCard(attachment) &&\n getCardAttachmentConfiguration(attachment) as attachmentConfiguration\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.cardAttachmentTemplate$ | async) ||\n defaultCard;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultCard let-attachmentContext=\"attachment\">\n <div\n class=\"str-chat__message-attachment-card str-chat__message-attachment-card--{{\n attachmentContext.type\n }}\"\n >\n <div\n *ngIf=\"attachmentConfiguration.url\"\n class=\"str-chat__message-attachment-card--header\"\n >\n <img\n fetchpriority=\"low\"\n loading=\"lazy\"\n data-testclass=\"card-img\"\n alt=\"{{ attachmentConfiguration.url }}\"\n src=\"{{ attachmentConfiguration.url }}\"\n [ngStyle]=\"{\n height: attachmentConfiguration.height,\n width: attachmentConfiguration.width\n }\"\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=\"attachmentContext.title\"\n data-testclass=\"card-title\"\n class=\"str-chat__message-attachment-card--title\"\n >\n {{ attachmentContext.title }}\n </div>\n <div\n *ngIf=\"attachmentContext.text\"\n class=\"str-chat__message-attachment-card--text\"\n data-testclass=\"card-text\"\n >\n {{ attachmentContext.text }}\n </div>\n <a\n *ngIf=\"\n attachmentContext.title_link ||\n attachmentContext.og_scrape_url\n \"\n class=\"str-chat__message-attachment-card--url\"\n data-testclass=\"url-link\"\n noopener\n noreferrer\n target=\"_blank\"\n href=\"{{\n attachmentContext.title_link ||\n attachmentContext.og_scrape_url\n }}\"\n >\n {{\n trimUrl(\n attachmentContext.title_link ||\n attachmentContext.og_scrape_url\n )\n }}\n </a>\n </div>\n </div>\n </div>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"attachment.actions && attachment.actions.length > 0\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.attachmentActionsTemplate$ | async) ||\n defaultActions;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultActions let-attachmentContext=\"attachment\">\n <div class=\"str-chat__message-attachment-actions\">\n <div class=\"str-chat__message-attachment-actions-form\">\n <button\n *ngFor=\"\n let action of attachmentContext.actions;\n trackBy: trackByActionValue\n \"\n data-testclass=\"attachment-action\"\n class=\"str-chat__message-attachment-actions-button str-chat__message-attachment-actions-button--{{\n action.style\n }}\"\n (click)=\"sendAction(action)\"\n (keyup.enter)=\"sendAction(action)\"\n >\n {{ action.text }}\n </button>\n </div>\n </div>\n </ng-template>\n </ng-container>\n </div>\n </ng-container>\n <ng-container *ngIf=\"customAttachmentsTemplate\">\n <ng-template\n *ngTemplateOutlet=\"\n customAttachmentsTemplate;\n context: {\n messageId: messageId,\n parentMessageId: parentMessageId,\n attachments: customAttachments\n }\n \"\n ></ng-template>\n </ng-container>\n\n <ng-container *ngIf=\"imagesToView && imagesToView.length > 0\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.modalTemplate$ | async) || defaultModal;\n context: getModalContext()\n \"\n ></ng-container>\n </ng-container>\n</div>\n\n<ng-template\n #defaultModal\n let-isOpen=\"isOpen\"\n let-isOpenChangeHandler=\"isOpenChangeHandler\"\n let-content=\"content\"\n>\n <stream-modal\n class=\"stream-chat-angular__image-modal-host\"\n [isOpen]=\"isOpen\"\n [content]=\"content\"\n (isOpenChange)=\"isOpenChangeHandler($event)\"\n >\n </stream-modal>\n</ng-template>\n\n<ng-template #modalContent>\n <div class=\"stream-chat-angular__image-modal str-chat__image-carousel\">\n <img\n #imgElement\n class=\"stream-chat-angular__image-modal-image str-chat__image-carousel-image\"\n data-testid=\"modal-image\"\n [src]=\"\n getCarouselImageAttachmentConfiguration(\n imagesToView[imagesToViewCurrentIndex],\n imgElement\n ).url\n \"\n [style.--original-height]=\"\n getCarouselImageAttachmentConfiguration(\n imagesToView[imagesToViewCurrentIndex],\n imgElement\n ).originalHeight\n \"\n [style.--original-width]=\"\n getCarouselImageAttachmentConfiguration(\n imagesToView[imagesToViewCurrentIndex],\n imgElement\n ).originalWidth\n \"\n [alt]=\"imagesToView[imagesToViewCurrentIndex].fallback\"\n [ngStyle]=\"{\n width: getCarouselImageAttachmentConfiguration(\n imagesToView[imagesToViewCurrentIndex],\n imgElement\n ).width,\n height: getCarouselImageAttachmentConfiguration(\n imagesToView[imagesToViewCurrentIndex],\n imgElement\n ).height\n }\"\n />\n <div>\n <button\n class=\"stream-chat-angular__image-modal-stepper str-chat__image-carousel-stepper str-chat__image-carousel-stepper-prev\"\n data-testid=\"image-modal-prev\"\n type=\"button\"\n [ngStyle]=\"{\n visibility: isImageModalPrevButtonVisible ? 'visible' : 'hidden'\n }\"\n (click)=\"stepImages(-1)\"\n (keyup.enter)=\"stepImages(-1)\"\n >\n <stream-icon-placeholder icon=\"arrow-left\"></stream-icon-placeholder>\n </button>\n <button\n class=\"stream-chat-angular__image-modal-stepper str-chat__image-carousel-stepper str-chat__image-carousel-stepper-next\"\n type=\"button\"\n data-testid=\"image-modal-next\"\n [ngStyle]=\"{\n visibility: isImageModalNextButtonVisible ? 'visible' : 'hidden'\n }\"\n (click)=\"stepImages(1)\"\n (keyup.enter)=\"stepImages(1)\"\n >\n <stream-icon-placeholder icon=\"arrow-right\"></stream-icon-placeholder>\n </button>\n </div>\n </div>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i4.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: VoiceRecordingComponent, selector: "stream-voice-recording", inputs: ["attachment"] }, { kind: "component", type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon"] }, { kind: "component", type: ModalComponent, selector: "stream-modal", inputs: ["isOpen", "content"], outputs: ["isOpenChange"] }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }, { kind: "pipe", type: i10.TranslatePipe, name: "translate" }] });
|
|
4862
4934
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: AttachmentListComponent, decorators: [{
|
|
4863
4935
|
type: Component,
|
|
4864
|
-
args: [{ selector: 'stream-attachment-list', template: "<div *ngIf=\"orderedAttachments.length > 0\" class=\"str-chat__attachment-list\">\n <ng-container\n *ngFor=\"let attachment of orderedAttachments; trackBy: trackByUrl\"\n >\n <div\n data-testclass=\"attachment-container\"\n class=\"str-chat__message-attachment str-chat__message-attachment--{{\n attachment.type\n }} str-chat__message-attachment-dynamic-size\"\n [class.str-chat__message-attachment--card]=\"isCard(attachment)\"\n [class.str-chat-angular__message-attachment-file-single]=\"\n isFile(attachment)\n \"\n [class.str-chat__message-attachment--voice-recording]=\"\n isVoiceMessage(attachment)\n \"\n [class.str-chat__message-attachment-with-actions]=\"\n attachment.actions && attachment.actions.length > 0\n \"\n [class.str-chat__message-attachment--svg-image]=\"isSvg(attachment)\"\n >\n <ng-container *ngIf=\"isImage(attachment)\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.imageAttachmentTemplate$ | async) ||\n defaultImage;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultImage let-attachmentContext=\"attachment\">\n <img\n #imgElement\n class=\"str-chat__message-attachment--img\"\n data-testclass=\"image\"\n [src]=\"\n getImageAttachmentConfiguration(\n attachmentContext,\n 'single',\n imgElement\n ).url\n \"\n [alt]=\"attachmentContext?.fallback\"\n [ngStyle]=\"{\n height: getImageAttachmentConfiguration(\n attachmentContext,\n 'single',\n imgElement\n ).height,\n width: getImageAttachmentConfiguration(\n attachmentContext,\n 'single',\n imgElement\n ).width,\n '--original-height': getImageAttachmentConfiguration(\n attachmentContext,\n 'single',\n imgElement\n ).originalHeight,\n '--original-width': getImageAttachmentConfiguration(\n attachmentContext,\n 'single',\n imgElement\n ).originalWidth\n }\"\n (click)=\"openImageModal([attachmentContext])\"\n (keyup.enter)=\"openImageModal([attachmentContext])\"\n />\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"isGallery(attachment)\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.galleryAttachmentTemplate$ | async) ||\n defaultGallery;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultGallery let-attachmentContext=\"attachment\">\n <div\n class=\"str-chat__gallery\"\n data-testid=\"image-gallery\"\n [class.str-chat__gallery--square]=\"\n (attachmentContext?.images)!.length > 3\n \"\n [class.str-chat__gallery-two-rows]=\"\n (attachmentContext?.images)!.length > 2\n \"\n >\n <ng-container\n *ngFor=\"\n let galleryImage of attachmentContext.images;\n let index = index;\n let isLast = last;\n trackBy: trackByImageUrl\n \"\n >\n <button\n *ngIf=\"index < 3 || (index === 3 && isLast)\"\n class=\"str-chat__gallery-image\"\n data-testclass=\"gallery-image\"\n [class.str-chat__message-attachment--svg-image]=\"\n isSvg(galleryImage)\n \"\n (click)=\"openImageModal(attachmentContext.images!, index)\"\n (keyup.enter)=\"openImageModal(attachmentContext.images!, index)\"\n >\n <img\n #imgElement\n fetchpriority=\"low\"\n loading=\"lazy\"\n [src]=\"\n getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n imgElement\n ).url\n \"\n [alt]=\"galleryImage.fallback\"\n [style.--original-height]=\"\n getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n imgElement\n ).originalHeight\n \"\n [style.--original-width]=\"\n getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n imgElement\n ).originalWidth\n \"\n [ngStyle]=\"{\n height: getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n imgElement\n ).height,\n width: getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n imgElement\n ).width\n }\"\n />\n </button>\n <button\n *ngIf=\"index === 3 && !isLast\"\n #element\n class=\"str-chat__gallery-placeholder\"\n data-testclass=\"gallery-image\"\n data-testid=\"more-image-button\"\n [class.str-chat__message-attachment--svg-image]=\"\n isSvg(galleryImage)\n \"\n [ngStyle]=\"{\n 'background-image':\n 'url(' +\n getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n element\n ).url +\n ')',\n height: getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n element\n ).height,\n width: getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n element\n ).width,\n '--original-height': getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n element\n ).originalHeight,\n '--original-width': getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n element\n ).originalWidth\n }\"\n (click)=\"openImageModal(attachmentContext.images!, index)\"\n (keyup.enter)=\"openImageModal(attachmentContext.images!, index)\"\n >\n <p\n [innerHTML]=\"\n 'streamChat.{{ imageCount }} more'\n | translate\n : { imageCount: attachmentContext!.images!.length - 4 }\n \"\n ></p>\n </button>\n </ng-container>\n </div>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"isVideo(attachment)\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.videoAttachmentTemplate$ | async) ||\n defaultVideo;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultVideo let-attachmentContext=\"attachment\">\n <div\n class=\"str-chat__player-wrapper\"\n data-testclass=\"video-attachment-parent\"\n [style.--original-height]=\"\n getVideoAttachmentConfiguration(attachmentContext, videoElement)\n .originalHeight\n \"\n [style.--original-width]=\"\n getVideoAttachmentConfiguration(attachmentContext, videoElement)\n .originalWidth\n \"\n [ngStyle]=\"{\n height: getVideoAttachmentConfiguration(\n attachmentContext,\n videoElement\n ).height,\n width: getVideoAttachmentConfiguration(\n attachmentContext,\n videoElement\n ).width\n }\"\n >\n <video\n #videoElement\n class=\"str-chat__video-angular\"\n controls\n data-testclass=\"video-attachment\"\n [src]=\"\n getVideoAttachmentConfiguration(attachmentContext, videoElement)\n .url\n \"\n [poster]=\"\n getVideoAttachmentConfiguration(attachmentContext, videoElement)\n .thumbUrl\n \"\n ></video>\n </div>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"isFile(attachment)\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.fileAttachmentTemplate$ | async) ||\n defaultFile;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultFile let-attachmentContext=\"attachment\">\n <div\n class=\"str-chat__message-attachment-file--item str-chat-angular__message-attachment-file-single\"\n >\n <stream-icon-placeholder\n class=\"str-chat__attachment-type-icon\"\n icon=\"unspecified-filetype\"\n ></stream-icon-placeholder>\n <div class=\"str-chat__message-attachment-file--item-text\">\n <a\n class=\"str-chat__message-attachment-file--item-first-row\"\n data-testclass=\"file-link\"\n target=\"_blank\"\n href=\"{{ attachmentContext.asset_url }}\"\n >\n <div\n data-testclass=\"file-title\"\n class=\"str-chat__message-attachment-file--item-name\"\n >\n {{ attachmentContext.title }}\n </div>\n <stream-icon-placeholder\n class=\"str-chat__message-attachment-download-icon\"\n icon=\"download\"\n ></stream-icon-placeholder>\n </a>\n <span\n *ngIf=\"hasFileSize(attachmentContext)\"\n class=\"str-chat__message-attachment-file--item-size\"\n data-testclass=\"size\"\n >{{ getFileSize(attachmentContext) }}</span\n >\n </div>\n </div>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"isVoiceMessage(attachment)\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.voiceRecordingAttachmentTemplate$\n | async) || defaultRecording;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultRecording>\n <stream-voice-recording\n data-testclass=\"voice-recording\"\n [attachment]=\"attachment\"\n ></stream-voice-recording>\n </ng-template>\n </ng-container>\n <ng-container\n *ngIf=\"\n isCard(attachment) &&\n getCardAttachmentConfiguration(attachment) as attachmentConfiguration\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.cardAttachmentTemplate$ | async) ||\n defaultCard;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultCard let-attachmentContext=\"attachment\">\n <div\n class=\"str-chat__message-attachment-card str-chat__message-attachment-card--{{\n attachmentContext.type\n }}\"\n >\n <div\n *ngIf=\"attachmentConfiguration.url\"\n class=\"str-chat__message-attachment-card--header\"\n >\n <img\n fetchpriority=\"low\"\n loading=\"lazy\"\n data-testclass=\"card-img\"\n alt=\"{{ attachmentConfiguration.url }}\"\n src=\"{{ attachmentConfiguration.url }}\"\n [ngStyle]=\"{\n height: attachmentConfiguration.height,\n width: attachmentConfiguration.width\n }\"\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=\"attachmentContext.title\"\n data-testclass=\"card-title\"\n class=\"str-chat__message-attachment-card--title\"\n >\n {{ attachmentContext.title }}\n </div>\n <div\n *ngIf=\"attachmentContext.text\"\n class=\"str-chat__message-attachment-card--text\"\n data-testclass=\"card-text\"\n >\n {{ attachmentContext.text }}\n </div>\n <a\n *ngIf=\"\n attachmentContext.title_link ||\n attachmentContext.og_scrape_url\n \"\n class=\"str-chat__message-attachment-card--url\"\n data-testclass=\"url-link\"\n noopener\n noreferrer\n target=\"_blank\"\n href=\"{{\n attachmentContext.title_link ||\n attachmentContext.og_scrape_url\n }}\"\n >\n {{\n trimUrl(\n attachmentContext.title_link ||\n attachmentContext.og_scrape_url\n )\n }}\n </a>\n </div>\n </div>\n </div>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"attachment.actions && attachment.actions.length > 0\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.attachmentActionsTemplate$ | async) ||\n defaultActions;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultActions let-attachmentContext=\"attachment\">\n <div class=\"str-chat__message-attachment-actions\">\n <div class=\"str-chat__message-attachment-actions-form\">\n <button\n *ngFor=\"\n let action of attachmentContext.actions;\n trackBy: trackByActionValue\n \"\n data-testclass=\"attachment-action\"\n class=\"str-chat__message-attachment-actions-button str-chat__message-attachment-actions-button--{{\n action.style\n }}\"\n (click)=\"sendAction(action)\"\n (keyup.enter)=\"sendAction(action)\"\n >\n {{ action.text }}\n </button>\n </div>\n </div>\n </ng-template>\n </ng-container>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"imagesToView && imagesToView.length > 0\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.modalTemplate$ | async) || defaultModal;\n context: getModalContext()\n \"\n ></ng-container>\n </ng-container>\n</div>\n\n<ng-template\n #defaultModal\n let-isOpen=\"isOpen\"\n let-isOpenChangeHandler=\"isOpenChangeHandler\"\n let-content=\"content\"\n>\n <stream-modal\n class=\"stream-chat-angular__image-modal-host\"\n [isOpen]=\"isOpen\"\n [content]=\"content\"\n (isOpenChange)=\"isOpenChangeHandler($event)\"\n >\n </stream-modal>\n</ng-template>\n\n<ng-template #modalContent>\n <div class=\"stream-chat-angular__image-modal str-chat__image-carousel\">\n <img\n #imgElement\n class=\"stream-chat-angular__image-modal-image str-chat__image-carousel-image\"\n data-testid=\"modal-image\"\n [src]=\"\n getCarouselImageAttachmentConfiguration(\n imagesToView[imagesToViewCurrentIndex],\n imgElement\n ).url\n \"\n [style.--original-height]=\"\n getCarouselImageAttachmentConfiguration(\n imagesToView[imagesToViewCurrentIndex],\n imgElement\n ).originalHeight\n \"\n [style.--original-width]=\"\n getCarouselImageAttachmentConfiguration(\n imagesToView[imagesToViewCurrentIndex],\n imgElement\n ).originalWidth\n \"\n [alt]=\"imagesToView[imagesToViewCurrentIndex].fallback\"\n [ngStyle]=\"{\n width: getCarouselImageAttachmentConfiguration(\n imagesToView[imagesToViewCurrentIndex],\n imgElement\n ).width,\n height: getCarouselImageAttachmentConfiguration(\n imagesToView[imagesToViewCurrentIndex],\n imgElement\n ).height\n }\"\n />\n <div>\n <button\n class=\"stream-chat-angular__image-modal-stepper str-chat__image-carousel-stepper str-chat__image-carousel-stepper-prev\"\n data-testid=\"image-modal-prev\"\n type=\"button\"\n [ngStyle]=\"{\n visibility: isImageModalPrevButtonVisible ? 'visible' : 'hidden'\n }\"\n (click)=\"stepImages(-1)\"\n (keyup.enter)=\"stepImages(-1)\"\n >\n <stream-icon-placeholder icon=\"arrow-left\"></stream-icon-placeholder>\n </button>\n <button\n class=\"stream-chat-angular__image-modal-stepper str-chat__image-carousel-stepper str-chat__image-carousel-stepper-next\"\n type=\"button\"\n data-testid=\"image-modal-next\"\n [ngStyle]=\"{\n visibility: isImageModalNextButtonVisible ? 'visible' : 'hidden'\n }\"\n (click)=\"stepImages(1)\"\n (keyup.enter)=\"stepImages(1)\"\n >\n <stream-icon-placeholder icon=\"arrow-right\"></stream-icon-placeholder>\n </button>\n </div>\n </div>\n</ng-template>\n" }]
|
|
4865
|
-
}], ctorParameters: function () { return [{ type: CustomTemplatesService }, { type: ChannelService }, { type: AttachmentConfigurationService }]; }, propDecorators: { messageId: [{
|
|
4936
|
+
args: [{ selector: 'stream-attachment-list', template: "<div\n *ngIf=\"\n orderedAttachments.length > 0 ||\n (customAttachments.length > 0 && customAttachmentsTemplate)\n \"\n class=\"str-chat__attachment-list\"\n>\n <ng-container\n *ngFor=\"let attachment of orderedAttachments; trackBy: trackByUrl\"\n >\n <div\n data-testclass=\"attachment-container\"\n class=\"str-chat__message-attachment str-chat__message-attachment--{{\n attachment.type\n }} str-chat__message-attachment-dynamic-size\"\n [class.str-chat__message-attachment--card]=\"isCard(attachment)\"\n [class.str-chat-angular__message-attachment-file-single]=\"\n isFile(attachment)\n \"\n [class.str-chat__message-attachment--voice-recording]=\"\n isVoiceMessage(attachment)\n \"\n [class.str-chat__message-attachment-with-actions]=\"\n attachment.actions && attachment.actions.length > 0\n \"\n [class.str-chat__message-attachment--svg-image]=\"isSvg(attachment)\"\n >\n <ng-container *ngIf=\"isImage(attachment)\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.imageAttachmentTemplate$ | async) ||\n defaultImage;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultImage let-attachmentContext=\"attachment\">\n <img\n #imgElement\n class=\"str-chat__message-attachment--img\"\n data-testclass=\"image\"\n [src]=\"\n getImageAttachmentConfiguration(\n attachmentContext,\n 'single',\n imgElement\n ).url\n \"\n [alt]=\"attachmentContext?.fallback\"\n [ngStyle]=\"{\n height: getImageAttachmentConfiguration(\n attachmentContext,\n 'single',\n imgElement\n ).height,\n width: getImageAttachmentConfiguration(\n attachmentContext,\n 'single',\n imgElement\n ).width,\n '--original-height': getImageAttachmentConfiguration(\n attachmentContext,\n 'single',\n imgElement\n ).originalHeight,\n '--original-width': getImageAttachmentConfiguration(\n attachmentContext,\n 'single',\n imgElement\n ).originalWidth\n }\"\n (click)=\"openImageModal([attachmentContext])\"\n (keyup.enter)=\"openImageModal([attachmentContext])\"\n />\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"isGallery(attachment)\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.galleryAttachmentTemplate$ | async) ||\n defaultGallery;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultGallery let-attachmentContext=\"attachment\">\n <div\n class=\"str-chat__gallery\"\n data-testid=\"image-gallery\"\n [class.str-chat__gallery--square]=\"\n (attachmentContext?.images)!.length > 3\n \"\n [class.str-chat__gallery-two-rows]=\"\n (attachmentContext?.images)!.length > 2\n \"\n >\n <ng-container\n *ngFor=\"\n let galleryImage of attachmentContext.images;\n let index = index;\n let isLast = last;\n trackBy: trackByImageUrl\n \"\n >\n <button\n *ngIf=\"index < 3 || (index === 3 && isLast)\"\n class=\"str-chat__gallery-image\"\n data-testclass=\"gallery-image\"\n [class.str-chat__message-attachment--svg-image]=\"\n isSvg(galleryImage)\n \"\n (click)=\"openImageModal(attachmentContext.images!, index)\"\n (keyup.enter)=\"openImageModal(attachmentContext.images!, index)\"\n >\n <img\n #imgElement\n fetchpriority=\"low\"\n loading=\"lazy\"\n [src]=\"\n getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n imgElement\n ).url\n \"\n [alt]=\"galleryImage.fallback\"\n [style.--original-height]=\"\n getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n imgElement\n ).originalHeight\n \"\n [style.--original-width]=\"\n getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n imgElement\n ).originalWidth\n \"\n [ngStyle]=\"{\n height: getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n imgElement\n ).height,\n width: getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n imgElement\n ).width\n }\"\n />\n </button>\n <button\n *ngIf=\"index === 3 && !isLast\"\n #element\n class=\"str-chat__gallery-placeholder\"\n data-testclass=\"gallery-image\"\n data-testid=\"more-image-button\"\n [class.str-chat__message-attachment--svg-image]=\"\n isSvg(galleryImage)\n \"\n [ngStyle]=\"{\n 'background-image':\n 'url(' +\n getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n element\n ).url +\n ')',\n height: getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n element\n ).height,\n width: getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n element\n ).width,\n '--original-height': getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n element\n ).originalHeight,\n '--original-width': getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n element\n ).originalWidth\n }\"\n (click)=\"openImageModal(attachmentContext.images!, index)\"\n (keyup.enter)=\"openImageModal(attachmentContext.images!, index)\"\n >\n <p\n [innerHTML]=\"\n 'streamChat.{{ imageCount }} more'\n | translate\n : { imageCount: attachmentContext!.images!.length - 4 }\n \"\n ></p>\n </button>\n </ng-container>\n </div>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"isVideo(attachment)\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.videoAttachmentTemplate$ | async) ||\n defaultVideo;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultVideo let-attachmentContext=\"attachment\">\n <div\n class=\"str-chat__player-wrapper\"\n data-testclass=\"video-attachment-parent\"\n [style.--original-height]=\"\n getVideoAttachmentConfiguration(attachmentContext, videoElement)\n .originalHeight\n \"\n [style.--original-width]=\"\n getVideoAttachmentConfiguration(attachmentContext, videoElement)\n .originalWidth\n \"\n [ngStyle]=\"{\n height: getVideoAttachmentConfiguration(\n attachmentContext,\n videoElement\n ).height,\n width: getVideoAttachmentConfiguration(\n attachmentContext,\n videoElement\n ).width\n }\"\n >\n <video\n #videoElement\n class=\"str-chat__video-angular\"\n controls\n data-testclass=\"video-attachment\"\n [src]=\"\n getVideoAttachmentConfiguration(attachmentContext, videoElement)\n .url\n \"\n [poster]=\"\n getVideoAttachmentConfiguration(attachmentContext, videoElement)\n .thumbUrl\n \"\n ></video>\n </div>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"isFile(attachment)\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.fileAttachmentTemplate$ | async) ||\n defaultFile;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultFile let-attachmentContext=\"attachment\">\n <div\n class=\"str-chat__message-attachment-file--item str-chat-angular__message-attachment-file-single\"\n >\n <stream-icon-placeholder\n class=\"str-chat__attachment-type-icon\"\n icon=\"unspecified-filetype\"\n ></stream-icon-placeholder>\n <div class=\"str-chat__message-attachment-file--item-text\">\n <a\n class=\"str-chat__message-attachment-file--item-first-row\"\n data-testclass=\"file-link\"\n target=\"_blank\"\n href=\"{{ attachmentContext.asset_url }}\"\n >\n <div\n data-testclass=\"file-title\"\n class=\"str-chat__message-attachment-file--item-name\"\n >\n {{ attachmentContext.title }}\n </div>\n <stream-icon-placeholder\n class=\"str-chat__message-attachment-download-icon\"\n icon=\"download\"\n ></stream-icon-placeholder>\n </a>\n <span\n *ngIf=\"hasFileSize(attachmentContext)\"\n class=\"str-chat__message-attachment-file--item-size\"\n data-testclass=\"size\"\n >{{ getFileSize(attachmentContext) }}</span\n >\n </div>\n </div>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"isVoiceMessage(attachment)\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.voiceRecordingAttachmentTemplate$\n | async) || defaultRecording;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultRecording>\n <stream-voice-recording\n data-testclass=\"voice-recording\"\n [attachment]=\"attachment\"\n ></stream-voice-recording>\n </ng-template>\n </ng-container>\n <ng-container\n *ngIf=\"\n isCard(attachment) &&\n getCardAttachmentConfiguration(attachment) as attachmentConfiguration\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.cardAttachmentTemplate$ | async) ||\n defaultCard;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultCard let-attachmentContext=\"attachment\">\n <div\n class=\"str-chat__message-attachment-card str-chat__message-attachment-card--{{\n attachmentContext.type\n }}\"\n >\n <div\n *ngIf=\"attachmentConfiguration.url\"\n class=\"str-chat__message-attachment-card--header\"\n >\n <img\n fetchpriority=\"low\"\n loading=\"lazy\"\n data-testclass=\"card-img\"\n alt=\"{{ attachmentConfiguration.url }}\"\n src=\"{{ attachmentConfiguration.url }}\"\n [ngStyle]=\"{\n height: attachmentConfiguration.height,\n width: attachmentConfiguration.width\n }\"\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=\"attachmentContext.title\"\n data-testclass=\"card-title\"\n class=\"str-chat__message-attachment-card--title\"\n >\n {{ attachmentContext.title }}\n </div>\n <div\n *ngIf=\"attachmentContext.text\"\n class=\"str-chat__message-attachment-card--text\"\n data-testclass=\"card-text\"\n >\n {{ attachmentContext.text }}\n </div>\n <a\n *ngIf=\"\n attachmentContext.title_link ||\n attachmentContext.og_scrape_url\n \"\n class=\"str-chat__message-attachment-card--url\"\n data-testclass=\"url-link\"\n noopener\n noreferrer\n target=\"_blank\"\n href=\"{{\n attachmentContext.title_link ||\n attachmentContext.og_scrape_url\n }}\"\n >\n {{\n trimUrl(\n attachmentContext.title_link ||\n attachmentContext.og_scrape_url\n )\n }}\n </a>\n </div>\n </div>\n </div>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"attachment.actions && attachment.actions.length > 0\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.attachmentActionsTemplate$ | async) ||\n defaultActions;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultActions let-attachmentContext=\"attachment\">\n <div class=\"str-chat__message-attachment-actions\">\n <div class=\"str-chat__message-attachment-actions-form\">\n <button\n *ngFor=\"\n let action of attachmentContext.actions;\n trackBy: trackByActionValue\n \"\n data-testclass=\"attachment-action\"\n class=\"str-chat__message-attachment-actions-button str-chat__message-attachment-actions-button--{{\n action.style\n }}\"\n (click)=\"sendAction(action)\"\n (keyup.enter)=\"sendAction(action)\"\n >\n {{ action.text }}\n </button>\n </div>\n </div>\n </ng-template>\n </ng-container>\n </div>\n </ng-container>\n <ng-container *ngIf=\"customAttachmentsTemplate\">\n <ng-template\n *ngTemplateOutlet=\"\n customAttachmentsTemplate;\n context: {\n messageId: messageId,\n parentMessageId: parentMessageId,\n attachments: customAttachments\n }\n \"\n ></ng-template>\n </ng-container>\n\n <ng-container *ngIf=\"imagesToView && imagesToView.length > 0\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.modalTemplate$ | async) || defaultModal;\n context: getModalContext()\n \"\n ></ng-container>\n </ng-container>\n</div>\n\n<ng-template\n #defaultModal\n let-isOpen=\"isOpen\"\n let-isOpenChangeHandler=\"isOpenChangeHandler\"\n let-content=\"content\"\n>\n <stream-modal\n class=\"stream-chat-angular__image-modal-host\"\n [isOpen]=\"isOpen\"\n [content]=\"content\"\n (isOpenChange)=\"isOpenChangeHandler($event)\"\n >\n </stream-modal>\n</ng-template>\n\n<ng-template #modalContent>\n <div class=\"stream-chat-angular__image-modal str-chat__image-carousel\">\n <img\n #imgElement\n class=\"stream-chat-angular__image-modal-image str-chat__image-carousel-image\"\n data-testid=\"modal-image\"\n [src]=\"\n getCarouselImageAttachmentConfiguration(\n imagesToView[imagesToViewCurrentIndex],\n imgElement\n ).url\n \"\n [style.--original-height]=\"\n getCarouselImageAttachmentConfiguration(\n imagesToView[imagesToViewCurrentIndex],\n imgElement\n ).originalHeight\n \"\n [style.--original-width]=\"\n getCarouselImageAttachmentConfiguration(\n imagesToView[imagesToViewCurrentIndex],\n imgElement\n ).originalWidth\n \"\n [alt]=\"imagesToView[imagesToViewCurrentIndex].fallback\"\n [ngStyle]=\"{\n width: getCarouselImageAttachmentConfiguration(\n imagesToView[imagesToViewCurrentIndex],\n imgElement\n ).width,\n height: getCarouselImageAttachmentConfiguration(\n imagesToView[imagesToViewCurrentIndex],\n imgElement\n ).height\n }\"\n />\n <div>\n <button\n class=\"stream-chat-angular__image-modal-stepper str-chat__image-carousel-stepper str-chat__image-carousel-stepper-prev\"\n data-testid=\"image-modal-prev\"\n type=\"button\"\n [ngStyle]=\"{\n visibility: isImageModalPrevButtonVisible ? 'visible' : 'hidden'\n }\"\n (click)=\"stepImages(-1)\"\n (keyup.enter)=\"stepImages(-1)\"\n >\n <stream-icon-placeholder icon=\"arrow-left\"></stream-icon-placeholder>\n </button>\n <button\n class=\"stream-chat-angular__image-modal-stepper str-chat__image-carousel-stepper str-chat__image-carousel-stepper-next\"\n type=\"button\"\n data-testid=\"image-modal-next\"\n [ngStyle]=\"{\n visibility: isImageModalNextButtonVisible ? 'visible' : 'hidden'\n }\"\n (click)=\"stepImages(1)\"\n (keyup.enter)=\"stepImages(1)\"\n >\n <stream-icon-placeholder icon=\"arrow-right\"></stream-icon-placeholder>\n </button>\n </div>\n </div>\n</ng-template>\n" }]
|
|
4937
|
+
}], ctorParameters: function () { return [{ type: CustomTemplatesService }, { type: ChannelService }, { type: AttachmentConfigurationService }, { type: MessageService }]; }, propDecorators: { messageId: [{
|
|
4866
4938
|
type: Input
|
|
4867
4939
|
}], parentMessageId: [{
|
|
4868
4940
|
type: Input
|
|
@@ -6297,7 +6369,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImpor
|
|
|
6297
6369
|
* The `AttachmentPreviewList` component displays a preview of the attachments uploaded to a message. Users can delete attachments using the preview component, or retry upload if it failed previously.
|
|
6298
6370
|
*/
|
|
6299
6371
|
class AttachmentPreviewListComponent {
|
|
6300
|
-
constructor() {
|
|
6372
|
+
constructor(customTemplateService, attachmentService) {
|
|
6373
|
+
this.customTemplateService = customTemplateService;
|
|
6374
|
+
this.attachmentService = attachmentService;
|
|
6301
6375
|
/**
|
|
6302
6376
|
* An output to notify the parent component if the user tries to retry a failed upload
|
|
6303
6377
|
*/
|
|
@@ -6306,6 +6380,15 @@ class AttachmentPreviewListComponent {
|
|
|
6306
6380
|
* An output to notify the parent component if the user wants to delete a file
|
|
6307
6381
|
*/
|
|
6308
6382
|
this.deleteAttachment = new EventEmitter();
|
|
6383
|
+
this.customAttachments = [];
|
|
6384
|
+
this.subscriptions = [];
|
|
6385
|
+
}
|
|
6386
|
+
ngOnInit() {
|
|
6387
|
+
this.subscriptions.push(this.customTemplateService.customAttachmentPreviewListTemplate$.subscribe((t) => (this.customAttachmentsPreview = t)));
|
|
6388
|
+
this.subscriptions.push(this.attachmentService.customAttachments$.subscribe((a) => (this.customAttachments = a)));
|
|
6389
|
+
}
|
|
6390
|
+
ngOnDestroy() {
|
|
6391
|
+
this.subscriptions.forEach((s) => s.unsubscribe());
|
|
6309
6392
|
}
|
|
6310
6393
|
attachmentUploadRetried(file) {
|
|
6311
6394
|
this.retryAttachmentUpload.emit(file);
|
|
@@ -6317,12 +6400,12 @@ class AttachmentPreviewListComponent {
|
|
|
6317
6400
|
return item.file;
|
|
6318
6401
|
}
|
|
6319
6402
|
}
|
|
6320
|
-
AttachmentPreviewListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: AttachmentPreviewListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
6321
|
-
AttachmentPreviewListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: AttachmentPreviewListComponent, selector: "stream-attachment-preview-list", inputs: { attachmentUploads$: "attachmentUploads$" }, outputs: { retryAttachmentUpload: "retryAttachmentUpload", deleteAttachment: "deleteAttachment" }, ngImport: i0, template: "<div\n *ngIf=\"(attachmentUploads$ | async)?.length\"\n class=\"str-chat__attachment-preview-list\"\n>\n <div class=\"str-chat__attachment-list-scroll-container\">\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=\"str-chat__attachment-preview-image\"\n data-testclass=\"attachment-image-preview\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n deleteButton;\n context: { attachmentUpload: attachmentUpload }\n \"\n ></ng-container>\n <div\n *ngIf=\"attachmentUpload.state === 'uploading'\"\n class=\"str-chat__attachment-preview-image-loading\"\n >\n <stream-loading-indicator-placeholder\n data-testclass=\"loading-indicator\"\n ></stream-loading-indicator-placeholder>\n </div>\n <ng-container\n *ngTemplateOutlet=\"\n retryButton;\n context: { attachmentUpload: attachmentUpload }\n \"\n ></ng-container>\n <img\n *ngIf=\"attachmentUpload.url || attachmentUpload.previewUri\"\n class=\"str-chat__attachment-preview-thumbnail\"\n data-testclass=\"attachment-image\"\n src=\"{{\n attachmentUpload.url\n ? attachmentUpload.url\n : attachmentUpload.previewUri\n }}\"\n alt=\"{{ attachmentUpload.file.name }}\"\n />\n </div>\n <div\n *ngIf=\"\n attachmentUpload.type === 'file' ||\n attachmentUpload.type === 'video' ||\n attachmentUpload.type === 'voiceRecording'\n \"\n class=\"str-chat__attachment-preview-file str-chat__attachment-preview-type-{{\n attachmentUpload.type\n }}\"\n data-testclass=\"attachment-file-preview\"\n >\n <stream-icon-placeholder\n class=\"str-chat__attachment-preview-file-icon\"\n icon=\"unspecified-filetype\"\n ></stream-icon-placeholder>\n\n <div class=\"str-chat__attachment-preview-file-end\">\n <div\n class=\"str-chat__attachment-preview-file-name\"\n title=\"{{ attachmentUpload.file.name }}\"\n >\n {{ attachmentUpload.file.name }}\n </div>\n <a\n *ngIf=\"attachmentUpload.state === 'success'\"\n class=\"str-chat__attachment-preview-file-download\"\n data-testclass=\"file-download-link\"\n download\n href=\"{{ attachmentUpload.url }}\"\n (click)=\"attachmentUpload.url ? null : $event.preventDefault()\"\n (keyup.enter)=\"\n attachmentUpload.url ? null : $event.preventDefault()\n \"\n >\n <stream-icon-placeholder icon=\"download\"></stream-icon-placeholder>\n </a>\n <stream-loading-indicator-placeholder\n *ngIf=\"attachmentUpload.state === 'uploading'\"\n data-testclass=\"loading-indicator\"\n ></stream-loading-indicator-placeholder>\n </div>\n <ng-container\n *ngTemplateOutlet=\"\n deleteButton;\n context: { attachmentUpload: attachmentUpload }\n \"\n ></ng-container>\n <ng-container\n *ngTemplateOutlet=\"\n retryButton;\n context: { attachmentUpload: attachmentUpload }\n \"\n ></ng-container>\n </div>\n </ng-container>\n </div>\n</div>\n\n<ng-template #deleteButton let-attachmentUpload=\"attachmentUpload\">\n <div\n class=\"str-chat__attachment-preview-delete\"\n data-testclass=\"file-delete\"\n role=\"button\"\n (click)=\"attachmentDeleted(attachmentUpload)\"\n (keyup.enter)=\"attachmentDeleted(attachmentUpload)\"\n >\n <stream-icon-placeholder icon=\"close\"></stream-icon-placeholder>\n </div>\n</ng-template>\n\n<ng-template #retryButton let-attachmentUpload=\"attachmentUpload\">\n <div\n *ngIf=\"attachmentUpload.state === 'error'\"\n data-testclass=\"upload-retry\"\n class=\"str-chat__attachment-preview-error str-chat__attachment-preview-error-{{\n attachmentUpload.type === 'image' ? 'image' : 'file'\n }}\"\n (click)=\"attachmentUploadRetried(attachmentUpload.file)\"\n (keyup.enter)=\"attachmentUploadRetried(attachmentUpload.file)\"\n >\n <stream-icon-placeholder icon=\"retry\"></stream-icon-placeholder>\n </div>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon"] }, { kind: "component", type: LoadingIndicatorPlaceholderComponent, selector: "stream-loading-indicator-placeholder" }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }] });
|
|
6403
|
+
AttachmentPreviewListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: AttachmentPreviewListComponent, deps: [{ token: CustomTemplatesService }, { token: AttachmentService }], target: i0.ɵɵFactoryTarget.Component });
|
|
6404
|
+
AttachmentPreviewListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: AttachmentPreviewListComponent, selector: "stream-attachment-preview-list", inputs: { attachmentUploads$: "attachmentUploads$" }, outputs: { retryAttachmentUpload: "retryAttachmentUpload", deleteAttachment: "deleteAttachment" }, ngImport: i0, template: "<div\n *ngIf=\"\n (attachmentUploads$ | async)?.length ||\n (customAttachments.length > 0 && customAttachmentsPreview)\n \"\n class=\"str-chat__attachment-preview-list\"\n>\n <div class=\"str-chat__attachment-list-scroll-container\">\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=\"str-chat__attachment-preview-image\"\n data-testclass=\"attachment-image-preview\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n deleteButton;\n context: { attachmentUpload: attachmentUpload }\n \"\n ></ng-container>\n <div\n *ngIf=\"attachmentUpload.state === 'uploading'\"\n class=\"str-chat__attachment-preview-image-loading\"\n >\n <stream-loading-indicator-placeholder\n data-testclass=\"loading-indicator\"\n ></stream-loading-indicator-placeholder>\n </div>\n <ng-container\n *ngTemplateOutlet=\"\n retryButton;\n context: { attachmentUpload: attachmentUpload }\n \"\n ></ng-container>\n <img\n *ngIf=\"attachmentUpload.url || attachmentUpload.previewUri\"\n class=\"str-chat__attachment-preview-thumbnail\"\n data-testclass=\"attachment-image\"\n src=\"{{\n attachmentUpload.url\n ? attachmentUpload.url\n : attachmentUpload.previewUri\n }}\"\n alt=\"{{ attachmentUpload.file.name }}\"\n />\n </div>\n <div\n *ngIf=\"\n attachmentUpload.type === 'file' ||\n attachmentUpload.type === 'video' ||\n attachmentUpload.type === 'voiceRecording'\n \"\n class=\"str-chat__attachment-preview-file str-chat__attachment-preview-type-{{\n attachmentUpload.type\n }}\"\n data-testclass=\"attachment-file-preview\"\n >\n <stream-icon-placeholder\n class=\"str-chat__attachment-preview-file-icon\"\n icon=\"unspecified-filetype\"\n ></stream-icon-placeholder>\n\n <div class=\"str-chat__attachment-preview-file-end\">\n <div\n class=\"str-chat__attachment-preview-file-name\"\n title=\"{{ attachmentUpload.file.name }}\"\n >\n {{ attachmentUpload.file.name }}\n </div>\n <a\n *ngIf=\"attachmentUpload.state === 'success'\"\n class=\"str-chat__attachment-preview-file-download\"\n data-testclass=\"file-download-link\"\n download\n href=\"{{ attachmentUpload.url }}\"\n (click)=\"attachmentUpload.url ? null : $event.preventDefault()\"\n (keyup.enter)=\"\n attachmentUpload.url ? null : $event.preventDefault()\n \"\n >\n <stream-icon-placeholder icon=\"download\"></stream-icon-placeholder>\n </a>\n <stream-loading-indicator-placeholder\n *ngIf=\"attachmentUpload.state === 'uploading'\"\n data-testclass=\"loading-indicator\"\n ></stream-loading-indicator-placeholder>\n </div>\n <ng-container\n *ngTemplateOutlet=\"\n deleteButton;\n context: { attachmentUpload: attachmentUpload }\n \"\n ></ng-container>\n <ng-container\n *ngTemplateOutlet=\"\n retryButton;\n context: { attachmentUpload: attachmentUpload }\n \"\n ></ng-container>\n </div>\n </ng-container>\n <ng-container *ngIf=\"customAttachmentsPreview\">\n <ng-template\n *ngTemplateOutlet=\"\n customAttachmentsPreview;\n context: { service: attachmentService }\n \"\n ></ng-template>\n </ng-container>\n </div>\n</div>\n\n<ng-template #deleteButton let-attachmentUpload=\"attachmentUpload\">\n <div\n class=\"str-chat__attachment-preview-delete\"\n data-testclass=\"file-delete\"\n role=\"button\"\n (click)=\"attachmentDeleted(attachmentUpload)\"\n (keyup.enter)=\"attachmentDeleted(attachmentUpload)\"\n >\n <stream-icon-placeholder icon=\"close\"></stream-icon-placeholder>\n </div>\n</ng-template>\n\n<ng-template #retryButton let-attachmentUpload=\"attachmentUpload\">\n <div\n *ngIf=\"attachmentUpload.state === 'error'\"\n data-testclass=\"upload-retry\"\n class=\"str-chat__attachment-preview-error str-chat__attachment-preview-error-{{\n attachmentUpload.type === 'image' ? 'image' : 'file'\n }}\"\n (click)=\"attachmentUploadRetried(attachmentUpload.file)\"\n (keyup.enter)=\"attachmentUploadRetried(attachmentUpload.file)\"\n >\n <stream-icon-placeholder icon=\"retry\"></stream-icon-placeholder>\n </div>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon"] }, { kind: "component", type: LoadingIndicatorPlaceholderComponent, selector: "stream-loading-indicator-placeholder" }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }] });
|
|
6322
6405
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: AttachmentPreviewListComponent, decorators: [{
|
|
6323
6406
|
type: Component,
|
|
6324
|
-
args: [{ selector: 'stream-attachment-preview-list', template: "<div\n *ngIf=\"(attachmentUploads$ | async)?.length\"\n class=\"str-chat__attachment-preview-list\"\n>\n <div class=\"str-chat__attachment-list-scroll-container\">\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=\"str-chat__attachment-preview-image\"\n data-testclass=\"attachment-image-preview\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n deleteButton;\n context: { attachmentUpload: attachmentUpload }\n \"\n ></ng-container>\n <div\n *ngIf=\"attachmentUpload.state === 'uploading'\"\n class=\"str-chat__attachment-preview-image-loading\"\n >\n <stream-loading-indicator-placeholder\n data-testclass=\"loading-indicator\"\n ></stream-loading-indicator-placeholder>\n </div>\n <ng-container\n *ngTemplateOutlet=\"\n retryButton;\n context: { attachmentUpload: attachmentUpload }\n \"\n ></ng-container>\n <img\n *ngIf=\"attachmentUpload.url || attachmentUpload.previewUri\"\n class=\"str-chat__attachment-preview-thumbnail\"\n data-testclass=\"attachment-image\"\n src=\"{{\n attachmentUpload.url\n ? attachmentUpload.url\n : attachmentUpload.previewUri\n }}\"\n alt=\"{{ attachmentUpload.file.name }}\"\n />\n </div>\n <div\n *ngIf=\"\n attachmentUpload.type === 'file' ||\n attachmentUpload.type === 'video' ||\n attachmentUpload.type === 'voiceRecording'\n \"\n class=\"str-chat__attachment-preview-file str-chat__attachment-preview-type-{{\n attachmentUpload.type\n }}\"\n data-testclass=\"attachment-file-preview\"\n >\n <stream-icon-placeholder\n class=\"str-chat__attachment-preview-file-icon\"\n icon=\"unspecified-filetype\"\n ></stream-icon-placeholder>\n\n <div class=\"str-chat__attachment-preview-file-end\">\n <div\n class=\"str-chat__attachment-preview-file-name\"\n title=\"{{ attachmentUpload.file.name }}\"\n >\n {{ attachmentUpload.file.name }}\n </div>\n <a\n *ngIf=\"attachmentUpload.state === 'success'\"\n class=\"str-chat__attachment-preview-file-download\"\n data-testclass=\"file-download-link\"\n download\n href=\"{{ attachmentUpload.url }}\"\n (click)=\"attachmentUpload.url ? null : $event.preventDefault()\"\n (keyup.enter)=\"\n attachmentUpload.url ? null : $event.preventDefault()\n \"\n >\n <stream-icon-placeholder icon=\"download\"></stream-icon-placeholder>\n </a>\n <stream-loading-indicator-placeholder\n *ngIf=\"attachmentUpload.state === 'uploading'\"\n data-testclass=\"loading-indicator\"\n ></stream-loading-indicator-placeholder>\n </div>\n <ng-container\n *ngTemplateOutlet=\"\n deleteButton;\n context: { attachmentUpload: attachmentUpload }\n \"\n ></ng-container>\n <ng-container\n *ngTemplateOutlet=\"\n retryButton;\n context: { attachmentUpload: attachmentUpload }\n \"\n ></ng-container>\n </div>\n </ng-container>\n </div>\n</div>\n\n<ng-template #deleteButton let-attachmentUpload=\"attachmentUpload\">\n <div\n class=\"str-chat__attachment-preview-delete\"\n data-testclass=\"file-delete\"\n role=\"button\"\n (click)=\"attachmentDeleted(attachmentUpload)\"\n (keyup.enter)=\"attachmentDeleted(attachmentUpload)\"\n >\n <stream-icon-placeholder icon=\"close\"></stream-icon-placeholder>\n </div>\n</ng-template>\n\n<ng-template #retryButton let-attachmentUpload=\"attachmentUpload\">\n <div\n *ngIf=\"attachmentUpload.state === 'error'\"\n data-testclass=\"upload-retry\"\n class=\"str-chat__attachment-preview-error str-chat__attachment-preview-error-{{\n attachmentUpload.type === 'image' ? 'image' : 'file'\n }}\"\n (click)=\"attachmentUploadRetried(attachmentUpload.file)\"\n (keyup.enter)=\"attachmentUploadRetried(attachmentUpload.file)\"\n >\n <stream-icon-placeholder icon=\"retry\"></stream-icon-placeholder>\n </div>\n</ng-template>\n" }]
|
|
6325
|
-
}], ctorParameters: function () { return []; }, propDecorators: { attachmentUploads$: [{
|
|
6407
|
+
args: [{ selector: 'stream-attachment-preview-list', template: "<div\n *ngIf=\"\n (attachmentUploads$ | async)?.length ||\n (customAttachments.length > 0 && customAttachmentsPreview)\n \"\n class=\"str-chat__attachment-preview-list\"\n>\n <div class=\"str-chat__attachment-list-scroll-container\">\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=\"str-chat__attachment-preview-image\"\n data-testclass=\"attachment-image-preview\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n deleteButton;\n context: { attachmentUpload: attachmentUpload }\n \"\n ></ng-container>\n <div\n *ngIf=\"attachmentUpload.state === 'uploading'\"\n class=\"str-chat__attachment-preview-image-loading\"\n >\n <stream-loading-indicator-placeholder\n data-testclass=\"loading-indicator\"\n ></stream-loading-indicator-placeholder>\n </div>\n <ng-container\n *ngTemplateOutlet=\"\n retryButton;\n context: { attachmentUpload: attachmentUpload }\n \"\n ></ng-container>\n <img\n *ngIf=\"attachmentUpload.url || attachmentUpload.previewUri\"\n class=\"str-chat__attachment-preview-thumbnail\"\n data-testclass=\"attachment-image\"\n src=\"{{\n attachmentUpload.url\n ? attachmentUpload.url\n : attachmentUpload.previewUri\n }}\"\n alt=\"{{ attachmentUpload.file.name }}\"\n />\n </div>\n <div\n *ngIf=\"\n attachmentUpload.type === 'file' ||\n attachmentUpload.type === 'video' ||\n attachmentUpload.type === 'voiceRecording'\n \"\n class=\"str-chat__attachment-preview-file str-chat__attachment-preview-type-{{\n attachmentUpload.type\n }}\"\n data-testclass=\"attachment-file-preview\"\n >\n <stream-icon-placeholder\n class=\"str-chat__attachment-preview-file-icon\"\n icon=\"unspecified-filetype\"\n ></stream-icon-placeholder>\n\n <div class=\"str-chat__attachment-preview-file-end\">\n <div\n class=\"str-chat__attachment-preview-file-name\"\n title=\"{{ attachmentUpload.file.name }}\"\n >\n {{ attachmentUpload.file.name }}\n </div>\n <a\n *ngIf=\"attachmentUpload.state === 'success'\"\n class=\"str-chat__attachment-preview-file-download\"\n data-testclass=\"file-download-link\"\n download\n href=\"{{ attachmentUpload.url }}\"\n (click)=\"attachmentUpload.url ? null : $event.preventDefault()\"\n (keyup.enter)=\"\n attachmentUpload.url ? null : $event.preventDefault()\n \"\n >\n <stream-icon-placeholder icon=\"download\"></stream-icon-placeholder>\n </a>\n <stream-loading-indicator-placeholder\n *ngIf=\"attachmentUpload.state === 'uploading'\"\n data-testclass=\"loading-indicator\"\n ></stream-loading-indicator-placeholder>\n </div>\n <ng-container\n *ngTemplateOutlet=\"\n deleteButton;\n context: { attachmentUpload: attachmentUpload }\n \"\n ></ng-container>\n <ng-container\n *ngTemplateOutlet=\"\n retryButton;\n context: { attachmentUpload: attachmentUpload }\n \"\n ></ng-container>\n </div>\n </ng-container>\n <ng-container *ngIf=\"customAttachmentsPreview\">\n <ng-template\n *ngTemplateOutlet=\"\n customAttachmentsPreview;\n context: { service: attachmentService }\n \"\n ></ng-template>\n </ng-container>\n </div>\n</div>\n\n<ng-template #deleteButton let-attachmentUpload=\"attachmentUpload\">\n <div\n class=\"str-chat__attachment-preview-delete\"\n data-testclass=\"file-delete\"\n role=\"button\"\n (click)=\"attachmentDeleted(attachmentUpload)\"\n (keyup.enter)=\"attachmentDeleted(attachmentUpload)\"\n >\n <stream-icon-placeholder icon=\"close\"></stream-icon-placeholder>\n </div>\n</ng-template>\n\n<ng-template #retryButton let-attachmentUpload=\"attachmentUpload\">\n <div\n *ngIf=\"attachmentUpload.state === 'error'\"\n data-testclass=\"upload-retry\"\n class=\"str-chat__attachment-preview-error str-chat__attachment-preview-error-{{\n attachmentUpload.type === 'image' ? 'image' : 'file'\n }}\"\n (click)=\"attachmentUploadRetried(attachmentUpload.file)\"\n (keyup.enter)=\"attachmentUploadRetried(attachmentUpload.file)\"\n >\n <stream-icon-placeholder icon=\"retry\"></stream-icon-placeholder>\n </div>\n</ng-template>\n" }]
|
|
6408
|
+
}], ctorParameters: function () { return [{ type: CustomTemplatesService }, { type: AttachmentService }]; }, propDecorators: { attachmentUploads$: [{
|
|
6326
6409
|
type: Input
|
|
6327
6410
|
}], retryAttachmentUpload: [{
|
|
6328
6411
|
type: Output
|
|
@@ -6420,6 +6503,7 @@ class MessageInputComponent {
|
|
|
6420
6503
|
this.checkIfInEditMode();
|
|
6421
6504
|
}));
|
|
6422
6505
|
this.attachmentUploads$ = this.attachmentService.attachmentUploads$;
|
|
6506
|
+
this.customAttachments$ = this.attachmentService.customAttachments$;
|
|
6423
6507
|
this.attachmentUploadInProgressCounter$ =
|
|
6424
6508
|
this.attachmentService.attachmentUploadInProgressCounter$;
|
|
6425
6509
|
this.isFileUploadEnabled = this.configService.isFileUploadEnabled;
|
|
@@ -6617,6 +6701,7 @@ class MessageInputComponent {
|
|
|
6617
6701
|
attachmentUploads$: this.attachmentService.attachmentUploads$,
|
|
6618
6702
|
deleteUploadHandler: this.deleteUpload.bind(this),
|
|
6619
6703
|
retryUploadHandler: this.retryUpload.bind(this),
|
|
6704
|
+
service: this.attachmentService,
|
|
6620
6705
|
};
|
|
6621
6706
|
}
|
|
6622
6707
|
getAttachmentUploadContext() {
|
|
@@ -6752,10 +6837,10 @@ class MessageInputComponent {
|
|
|
6752
6837
|
}
|
|
6753
6838
|
}
|
|
6754
6839
|
MessageInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: MessageInputComponent, deps: [{ token: ChannelService }, { token: NotificationService }, { token: AttachmentService }, { token: MessageInputConfigService }, { token: textareaInjectionToken }, { token: i0.ComponentFactoryResolver }, { token: i0.ChangeDetectorRef }, { token: EmojiInputService }, { token: CustomTemplatesService }, { token: MessageActionsService }, { token: VoiceRecorderService }, { token: AudioRecorderService, optional: true }], target: i0.ɵɵFactoryTarget.Component });
|
|
6755
|
-
MessageInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: MessageInputComponent, selector: "stream-message-input", inputs: { isFileUploadEnabled: "isFileUploadEnabled", areMentionsEnabled: "areMentionsEnabled", mentionScope: "mentionScope", mode: "mode", isMultipleFileUploadEnabled: "isMultipleFileUploadEnabled", message: "message", sendMessage$: "sendMessage$", inputMode: "inputMode", autoFocus: "autoFocus", watchForMessageToEdit: "watchForMessageToEdit", displaySendButton: "displaySendButton", displayVoiceRecordingButton: "displayVoiceRecordingButton" }, outputs: { messageUpdate: "messageUpdate" }, host: { properties: { "class": "this.class" } }, providers: [AttachmentService, EmojiInputService, VoiceRecorderService], queries: [{ propertyName: "voiceRecorderRef", first: true, predicate: TemplateRef, descendants: true }], 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__message-input str-chat-angular__message-input\"\n [style.display]=\"isVoiceRecording ? 'none' : 'flex'\"\n>\n <div *ngIf=\"quotedMessage\" class=\"str-chat__quoted-message-preview-header\">\n <div class=\"str-chat__quoted-message-reply-to-message\">\n {{ \"streamChat.Reply to Message\" | translate }}\n </div>\n <button\n class=\"str-chat__quoted-message-remove\"\n data-testid=\"remove-quote\"\n (click)=\"deselectMessageToQuote()\"\n (keyup.enter)=\"deselectMessageToQuote()\"\n >\n <stream-icon-placeholder icon=\"close\"></stream-icon-placeholder>\n </button>\n </div>\n <div *ngIf=\"isUpdate\" class=\"str-chat__quoted-message-preview-header\">\n <div class=\"str-chat__quoted-message-reply-to-message\">\n {{ \"streamChat.Edit Message\" | translate }}\n </div>\n <button\n class=\"str-chat__quoted-message-remove\"\n data-testid=\"remove-quote\"\n (click)=\"deselectMessageToEdit()\"\n (keyup.enter)=\"deselectMessageToEdit()\"\n >\n <stream-icon-placeholder icon=\"close\"></stream-icon-placeholder>\n </button>\n </div>\n <ng-container *ngIf=\"canSendMessages; else notAllowed\">\n <div\n class=\"str-chat__message-input-inner str-chat-angular__message-input-inner\"\n >\n <ng-content select=\"[message-input-start]\"></ng-content>\n <ng-container\n *ngIf=\"isFileUploadEnabled && isFileUploadAuthorized && canSendMessages\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n customAttachmentUploadTemplate || defaultAttachmentUpload;\n context: getAttachmentUploadContext()\n \"\n ></ng-container>\n <ng-template #defaultAttachmentUpload>\n <div\n class=\"str-chat__file-input-container\"\n data-testid=\"file-upload-button\"\n >\n <input\n #fileInput\n type=\"file\"\n class=\"str-chat__file-input\"\n data-testid=\"file-input\"\n [multiple]=\"isMultipleFileUploadEnabled\"\n id=\"{{ fileInputId }}\"\n (change)=\"filesSelected(fileInput.files)\"\n />\n <label class=\"str-chat__file-input-label\" for=\"{{ fileInputId }}\">\n <stream-icon-placeholder icon=\"attach\"></stream-icon-placeholder>\n </label>\n </div>\n </ng-template>\n </ng-container>\n <div class=\"str-chat__message-textarea-container\">\n <div\n *ngIf=\"quotedMessage\"\n data-testid=\"quoted-message-container\"\n class=\"str-chat__quoted-message-preview\"\n >\n <stream-avatar-placeholder\n data-testid=\"qouted-message-avatar\"\n class=\"str-chat-angular__avatar-host str-chat__message-sender-avatar\"\n type=\"user\"\n location=\"quoted-message-sender\"\n [imageUrl]=\"quotedMessage.user?.image\"\n [name]=\"quotedMessage.user?.name || quotedMessage.user?.id\"\n [user]=\"quotedMessage.user || undefined\"\n ></stream-avatar-placeholder>\n <div\n class=\"quoted-message-preview-content-inner str-chat__quoted-message-bubble\"\n >\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 class=\"str-chat__quoted-message-text\"\n data-testid=\"quoted-message-text\"\n [innerHTML]=\"\n quotedMessage.translation ||\n quotedMessage.html ||\n quotedMessage.text\n \"\n ></div>\n </div>\n </div>\n <ng-template\n #defaultAttachmentsPreview\n let-attachmentUploads$=\"attachmentUploads$\"\n let-retryUploadHandler=\"retryUploadHandler\"\n let-deleteUploadHandler=\"deleteUploadHandler\"\n >\n <stream-attachment-preview-list\n class=\"str-chat__attachment-preview-list-angular-host\"\n [attachmentUploads$]=\"attachmentUploads$\"\n (retryAttachmentUpload)=\"retryUploadHandler($event)\"\n (deleteAttachment)=\"deleteUploadHandler($event)\"\n ></stream-attachment-preview-list>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n attachmentPreviewListTemplate || defaultAttachmentsPreview;\n context: getAttachmentPreviewListContext()\n \"\n ></ng-container>\n <div class=\"str-chat__message-textarea-with-emoji-picker\">\n <ng-container\n streamTextarea\n [componentRef]=\"textareaRef\"\n [areMentionsEnabled]=\"areMentionsEnabled\"\n [mentionScope]=\"mentionScope\"\n [inputMode]=\"inputMode\"\n [autoFocus]=\"autoFocus\"\n [placeholder]=\"textareaPlaceholder\"\n [(value)]=\"textareaValue\"\n (valueChange)=\"typingStart$.next()\"\n (send)=\"messageSent()\"\n (userMentions)=\"mentionedUsers = $event\"\n ></ng-container>\n <ng-container *ngIf=\"emojiPickerTemplate\" data-testid=\"emoji-picker\">\n <ng-container\n *ngTemplateOutlet=\"\n emojiPickerTemplate;\n context: getEmojiPickerContext()\n \"\n ></ng-container>\n </ng-container>\n </div>\n </div>\n <button\n *ngIf=\"canSendMessages && !isCooldownInProgress && displaySendButton\"\n data-testid=\"send-button\"\n class=\"str-chat__send-button\"\n [disabled]=\"\n (attachmentUploadInProgressCounter$ | async)! > 0 ||\n (!textareaValue
|
|
6840
|
+
MessageInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: MessageInputComponent, selector: "stream-message-input", inputs: { isFileUploadEnabled: "isFileUploadEnabled", areMentionsEnabled: "areMentionsEnabled", mentionScope: "mentionScope", mode: "mode", isMultipleFileUploadEnabled: "isMultipleFileUploadEnabled", message: "message", sendMessage$: "sendMessage$", inputMode: "inputMode", autoFocus: "autoFocus", watchForMessageToEdit: "watchForMessageToEdit", displaySendButton: "displaySendButton", displayVoiceRecordingButton: "displayVoiceRecordingButton" }, outputs: { messageUpdate: "messageUpdate" }, host: { properties: { "class": "this.class" } }, providers: [AttachmentService, EmojiInputService, VoiceRecorderService], queries: [{ propertyName: "voiceRecorderRef", first: true, predicate: TemplateRef, descendants: true }], 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__message-input str-chat-angular__message-input\"\n [style.display]=\"isVoiceRecording ? 'none' : 'flex'\"\n>\n <div *ngIf=\"quotedMessage\" class=\"str-chat__quoted-message-preview-header\">\n <div class=\"str-chat__quoted-message-reply-to-message\">\n {{ \"streamChat.Reply to Message\" | translate }}\n </div>\n <button\n class=\"str-chat__quoted-message-remove\"\n data-testid=\"remove-quote\"\n (click)=\"deselectMessageToQuote()\"\n (keyup.enter)=\"deselectMessageToQuote()\"\n >\n <stream-icon-placeholder icon=\"close\"></stream-icon-placeholder>\n </button>\n </div>\n <div *ngIf=\"isUpdate\" class=\"str-chat__quoted-message-preview-header\">\n <div class=\"str-chat__quoted-message-reply-to-message\">\n {{ \"streamChat.Edit Message\" | translate }}\n </div>\n <button\n class=\"str-chat__quoted-message-remove\"\n data-testid=\"remove-quote\"\n (click)=\"deselectMessageToEdit()\"\n (keyup.enter)=\"deselectMessageToEdit()\"\n >\n <stream-icon-placeholder icon=\"close\"></stream-icon-placeholder>\n </button>\n </div>\n <ng-container *ngIf=\"canSendMessages; else notAllowed\">\n <div\n class=\"str-chat__message-input-inner str-chat-angular__message-input-inner\"\n >\n <ng-content select=\"[message-input-start]\"></ng-content>\n <ng-container\n *ngIf=\"isFileUploadEnabled && isFileUploadAuthorized && canSendMessages\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n customAttachmentUploadTemplate || defaultAttachmentUpload;\n context: getAttachmentUploadContext()\n \"\n ></ng-container>\n <ng-template #defaultAttachmentUpload>\n <div\n class=\"str-chat__file-input-container\"\n data-testid=\"file-upload-button\"\n >\n <input\n #fileInput\n type=\"file\"\n class=\"str-chat__file-input\"\n data-testid=\"file-input\"\n [multiple]=\"isMultipleFileUploadEnabled\"\n id=\"{{ fileInputId }}\"\n (change)=\"filesSelected(fileInput.files)\"\n />\n <label class=\"str-chat__file-input-label\" for=\"{{ fileInputId }}\">\n <stream-icon-placeholder icon=\"attach\"></stream-icon-placeholder>\n </label>\n </div>\n </ng-template>\n </ng-container>\n <div class=\"str-chat__message-textarea-container\">\n <div\n *ngIf=\"quotedMessage\"\n data-testid=\"quoted-message-container\"\n class=\"str-chat__quoted-message-preview\"\n >\n <stream-avatar-placeholder\n data-testid=\"qouted-message-avatar\"\n class=\"str-chat-angular__avatar-host str-chat__message-sender-avatar\"\n type=\"user\"\n location=\"quoted-message-sender\"\n [imageUrl]=\"quotedMessage.user?.image\"\n [name]=\"quotedMessage.user?.name || quotedMessage.user?.id\"\n [user]=\"quotedMessage.user || undefined\"\n ></stream-avatar-placeholder>\n <div\n class=\"quoted-message-preview-content-inner str-chat__quoted-message-bubble\"\n >\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 class=\"str-chat__quoted-message-text\"\n data-testid=\"quoted-message-text\"\n [innerHTML]=\"\n quotedMessage.translation ||\n quotedMessage.html ||\n quotedMessage.text\n \"\n ></div>\n </div>\n </div>\n <ng-template\n #defaultAttachmentsPreview\n let-attachmentUploads$=\"attachmentUploads$\"\n let-retryUploadHandler=\"retryUploadHandler\"\n let-deleteUploadHandler=\"deleteUploadHandler\"\n >\n <stream-attachment-preview-list\n class=\"str-chat__attachment-preview-list-angular-host\"\n [attachmentUploads$]=\"attachmentUploads$\"\n (retryAttachmentUpload)=\"retryUploadHandler($event)\"\n (deleteAttachment)=\"deleteUploadHandler($event)\"\n ></stream-attachment-preview-list>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n attachmentPreviewListTemplate || defaultAttachmentsPreview;\n context: getAttachmentPreviewListContext()\n \"\n ></ng-container>\n <div class=\"str-chat__message-textarea-with-emoji-picker\">\n <ng-container\n streamTextarea\n [componentRef]=\"textareaRef\"\n [areMentionsEnabled]=\"areMentionsEnabled\"\n [mentionScope]=\"mentionScope\"\n [inputMode]=\"inputMode\"\n [autoFocus]=\"autoFocus\"\n [placeholder]=\"textareaPlaceholder\"\n [(value)]=\"textareaValue\"\n (valueChange)=\"typingStart$.next()\"\n (send)=\"messageSent()\"\n (userMentions)=\"mentionedUsers = $event\"\n ></ng-container>\n <ng-container *ngIf=\"emojiPickerTemplate\" data-testid=\"emoji-picker\">\n <ng-container\n *ngTemplateOutlet=\"\n emojiPickerTemplate;\n context: getEmojiPickerContext()\n \"\n ></ng-container>\n </ng-container>\n </div>\n </div>\n <button\n *ngIf=\"canSendMessages && !isCooldownInProgress && displaySendButton\"\n data-testid=\"send-button\"\n class=\"str-chat__send-button\"\n [disabled]=\"\n (attachmentUploadInProgressCounter$ | async)! > 0 ||\n (!textareaValue &&\n (attachmentUploads$ | async)!.length === 0 &&\n (customAttachments$ | async)!.length === 0)\n \"\n (click)=\"messageSent()\"\n (keyup.enter)=\"messageSent()\"\n >\n <stream-icon-placeholder icon=\"send\"></stream-icon-placeholder>\n </button>\n <div\n *ngIf=\"isCooldownInProgress\"\n class=\"str-chat__message-input-cooldown\"\n data-testid=\"cooldown-timer\"\n >\n {{ cooldown$ | async }}\n </div>\n <button\n *ngIf=\"displayVoiceRecordingButton\"\n class=\"str-chat__start-recording-audio-button\"\n data-testid=\"start-voice-recording\"\n [disabled]=\"\n voiceRecorderService.isRecorderVisible$.value ||\n audioRecorder?.isRecording\n \"\n (click)=\"startVoiceRecording()\"\n (keyup.enter)=\"startVoiceRecording()\"\n >\n <stream-icon-placeholder icon=\"mic\"></stream-icon-placeholder>\n </button>\n <ng-content select=\"[message-input-end]\"></ng-content>\n </div>\n </ng-container>\n <ng-template #notAllowed>\n <div\n class=\"str-chat__message-input-not-allowed\"\n data-testid=\"disabled-textarea\"\n >\n {{ disabledTextareaText | translate }}\n </div>\n </ng-template>\n</div>\n<ng-template\n *ngIf=\"voiceRecorderRef\"\n [ngTemplateOutlet]=\"voiceRecorderRef\"\n [ngTemplateOutletContext]=\"{ service: voiceRecorderService }\"\n></ng-template>\n", dependencies: [{ kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: AvatarPlaceholderComponent, selector: "stream-avatar-placeholder", inputs: ["name", "imageUrl", "location", "channel", "user", "type", "initialsType", "showOnlineIndicator"] }, { kind: "component", type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon"] }, { kind: "component", type: AttachmentListComponent, selector: "stream-attachment-list", inputs: ["messageId", "parentMessageId", "attachments"], outputs: ["imageModalStateChange"] }, { kind: "component", type: AttachmentPreviewListComponent, selector: "stream-attachment-preview-list", inputs: ["attachmentUploads$"], outputs: ["retryAttachmentUpload", "deleteAttachment"] }, { kind: "directive", type: TextareaDirective, selector: "[streamTextarea]", inputs: ["componentRef", "areMentionsEnabled", "mentionScope", "inputMode", "value", "placeholder", "autoFocus"], outputs: ["valueChange", "send", "userMentions"] }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }, { kind: "pipe", type: i10.TranslatePipe, name: "translate" }] });
|
|
6756
6841
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: MessageInputComponent, decorators: [{
|
|
6757
6842
|
type: Component,
|
|
6758
|
-
args: [{ selector: 'stream-message-input', providers: [AttachmentService, EmojiInputService, VoiceRecorderService], template: "<div\n class=\"str-chat__message-input str-chat-angular__message-input\"\n [style.display]=\"isVoiceRecording ? 'none' : 'flex'\"\n>\n <div *ngIf=\"quotedMessage\" class=\"str-chat__quoted-message-preview-header\">\n <div class=\"str-chat__quoted-message-reply-to-message\">\n {{ \"streamChat.Reply to Message\" | translate }}\n </div>\n <button\n class=\"str-chat__quoted-message-remove\"\n data-testid=\"remove-quote\"\n (click)=\"deselectMessageToQuote()\"\n (keyup.enter)=\"deselectMessageToQuote()\"\n >\n <stream-icon-placeholder icon=\"close\"></stream-icon-placeholder>\n </button>\n </div>\n <div *ngIf=\"isUpdate\" class=\"str-chat__quoted-message-preview-header\">\n <div class=\"str-chat__quoted-message-reply-to-message\">\n {{ \"streamChat.Edit Message\" | translate }}\n </div>\n <button\n class=\"str-chat__quoted-message-remove\"\n data-testid=\"remove-quote\"\n (click)=\"deselectMessageToEdit()\"\n (keyup.enter)=\"deselectMessageToEdit()\"\n >\n <stream-icon-placeholder icon=\"close\"></stream-icon-placeholder>\n </button>\n </div>\n <ng-container *ngIf=\"canSendMessages; else notAllowed\">\n <div\n class=\"str-chat__message-input-inner str-chat-angular__message-input-inner\"\n >\n <ng-content select=\"[message-input-start]\"></ng-content>\n <ng-container\n *ngIf=\"isFileUploadEnabled && isFileUploadAuthorized && canSendMessages\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n customAttachmentUploadTemplate || defaultAttachmentUpload;\n context: getAttachmentUploadContext()\n \"\n ></ng-container>\n <ng-template #defaultAttachmentUpload>\n <div\n class=\"str-chat__file-input-container\"\n data-testid=\"file-upload-button\"\n >\n <input\n #fileInput\n type=\"file\"\n class=\"str-chat__file-input\"\n data-testid=\"file-input\"\n [multiple]=\"isMultipleFileUploadEnabled\"\n id=\"{{ fileInputId }}\"\n (change)=\"filesSelected(fileInput.files)\"\n />\n <label class=\"str-chat__file-input-label\" for=\"{{ fileInputId }}\">\n <stream-icon-placeholder icon=\"attach\"></stream-icon-placeholder>\n </label>\n </div>\n </ng-template>\n </ng-container>\n <div class=\"str-chat__message-textarea-container\">\n <div\n *ngIf=\"quotedMessage\"\n data-testid=\"quoted-message-container\"\n class=\"str-chat__quoted-message-preview\"\n >\n <stream-avatar-placeholder\n data-testid=\"qouted-message-avatar\"\n class=\"str-chat-angular__avatar-host str-chat__message-sender-avatar\"\n type=\"user\"\n location=\"quoted-message-sender\"\n [imageUrl]=\"quotedMessage.user?.image\"\n [name]=\"quotedMessage.user?.name || quotedMessage.user?.id\"\n [user]=\"quotedMessage.user || undefined\"\n ></stream-avatar-placeholder>\n <div\n class=\"quoted-message-preview-content-inner str-chat__quoted-message-bubble\"\n >\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 class=\"str-chat__quoted-message-text\"\n data-testid=\"quoted-message-text\"\n [innerHTML]=\"\n quotedMessage.translation ||\n quotedMessage.html ||\n quotedMessage.text\n \"\n ></div>\n </div>\n </div>\n <ng-template\n #defaultAttachmentsPreview\n let-attachmentUploads$=\"attachmentUploads$\"\n let-retryUploadHandler=\"retryUploadHandler\"\n let-deleteUploadHandler=\"deleteUploadHandler\"\n >\n <stream-attachment-preview-list\n class=\"str-chat__attachment-preview-list-angular-host\"\n [attachmentUploads$]=\"attachmentUploads$\"\n (retryAttachmentUpload)=\"retryUploadHandler($event)\"\n (deleteAttachment)=\"deleteUploadHandler($event)\"\n ></stream-attachment-preview-list>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n attachmentPreviewListTemplate || defaultAttachmentsPreview;\n context: getAttachmentPreviewListContext()\n \"\n ></ng-container>\n <div class=\"str-chat__message-textarea-with-emoji-picker\">\n <ng-container\n streamTextarea\n [componentRef]=\"textareaRef\"\n [areMentionsEnabled]=\"areMentionsEnabled\"\n [mentionScope]=\"mentionScope\"\n [inputMode]=\"inputMode\"\n [autoFocus]=\"autoFocus\"\n [placeholder]=\"textareaPlaceholder\"\n [(value)]=\"textareaValue\"\n (valueChange)=\"typingStart$.next()\"\n (send)=\"messageSent()\"\n (userMentions)=\"mentionedUsers = $event\"\n ></ng-container>\n <ng-container *ngIf=\"emojiPickerTemplate\" data-testid=\"emoji-picker\">\n <ng-container\n *ngTemplateOutlet=\"\n emojiPickerTemplate;\n context: getEmojiPickerContext()\n \"\n ></ng-container>\n </ng-container>\n </div>\n </div>\n <button\n *ngIf=\"canSendMessages && !isCooldownInProgress && displaySendButton\"\n data-testid=\"send-button\"\n class=\"str-chat__send-button\"\n [disabled]=\"\n (attachmentUploadInProgressCounter$ | async)! > 0 ||\n (!textareaValue
|
|
6843
|
+
args: [{ selector: 'stream-message-input', providers: [AttachmentService, EmojiInputService, VoiceRecorderService], template: "<div\n class=\"str-chat__message-input str-chat-angular__message-input\"\n [style.display]=\"isVoiceRecording ? 'none' : 'flex'\"\n>\n <div *ngIf=\"quotedMessage\" class=\"str-chat__quoted-message-preview-header\">\n <div class=\"str-chat__quoted-message-reply-to-message\">\n {{ \"streamChat.Reply to Message\" | translate }}\n </div>\n <button\n class=\"str-chat__quoted-message-remove\"\n data-testid=\"remove-quote\"\n (click)=\"deselectMessageToQuote()\"\n (keyup.enter)=\"deselectMessageToQuote()\"\n >\n <stream-icon-placeholder icon=\"close\"></stream-icon-placeholder>\n </button>\n </div>\n <div *ngIf=\"isUpdate\" class=\"str-chat__quoted-message-preview-header\">\n <div class=\"str-chat__quoted-message-reply-to-message\">\n {{ \"streamChat.Edit Message\" | translate }}\n </div>\n <button\n class=\"str-chat__quoted-message-remove\"\n data-testid=\"remove-quote\"\n (click)=\"deselectMessageToEdit()\"\n (keyup.enter)=\"deselectMessageToEdit()\"\n >\n <stream-icon-placeholder icon=\"close\"></stream-icon-placeholder>\n </button>\n </div>\n <ng-container *ngIf=\"canSendMessages; else notAllowed\">\n <div\n class=\"str-chat__message-input-inner str-chat-angular__message-input-inner\"\n >\n <ng-content select=\"[message-input-start]\"></ng-content>\n <ng-container\n *ngIf=\"isFileUploadEnabled && isFileUploadAuthorized && canSendMessages\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n customAttachmentUploadTemplate || defaultAttachmentUpload;\n context: getAttachmentUploadContext()\n \"\n ></ng-container>\n <ng-template #defaultAttachmentUpload>\n <div\n class=\"str-chat__file-input-container\"\n data-testid=\"file-upload-button\"\n >\n <input\n #fileInput\n type=\"file\"\n class=\"str-chat__file-input\"\n data-testid=\"file-input\"\n [multiple]=\"isMultipleFileUploadEnabled\"\n id=\"{{ fileInputId }}\"\n (change)=\"filesSelected(fileInput.files)\"\n />\n <label class=\"str-chat__file-input-label\" for=\"{{ fileInputId }}\">\n <stream-icon-placeholder icon=\"attach\"></stream-icon-placeholder>\n </label>\n </div>\n </ng-template>\n </ng-container>\n <div class=\"str-chat__message-textarea-container\">\n <div\n *ngIf=\"quotedMessage\"\n data-testid=\"quoted-message-container\"\n class=\"str-chat__quoted-message-preview\"\n >\n <stream-avatar-placeholder\n data-testid=\"qouted-message-avatar\"\n class=\"str-chat-angular__avatar-host str-chat__message-sender-avatar\"\n type=\"user\"\n location=\"quoted-message-sender\"\n [imageUrl]=\"quotedMessage.user?.image\"\n [name]=\"quotedMessage.user?.name || quotedMessage.user?.id\"\n [user]=\"quotedMessage.user || undefined\"\n ></stream-avatar-placeholder>\n <div\n class=\"quoted-message-preview-content-inner str-chat__quoted-message-bubble\"\n >\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 class=\"str-chat__quoted-message-text\"\n data-testid=\"quoted-message-text\"\n [innerHTML]=\"\n quotedMessage.translation ||\n quotedMessage.html ||\n quotedMessage.text\n \"\n ></div>\n </div>\n </div>\n <ng-template\n #defaultAttachmentsPreview\n let-attachmentUploads$=\"attachmentUploads$\"\n let-retryUploadHandler=\"retryUploadHandler\"\n let-deleteUploadHandler=\"deleteUploadHandler\"\n >\n <stream-attachment-preview-list\n class=\"str-chat__attachment-preview-list-angular-host\"\n [attachmentUploads$]=\"attachmentUploads$\"\n (retryAttachmentUpload)=\"retryUploadHandler($event)\"\n (deleteAttachment)=\"deleteUploadHandler($event)\"\n ></stream-attachment-preview-list>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n attachmentPreviewListTemplate || defaultAttachmentsPreview;\n context: getAttachmentPreviewListContext()\n \"\n ></ng-container>\n <div class=\"str-chat__message-textarea-with-emoji-picker\">\n <ng-container\n streamTextarea\n [componentRef]=\"textareaRef\"\n [areMentionsEnabled]=\"areMentionsEnabled\"\n [mentionScope]=\"mentionScope\"\n [inputMode]=\"inputMode\"\n [autoFocus]=\"autoFocus\"\n [placeholder]=\"textareaPlaceholder\"\n [(value)]=\"textareaValue\"\n (valueChange)=\"typingStart$.next()\"\n (send)=\"messageSent()\"\n (userMentions)=\"mentionedUsers = $event\"\n ></ng-container>\n <ng-container *ngIf=\"emojiPickerTemplate\" data-testid=\"emoji-picker\">\n <ng-container\n *ngTemplateOutlet=\"\n emojiPickerTemplate;\n context: getEmojiPickerContext()\n \"\n ></ng-container>\n </ng-container>\n </div>\n </div>\n <button\n *ngIf=\"canSendMessages && !isCooldownInProgress && displaySendButton\"\n data-testid=\"send-button\"\n class=\"str-chat__send-button\"\n [disabled]=\"\n (attachmentUploadInProgressCounter$ | async)! > 0 ||\n (!textareaValue &&\n (attachmentUploads$ | async)!.length === 0 &&\n (customAttachments$ | async)!.length === 0)\n \"\n (click)=\"messageSent()\"\n (keyup.enter)=\"messageSent()\"\n >\n <stream-icon-placeholder icon=\"send\"></stream-icon-placeholder>\n </button>\n <div\n *ngIf=\"isCooldownInProgress\"\n class=\"str-chat__message-input-cooldown\"\n data-testid=\"cooldown-timer\"\n >\n {{ cooldown$ | async }}\n </div>\n <button\n *ngIf=\"displayVoiceRecordingButton\"\n class=\"str-chat__start-recording-audio-button\"\n data-testid=\"start-voice-recording\"\n [disabled]=\"\n voiceRecorderService.isRecorderVisible$.value ||\n audioRecorder?.isRecording\n \"\n (click)=\"startVoiceRecording()\"\n (keyup.enter)=\"startVoiceRecording()\"\n >\n <stream-icon-placeholder icon=\"mic\"></stream-icon-placeholder>\n </button>\n <ng-content select=\"[message-input-end]\"></ng-content>\n </div>\n </ng-container>\n <ng-template #notAllowed>\n <div\n class=\"str-chat__message-input-not-allowed\"\n data-testid=\"disabled-textarea\"\n >\n {{ disabledTextareaText | translate }}\n </div>\n </ng-template>\n</div>\n<ng-template\n *ngIf=\"voiceRecorderRef\"\n [ngTemplateOutlet]=\"voiceRecorderRef\"\n [ngTemplateOutletContext]=\"{ service: voiceRecorderService }\"\n></ng-template>\n" }]
|
|
6759
6844
|
}], ctorParameters: function () {
|
|
6760
6845
|
return [{ type: ChannelService }, { type: NotificationService }, { type: AttachmentService }, { type: MessageInputConfigService }, { type: i0.Type, decorators: [{
|
|
6761
6846
|
type: Inject,
|