stream-chat-angular 4.59.2 → 4.60.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/i18n/en.d.ts +2 -0
- package/assets/version.d.ts +1 -1
- package/bundles/stream-chat-angular.umd.js +347 -173
- package/bundles/stream-chat-angular.umd.js.map +1 -1
- package/esm2015/assets/i18n/en.js +3 -1
- package/esm2015/assets/version.js +2 -2
- package/esm2015/lib/channel/channel.component.js +13 -9
- package/esm2015/lib/channel.service.js +24 -2
- package/esm2015/lib/custom-templates.service.js +9 -1
- package/esm2015/lib/edit-message-form/edit-message-form.component.js +87 -0
- package/esm2015/lib/message/message.component.js +16 -25
- package/esm2015/lib/message-actions-box/message-actions-box.component.js +6 -46
- package/esm2015/lib/message-bounce-prompt/message-bounce-prompt.component.js +80 -0
- package/esm2015/lib/message-list/message-list.component.js +14 -8
- package/esm2015/lib/parse-date.js +2 -2
- package/esm2015/lib/stream-chat.module.js +13 -3
- package/esm2015/lib/types.js +1 -1
- package/esm2015/public-api.js +3 -1
- package/fesm2015/stream-chat-angular.js +319 -169
- package/fesm2015/stream-chat-angular.js.map +1 -1
- package/lib/channel/channel.component.d.ts +3 -1
- package/lib/channel.service.d.ts +10 -9
- package/lib/custom-templates.service.d.ts +8 -0
- package/lib/edit-message-form/edit-message-form.component.d.ts +31 -0
- package/lib/message/message.component.d.ts +2 -1
- package/lib/message-actions-box/message-actions-box.component.d.ts +2 -11
- package/lib/message-bounce-prompt/message-bounce-prompt.component.d.ts +28 -0
- package/lib/stream-chat.module.d.ts +7 -5
- package/lib/types.d.ts +0 -6
- package/package.json +1 -1
- package/public-api.d.ts +2 -0
- package/src/assets/i18n/en.ts +3 -0
- package/src/assets/styles/css/index.css +1 -1
- package/src/assets/styles/scss/Message.scss +21 -17
- package/src/assets/styles/scss/MessageActions.scss +0 -9
- package/src/assets/styles/scss/_base.scss +8 -1
- package/src/assets/styles/v2/css/index.css +1 -1
- package/src/assets/styles/v2/css/index.layout.css +1 -1
- package/src/assets/styles/v2/scss/AttachmentList/AttachmentList-layout.scss +6 -0
- package/src/assets/styles/v2/scss/EditMessageForm/EditMessageForm-layout.scss +13 -15
- package/src/assets/styles/v2/scss/Message/Message-layout.scss +14 -3
- package/src/assets/styles/v2/scss/MessageActionsBox/MessageActionsBox-layout.scss +0 -8
- package/src/assets/styles/v2/scss/_utils.scss +0 -1
- package/src/assets/version.ts +1 -1
|
@@ -20,7 +20,7 @@ import transliterate from '@stream-io/transliterate';
|
|
|
20
20
|
import * as i8 from 'angular-mentions';
|
|
21
21
|
import { MentionModule } from 'angular-mentions';
|
|
22
22
|
|
|
23
|
-
const version = '4.
|
|
23
|
+
const version = '4.60.0';
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
26
|
* The `NotificationService` can be used to add or remove notifications. By default the [`NotificationList`](../components/NotificationListComponent.mdx) component displays the currently active notifications.
|
|
@@ -384,6 +384,7 @@ class ChannelService {
|
|
|
384
384
|
const channel = this.activeChannelSubject.getValue();
|
|
385
385
|
return messages.map((message) => this.transformToStreamMessage(message, channel));
|
|
386
386
|
}), shareReplay(1));
|
|
387
|
+
this.bouncedMessage$ = new BehaviorSubject(undefined);
|
|
387
388
|
this.hasMoreChannels$ = this.hasMoreChannelsSubject
|
|
388
389
|
.asObservable()
|
|
389
390
|
.pipe(shareReplay(1));
|
|
@@ -725,18 +726,39 @@ class ChannelService {
|
|
|
725
726
|
if (this.beforeUpdateMessage) {
|
|
726
727
|
messageToUpdate = yield this.beforeUpdateMessage(messageToUpdate);
|
|
727
728
|
}
|
|
729
|
+
if (message.moderation_details) {
|
|
730
|
+
return this.resendMessage(message);
|
|
731
|
+
}
|
|
728
732
|
const response = yield this.chatClientService.chatClient.updateMessage(messageToUpdate);
|
|
729
733
|
const channel = (_a = this.channelsSubject
|
|
730
734
|
.getValue()) === null || _a === void 0 ? void 0 : _a.find((c) => c.cid === message.cid);
|
|
735
|
+
if (response.message.type === 'error' &&
|
|
736
|
+
response.message.moderation_details) {
|
|
737
|
+
this.notificationService.addTemporaryNotification('streamChat.This message did not meet our content guidelines');
|
|
738
|
+
return message;
|
|
739
|
+
}
|
|
731
740
|
return this.transformToStreamMessage(response.message, channel);
|
|
732
741
|
});
|
|
733
742
|
}
|
|
734
743
|
/**
|
|
735
744
|
* Deletes the message from the active channel
|
|
736
745
|
* @param message Message to be deleted
|
|
746
|
+
* @param isLocalDelete set this `true` if you want to delete a message that's only part of the local state, not yet saved on the backend
|
|
737
747
|
*/
|
|
738
|
-
deleteMessage(message) {
|
|
748
|
+
deleteMessage(message, isLocalDelete = false) {
|
|
739
749
|
return __awaiter(this, void 0, void 0, function* () {
|
|
750
|
+
if (isLocalDelete && this.activeChannel) {
|
|
751
|
+
const result = this.activeChannel.state.removeMessage({
|
|
752
|
+
id: message.id,
|
|
753
|
+
parent_id: message.parent_id,
|
|
754
|
+
});
|
|
755
|
+
if (result) {
|
|
756
|
+
message.parent_id
|
|
757
|
+
? this.activeThreadMessagesSubject.next(this.activeChannel.state.threads[message.parent_id])
|
|
758
|
+
: this.activeChannelMessagesSubject.next(this.activeChannel.state.messages);
|
|
759
|
+
}
|
|
760
|
+
return;
|
|
761
|
+
}
|
|
740
762
|
if (this.messageDeleteConfirmationHandler) {
|
|
741
763
|
const result = yield this.messageDeleteConfirmationHandler(message);
|
|
742
764
|
if (result) {
|
|
@@ -2449,6 +2471,8 @@ const en = {
|
|
|
2449
2471
|
'Unread messages': 'Unread messages',
|
|
2450
2472
|
'{{count}} unread messages': '{{count}} unread messages',
|
|
2451
2473
|
'{{count}} unread message': '{{count}} unread message',
|
|
2474
|
+
'This message did not meet our content guidelines': 'This message did not meet our content guidelines',
|
|
2475
|
+
'Send Anyway': 'Send Anyway',
|
|
2452
2476
|
},
|
|
2453
2477
|
};
|
|
2454
2478
|
|
|
@@ -2865,6 +2889,14 @@ class CustomTemplatesService {
|
|
|
2865
2889
|
* The template to show if the thread message list is empty
|
|
2866
2890
|
*/
|
|
2867
2891
|
this.emptyThreadMessageListPlaceholder$ = new BehaviorSubject(undefined);
|
|
2892
|
+
/**
|
|
2893
|
+
* The template used to display the [edit message form](../components/EditMessageFormComponent.mdx)
|
|
2894
|
+
*/
|
|
2895
|
+
this.editMessageFormTemplate$ = new BehaviorSubject(undefined);
|
|
2896
|
+
/**
|
|
2897
|
+
* The template used to display the [message bounce prompt](../components/MessageBouncePromptComponent.mdx)
|
|
2898
|
+
*/
|
|
2899
|
+
this.messageBouncePromptTemplate$ = new BehaviorSubject(undefined);
|
|
2868
2900
|
}
|
|
2869
2901
|
}
|
|
2870
2902
|
CustomTemplatesService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: CustomTemplatesService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
@@ -3175,6 +3207,137 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
3175
3207
|
}]
|
|
3176
3208
|
}], ctorParameters: function () { return [{ type: ChatClientService }, { type: NotificationService }, { type: ChannelService }]; } });
|
|
3177
3209
|
|
|
3210
|
+
/**
|
|
3211
|
+
* The `MessageActionsBox` component displays a list of message actions (i.e edit), that can be opened or closed. You can find the [list of the supported actions](../concepts/message-interactions.mdx) in the message interaction guide.
|
|
3212
|
+
*/
|
|
3213
|
+
class MessageActionsBoxComponent {
|
|
3214
|
+
constructor(customTemplatesService, messageActionsService, cdRef) {
|
|
3215
|
+
this.customTemplatesService = customTemplatesService;
|
|
3216
|
+
this.messageActionsService = messageActionsService;
|
|
3217
|
+
this.cdRef = cdRef;
|
|
3218
|
+
/**
|
|
3219
|
+
* Indicates if the list should be opened or closed. Adding a UI element to open and close the list is the parent's component responsibility.
|
|
3220
|
+
* @deprecated No need for this since [theme-v2](../theming/introduction.mdx)
|
|
3221
|
+
*/
|
|
3222
|
+
this.isOpen = false;
|
|
3223
|
+
/**
|
|
3224
|
+
* Indicates if the message actions are belonging to a message that was sent by the current user or not.
|
|
3225
|
+
*/
|
|
3226
|
+
this.isMine = false;
|
|
3227
|
+
/**
|
|
3228
|
+
* The list of [channel capabilities](https://getstream.io/chat/docs/javascript/channel_capabilities/?language=javascript) that are enabled for the current user, the list of [supported interactions](../concepts/message-interactions.mdx) can be found in our message interaction guide. Unathorized actions won't be displayed on the UI.
|
|
3229
|
+
*/
|
|
3230
|
+
this.enabledActions = [];
|
|
3231
|
+
/**
|
|
3232
|
+
* A list of custom message actions to be displayed in the action box
|
|
3233
|
+
*
|
|
3234
|
+
* In the next major release this will be released with `messageReactionsService.customActions$`
|
|
3235
|
+
*
|
|
3236
|
+
* More information: https://getstream.io/chat/docs/sdk/angular/services/MessageActionsService
|
|
3237
|
+
*/
|
|
3238
|
+
this.customActions = [];
|
|
3239
|
+
/**
|
|
3240
|
+
* The number of authorized actions (it can be less or equal than the number of enabled actions)
|
|
3241
|
+
*
|
|
3242
|
+
* @deprecated components should use `messageReactionsService.getAuthorizedMessageActionsCount` method
|
|
3243
|
+
*
|
|
3244
|
+
* More information: https://getstream.io/chat/docs/sdk/angular/services/MessageActionsService
|
|
3245
|
+
*/
|
|
3246
|
+
this.displayedActionsCount = new EventEmitter();
|
|
3247
|
+
/**
|
|
3248
|
+
* An event which emits `true` if the edit message modal is open, and `false` when it is closed.
|
|
3249
|
+
*
|
|
3250
|
+
* @deprecated components should use `messageReactionsService.messageToEdit$` Observable
|
|
3251
|
+
*
|
|
3252
|
+
* More information: https://getstream.io/chat/docs/sdk/angular/services/MessageActionsService
|
|
3253
|
+
*/
|
|
3254
|
+
this.isEditing = new EventEmitter();
|
|
3255
|
+
this.visibleMessageActionItems = [];
|
|
3256
|
+
this.isEditModalOpen = false;
|
|
3257
|
+
this.subscriptions = [];
|
|
3258
|
+
this.isViewInited = false;
|
|
3259
|
+
this.messageActionItems = this.messageActionsService.defaultActions;
|
|
3260
|
+
}
|
|
3261
|
+
ngOnInit() {
|
|
3262
|
+
this.subscriptions.push(this.messageActionsService.messageToEdit$.subscribe((m) => {
|
|
3263
|
+
var _a;
|
|
3264
|
+
let isEditModalOpen = false;
|
|
3265
|
+
if (m && m.id === ((_a = this.message) === null || _a === void 0 ? void 0 : _a.id)) {
|
|
3266
|
+
isEditModalOpen = true;
|
|
3267
|
+
}
|
|
3268
|
+
if (isEditModalOpen !== this.isEditModalOpen) {
|
|
3269
|
+
this.isEditModalOpen = isEditModalOpen;
|
|
3270
|
+
this.isEditing.emit(this.isEditModalOpen);
|
|
3271
|
+
if (this.isViewInited) {
|
|
3272
|
+
this.cdRef.detectChanges();
|
|
3273
|
+
}
|
|
3274
|
+
}
|
|
3275
|
+
}));
|
|
3276
|
+
}
|
|
3277
|
+
ngOnChanges(changes) {
|
|
3278
|
+
if (changes.isMine ||
|
|
3279
|
+
changes.enabledActions ||
|
|
3280
|
+
changes.message ||
|
|
3281
|
+
changes.customActions) {
|
|
3282
|
+
this.setVisibleActions();
|
|
3283
|
+
}
|
|
3284
|
+
}
|
|
3285
|
+
ngAfterViewInit() {
|
|
3286
|
+
this.isViewInited = true;
|
|
3287
|
+
}
|
|
3288
|
+
ngOnDestroy() {
|
|
3289
|
+
this.subscriptions.forEach((s) => s.unsubscribe());
|
|
3290
|
+
}
|
|
3291
|
+
getActionLabel(actionLabelOrTranslationKey) {
|
|
3292
|
+
return typeof actionLabelOrTranslationKey === 'string'
|
|
3293
|
+
? actionLabelOrTranslationKey
|
|
3294
|
+
: actionLabelOrTranslationKey(this.message);
|
|
3295
|
+
}
|
|
3296
|
+
getMessageActionTemplateContext(item) {
|
|
3297
|
+
return {
|
|
3298
|
+
actionHandler: item.actionHandler,
|
|
3299
|
+
isMine: this.isMine,
|
|
3300
|
+
actionName: item.actionName,
|
|
3301
|
+
message: this.message,
|
|
3302
|
+
actionLabelOrTranslationKey: item.actionLabelOrTranslationKey,
|
|
3303
|
+
};
|
|
3304
|
+
}
|
|
3305
|
+
trackByActionName(_, item) {
|
|
3306
|
+
return item.actionName;
|
|
3307
|
+
}
|
|
3308
|
+
setVisibleActions() {
|
|
3309
|
+
this.visibleMessageActionItems = [
|
|
3310
|
+
...this.messageActionItems,
|
|
3311
|
+
...this.customActions,
|
|
3312
|
+
].filter((item) => item.isVisible(this.enabledActions, this.isMine, this.message));
|
|
3313
|
+
this.displayedActionsCount.emit(this.visibleMessageActionItems.length);
|
|
3314
|
+
}
|
|
3315
|
+
}
|
|
3316
|
+
MessageActionsBoxComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: MessageActionsBoxComponent, deps: [{ token: CustomTemplatesService }, { token: MessageActionsService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
3317
|
+
MessageActionsBoxComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: MessageActionsBoxComponent, selector: "stream-message-actions-box", inputs: { isOpen: "isOpen", isMine: "isMine", message: "message", enabledActions: "enabledActions", customActions: "customActions" }, outputs: { displayedActionsCount: "displayedActionsCount", isEditing: "isEditing" }, usesOnChanges: true, ngImport: i0, template: "<div\n #actionBox\n data-testid=\"action-box\"\n class=\"str-chat__message-actions-box str-chat__message-actions-box-angular\"\n [class.str-chat__message-actions-box--open]=\"true\"\n>\n <ul class=\"str-chat__message-actions-list\">\n <ng-container\n *ngFor=\"let item of visibleMessageActionItems; trackBy: trackByActionName\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.messageActionsBoxItemTemplate$ | async) ||\n defaultMessageActionItem;\n context: getMessageActionTemplateContext(item)\n \"\n ></ng-container>\n </ng-container>\n </ul>\n</div>\n\n<ng-template\n #defaultMessageActionItem\n let-actionName=\"actionName\"\n let-actionHandler=\"actionHandler\"\n let-actionLabelOrTranslationKey=\"actionLabelOrTranslationKey\"\n>\n <button\n class=\"str-chat__message-actions-list-item-button\"\n [attr.data-testid]=\"actionName + '-action'\"\n (click)=\"actionHandler(message, isMine)\"\n >\n <li class=\"str-chat__message-actions-list-item\">\n {{ getActionLabel(actionLabelOrTranslationKey) | translate }}\n </li>\n </button>\n</ng-template>\n", directives: [{ type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i5.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], pipes: { "async": i5.AsyncPipe, "translate": i6.TranslatePipe } });
|
|
3318
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: MessageActionsBoxComponent, decorators: [{
|
|
3319
|
+
type: Component,
|
|
3320
|
+
args: [{
|
|
3321
|
+
selector: 'stream-message-actions-box',
|
|
3322
|
+
templateUrl: './message-actions-box.component.html',
|
|
3323
|
+
styles: [],
|
|
3324
|
+
}]
|
|
3325
|
+
}], ctorParameters: function () { return [{ type: CustomTemplatesService }, { type: MessageActionsService }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { isOpen: [{
|
|
3326
|
+
type: Input
|
|
3327
|
+
}], isMine: [{
|
|
3328
|
+
type: Input
|
|
3329
|
+
}], message: [{
|
|
3330
|
+
type: Input
|
|
3331
|
+
}], enabledActions: [{
|
|
3332
|
+
type: Input
|
|
3333
|
+
}], customActions: [{
|
|
3334
|
+
type: Input
|
|
3335
|
+
}], displayedActionsCount: [{
|
|
3336
|
+
type: Output
|
|
3337
|
+
}], isEditing: [{
|
|
3338
|
+
type: Output
|
|
3339
|
+
}] } });
|
|
3340
|
+
|
|
3178
3341
|
/**
|
|
3179
3342
|
* The `Modal` component displays its content in an overlay. The modal can be closed with a close button, if the user clicks outside of the modal content, or if the escape button is pressed. The modal can also be closed from outside.
|
|
3180
3343
|
*/
|
|
@@ -4105,113 +4268,49 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
4105
4268
|
}], ctorParameters: function () { return [{ type: CustomTemplatesService }, { type: NotificationService }, { type: ThemeService }]; } });
|
|
4106
4269
|
|
|
4107
4270
|
/**
|
|
4108
|
-
* The
|
|
4271
|
+
* The edit message form displays a modal that's opened when a user edits a message. The component uses the [`MessageActionsService`](../../services/MessageActionsService) to know which message is being edited.
|
|
4272
|
+
*
|
|
4273
|
+
* By default this is displayed within the [`stream-channel` component](../../components/ChannelComponent).
|
|
4109
4274
|
*/
|
|
4110
|
-
class
|
|
4111
|
-
constructor(customTemplatesService, messageActionsService
|
|
4275
|
+
class EditMessageFormComponent {
|
|
4276
|
+
constructor(customTemplatesService, messageActionsService) {
|
|
4112
4277
|
this.customTemplatesService = customTemplatesService;
|
|
4113
4278
|
this.messageActionsService = messageActionsService;
|
|
4114
|
-
this.
|
|
4115
|
-
|
|
4116
|
-
* Indicates if the list should be opened or closed. Adding a UI element to open and close the list is the parent's component responsibility.
|
|
4117
|
-
* @deprecated No need for this since [theme-v2](../theming/introduction.mdx)
|
|
4118
|
-
*/
|
|
4119
|
-
this.isOpen = false;
|
|
4120
|
-
/**
|
|
4121
|
-
* Indicates if the message actions are belonging to a message that was sent by the current user or not.
|
|
4122
|
-
*/
|
|
4123
|
-
this.isMine = false;
|
|
4124
|
-
/**
|
|
4125
|
-
* The list of [channel capabilities](https://getstream.io/chat/docs/javascript/channel_capabilities/?language=javascript) that are enabled for the current user, the list of [supported interactions](../concepts/message-interactions.mdx) can be found in our message interaction guide. Unathorized actions won't be displayed on the UI.
|
|
4126
|
-
*/
|
|
4127
|
-
this.enabledActions = [];
|
|
4128
|
-
/**
|
|
4129
|
-
* A list of custom message actions to be displayed in the action box
|
|
4130
|
-
*
|
|
4131
|
-
* In the next major release this will be released with `messageReactionsService.customActions$`
|
|
4132
|
-
*
|
|
4133
|
-
* More information: https://getstream.io/chat/docs/sdk/angular/services/MessageActionsService
|
|
4134
|
-
*/
|
|
4135
|
-
this.customActions = [];
|
|
4136
|
-
/**
|
|
4137
|
-
* The number of authorized actions (it can be less or equal than the number of enabled actions)
|
|
4138
|
-
*
|
|
4139
|
-
* @deprecated components should use `messageReactionsService.getAuthorizedMessageActionsCount` method
|
|
4140
|
-
*
|
|
4141
|
-
* More information: https://getstream.io/chat/docs/sdk/angular/services/MessageActionsService
|
|
4142
|
-
*/
|
|
4143
|
-
this.displayedActionsCount = new EventEmitter();
|
|
4144
|
-
/**
|
|
4145
|
-
* An event which emits `true` if the edit message modal is open, and `false` when it is closed.
|
|
4146
|
-
*
|
|
4147
|
-
* @deprecated components should use `messageReactionsService.messageToEdit$` Observable
|
|
4148
|
-
*
|
|
4149
|
-
* More information: https://getstream.io/chat/docs/sdk/angular/services/MessageActionsService
|
|
4150
|
-
*/
|
|
4151
|
-
this.isEditing = new EventEmitter();
|
|
4152
|
-
this.isEditModalOpen = false;
|
|
4153
|
-
this.visibleMessageActionItems = [];
|
|
4279
|
+
this.class = 'str-chat-angular__edit-message-form';
|
|
4280
|
+
this.isModalOpen = false;
|
|
4154
4281
|
this.sendMessageSubject = new Subject();
|
|
4155
4282
|
this.subscriptions = [];
|
|
4156
|
-
this.isViewInited = false;
|
|
4157
|
-
this.modalClosed = () => {
|
|
4158
|
-
this.isEditModalOpen = false;
|
|
4159
|
-
this.messageActionsService.messageToEdit$.next(undefined);
|
|
4160
|
-
};
|
|
4161
|
-
this.messageActionItems = this.messageActionsService.defaultActions;
|
|
4162
4283
|
this.sendMessage$ = this.sendMessageSubject.asObservable();
|
|
4163
4284
|
}
|
|
4164
4285
|
ngOnInit() {
|
|
4165
|
-
this.
|
|
4166
|
-
|
|
4167
|
-
|
|
4168
|
-
|
|
4169
|
-
isEditModalOpen = true;
|
|
4286
|
+
this.messageActionsService.messageToEdit$.subscribe((message) => {
|
|
4287
|
+
if ((message && !this.isModalOpen) || (!message && this.isModalOpen)) {
|
|
4288
|
+
this.message = message;
|
|
4289
|
+
this.isModalOpen = !!message;
|
|
4170
4290
|
}
|
|
4171
|
-
|
|
4172
|
-
this.isEditModalOpen = isEditModalOpen;
|
|
4173
|
-
this.isEditing.emit(this.isEditModalOpen);
|
|
4174
|
-
if (this.isViewInited) {
|
|
4175
|
-
this.cdRef.detectChanges();
|
|
4176
|
-
}
|
|
4177
|
-
}
|
|
4178
|
-
}));
|
|
4179
|
-
}
|
|
4180
|
-
ngOnChanges(changes) {
|
|
4181
|
-
if (changes.isMine ||
|
|
4182
|
-
changes.enabledActions ||
|
|
4183
|
-
changes.message ||
|
|
4184
|
-
changes.customActions) {
|
|
4185
|
-
this.setVisibleActions();
|
|
4186
|
-
}
|
|
4187
|
-
}
|
|
4188
|
-
ngAfterViewInit() {
|
|
4189
|
-
this.isViewInited = true;
|
|
4291
|
+
});
|
|
4190
4292
|
}
|
|
4191
4293
|
ngOnDestroy() {
|
|
4192
4294
|
this.subscriptions.forEach((s) => s.unsubscribe());
|
|
4193
4295
|
}
|
|
4194
|
-
|
|
4195
|
-
return typeof actionLabelOrTranslationKey === 'string'
|
|
4196
|
-
? actionLabelOrTranslationKey
|
|
4197
|
-
: actionLabelOrTranslationKey(this.message);
|
|
4198
|
-
}
|
|
4199
|
-
getMessageActionTemplateContext(item) {
|
|
4296
|
+
getEditModalContext() {
|
|
4200
4297
|
return {
|
|
4201
|
-
|
|
4202
|
-
|
|
4203
|
-
|
|
4204
|
-
|
|
4205
|
-
|
|
4298
|
+
isOpen: this.isModalOpen,
|
|
4299
|
+
isOpenChangeHandler: (isOpen) => {
|
|
4300
|
+
this.isModalOpen = isOpen;
|
|
4301
|
+
if (!this.isModalOpen) {
|
|
4302
|
+
this.dismissed();
|
|
4303
|
+
}
|
|
4304
|
+
},
|
|
4305
|
+
content: this.modalContent,
|
|
4206
4306
|
};
|
|
4207
4307
|
}
|
|
4208
|
-
sendClicked() {
|
|
4209
|
-
this.sendMessageSubject.next();
|
|
4210
|
-
}
|
|
4211
4308
|
getMessageInputContext() {
|
|
4212
4309
|
return {
|
|
4213
4310
|
message: this.message,
|
|
4214
|
-
messageUpdateHandler:
|
|
4311
|
+
messageUpdateHandler: () => {
|
|
4312
|
+
this.dismissed();
|
|
4313
|
+
},
|
|
4215
4314
|
isFileUploadEnabled: undefined,
|
|
4216
4315
|
areMentionsEnabled: undefined,
|
|
4217
4316
|
isMultipleFileUploadEnabled: undefined,
|
|
@@ -4220,64 +4319,110 @@ class MessageActionsBoxComponent {
|
|
|
4220
4319
|
sendMessage$: this.sendMessage$,
|
|
4221
4320
|
};
|
|
4222
4321
|
}
|
|
4223
|
-
|
|
4224
|
-
|
|
4225
|
-
isOpen: this.isEditModalOpen,
|
|
4226
|
-
isOpenChangeHandler: (isOpen) => {
|
|
4227
|
-
this.isEditModalOpen = isOpen;
|
|
4228
|
-
if (!this.isEditModalOpen) {
|
|
4229
|
-
this.modalClosed();
|
|
4230
|
-
}
|
|
4231
|
-
},
|
|
4232
|
-
content: this.modalContent,
|
|
4233
|
-
};
|
|
4234
|
-
}
|
|
4235
|
-
trackByActionName(_, item) {
|
|
4236
|
-
return item.actionName;
|
|
4322
|
+
sendClicked() {
|
|
4323
|
+
this.sendMessageSubject.next();
|
|
4237
4324
|
}
|
|
4238
|
-
|
|
4239
|
-
this.
|
|
4240
|
-
|
|
4241
|
-
|
|
4242
|
-
].filter((item) => item.isVisible(this.enabledActions, this.isMine, this.message));
|
|
4243
|
-
this.displayedActionsCount.emit(this.visibleMessageActionItems.length);
|
|
4325
|
+
dismissed() {
|
|
4326
|
+
this.isModalOpen = false;
|
|
4327
|
+
this.message = undefined;
|
|
4328
|
+
this.messageActionsService.messageToEdit$.next(undefined);
|
|
4244
4329
|
}
|
|
4245
4330
|
}
|
|
4246
|
-
|
|
4247
|
-
|
|
4248
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type:
|
|
4331
|
+
EditMessageFormComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: EditMessageFormComponent, deps: [{ token: CustomTemplatesService }, { token: MessageActionsService }], target: i0.ɵɵFactoryTarget.Component });
|
|
4332
|
+
EditMessageFormComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: EditMessageFormComponent, selector: "stream-edit-message-form", host: { properties: { "class": "this.class" } }, viewQueries: [{ propertyName: "modalContent", first: true, predicate: ["editMessageForm"], descendants: true, static: true }], ngImport: i0, template: "<ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.modalTemplate$ | async) || defaultModal;\n context: getEditModalContext()\n \"\n></ng-container>\n\n<ng-template\n #defaultModal\n let-isOpen=\"isOpen\"\n let-isOpenChangeHandler=\"isOpenChangeHandler\"\n let-content=\"content\"\n>\n <stream-modal\n [isOpen]=\"isOpen\"\n *ngIf=\"isOpen\"\n (isOpenChange)=\"isOpenChangeHandler($event)\"\n [content]=\"content\"\n >\n </stream-modal>\n</ng-template>\n\n<ng-template #editMessageForm>\n <div class=\"str-chat__edit-message-form\">\n <ng-template\n #defaultInput\n let-messageInput=\"message\"\n let-messageUpdateHandler=\"messageUpdateHandler\"\n let-sendMessage$Input=\"sendMessage$\"\n >\n <stream-message-input\n [message]=\"messageInput\"\n (messageUpdate)=\"messageUpdateHandler()\"\n [sendMessage$]=\"sendMessage$Input\"\n ></stream-message-input>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.messageInputTemplate$ | async) || defaultInput;\n context: getMessageInputContext()\n \"\n >\n </ng-container>\n\n <stream-notification-list></stream-notification-list>\n <div\n class=\"\n str-chat__message-team-form-footer\n str-chat__message-team-form-footer-angular\n \"\n >\n <div class=\"str-chat__edit-message-form-options\">\n <button\n class=\"str-chat__edit-message-cancel\"\n translate\n data-testid=\"cancel-button\"\n (click)=\"dismissed()\"\n >\n streamChat.Cancel\n </button>\n <button\n type=\"submit\"\n translate\n class=\"str-chat__edit-message-send\"\n data-testid=\"send-button\"\n (click)=\"sendClicked()\"\n (keyup.enter)=\"sendClicked()\"\n >\n streamChat.Send\n </button>\n </div>\n </div>\n </div>\n</ng-template>\n", components: [{ type: ModalComponent, selector: "stream-modal", inputs: ["isOpen", "content"], outputs: ["isOpenChange"] }, { type: MessageInputComponent, selector: "stream-message-input", inputs: ["isFileUploadEnabled", "areMentionsEnabled", "mentionScope", "mode", "isMultipleFileUploadEnabled", "message", "sendMessage$", "inputMode", "autoFocus"], outputs: ["messageUpdate"] }, { type: NotificationListComponent, selector: "stream-notification-list" }], directives: [{ type: i5.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i6.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }], pipes: { "async": i5.AsyncPipe } });
|
|
4333
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: EditMessageFormComponent, decorators: [{
|
|
4249
4334
|
type: Component,
|
|
4250
4335
|
args: [{
|
|
4251
|
-
selector: 'stream-message-
|
|
4252
|
-
templateUrl: './message-
|
|
4336
|
+
selector: 'stream-edit-message-form',
|
|
4337
|
+
templateUrl: './edit-message-form.component.html',
|
|
4253
4338
|
styles: [],
|
|
4254
4339
|
}]
|
|
4255
|
-
}], ctorParameters: function () { return [{ type: CustomTemplatesService }, { type: MessageActionsService }
|
|
4256
|
-
type:
|
|
4257
|
-
}], isMine: [{
|
|
4258
|
-
type: Input
|
|
4259
|
-
}], message: [{
|
|
4260
|
-
type: Input
|
|
4261
|
-
}], enabledActions: [{
|
|
4262
|
-
type: Input
|
|
4263
|
-
}], customActions: [{
|
|
4264
|
-
type: Input
|
|
4265
|
-
}], displayedActionsCount: [{
|
|
4266
|
-
type: Output
|
|
4267
|
-
}], isEditing: [{
|
|
4268
|
-
type: Output
|
|
4340
|
+
}], ctorParameters: function () { return [{ type: CustomTemplatesService }, { type: MessageActionsService }]; }, propDecorators: { class: [{
|
|
4341
|
+
type: HostBinding
|
|
4269
4342
|
}], modalContent: [{
|
|
4270
4343
|
type: ViewChild,
|
|
4271
|
-
args: ['
|
|
4344
|
+
args: ['editMessageForm', { static: true }]
|
|
4345
|
+
}] } });
|
|
4346
|
+
|
|
4347
|
+
/**
|
|
4348
|
+
* The component watches for the [`channelService.bouncedMessage$` stream](../../services/ChannelService/#bouncedmessage) and opens the bounce modal if a message is emitted.
|
|
4349
|
+
*
|
|
4350
|
+
* To bounce messages, you need to set up [semantic filters for moderation](https://getstream.io/automated-moderation/docs/automod_configuration/?q=semantic%20filters).
|
|
4351
|
+
*/
|
|
4352
|
+
class MessageBouncePromptComponent {
|
|
4353
|
+
constructor(channelService, customTemplatesService, messageActionsService) {
|
|
4354
|
+
this.channelService = channelService;
|
|
4355
|
+
this.customTemplatesService = customTemplatesService;
|
|
4356
|
+
this.messageActionsService = messageActionsService;
|
|
4357
|
+
this.class = 'str-chat__message-bounce-prompt';
|
|
4358
|
+
this.isModalOpen = false;
|
|
4359
|
+
this.subscriptions = [];
|
|
4360
|
+
this.messageBounceModalOpenChanged = (isOpen) => {
|
|
4361
|
+
this.isModalOpen = isOpen;
|
|
4362
|
+
if (!isOpen) {
|
|
4363
|
+
this.message = undefined;
|
|
4364
|
+
this.channelService.bouncedMessage$.next(undefined);
|
|
4365
|
+
}
|
|
4366
|
+
};
|
|
4367
|
+
this.subscriptions.push(this.channelService.bouncedMessage$.subscribe((m) => {
|
|
4368
|
+
if (m !== this.message) {
|
|
4369
|
+
this.message = m;
|
|
4370
|
+
if (this.message) {
|
|
4371
|
+
this.isModalOpen = true;
|
|
4372
|
+
}
|
|
4373
|
+
}
|
|
4374
|
+
}));
|
|
4375
|
+
}
|
|
4376
|
+
ngOnDestroy() {
|
|
4377
|
+
this.subscriptions.forEach((s) => s.unsubscribe());
|
|
4378
|
+
}
|
|
4379
|
+
resendMessage() {
|
|
4380
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
4381
|
+
this.isModalOpen = false;
|
|
4382
|
+
yield this.channelService.resendMessage(this.message);
|
|
4383
|
+
this.message = undefined;
|
|
4384
|
+
this.channelService.bouncedMessage$.next(undefined);
|
|
4385
|
+
});
|
|
4386
|
+
}
|
|
4387
|
+
deleteMessage() {
|
|
4388
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
4389
|
+
if (!this.message) {
|
|
4390
|
+
return;
|
|
4391
|
+
}
|
|
4392
|
+
this.isModalOpen = false;
|
|
4393
|
+
yield this.channelService.deleteMessage(this.message, true);
|
|
4394
|
+
this.message = undefined;
|
|
4395
|
+
this.channelService.bouncedMessage$.next(undefined);
|
|
4396
|
+
});
|
|
4397
|
+
}
|
|
4398
|
+
editMessage() {
|
|
4399
|
+
this.isModalOpen = false;
|
|
4400
|
+
this.messageActionsService.messageToEdit$.next(this.message);
|
|
4401
|
+
this.message = undefined;
|
|
4402
|
+
this.channelService.bouncedMessage$.next(undefined);
|
|
4403
|
+
}
|
|
4404
|
+
}
|
|
4405
|
+
MessageBouncePromptComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: MessageBouncePromptComponent, deps: [{ token: ChannelService }, { token: CustomTemplatesService }, { token: MessageActionsService }], target: i0.ɵɵFactoryTarget.Component });
|
|
4406
|
+
MessageBouncePromptComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: MessageBouncePromptComponent, selector: "stream-message-bounce-prompt", host: { properties: { "class": "this.class" } }, ngImport: i0, template: "<ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.modalTemplate$ | async) || defaultModal;\n context: {\n message: message,\n isOpen: isModalOpen,\n isOpenChangeHandler: messageBounceModalOpenChanged,\n content: modalContent\n }\n \"\n></ng-container>\n\n<ng-template\n #defaultModal\n let-isOpen=\"isOpen\"\n let-isOpenChangeHandler=\"isOpenChangeHandler\"\n let-content=\"content\"\n>\n <stream-modal\n [isOpen]=\"isOpen\"\n *ngIf=\"isOpen\"\n (isOpenChange)=\"isOpenChangeHandler($event)\"\n [content]=\"content\"\n >\n </stream-modal>\n</ng-template>\n\n<ng-template #modalContent>\n <div\n class=\"str-chat__message-bounce-prompt\"\n data-testid=\"message-bounce-prompt\"\n >\n <div class=\"str-chat__message-bounce-prompt-header\">\n {{\n \"streamChat.This message did not meet our content guidelines\"\n | translate\n }}\n </div>\n <div class=\"str-chat__message-bounce-actions\">\n <button\n class=\"str-chat__message-bounce-edit\"\n data-testid=\"message-bounce-edit\"\n (click)=\"editMessage()\"\n (keyup.enter)=\"editMessage()\"\n type=\"button\"\n >\n {{ \"streamChat.Edit Message\" | translate }}\n </button>\n <button\n class=\"str-chat__message-bounce-send\"\n data-testid=\"message-bounce-send\"\n (click)=\"resendMessage()\"\n (keyup.enter)=\"resendMessage()\"\n >\n {{ \"streamChat.Send Anyway\" | translate }}\n </button>\n <button\n class=\"str-chat__message-bounce-delete\"\n data-testid=\"message-bounce-delete\"\n (click)=\"deleteMessage()\"\n (keyup.enter)=\"deleteMessage()\"\n >\n {{ \"streamChat.Delete\" | translate }}\n </button>\n </div>\n </div>\n</ng-template>\n", components: [{ type: ModalComponent, selector: "stream-modal", inputs: ["isOpen", "content"], outputs: ["isOpenChange"] }], directives: [{ type: i5.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], pipes: { "async": i5.AsyncPipe, "translate": i6.TranslatePipe } });
|
|
4407
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: MessageBouncePromptComponent, decorators: [{
|
|
4408
|
+
type: Component,
|
|
4409
|
+
args: [{
|
|
4410
|
+
selector: 'stream-message-bounce-prompt',
|
|
4411
|
+
templateUrl: './message-bounce-prompt.component.html',
|
|
4412
|
+
styles: [],
|
|
4413
|
+
}]
|
|
4414
|
+
}], ctorParameters: function () { return [{ type: ChannelService }, { type: CustomTemplatesService }, { type: MessageActionsService }]; }, propDecorators: { class: [{
|
|
4415
|
+
type: HostBinding
|
|
4272
4416
|
}] } });
|
|
4273
4417
|
|
|
4274
4418
|
/**
|
|
4275
4419
|
* The `Channel` component is a container component that displays the [`ChannelHeader`](./ChannelHeaderComponent.mdx), [`MessageList`](./MessageListComponent.mdx), [`NotificationList`](./NotificationListComponent.mdx) and [`MessageInput`](./MessageInputComponent.mdx) components. You can also provide the [`Thread`](./ThreadComponent.mdx) component to use message [threads](https://getstream.io/chat/docs/javascript/threads/?language=javascript).
|
|
4276
4420
|
*/
|
|
4277
4421
|
class ChannelComponent {
|
|
4278
|
-
constructor(channelService, themeService) {
|
|
4422
|
+
constructor(channelService, themeService, customTemplatesService) {
|
|
4279
4423
|
this.channelService = channelService;
|
|
4280
4424
|
this.themeService = themeService;
|
|
4425
|
+
this.customTemplatesService = customTemplatesService;
|
|
4281
4426
|
this.subscriptions = [];
|
|
4282
4427
|
this.isError$ = combineLatest([
|
|
4283
4428
|
this.channelService.channelQueryState$,
|
|
@@ -4296,8 +4441,8 @@ class ChannelComponent {
|
|
|
4296
4441
|
this.isActiveChannel$ = this.channelService.activeChannel$.pipe(map((c) => !!c));
|
|
4297
4442
|
}
|
|
4298
4443
|
}
|
|
4299
|
-
ChannelComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ChannelComponent, deps: [{ token: ChannelService }, { token: ThemeService }], target: i0.ɵɵFactoryTarget.Component });
|
|
4300
|
-
ChannelComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: ChannelComponent, selector: "stream-channel", ngImport: i0, template: "<div\n class=\"str-chat str-chat-channel messaging str-chat__channel str-chat__theme-{{\n theme$ | async\n }}\"\n>\n <div\n class=\"str-chat__container\"\n *ngIf=\"\n (isError$ | async) === false &&\n (isInitializing$ | async) === false &&\n (isActiveChannel$ | async) === true;\n else noChannel\n \"\n >\n <div class=\"str-chat__main-panel\">\n <ng-content></ng-content>\n </div>\n <ng-content\n *ngIf=\"isActiveThread$ | async\"\n select='[name=\"thread\"]'\n ></ng-content>\n </div>\n <ng-template #noChannel>\n <div\n class=\"str-chat__empty-channel\"\n *ngIf=\"\n (isInitializing$ | async) === false &&\n ((isError$ | async) === true || (isActiveChannel$ | async) === false)\n \"\n >\n <stream-icon icon=\"chat-bubble\"></stream-icon>\n <p class=\"str-chat__empty-channel-text\">\n {{ \"streamChat.No chats here yet\u2026\" | translate }}\n </p>\n <div class=\"str-chat__empty-channel-notifications\">\n <stream-notification-list></stream-notification-list>\n </div>\n </div>\n <div\n *ngIf=\"\n (isInitializing$ | async) === true &&\n (isError$ | async) === false &&\n (isActiveChannel$ | async) === false\n \"\n class=\"str-chat__loading-channel\"\n >\n <div class=\"str-chat__loading-channel-header\">\n <div class=\"str-chat__loading-channel-header-avatar\"></div>\n <div class=\"str-chat__loading-channel-header-end\">\n <div class=\"str-chat__loading-channel-header-name\"></div>\n <div class=\"str-chat__loading-channel-header-info\"></div>\n </div>\n </div>\n <div class=\"str-chat__loading-channel-message-list\">\n <div class=\"str-chat__loading-channel-message\">\n <div class=\"str-chat__loading-channel-message-avatar\"></div>\n <div class=\"str-chat__loading-channel-message-end\">\n <div class=\"str-chat__loading-channel-message-sender\"></div>\n <div class=\"str-chat__loading-channel-message-last-row\">\n <div class=\"str-chat__loading-channel-message-text\"></div>\n <div class=\"str-chat__loading-channel-message-date\"></div>\n </div>\n </div>\n </div>\n <div class=\"str-chat__loading-channel-message\">\n <div class=\"str-chat__loading-channel-message-avatar\"></div>\n <div class=\"str-chat__loading-channel-message-end\">\n <div class=\"str-chat__loading-channel-message-sender\"></div>\n <div class=\"str-chat__loading-channel-message-last-row\">\n <div class=\"str-chat__loading-channel-message-text\"></div>\n <div class=\"str-chat__loading-channel-message-date\"></div>\n </div>\n </div>\n </div>\n <div class=\"str-chat__loading-channel-message\">\n <div class=\"str-chat__loading-channel-message-avatar\"></div>\n <div class=\"str-chat__loading-channel-message-end\">\n <div class=\"str-chat__loading-channel-message-sender\"></div>\n <div class=\"str-chat__loading-channel-message-last-row\">\n <div class=\"str-chat__loading-channel-message-text\"></div>\n <div class=\"str-chat__loading-channel-message-date\"></div>\n </div>\n </div>\n </div>\n </div>\n <div class=\"str-chat__loading-channel-message-input-row\">\n <div class=\"str-chat__loading-channel-message-input\"></div>\n <div class=\"str-chat__loading-channel-message-send\"></div>\n </div>\n </div>\n </ng-template>\n</div>\n", components: [{ type: IconComponent, selector: "stream-icon", inputs: ["icon", "size"] }, { type: NotificationListComponent, selector: "stream-notification-list" }], directives: [{ type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], pipes: { "async": i5.AsyncPipe, "translate": i6.TranslatePipe } });
|
|
4444
|
+
ChannelComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ChannelComponent, deps: [{ token: ChannelService }, { token: ThemeService }, { token: CustomTemplatesService }], target: i0.ɵɵFactoryTarget.Component });
|
|
4445
|
+
ChannelComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: ChannelComponent, selector: "stream-channel", ngImport: i0, template: "<div\n class=\"str-chat str-chat-channel messaging str-chat__channel str-chat__theme-{{\n theme$ | async\n }}\"\n>\n <div\n class=\"str-chat__container\"\n *ngIf=\"\n (isError$ | async) === false &&\n (isInitializing$ | async) === false &&\n (isActiveChannel$ | async) === true;\n else noChannel\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.editMessageFormTemplate$ | async) ||\n defaultEditMessageForm\n \"\n ></ng-container>\n <ng-template #defaultEditMessageForm>\n <stream-edit-message-form></stream-edit-message-form>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.messageBouncePromptTemplate$ | async) ||\n defaultMessageBouncePrompt\n \"\n ></ng-container>\n <ng-template #defaultMessageBouncePrompt>\n <stream-message-bounce-prompt></stream-message-bounce-prompt>\n </ng-template>\n <div class=\"str-chat__main-panel\">\n <ng-content></ng-content>\n </div>\n <ng-content\n *ngIf=\"isActiveThread$ | async\"\n select='[name=\"thread\"]'\n ></ng-content>\n </div>\n <ng-template #noChannel>\n <div\n class=\"str-chat__empty-channel\"\n *ngIf=\"\n (isInitializing$ | async) === false &&\n ((isError$ | async) === true || (isActiveChannel$ | async) === false)\n \"\n >\n <stream-icon icon=\"chat-bubble\"></stream-icon>\n <p class=\"str-chat__empty-channel-text\">\n {{ \"streamChat.No chats here yet\u2026\" | translate }}\n </p>\n <div class=\"str-chat__empty-channel-notifications\">\n <stream-notification-list></stream-notification-list>\n </div>\n </div>\n <div\n *ngIf=\"\n (isInitializing$ | async) === true &&\n (isError$ | async) === false &&\n (isActiveChannel$ | async) === false\n \"\n class=\"str-chat__loading-channel\"\n >\n <div class=\"str-chat__loading-channel-header\">\n <div class=\"str-chat__loading-channel-header-avatar\"></div>\n <div class=\"str-chat__loading-channel-header-end\">\n <div class=\"str-chat__loading-channel-header-name\"></div>\n <div class=\"str-chat__loading-channel-header-info\"></div>\n </div>\n </div>\n <div class=\"str-chat__loading-channel-message-list\">\n <div class=\"str-chat__loading-channel-message\">\n <div class=\"str-chat__loading-channel-message-avatar\"></div>\n <div class=\"str-chat__loading-channel-message-end\">\n <div class=\"str-chat__loading-channel-message-sender\"></div>\n <div class=\"str-chat__loading-channel-message-last-row\">\n <div class=\"str-chat__loading-channel-message-text\"></div>\n <div class=\"str-chat__loading-channel-message-date\"></div>\n </div>\n </div>\n </div>\n <div class=\"str-chat__loading-channel-message\">\n <div class=\"str-chat__loading-channel-message-avatar\"></div>\n <div class=\"str-chat__loading-channel-message-end\">\n <div class=\"str-chat__loading-channel-message-sender\"></div>\n <div class=\"str-chat__loading-channel-message-last-row\">\n <div class=\"str-chat__loading-channel-message-text\"></div>\n <div class=\"str-chat__loading-channel-message-date\"></div>\n </div>\n </div>\n </div>\n <div class=\"str-chat__loading-channel-message\">\n <div class=\"str-chat__loading-channel-message-avatar\"></div>\n <div class=\"str-chat__loading-channel-message-end\">\n <div class=\"str-chat__loading-channel-message-sender\"></div>\n <div class=\"str-chat__loading-channel-message-last-row\">\n <div class=\"str-chat__loading-channel-message-text\"></div>\n <div class=\"str-chat__loading-channel-message-date\"></div>\n </div>\n </div>\n </div>\n </div>\n <div class=\"str-chat__loading-channel-message-input-row\">\n <div class=\"str-chat__loading-channel-message-input\"></div>\n <div class=\"str-chat__loading-channel-message-send\"></div>\n </div>\n </div>\n </ng-template>\n</div>\n", components: [{ type: EditMessageFormComponent, selector: "stream-edit-message-form" }, { type: MessageBouncePromptComponent, selector: "stream-message-bounce-prompt" }, { type: IconComponent, selector: "stream-icon", inputs: ["icon", "size"] }, { type: NotificationListComponent, selector: "stream-notification-list" }], directives: [{ type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i5.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], pipes: { "async": i5.AsyncPipe, "translate": i6.TranslatePipe } });
|
|
4301
4446
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ChannelComponent, decorators: [{
|
|
4302
4447
|
type: Component,
|
|
4303
4448
|
args: [{
|
|
@@ -4305,7 +4450,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
4305
4450
|
templateUrl: './channel.component.html',
|
|
4306
4451
|
styles: [],
|
|
4307
4452
|
}]
|
|
4308
|
-
}], ctorParameters: function () { return [{ type: ChannelService }, { type: ThemeService }]; } });
|
|
4453
|
+
}], ctorParameters: function () { return [{ type: ChannelService }, { type: ThemeService }, { type: CustomTemplatesService }]; } });
|
|
4309
4454
|
|
|
4310
4455
|
const listUsers = (users) => {
|
|
4311
4456
|
let outStr = '';
|
|
@@ -4680,7 +4825,7 @@ const parseDate = (date, format = 'date-time') => {
|
|
|
4680
4825
|
nextWeek: 'dddd',
|
|
4681
4826
|
lastDay: '[Yesterday]',
|
|
4682
4827
|
lastWeek: '[Last] dddd',
|
|
4683
|
-
sameElse: 'DD/
|
|
4828
|
+
sameElse: 'MM/DD/YYYY', // Everything else ( 10/17/2011 )
|
|
4684
4829
|
});
|
|
4685
4830
|
};
|
|
4686
4831
|
|
|
@@ -5091,22 +5236,6 @@ class MessageComponent {
|
|
|
5091
5236
|
}
|
|
5092
5237
|
}
|
|
5093
5238
|
}));
|
|
5094
|
-
this.subscriptions.push(this.messageActionsService.messageToEdit$.subscribe((m) => {
|
|
5095
|
-
var _a;
|
|
5096
|
-
let isEditing = false;
|
|
5097
|
-
if (m && m.id === ((_a = this.message) === null || _a === void 0 ? void 0 : _a.id)) {
|
|
5098
|
-
isEditing = true;
|
|
5099
|
-
}
|
|
5100
|
-
if (isEditing !== this.isEditing) {
|
|
5101
|
-
this.isEditing = isEditing;
|
|
5102
|
-
if (!this.isEditing) {
|
|
5103
|
-
this.isActionBoxOpen = false;
|
|
5104
|
-
}
|
|
5105
|
-
if (this.isViewInited) {
|
|
5106
|
-
this.cdRef.detectChanges();
|
|
5107
|
-
}
|
|
5108
|
-
}
|
|
5109
|
-
}));
|
|
5110
5239
|
}
|
|
5111
5240
|
ngOnChanges(changes) {
|
|
5112
5241
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
@@ -5205,9 +5334,6 @@ class MessageComponent {
|
|
|
5205
5334
|
}
|
|
5206
5335
|
}
|
|
5207
5336
|
messageActionsBoxClicked(popperContent) {
|
|
5208
|
-
if (this.isEditing) {
|
|
5209
|
-
return;
|
|
5210
|
-
}
|
|
5211
5337
|
popperContent.hide();
|
|
5212
5338
|
}
|
|
5213
5339
|
getAttachmentListContext() {
|
|
@@ -5249,6 +5375,17 @@ class MessageComponent {
|
|
|
5249
5375
|
ownReactions: ((_d = this.message) === null || _d === void 0 ? void 0 : _d.own_reactions) || [],
|
|
5250
5376
|
};
|
|
5251
5377
|
}
|
|
5378
|
+
unsentMessageClicked() {
|
|
5379
|
+
var _a, _b, _c, _d;
|
|
5380
|
+
if (((_a = this.message) === null || _a === void 0 ? void 0 : _a.status) === 'failed' &&
|
|
5381
|
+
((_b = this.message) === null || _b === void 0 ? void 0 : _b.errorStatusCode) !== 403) {
|
|
5382
|
+
this.resendMessage();
|
|
5383
|
+
}
|
|
5384
|
+
else if (((_c = this.message) === null || _c === void 0 ? void 0 : _c.type) === 'error' &&
|
|
5385
|
+
((_d = this.message) === null || _d === void 0 ? void 0 : _d.moderation_details)) {
|
|
5386
|
+
this.openMessageBouncePrompt();
|
|
5387
|
+
}
|
|
5388
|
+
}
|
|
5252
5389
|
resendMessage() {
|
|
5253
5390
|
void this.channelService.resendMessage(this.message);
|
|
5254
5391
|
}
|
|
@@ -5277,10 +5414,6 @@ class MessageComponent {
|
|
|
5277
5414
|
// message action box changes UI bindings in parent, so we'll have to rerun change detection
|
|
5278
5415
|
this.cdRef.detectChanges();
|
|
5279
5416
|
},
|
|
5280
|
-
isEditingChangeHandler: (isEditing) => {
|
|
5281
|
-
this.isEditing = isEditing;
|
|
5282
|
-
this.isActionBoxOpen = !this.isEditing;
|
|
5283
|
-
},
|
|
5284
5417
|
customActions: this.customActions || [],
|
|
5285
5418
|
};
|
|
5286
5419
|
}
|
|
@@ -5314,6 +5447,9 @@ class MessageComponent {
|
|
|
5314
5447
|
displayOriginalMessage() {
|
|
5315
5448
|
this.createMessageParts(false);
|
|
5316
5449
|
}
|
|
5450
|
+
openMessageBouncePrompt() {
|
|
5451
|
+
this.channelService.bouncedMessage$.next(this.message);
|
|
5452
|
+
}
|
|
5317
5453
|
createMessageParts(shouldTranslate = true) {
|
|
5318
5454
|
this.messageTextParts = undefined;
|
|
5319
5455
|
this.messageText = undefined;
|
|
@@ -5403,7 +5539,7 @@ class MessageComponent {
|
|
|
5403
5539
|
}
|
|
5404
5540
|
}
|
|
5405
5541
|
MessageComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: MessageComponent, deps: [{ token: ChatClientService }, { token: ChannelService }, { token: CustomTemplatesService }, { token: i0.ChangeDetectorRef }, { token: ThemeService }, { token: DateParserService }, { token: i0.NgZone }, { token: MessageService }, { token: MessageActionsService }], target: i0.ɵɵFactoryTarget.Component });
|
|
5406
|
-
MessageComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: MessageComponent, selector: "stream-message", inputs: { message: "message", enabledMessageActions: "enabledMessageActions", isLastSentMessage: "isLastSentMessage", mode: "mode", isHighlighted: "isHighlighted", customActions: "customActions" }, viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div\n #container\n class=\"str-chat__message-simple str-chat__message str-chat__message--{{\n message?.type\n }} str-chat__message--{{ message?.status }} {{\n message?.text ? 'str-chat__message--has-text' : 'has-no-text'\n }}\"\n [class.str-chat__message--me]=\"isSentByCurrentUser\"\n [class.str-chat__message--other]=\"!isSentByCurrentUser\"\n [class.str-chat__message-simple--me]=\"isSentByCurrentUser\"\n [class.str-chat__message--has-attachment]=\"hasAttachment\"\n [class.str-chat__message--with-reactions]=\"hasReactions\"\n [class.str-chat__message--highlighted]=\"isHighlighted\"\n [class.str-chat__message-with-thread-link]=\"shouldDisplayThreadLink\"\n [class.str-chat__message-send-can-be-retried]=\"\n message?.status === 'failed' && message?.errorStatusCode !== 403\n \"\n data-testid=\"message-container\"\n>\n <ng-container *ngIf=\"!message?.deleted_at; else deletedMessage\">\n <ng-container *ngIf=\"message?.type !== 'system'; else systemMessage\">\n <ng-container *ngIf=\"themeVersion === '1'\">\n <ng-container *ngTemplateOutlet=\"messageStatus\"></ng-container>\n </ng-container>\n <stream-avatar-placeholder\n data-testid=\"avatar\"\n class=\"str-chat-angular__avatar-host str-chat__message-sender-avatar\"\n [imageUrl]=\"message?.user?.image\"\n [name]=\"message?.user?.name || message?.user?.id\"\n type=\"user\"\n location=\"message-sender\"\n [user]=\"message?.user || undefined\"\n ></stream-avatar-placeholder>\n <div class=\"str-chat__message-inner\">\n <div\n class=\"str-chat__message-simple__actions str-chat__message-options\"\n data-testid=\"message-options\"\n [class.str-chat__message-actions-open]=\"isActionBoxOpen\"\n [class.str-chat__message-edit-in-progress]=\"isEditing\"\n *ngIf=\"areOptionsVisible\"\n >\n <div\n data-testid=\"message-actions-container\"\n #messageActionsToggle\n class=\"\n str-chat__message-actions-container\n str-chat__message-simple__actions__action\n str-chat__message-simple__actions__action--options\n \"\n [class.str-chat-angular__message-simple__actions__action--options--editing]=\"\n isEditing\n \"\n [popper]=\"popperContent\"\n [popperTrigger]=\"popperTriggerClick\"\n [popperPlacement]=\"popperPlacementAuto\"\n [popperHideOnScroll]=\"false\"\n [popperHideOnClickOutside]=\"true\"\n [popperHideOnMouseLeave]=\"false\"\n [popperDisableAnimation]=\"true\"\n (popperOnHidden)=\"isActionBoxOpen = false\"\n >\n <popper-content #popperContent>\n <ng-template\n #defaultMessageActionsBox\n let-isOpen=\"isOpen\"\n let-isMine=\"isMine\"\n let-enabledActions=\"enabledActions\"\n let-messageInput=\"message\"\n let-customActions=\"customActions\"\n >\n <stream-message-actions-box\n (click)=\"messageActionsBoxClicked(popperContent)\"\n *ngIf=\"isOpen\"\n [isOpen]=\"isOpen\"\n [isMine]=\"isMine\"\n [enabledActions]=\"enabledActions\"\n [customActions]=\"customActions\"\n [message]=\"messageInput\"\n ></stream-message-actions-box>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.messageActionsBoxTemplate$ | async) ||\n defaultMessageActionsBox;\n context: getMessageActionsBoxContext()\n \"\n >\n </ng-container>\n </popper-content>\n <div\n class=\"str-chat__message-actions-box-button\"\n data-testid=\"action-icon\"\n (click)=\"messageActionsClicked()\"\n (keyup.enter)=\"messageActionsClicked()\"\n *ngIf=\"visibleMessageActionsCount > 0\"\n >\n <stream-icon-placeholder\n icon=\"action-icon\"\n class=\"str-chat__message-action-icon\"\n ></stream-icon-placeholder>\n </div>\n </div>\n <div\n *ngIf=\"\n enabledMessageActions.indexOf('send-reply') !== -1 &&\n mode === 'main'\n \"\n class=\"\n str-chat__message-simple__actions__action\n str-chat__message-simple__actions__action--thread\n str-chat__message-reply-in-thread-button\n \"\n data-testid=\"reply-in-thread\"\n (click)=\"setAsActiveParentMessage()\"\n (keyup.enter)=\"setAsActiveParentMessage()\"\n >\n <stream-icon-placeholder\n class=\"str-chat__message-action-icon\"\n icon=\"reply-in-thread\"\n ></stream-icon-placeholder>\n </div>\n <div\n *ngIf=\"canReactToMessage\"\n class=\"\n str-chat__message-simple__actions__action\n str-chat__message-simple__actions__action--reactions\n str-chat__message-reactions-button\n \"\n data-testid=\"reaction-icon\"\n (click)=\"isReactionSelectorOpen = !isReactionSelectorOpen\"\n (keyup.enter)=\"isReactionSelectorOpen = !isReactionSelectorOpen\"\n >\n <stream-icon-placeholder\n class=\"str-chat__message-action-icon\"\n icon=\"reaction-icon\"\n ></stream-icon-placeholder>\n </div>\n </div>\n <div class=\"str-chat__message-reactions-host\">\n <ng-template\n #defaultMessageReactions\n let-messageReactionCounts=\"messageReactionCounts\"\n let-latestReactions=\"latestReactions\"\n let-isSelectorOpen=\"isSelectorOpen\"\n let-isSelectorOpenChangeHandler=\"isSelectorOpenChangeHandler\"\n let-messageId=\"messageId\"\n let-ownReactions=\"ownReactions\"\n >\n <stream-message-reactions\n [messageReactionCounts]=\"messageReactionCounts\"\n [latestReactions]=\"latestReactions\"\n [isSelectorOpen]=\"isSelectorOpen\"\n (isSelectorOpenChange)=\"isSelectorOpenChangeHandler($event)\"\n [messageId]=\"messageId\"\n [ownReactions]=\"ownReactions\"\n ></stream-message-reactions>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.messageReactionsTemplate$ | async) ||\n defaultMessageReactions;\n context: getMessageReactionsContext()\n \"\n ></ng-container>\n </div>\n <!-- transform: translate3d(0, 0, 0) fixes scrolling issues on iOS, see: https://stackoverflow.com/questions/50105780/elements-disappear-when-scrolling-in-safari-webkit-transform-fix-only-works-t/50144295#50144295 -->\n <!-- transform: none is required when image carousel is open in order for the modal to be correctly positioned, see how the transform property changes the behavior of fixed positioned elements https://developer.mozilla.org/en-US/docs/Web/CSS/position -->\n <div\n class=\"str-chat__message-bubble\"\n style=\"transform: {{\n imageAttachmentModalState === 'opened'\n ? 'none'\n : 'translate3d(0, 0, 0)'\n }}\"\n >\n <ng-container *ngIf=\"hasAttachment && !message?.quoted_message\">\n <ng-container\n *ngTemplateOutlet=\"attachmentsTemplate\"\n ></ng-container>\n </ng-container>\n <div\n class=\"str-chat__message-text\"\n tabindex=\"0\"\n *ngIf=\"message?.text || (message?.quoted_message && hasAttachment)\"\n >\n <div\n data-testid=\"inner-message\"\n class=\"\n str-chat__message-text-inner str-chat__message-simple-text-inner\n \"\n [class.str-chat__message-light-text-inner--has-attachment]=\"\n hasAttachment\n \"\n (click)=\"\n message?.status === 'failed' && message?.errorStatusCode !== 403\n ? resendMessage()\n : undefined\n \"\n (keyup.enter)=\"\n message?.status === 'failed' && message?.errorStatusCode !== 403\n ? resendMessage()\n : undefined\n \"\n >\n <ng-container *ngTemplateOutlet=\"quotedMessage\"></ng-container>\n <ng-container *ngIf=\"hasAttachment && message?.quoted_message\">\n <ng-container\n *ngTemplateOutlet=\"attachmentsTemplate\"\n ></ng-container>\n </ng-container>\n <div\n data-testid=\"client-error-message\"\n *ngIf=\"message?.type === 'error'\"\n class=\"\n str-chat__simple-message--error-message\n str-chat__message--error-message\n \"\n >\n {{ \"streamChat.Error \u00B7 Unsent\" | translate }}\n </div>\n <div\n data-testid=\"error-message\"\n *ngIf=\"message?.status === 'failed'\"\n class=\"\n str-chat__simple-message--error-message\n str-chat__message--error-message\n \"\n >\n {{\n (message?.errorStatusCode === 403\n ? \"streamChat.Message Failed \u00B7 Unauthorized\"\n : \"streamChat.Message Failed \u00B7 Click to try again\"\n ) | translate\n }}\n </div>\n <div data-testid=\"text\">\n <p>\n <ng-container *ngIf=\"messageTextParts; else defaultContent\">\n <!-- eslint-disable-next-line @angular-eslint/template/use-track-by-function -->\n <ng-container *ngFor=\"let part of messageTextParts\">\n <span\n *ngIf=\"part.type === 'text'; else mention\"\n [innerHTML]=\"part.content\"\n ></span>\n <ng-template #mention>\n <ng-template #defaultMention let-content=\"content\">\n <span class=\"str-chat__message-mention\">{{\n content\n }}</span>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.mentionTemplate$ | async) ||\n defaultMention;\n context: getMentionContext(part)\n \"\n ></ng-container>\n </ng-template>\n </ng-container>\n </ng-container>\n <ng-template #defaultContent>\n <ng-container *ngIf=\"displayAs === 'text'; else asHTML\">\n {{ messageText || \"\" }}\n </ng-container>\n <ng-template #asHTML\n ><span\n data-testid=\"html-content\"\n [innerHTML]=\"messageText\"\n ></span\n ></ng-template>\n </ng-template>\n </p>\n </div>\n </div>\n </div>\n <stream-icon-placeholder\n *ngIf=\"themeVersion === '2'\"\n class=\"str-chat__message-error-icon\"\n icon=\"error\"\n ></stream-icon-placeholder>\n </div>\n <ng-container\n *ngTemplateOutlet=\"\n replyCountButton;\n context: { position: 'inside-message-bubble' }\n \"\n ></ng-container>\n <ng-container\n *ngTemplateOutlet=\"\n messageDateAndSender;\n context: { position: 'inside-message-bubble' }\n \"\n ></ng-container>\n </div>\n <ng-container\n *ngTemplateOutlet=\"\n replyCountButton;\n context: { position: 'outside-message-bubble', message: message }\n \"\n ></ng-container>\n\n <ng-container\n *ngTemplateOutlet=\"\n messageDateAndSender;\n context: { position: 'outside-message-bubble' }\n \"\n ></ng-container>\n </ng-container>\n </ng-container>\n</div>\n\n<ng-template #deletedMessage>\n <div data-testid=\"message-deleted-component\">\n <div class=\"str-chat__message--deleted-inner\" translate>\n streamChat.This message was deleted...\n </div>\n </div>\n</ng-template>\n\n<ng-template #systemMessage>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.systemMessageTemplate$ | async) ||\n defaultSystemMessage;\n context: getMessageContext()\n \"\n ></ng-container>\n <ng-template #defaultSystemMessage let-messageInput=\"message\">\n <div data-testid=\"system-message\" class=\"str-chat__message--system\">\n <div class=\"str-chat__message--system__text\">\n <div class=\"str-chat__message--system__line\"></div>\n <p>{{ messageInput?.text }}</p>\n <div class=\"str-chat__message--system__line\"></div>\n </div>\n <div class=\"str-chat__message--system__date\">\n {{ parsedDate }}\n </div>\n </div>\n </ng-template>\n</ng-template>\n\n<ng-template #quotedMessage>\n <div\n *ngIf=\"message?.quoted_message\"\n class=\"quoted-message str-chat__quoted-message-preview\"\n data-testid=\"quoted-message-container\"\n [class.mine]=\"isSentByCurrentUser\"\n (click)=\"\n jumpToMessage(\n (message?.quoted_message)!.id,\n message?.quoted_message?.parent_id\n )\n \"\n (keyup.enter)=\"\n jumpToMessage(\n (message?.quoted_message)!.id,\n message?.quoted_message?.parent_id\n )\n \"\n >\n <stream-avatar-placeholder\n data-testid=\"qouted-message-avatar\"\n class=\"str-chat-angular__avatar-host str-chat__message-sender-avatar\"\n [imageUrl]=\"message?.quoted_message?.user?.image\"\n [name]=\"\n message?.quoted_message?.user?.name || message?.quoted_message?.user?.id\n \"\n [size]=\"20\"\n type=\"user\"\n location=\"quoted-message-sender\"\n [user]=\"message?.quoted_message?.user || undefined\"\n ></stream-avatar-placeholder>\n <div class=\"quoted-message-inner str-chat__quoted-message-bubble\">\n <ng-container\n *ngIf=\"\n message?.quoted_message?.attachments &&\n message?.quoted_message?.attachments?.length\n \"\n >\n <ng-template\n #defaultAttachments\n let-messageId=\"messageId\"\n let-attachments=\"attachments\"\n let-parentMessageId=\"parentMessageId\"\n let-imageModalStateChangeHandler=\"imageModalStateChangeHandler\"\n >\n <stream-attachment-list\n [messageId]=\"messageId\"\n [attachments]=\"attachments\"\n [parentMessageId]=\"parentMessageId\"\n (imageModalStateChange)=\"imageModalStateChangeHandler($event)\"\n ></stream-attachment-list>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.attachmentListTemplate$ | async) ||\n defaultAttachments;\n context: getQuotedMessageAttachmentListContext()\n \"\n ></ng-container>\n </ng-container>\n <div\n data-testid=\"quoted-message-text\"\n [innerHTML]=\"\n message?.quoted_message?.translation ||\n message?.quoted_message?.html ||\n message?.quoted_message?.text\n \"\n ></div>\n </div>\n </div>\n</ng-template>\n\n<!-- We need these markups in slightly different positions in theme-v1 and theme-v2, this soultion makes that possible without duplicating the code -->\n<ng-template #messageDateAndSender let-position=\"position\">\n <ng-container\n *ngIf=\"\n (position === 'inside-message-bubble' && themeVersion === '1') ||\n (position === 'outside-message-bubble' && themeVersion === '2')\n \"\n >\n <div\n class=\"str-chat__translation-notice\"\n *ngIf=\"shouldDisplayTranslationNotice\"\n data-testid=\"translation-notice\"\n >\n <button\n data-testid=\"see-original\"\n *ngIf=\"displayedMessageTextContent === 'translation'\"\n (click)=\"displayOriginalMessage()\"\n (keyup.enter)=\"displayOriginalMessage()\"\n translate\n >\n streamChat.See original (automatically translated)\n </button>\n <button\n data-testid=\"see-translation\"\n *ngIf=\"displayedMessageTextContent === 'original'\"\n (click)=\"displayTranslatedMessage()\"\n (keyup.enter)=\"displayTranslatedMessage()\"\n translate\n >\n streamChat.See translation\n </button>\n </div>\n <ng-container\n *ngIf=\"customTemplatesService.customMessageMetadataTemplate$ | async\"\n >\n <div class=\"str-chat__custom-message-metadata\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.customMessageMetadataTemplate$ | async)!;\n context: getMessageMetadataContext()\n \"\n ></ng-container>\n </div>\n </ng-container>\n <div\n class=\"\n str-chat__message-data\n str-chat__message-simple-data\n str-chat__message-metadata\n \"\n >\n <ng-container *ngIf=\"themeVersion === '2'\">\n <ng-container *ngTemplateOutlet=\"messageStatus\"></ng-container>\n </ng-container>\n <span\n data-testid=\"sender\"\n *ngIf=\"!isSentByCurrentUser\"\n class=\"str-chat__message-simple-name str-chat__message-sender-name\"\n >\n {{ message?.user?.name ? message?.user?.name : message?.user?.id }}\n </span>\n <span data-testid=\"date\" class=\"str-chat__message-simple-timestamp\">\n {{ parsedDate }}\n </span>\n </div>\n </ng-container>\n</ng-template>\n\n<ng-template #messageStatus>\n <ng-container\n *ngIf=\"\n isSentByCurrentUser &&\n ((isLastSentMessage && message?.status === 'received') ||\n message?.status === 'sending')\n \"\n >\n <ng-container *ngIf=\"message?.status === 'sending'; else sentStatus\">\n <ng-container *ngTemplateOutlet=\"sendingStatus\"></ng-container>\n </ng-container>\n <ng-template #sentStatus>\n <ng-container\n *ngIf=\"\n mode === 'main' && isMessageDeliveredAndRead && canDisplayReadStatus;\n else deliveredStatus\n \"\n >\n <ng-container *ngTemplateOutlet=\"readStatus\"></ng-container>\n </ng-container>\n </ng-template>\n <ng-template #deliveredStatus>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.deliveredStatusTemplate$ | async) ||\n defaultDeliveredStatus;\n context: getDeliveredStatusContext()\n \"\n ></ng-container>\n </ng-template>\n <ng-template #defaultDeliveredStatus>\n <span\n *ngIf=\"mode === 'main'\"\n class=\"\n str-chat__message-simple-status\n str-chat__message-simple-status-angular\n str-chat__message-status\n \"\n data-testid=\"delivered-indicator\"\n tabindex=\"0\"\n [popper]=\"popperContent\"\n [popperTrigger]=\"popperTriggerHover\"\n [popperPlacement]=\"popperPlacementAuto\"\n [popperHideOnScroll]=\"false\"\n [popperHideOnClickOutside]=\"false\"\n (hover)=\"$event.stopPropagation()\"\n >\n <popper-content #popperContent>\n <div class=\"str-chat__tooltip str-chat__tooltip-angular\">\n {{ \"streamChat.Delivered\" | translate }}\n </div>\n </popper-content>\n <stream-icon-placeholder\n data-testid=\"delivered-icon\"\n icon=\"delivered-icon\"\n ></stream-icon-placeholder>\n </span>\n </ng-template>\n <ng-template #sendingStatus>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.sendingStatusTemplate$ | async) ||\n defaultSendingStatus;\n context: getSendingStatusContext()\n \"\n ></ng-container>\n </ng-template>\n <ng-template #defaultSendingStatus>\n <span\n class=\"\n str-chat__message-simple-status\n str-chat__message-simple-status-angular\n str-chat__message-status\n \"\n data-testid=\"sending-indicator\"\n tabindex=\"0\"\n [popper]=\"popperContent\"\n [popperTrigger]=\"popperTriggerHover\"\n [popperPlacement]=\"popperPlacementAuto\"\n [popperHideOnScroll]=\"false\"\n [popperHideOnClickOutside]=\"false\"\n (hover)=\"$event.stopPropagation()\"\n >\n <popper-content #popperContent>\n <div class=\"str-chat__tooltip str-chat__tooltip-angular\">\n {{ \"streamChat.Sending...\" | translate }}\n </div>\n </popper-content>\n <stream-loading-indicator-placeholder\n data-testid=\"loading-indicator\"\n ></stream-loading-indicator-placeholder>\n </span>\n </ng-template>\n <ng-template #readStatus>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.readStatusTemplate$ | async) ||\n defaultReadStatus;\n context: getReadStatusContext()\n \"\n ></ng-container>\n </ng-template>\n <ng-template #defaultReadStatus>\n <span\n class=\"\n str-chat__message-simple-status\n str-chat__message-simple-status-angular\n str-chat__message-status\n \"\n data-testid=\"read-indicator\"\n tabindex=\"0\"\n [popper]=\"popperContent\"\n [popperTrigger]=\"popperTriggerHover\"\n [popperPlacement]=\"popperPlacementAuto\"\n [popperHideOnScroll]=\"false\"\n [popperHideOnClickOutside]=\"false\"\n (hover)=\"$event.stopPropagation()\"\n >\n <popper-content #popperContent>\n <div\n class=\"str-chat__tooltip str-chat__tooltip-angular\"\n data-testid=\"read-by-tooltip\"\n >\n {{ readByText }}\n </div>\n </popper-content>\n <stream-avatar-placeholder\n class=\"str-chat-angular__avatar-host\"\n data-test-id=\"last-read-user-avatar\"\n [size]=\"15\"\n [imageUrl]=\"lastReadUser?.image\"\n [name]=\"lastReadUser?.name || lastReadUser?.id\"\n type=\"user\"\n location=\"message-reader\"\n [user]=\"lastReadUser\"\n ></stream-avatar-placeholder>\n <span\n data-test-id=\"read-by-length\"\n *ngIf=\"isReadByMultipleUsers\"\n class=\"str-chat__message-simple-status-number\"\n >\n {{ (message?.readBy)!.length }}\n </span>\n </span>\n </ng-template>\n </ng-container>\n</ng-template>\n\n<ng-template #replyCountButton let-position=\"position\">\n <div\n *ngIf=\"\n (position === 'inside-message-bubble' && themeVersion === '1') ||\n (position === 'outside-message-bubble' && themeVersion === '2')\n \"\n class=\"\n str-chat__message-simple-reply-button\n str-chat__message-replies-count-button-wrapper\n \"\n >\n <button\n *ngIf=\"shouldDisplayThreadLink\"\n class=\"str-chat__message-replies-count-button\"\n data-testid=\"reply-count-button\"\n (click)=\"setAsActiveParentMessage()\"\n >\n <stream-icon-placeholder\n *ngIf=\"themeVersion === '1'\"\n stream-icon-placeholder\n icon=\"reply\"\n ></stream-icon-placeholder>\n {{message?.reply_count === 1 ? ('streamChat.1 reply' | translate) : ('streamChat.{{ replyCount }}\n replies' | translate:replyCountParam)}}\n </button>\n </div>\n</ng-template>\n\n<ng-template #attachmentsTemplate>\n <ng-template\n #defaultAttachments\n let-messageId=\"messageId\"\n let-attachments=\"attachments\"\n let-parentMessageId=\"parentMessageId\"\n let-imageModalStateChangeHandler=\"imageModalStateChangeHandler\"\n >\n <stream-attachment-list\n [messageId]=\"messageId\"\n [attachments]=\"attachments\"\n [parentMessageId]=\"parentMessageId\"\n (imageModalStateChange)=\"imageModalStateChangeHandler($event)\"\n ></stream-attachment-list>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.attachmentListTemplate$ | async) ||\n defaultAttachments;\n context: getAttachmentListContext()\n \"\n ></ng-container>\n</ng-template>\n", components: [{ type: AvatarPlaceholderComponent, selector: "stream-avatar-placeholder", inputs: ["name", "imageUrl", "size", "location", "channel", "user", "type", "initialsType", "showOnlineIndicator"] }, { type: i9.NgxPopperjsContentComponent, selector: "popper-content", exportAs: ["ngxPopperjsContent"] }, { type: MessageActionsBoxComponent, selector: "stream-message-actions-box", inputs: ["isOpen", "isMine", "message", "enabledActions", "customActions"], outputs: ["displayedActionsCount", "isEditing"] }, { type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon", "size"] }, { type: MessageReactionsComponent, selector: "stream-message-reactions", inputs: ["messageId", "messageReactionCounts", "isSelectorOpen", "latestReactions", "ownReactions"], outputs: ["isSelectorOpenChange"] }, { type: AttachmentListComponent, selector: "stream-attachment-list", inputs: ["messageId", "parentMessageId", "attachments"], outputs: ["imageModalStateChange"] }, { type: LoadingIndicatorPlaceholderComponent, selector: "stream-loading-indicator-placeholder", inputs: ["size", "color"] }], directives: [{ type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i5.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i9.NgxPopperjsDirective, selector: "[popper]", inputs: ["popperTimeout", "popperTimeoutAfterShow", "popperApplyClass", "popper", "popperDisabled", "popperPlacement", "popperApplyArrowClass", "popperPreventOverflow", "popperHideOnClickOutside", "popperTrigger", "popperStyles", "popperAriaDescribeBy", "popperAriaRole", "popperBoundaries", "popperCloseOnClickOutside", "popperDisableAnimation", "popperDisableStyle", "popperHideOnMouseLeave", "popperHideOnScroll", "popperAppendTo", "popperModifiers", "popperPositionFixed", "popperDelay", "popperShowOnStart", "popperTarget"], outputs: ["popperOnHidden", "popperOnShown", "popperOnUpdate"], exportAs: ["popper"] }, { type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i6.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }], pipes: { "async": i5.AsyncPipe, "translate": i6.TranslatePipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
5542
|
+
MessageComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: MessageComponent, selector: "stream-message", inputs: { message: "message", enabledMessageActions: "enabledMessageActions", isLastSentMessage: "isLastSentMessage", mode: "mode", isHighlighted: "isHighlighted", customActions: "customActions" }, viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div\n #container\n class=\"str-chat__message-simple str-chat__message str-chat__message--{{\n message?.type\n }} str-chat__message--{{ message?.status }} {{\n message?.text ? 'str-chat__message--has-text' : 'has-no-text'\n }}\"\n [class.str-chat__message--me]=\"isSentByCurrentUser\"\n [class.str-chat__message--other]=\"!isSentByCurrentUser\"\n [class.str-chat__message-simple--me]=\"isSentByCurrentUser\"\n [class.str-chat__message--has-attachment]=\"hasAttachment\"\n [class.str-chat__message--with-reactions]=\"hasReactions\"\n [class.str-chat__message--highlighted]=\"isHighlighted\"\n [class.str-chat__message-with-thread-link]=\"shouldDisplayThreadLink\"\n [class.str-chat__message-send-can-be-retried]=\"\n (message?.status === 'failed' && message?.errorStatusCode !== 403) ||\n (message?.type === 'error' && message?.moderation_details)\n \"\n data-testid=\"message-container\"\n>\n <ng-container *ngIf=\"!message?.deleted_at; else deletedMessage\">\n <ng-container *ngIf=\"message?.type !== 'system'; else systemMessage\">\n <ng-container *ngIf=\"themeVersion === '1'\">\n <ng-container *ngTemplateOutlet=\"messageStatus\"></ng-container>\n </ng-container>\n <stream-avatar-placeholder\n data-testid=\"avatar\"\n class=\"str-chat-angular__avatar-host str-chat__message-sender-avatar\"\n [imageUrl]=\"message?.user?.image\"\n [name]=\"message?.user?.name || message?.user?.id\"\n type=\"user\"\n location=\"message-sender\"\n [user]=\"message?.user || undefined\"\n ></stream-avatar-placeholder>\n <div class=\"str-chat__message-inner\">\n <div\n class=\"str-chat__message-simple__actions str-chat__message-options\"\n data-testid=\"message-options\"\n [class.str-chat__message-actions-open]=\"isActionBoxOpen\"\n *ngIf=\"areOptionsVisible\"\n >\n <div\n data-testid=\"message-actions-container\"\n #messageActionsToggle\n class=\"\n str-chat__message-actions-container\n str-chat__message-simple__actions__action\n str-chat__message-simple__actions__action--options\n \"\n [popper]=\"popperContent\"\n [popperTrigger]=\"popperTriggerClick\"\n [popperPlacement]=\"popperPlacementAuto\"\n [popperHideOnScroll]=\"false\"\n [popperHideOnClickOutside]=\"true\"\n [popperHideOnMouseLeave]=\"false\"\n [popperDisableAnimation]=\"true\"\n (popperOnHidden)=\"isActionBoxOpen = false\"\n >\n <popper-content #popperContent>\n <ng-template\n #defaultMessageActionsBox\n let-isOpen=\"isOpen\"\n let-isMine=\"isMine\"\n let-enabledActions=\"enabledActions\"\n let-messageInput=\"message\"\n let-customActions=\"customActions\"\n >\n <stream-message-actions-box\n (click)=\"messageActionsBoxClicked(popperContent)\"\n *ngIf=\"isOpen\"\n [isOpen]=\"isOpen\"\n [isMine]=\"isMine\"\n [enabledActions]=\"enabledActions\"\n [customActions]=\"customActions\"\n [message]=\"messageInput\"\n ></stream-message-actions-box>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.messageActionsBoxTemplate$ | async) ||\n defaultMessageActionsBox;\n context: getMessageActionsBoxContext()\n \"\n >\n </ng-container>\n </popper-content>\n <div\n class=\"str-chat__message-actions-box-button\"\n data-testid=\"action-icon\"\n (click)=\"messageActionsClicked()\"\n (keyup.enter)=\"messageActionsClicked()\"\n *ngIf=\"visibleMessageActionsCount > 0\"\n >\n <stream-icon-placeholder\n icon=\"action-icon\"\n class=\"str-chat__message-action-icon\"\n ></stream-icon-placeholder>\n </div>\n </div>\n <div\n *ngIf=\"\n enabledMessageActions.indexOf('send-reply') !== -1 &&\n mode === 'main'\n \"\n class=\"\n str-chat__message-simple__actions__action\n str-chat__message-simple__actions__action--thread\n str-chat__message-reply-in-thread-button\n \"\n data-testid=\"reply-in-thread\"\n (click)=\"setAsActiveParentMessage()\"\n (keyup.enter)=\"setAsActiveParentMessage()\"\n >\n <stream-icon-placeholder\n class=\"str-chat__message-action-icon\"\n icon=\"reply-in-thread\"\n ></stream-icon-placeholder>\n </div>\n <div\n *ngIf=\"canReactToMessage\"\n class=\"\n str-chat__message-simple__actions__action\n str-chat__message-simple__actions__action--reactions\n str-chat__message-reactions-button\n \"\n data-testid=\"reaction-icon\"\n (click)=\"isReactionSelectorOpen = !isReactionSelectorOpen\"\n (keyup.enter)=\"isReactionSelectorOpen = !isReactionSelectorOpen\"\n >\n <stream-icon-placeholder\n class=\"str-chat__message-action-icon\"\n icon=\"reaction-icon\"\n ></stream-icon-placeholder>\n </div>\n </div>\n <div class=\"str-chat__message-reactions-host\">\n <ng-template\n #defaultMessageReactions\n let-messageReactionCounts=\"messageReactionCounts\"\n let-latestReactions=\"latestReactions\"\n let-isSelectorOpen=\"isSelectorOpen\"\n let-isSelectorOpenChangeHandler=\"isSelectorOpenChangeHandler\"\n let-messageId=\"messageId\"\n let-ownReactions=\"ownReactions\"\n >\n <stream-message-reactions\n [messageReactionCounts]=\"messageReactionCounts\"\n [latestReactions]=\"latestReactions\"\n [isSelectorOpen]=\"isSelectorOpen\"\n (isSelectorOpenChange)=\"isSelectorOpenChangeHandler($event)\"\n [messageId]=\"messageId\"\n [ownReactions]=\"ownReactions\"\n ></stream-message-reactions>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.messageReactionsTemplate$ | async) ||\n defaultMessageReactions;\n context: getMessageReactionsContext()\n \"\n ></ng-container>\n </div>\n <!-- transform: translate3d(0, 0, 0) fixes scrolling issues on iOS, see: https://stackoverflow.com/questions/50105780/elements-disappear-when-scrolling-in-safari-webkit-transform-fix-only-works-t/50144295#50144295 -->\n <!-- transform: none is required when image carousel is open in order for the modal to be correctly positioned, see how the transform property changes the behavior of fixed positioned elements https://developer.mozilla.org/en-US/docs/Web/CSS/position -->\n <div\n class=\"str-chat__message-bubble\"\n style=\"transform: {{\n imageAttachmentModalState === 'opened'\n ? 'none'\n : 'translate3d(0, 0, 0)'\n }}\"\n >\n <ng-container *ngIf=\"hasAttachment && !message?.quoted_message\">\n <ng-container\n *ngTemplateOutlet=\"attachmentsTemplate\"\n ></ng-container>\n </ng-container>\n <div\n class=\"str-chat__message-text\"\n tabindex=\"0\"\n *ngIf=\"message?.text || (message?.quoted_message && hasAttachment)\"\n >\n <div\n data-testid=\"inner-message\"\n class=\"\n str-chat__message-text-inner str-chat__message-simple-text-inner\n \"\n [class.str-chat__message-light-text-inner--has-attachment]=\"\n hasAttachment\n \"\n (click)=\"unsentMessageClicked()\"\n (keyup.enter)=\"unsentMessageClicked()\"\n >\n <ng-container *ngTemplateOutlet=\"quotedMessage\"></ng-container>\n <ng-container *ngIf=\"hasAttachment && message?.quoted_message\">\n <ng-container\n *ngTemplateOutlet=\"attachmentsTemplate\"\n ></ng-container>\n </ng-container>\n <div\n data-testid=\"client-error-message\"\n *ngIf=\"message?.type === 'error'\"\n class=\"\n str-chat__simple-message--error-message\n str-chat__message--error-message\n \"\n >\n <ng-container *ngIf=\"!message?.moderation_details\">{{\n \"streamChat.Error \u00B7 Unsent\" | translate\n }}</ng-container>\n </div>\n <div\n data-testid=\"error-message\"\n *ngIf=\"message?.status === 'failed'\"\n class=\"\n str-chat__simple-message--error-message\n str-chat__message--error-message\n \"\n >\n {{\n (message?.errorStatusCode === 403\n ? \"streamChat.Message Failed \u00B7 Unauthorized\"\n : \"streamChat.Message Failed \u00B7 Click to try again\"\n ) | translate\n }}\n </div>\n <div data-testid=\"text\">\n <p>\n <ng-container *ngIf=\"messageTextParts; else defaultContent\">\n <!-- eslint-disable-next-line @angular-eslint/template/use-track-by-function -->\n <ng-container *ngFor=\"let part of messageTextParts\">\n <span\n *ngIf=\"part.type === 'text'; else mention\"\n [innerHTML]=\"part.content\"\n ></span>\n <ng-template #mention>\n <ng-template #defaultMention let-content=\"content\">\n <span class=\"str-chat__message-mention\">{{\n content\n }}</span>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.mentionTemplate$ | async) ||\n defaultMention;\n context: getMentionContext(part)\n \"\n ></ng-container>\n </ng-template>\n </ng-container>\n </ng-container>\n <ng-template #defaultContent>\n <ng-container *ngIf=\"displayAs === 'text'; else asHTML\">\n {{ messageText || \"\" }}\n </ng-container>\n <ng-template #asHTML\n ><span\n data-testid=\"html-content\"\n [innerHTML]=\"messageText\"\n ></span\n ></ng-template>\n </ng-template>\n </p>\n </div>\n </div>\n </div>\n <stream-icon-placeholder\n *ngIf=\"themeVersion === '2'\"\n class=\"str-chat__message-error-icon\"\n icon=\"error\"\n ></stream-icon-placeholder>\n </div>\n <ng-container\n *ngTemplateOutlet=\"\n replyCountButton;\n context: { position: 'inside-message-bubble' }\n \"\n ></ng-container>\n <ng-container\n *ngTemplateOutlet=\"\n messageDateAndSender;\n context: { position: 'inside-message-bubble' }\n \"\n ></ng-container>\n </div>\n <ng-container\n *ngTemplateOutlet=\"\n replyCountButton;\n context: { position: 'outside-message-bubble', message: message }\n \"\n ></ng-container>\n\n <ng-container\n *ngTemplateOutlet=\"\n messageDateAndSender;\n context: { position: 'outside-message-bubble' }\n \"\n ></ng-container>\n </ng-container>\n </ng-container>\n</div>\n\n<ng-template #deletedMessage>\n <div data-testid=\"message-deleted-component\">\n <div class=\"str-chat__message--deleted-inner\" translate>\n streamChat.This message was deleted...\n </div>\n </div>\n</ng-template>\n\n<ng-template #systemMessage>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.systemMessageTemplate$ | async) ||\n defaultSystemMessage;\n context: getMessageContext()\n \"\n ></ng-container>\n <ng-template #defaultSystemMessage let-messageInput=\"message\">\n <div data-testid=\"system-message\" class=\"str-chat__message--system\">\n <div class=\"str-chat__message--system__text\">\n <div class=\"str-chat__message--system__line\"></div>\n <p>{{ messageInput?.text }}</p>\n <div class=\"str-chat__message--system__line\"></div>\n </div>\n <div class=\"str-chat__message--system__date\">\n {{ parsedDate }}\n </div>\n </div>\n </ng-template>\n</ng-template>\n\n<ng-template #quotedMessage>\n <div\n *ngIf=\"message?.quoted_message\"\n class=\"quoted-message str-chat__quoted-message-preview\"\n data-testid=\"quoted-message-container\"\n [class.mine]=\"isSentByCurrentUser\"\n (click)=\"\n jumpToMessage(\n (message?.quoted_message)!.id,\n message?.quoted_message?.parent_id\n )\n \"\n (keyup.enter)=\"\n jumpToMessage(\n (message?.quoted_message)!.id,\n message?.quoted_message?.parent_id\n )\n \"\n >\n <stream-avatar-placeholder\n data-testid=\"qouted-message-avatar\"\n class=\"str-chat-angular__avatar-host str-chat__message-sender-avatar\"\n [imageUrl]=\"message?.quoted_message?.user?.image\"\n [name]=\"\n message?.quoted_message?.user?.name || message?.quoted_message?.user?.id\n \"\n [size]=\"20\"\n type=\"user\"\n location=\"quoted-message-sender\"\n [user]=\"message?.quoted_message?.user || undefined\"\n ></stream-avatar-placeholder>\n <div class=\"quoted-message-inner str-chat__quoted-message-bubble\">\n <ng-container\n *ngIf=\"\n message?.quoted_message?.attachments &&\n message?.quoted_message?.attachments?.length\n \"\n >\n <ng-template\n #defaultAttachments\n let-messageId=\"messageId\"\n let-attachments=\"attachments\"\n let-parentMessageId=\"parentMessageId\"\n let-imageModalStateChangeHandler=\"imageModalStateChangeHandler\"\n >\n <stream-attachment-list\n [messageId]=\"messageId\"\n [attachments]=\"attachments\"\n [parentMessageId]=\"parentMessageId\"\n (imageModalStateChange)=\"imageModalStateChangeHandler($event)\"\n ></stream-attachment-list>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.attachmentListTemplate$ | async) ||\n defaultAttachments;\n context: getQuotedMessageAttachmentListContext()\n \"\n ></ng-container>\n </ng-container>\n <div\n data-testid=\"quoted-message-text\"\n [innerHTML]=\"\n message?.quoted_message?.translation ||\n message?.quoted_message?.html ||\n message?.quoted_message?.text\n \"\n ></div>\n </div>\n </div>\n</ng-template>\n\n<!-- We need these markups in slightly different positions in theme-v1 and theme-v2, this soultion makes that possible without duplicating the code -->\n<ng-template #messageDateAndSender let-position=\"position\">\n <ng-container\n *ngIf=\"\n (position === 'inside-message-bubble' && themeVersion === '1') ||\n (position === 'outside-message-bubble' && themeVersion === '2')\n \"\n >\n <div\n class=\"str-chat__translation-notice\"\n *ngIf=\"shouldDisplayTranslationNotice\"\n data-testid=\"translation-notice\"\n >\n <button\n data-testid=\"see-original\"\n *ngIf=\"displayedMessageTextContent === 'translation'\"\n (click)=\"displayOriginalMessage()\"\n (keyup.enter)=\"displayOriginalMessage()\"\n translate\n >\n streamChat.See original (automatically translated)\n </button>\n <button\n data-testid=\"see-translation\"\n *ngIf=\"displayedMessageTextContent === 'original'\"\n (click)=\"displayTranslatedMessage()\"\n (keyup.enter)=\"displayTranslatedMessage()\"\n translate\n >\n streamChat.See translation\n </button>\n </div>\n <ng-container\n *ngIf=\"customTemplatesService.customMessageMetadataTemplate$ | async\"\n >\n <div class=\"str-chat__custom-message-metadata\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.customMessageMetadataTemplate$ | async)!;\n context: getMessageMetadataContext()\n \"\n ></ng-container>\n </div>\n </ng-container>\n <div\n class=\"\n str-chat__message-data\n str-chat__message-simple-data\n str-chat__message-metadata\n \"\n >\n <ng-container *ngIf=\"themeVersion === '2'\">\n <ng-container *ngTemplateOutlet=\"messageStatus\"></ng-container>\n </ng-container>\n <span\n data-testid=\"sender\"\n *ngIf=\"!isSentByCurrentUser\"\n class=\"str-chat__message-simple-name str-chat__message-sender-name\"\n >\n {{ message?.user?.name ? message?.user?.name : message?.user?.id }}\n </span>\n <span data-testid=\"date\" class=\"str-chat__message-simple-timestamp\">\n {{ parsedDate }}\n </span>\n </div>\n </ng-container>\n</ng-template>\n\n<ng-template #messageStatus>\n <ng-container\n *ngIf=\"\n isSentByCurrentUser &&\n ((isLastSentMessage && message?.status === 'received') ||\n message?.status === 'sending')\n \"\n >\n <ng-container *ngIf=\"message?.status === 'sending'; else sentStatus\">\n <ng-container *ngTemplateOutlet=\"sendingStatus\"></ng-container>\n </ng-container>\n <ng-template #sentStatus>\n <ng-container\n *ngIf=\"\n mode === 'main' && isMessageDeliveredAndRead && canDisplayReadStatus;\n else deliveredStatus\n \"\n >\n <ng-container *ngTemplateOutlet=\"readStatus\"></ng-container>\n </ng-container>\n </ng-template>\n <ng-template #deliveredStatus>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.deliveredStatusTemplate$ | async) ||\n defaultDeliveredStatus;\n context: getDeliveredStatusContext()\n \"\n ></ng-container>\n </ng-template>\n <ng-template #defaultDeliveredStatus>\n <span\n *ngIf=\"mode === 'main'\"\n class=\"\n str-chat__message-simple-status\n str-chat__message-simple-status-angular\n str-chat__message-status\n \"\n data-testid=\"delivered-indicator\"\n tabindex=\"0\"\n [popper]=\"popperContent\"\n [popperTrigger]=\"popperTriggerHover\"\n [popperPlacement]=\"popperPlacementAuto\"\n [popperHideOnScroll]=\"false\"\n [popperHideOnClickOutside]=\"false\"\n (hover)=\"$event.stopPropagation()\"\n >\n <popper-content #popperContent>\n <div class=\"str-chat__tooltip str-chat__tooltip-angular\">\n {{ \"streamChat.Delivered\" | translate }}\n </div>\n </popper-content>\n <stream-icon-placeholder\n data-testid=\"delivered-icon\"\n icon=\"delivered-icon\"\n ></stream-icon-placeholder>\n </span>\n </ng-template>\n <ng-template #sendingStatus>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.sendingStatusTemplate$ | async) ||\n defaultSendingStatus;\n context: getSendingStatusContext()\n \"\n ></ng-container>\n </ng-template>\n <ng-template #defaultSendingStatus>\n <span\n class=\"\n str-chat__message-simple-status\n str-chat__message-simple-status-angular\n str-chat__message-status\n \"\n data-testid=\"sending-indicator\"\n tabindex=\"0\"\n [popper]=\"popperContent\"\n [popperTrigger]=\"popperTriggerHover\"\n [popperPlacement]=\"popperPlacementAuto\"\n [popperHideOnScroll]=\"false\"\n [popperHideOnClickOutside]=\"false\"\n (hover)=\"$event.stopPropagation()\"\n >\n <popper-content #popperContent>\n <div class=\"str-chat__tooltip str-chat__tooltip-angular\">\n {{ \"streamChat.Sending...\" | translate }}\n </div>\n </popper-content>\n <stream-loading-indicator-placeholder\n data-testid=\"loading-indicator\"\n ></stream-loading-indicator-placeholder>\n </span>\n </ng-template>\n <ng-template #readStatus>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.readStatusTemplate$ | async) ||\n defaultReadStatus;\n context: getReadStatusContext()\n \"\n ></ng-container>\n </ng-template>\n <ng-template #defaultReadStatus>\n <span\n class=\"\n str-chat__message-simple-status\n str-chat__message-simple-status-angular\n str-chat__message-status\n \"\n data-testid=\"read-indicator\"\n tabindex=\"0\"\n [popper]=\"popperContent\"\n [popperTrigger]=\"popperTriggerHover\"\n [popperPlacement]=\"popperPlacementAuto\"\n [popperHideOnScroll]=\"false\"\n [popperHideOnClickOutside]=\"false\"\n (hover)=\"$event.stopPropagation()\"\n >\n <popper-content #popperContent>\n <div\n class=\"str-chat__tooltip str-chat__tooltip-angular\"\n data-testid=\"read-by-tooltip\"\n >\n {{ readByText }}\n </div>\n </popper-content>\n <stream-avatar-placeholder\n class=\"str-chat-angular__avatar-host\"\n data-test-id=\"last-read-user-avatar\"\n [size]=\"15\"\n [imageUrl]=\"lastReadUser?.image\"\n [name]=\"lastReadUser?.name || lastReadUser?.id\"\n type=\"user\"\n location=\"message-reader\"\n [user]=\"lastReadUser\"\n ></stream-avatar-placeholder>\n <span\n data-test-id=\"read-by-length\"\n *ngIf=\"isReadByMultipleUsers\"\n class=\"str-chat__message-simple-status-number\"\n >\n {{ (message?.readBy)!.length }}\n </span>\n </span>\n </ng-template>\n </ng-container>\n</ng-template>\n\n<ng-template #replyCountButton let-position=\"position\">\n <div\n *ngIf=\"\n (position === 'inside-message-bubble' && themeVersion === '1') ||\n (position === 'outside-message-bubble' && themeVersion === '2')\n \"\n class=\"\n str-chat__message-simple-reply-button\n str-chat__message-replies-count-button-wrapper\n \"\n >\n <button\n *ngIf=\"shouldDisplayThreadLink\"\n class=\"str-chat__message-replies-count-button\"\n data-testid=\"reply-count-button\"\n (click)=\"setAsActiveParentMessage()\"\n >\n <stream-icon-placeholder\n *ngIf=\"themeVersion === '1'\"\n stream-icon-placeholder\n icon=\"reply\"\n ></stream-icon-placeholder>\n {{message?.reply_count === 1 ? ('streamChat.1 reply' | translate) : ('streamChat.{{ replyCount }}\n replies' | translate:replyCountParam)}}\n </button>\n </div>\n</ng-template>\n\n<ng-template #attachmentsTemplate>\n <ng-template\n #defaultAttachments\n let-messageId=\"messageId\"\n let-attachments=\"attachments\"\n let-parentMessageId=\"parentMessageId\"\n let-imageModalStateChangeHandler=\"imageModalStateChangeHandler\"\n >\n <stream-attachment-list\n [messageId]=\"messageId\"\n [attachments]=\"attachments\"\n [parentMessageId]=\"parentMessageId\"\n (imageModalStateChange)=\"imageModalStateChangeHandler($event)\"\n ></stream-attachment-list>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.attachmentListTemplate$ | async) ||\n defaultAttachments;\n context: getAttachmentListContext()\n \"\n ></ng-container>\n</ng-template>\n", components: [{ type: AvatarPlaceholderComponent, selector: "stream-avatar-placeholder", inputs: ["name", "imageUrl", "size", "location", "channel", "user", "type", "initialsType", "showOnlineIndicator"] }, { type: i9.NgxPopperjsContentComponent, selector: "popper-content", exportAs: ["ngxPopperjsContent"] }, { type: MessageActionsBoxComponent, selector: "stream-message-actions-box", inputs: ["isOpen", "isMine", "message", "enabledActions", "customActions"], outputs: ["displayedActionsCount", "isEditing"] }, { type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon", "size"] }, { type: MessageReactionsComponent, selector: "stream-message-reactions", inputs: ["messageId", "messageReactionCounts", "isSelectorOpen", "latestReactions", "ownReactions"], outputs: ["isSelectorOpenChange"] }, { type: AttachmentListComponent, selector: "stream-attachment-list", inputs: ["messageId", "parentMessageId", "attachments"], outputs: ["imageModalStateChange"] }, { type: LoadingIndicatorPlaceholderComponent, selector: "stream-loading-indicator-placeholder", inputs: ["size", "color"] }], directives: [{ type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i5.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i9.NgxPopperjsDirective, selector: "[popper]", inputs: ["popperTimeout", "popperTimeoutAfterShow", "popperApplyClass", "popper", "popperDisabled", "popperPlacement", "popperApplyArrowClass", "popperPreventOverflow", "popperHideOnClickOutside", "popperTrigger", "popperStyles", "popperAriaDescribeBy", "popperAriaRole", "popperBoundaries", "popperCloseOnClickOutside", "popperDisableAnimation", "popperDisableStyle", "popperHideOnMouseLeave", "popperHideOnScroll", "popperAppendTo", "popperModifiers", "popperPositionFixed", "popperDelay", "popperShowOnStart", "popperTarget"], outputs: ["popperOnHidden", "popperOnShown", "popperOnUpdate"], exportAs: ["popper"] }, { type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i6.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }], pipes: { "async": i5.AsyncPipe, "translate": i6.TranslatePipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
5407
5543
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: MessageComponent, decorators: [{
|
|
5408
5544
|
type: Component,
|
|
5409
5545
|
args: [{
|
|
@@ -6377,8 +6513,8 @@ class MessageListComponent {
|
|
|
6377
6513
|
(_d = (_c = this.chatClientService.chatClient) === null || _c === void 0 ? void 0 : _c.logger) === null || _d === void 0 ? void 0 : _d.call(_c, 'info', `Received one or more messages`, {
|
|
6378
6514
|
tags: `message list ${this.mode}`,
|
|
6379
6515
|
});
|
|
6380
|
-
const
|
|
6381
|
-
this.newMessageReceived(
|
|
6516
|
+
const currentLatestMessageInState = messages[messages.length - 1];
|
|
6517
|
+
this.newMessageReceived(currentLatestMessageInState);
|
|
6382
6518
|
const currentOldestMessage = messages[0];
|
|
6383
6519
|
if (!this.oldestMessage ||
|
|
6384
6520
|
!messages.find((m) => m.id === this.oldestMessage.id)) {
|
|
@@ -6411,7 +6547,8 @@ class MessageListComponent {
|
|
|
6411
6547
|
this.isLatestMessageInList =
|
|
6412
6548
|
!this.latestMessage ||
|
|
6413
6549
|
messages.length === 0 ||
|
|
6414
|
-
messages[messages.length - 1].id === this.latestMessage.id
|
|
6550
|
+
messages[messages.length - 1].id === this.latestMessage.id ||
|
|
6551
|
+
this.mode === 'thread';
|
|
6415
6552
|
if (!this.isLatestMessageInList) {
|
|
6416
6553
|
this.isUserScrolled = true;
|
|
6417
6554
|
}
|
|
@@ -6468,15 +6605,20 @@ class MessageListComponent {
|
|
|
6468
6605
|
}
|
|
6469
6606
|
}
|
|
6470
6607
|
newMessageReceived(message) {
|
|
6471
|
-
var _a, _b, _c, _d, _e, _f;
|
|
6608
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
6609
|
+
const latestMessages = (_b = (_a = this.channelService.activeChannel) === null || _a === void 0 ? void 0 : _a.state) === null || _b === void 0 ? void 0 : _b.latestMessages;
|
|
6472
6610
|
if (!this.latestMessage ||
|
|
6473
|
-
((
|
|
6474
|
-
(
|
|
6611
|
+
((_c = this.latestMessage.created_at) === null || _c === void 0 ? void 0 : _c.getTime()) < message.created_at.getTime() ||
|
|
6612
|
+
(this.mode === 'main' &&
|
|
6613
|
+
latestMessages &&
|
|
6614
|
+
this.latestMessage &&
|
|
6615
|
+
((_d = latestMessages[latestMessages.length - 1]) === null || _d === void 0 ? void 0 : _d.id) !== this.latestMessage.id)) {
|
|
6616
|
+
(_f = (_e = this.chatClientService.chatClient) === null || _e === void 0 ? void 0 : _e.logger) === null || _f === void 0 ? void 0 : _f.call(_e, 'info', `Received new message`, { tags: `message list ${this.mode}` });
|
|
6475
6617
|
const isNewChannel = !this.latestMessage;
|
|
6476
6618
|
this.latestMessage = message;
|
|
6477
6619
|
this.hasNewMessages = true;
|
|
6478
6620
|
this.isNewMessageSentByUser =
|
|
6479
|
-
((
|
|
6621
|
+
((_g = message.user) === null || _g === void 0 ? void 0 : _g.id) === ((_j = (_h = this.chatClientService.chatClient) === null || _h === void 0 ? void 0 : _h.user) === null || _j === void 0 ? void 0 : _j.id);
|
|
6480
6622
|
if (this.isUserScrolled) {
|
|
6481
6623
|
this.newMessageCountWhileBeingScrolled++;
|
|
6482
6624
|
}
|
|
@@ -6647,7 +6789,9 @@ StreamChatModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", versio
|
|
|
6647
6789
|
TextareaDirective,
|
|
6648
6790
|
ThreadComponent,
|
|
6649
6791
|
IconPlaceholderComponent,
|
|
6650
|
-
LoadingIndicatorPlaceholderComponent
|
|
6792
|
+
LoadingIndicatorPlaceholderComponent,
|
|
6793
|
+
EditMessageFormComponent,
|
|
6794
|
+
MessageBouncePromptComponent], imports: [CommonModule,
|
|
6651
6795
|
TranslateModule,
|
|
6652
6796
|
StreamAvatarModule,
|
|
6653
6797
|
NgxPopperjsModule], exports: [ChannelComponent,
|
|
@@ -6669,7 +6813,9 @@ StreamChatModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", versio
|
|
|
6669
6813
|
StreamAvatarModule,
|
|
6670
6814
|
ThreadComponent,
|
|
6671
6815
|
IconPlaceholderComponent,
|
|
6672
|
-
LoadingIndicatorPlaceholderComponent
|
|
6816
|
+
LoadingIndicatorPlaceholderComponent,
|
|
6817
|
+
EditMessageFormComponent,
|
|
6818
|
+
MessageBouncePromptComponent] });
|
|
6673
6819
|
StreamChatModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: StreamChatModule, imports: [[
|
|
6674
6820
|
CommonModule,
|
|
6675
6821
|
TranslateModule,
|
|
@@ -6700,6 +6846,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
6700
6846
|
ThreadComponent,
|
|
6701
6847
|
IconPlaceholderComponent,
|
|
6702
6848
|
LoadingIndicatorPlaceholderComponent,
|
|
6849
|
+
EditMessageFormComponent,
|
|
6850
|
+
MessageBouncePromptComponent,
|
|
6703
6851
|
],
|
|
6704
6852
|
imports: [
|
|
6705
6853
|
CommonModule,
|
|
@@ -6728,6 +6876,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
6728
6876
|
ThreadComponent,
|
|
6729
6877
|
IconPlaceholderComponent,
|
|
6730
6878
|
LoadingIndicatorPlaceholderComponent,
|
|
6879
|
+
EditMessageFormComponent,
|
|
6880
|
+
MessageBouncePromptComponent,
|
|
6731
6881
|
],
|
|
6732
6882
|
}]
|
|
6733
6883
|
}] });
|
|
@@ -6790,5 +6940,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
6790
6940
|
* Generated bundle index. Do not edit.
|
|
6791
6941
|
*/
|
|
6792
6942
|
|
|
6793
|
-
export { AttachmentConfigurationService, AttachmentListComponent, AttachmentPreviewListComponent, AttachmentService, AutocompleteTextareaComponent, AvatarComponent, AvatarPlaceholderComponent, ChannelComponent, ChannelHeaderComponent, ChannelListComponent, ChannelListToggleService, ChannelPreviewComponent, ChannelService, ChatClientService, CustomTemplatesService, DateParserService, EmojiInputService, IconComponent, IconPlaceholderComponent, ImageLoadService, LoadingIndicatorComponent, LoadingIndicatorPlaceholderComponent, MessageActionsBoxComponent, MessageActionsService, MessageComponent, MessageInputComponent, MessageInputConfigService, MessageListComponent, MessageReactionsComponent, MessageReactionsService, MessageService, ModalComponent, NotificationComponent, NotificationListComponent, NotificationService, StreamAutocompleteTextareaModule, StreamAvatarModule, StreamChatModule, StreamI18nService, StreamTextareaModule, TextareaComponent, TextareaDirective, ThemeService, ThreadComponent, TransliterationService, createMessagePreview, getChannelDisplayText, getGroupStyles, getMessageTranslation, getReadBy, isImageAttachment, isImageFile, listUsers, parseDate, textareaInjectionToken };
|
|
6943
|
+
export { AttachmentConfigurationService, AttachmentListComponent, AttachmentPreviewListComponent, AttachmentService, AutocompleteTextareaComponent, AvatarComponent, AvatarPlaceholderComponent, ChannelComponent, ChannelHeaderComponent, ChannelListComponent, ChannelListToggleService, ChannelPreviewComponent, ChannelService, ChatClientService, CustomTemplatesService, DateParserService, EditMessageFormComponent, EmojiInputService, IconComponent, IconPlaceholderComponent, ImageLoadService, LoadingIndicatorComponent, LoadingIndicatorPlaceholderComponent, MessageActionsBoxComponent, MessageActionsService, MessageBouncePromptComponent, MessageComponent, MessageInputComponent, MessageInputConfigService, MessageListComponent, MessageReactionsComponent, MessageReactionsService, MessageService, ModalComponent, NotificationComponent, NotificationListComponent, NotificationService, StreamAutocompleteTextareaModule, StreamAvatarModule, StreamChatModule, StreamI18nService, StreamTextareaModule, TextareaComponent, TextareaDirective, ThemeService, ThreadComponent, TransliterationService, createMessagePreview, getChannelDisplayText, getGroupStyles, getMessageTranslation, getReadBy, isImageAttachment, isImageFile, listUsers, parseDate, textareaInjectionToken };
|
|
6794
6944
|
//# sourceMappingURL=stream-chat-angular.js.map
|