stream-chat-angular 2.21.0 → 3.0.0-beta.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. package/README.md +44 -12
  2. package/assets/version.d.ts +1 -1
  3. package/bundles/stream-chat-angular.umd.js +796 -566
  4. package/bundles/stream-chat-angular.umd.js.map +1 -1
  5. package/esm2015/assets/version.js +2 -2
  6. package/esm2015/lib/attachment-list/attachment-list.component.js +27 -15
  7. package/esm2015/lib/attachment-preview-list/attachment-preview-list.component.js +28 -22
  8. package/esm2015/lib/attachment.service.js +11 -5
  9. package/esm2015/lib/avatar-placeholder/avatar-placeholder.component.js +41 -0
  10. package/esm2015/lib/channel-header/channel-header.component.js +26 -12
  11. package/esm2015/lib/channel-list/channel-list.component.js +23 -13
  12. package/esm2015/lib/channel-preview/channel-preview.component.js +3 -3
  13. package/esm2015/lib/channel.service.js +40 -64
  14. package/esm2015/lib/chat-client.service.js +5 -4
  15. package/esm2015/lib/custom-templates.service.js +139 -0
  16. package/esm2015/lib/icon-placeholder/icon-placeholder.component.js +34 -0
  17. package/esm2015/lib/loading-indicator-placeholder/loading-indicator-placeholder.component.js +42 -0
  18. package/esm2015/lib/message/message.component.js +74 -29
  19. package/esm2015/lib/message-actions-box/message-actions-box.component.js +114 -99
  20. package/esm2015/lib/message-input/autocomplete-textarea/autocomplete-textarea.component.js +13 -13
  21. package/esm2015/lib/message-input/message-input-config.service.js +1 -1
  22. package/esm2015/lib/message-input/message-input.component.js +56 -45
  23. package/esm2015/lib/message-input/textarea.directive.js +2 -18
  24. package/esm2015/lib/message-input/textarea.interface.js +1 -1
  25. package/esm2015/lib/message-list/message-list.component.js +32 -93
  26. package/esm2015/lib/message-preview.js +4 -17
  27. package/esm2015/lib/message-reactions/message-reactions.component.js +3 -3
  28. package/esm2015/lib/modal/modal.component.js +9 -6
  29. package/esm2015/lib/notification/notification.component.js +5 -2
  30. package/esm2015/lib/notification-list/notification-list.component.js +12 -10
  31. package/esm2015/lib/read-by.js +1 -1
  32. package/esm2015/lib/stream-avatar.module.js +5 -4
  33. package/esm2015/lib/stream-chat.module.js +13 -3
  34. package/esm2015/lib/thread/thread.component.js +19 -11
  35. package/esm2015/lib/types.js +1 -1
  36. package/esm2015/public-api.js +5 -1
  37. package/fesm2015/stream-chat-angular.js +735 -478
  38. package/fesm2015/stream-chat-angular.js.map +1 -1
  39. package/lib/attachment-list/attachment-list.component.d.ts +12 -8
  40. package/lib/attachment-preview-list/attachment-preview-list.component.d.ts +17 -7
  41. package/lib/attachment.service.d.ts +1 -1
  42. package/lib/avatar-placeholder/avatar-placeholder.component.d.ts +25 -0
  43. package/lib/channel-header/channel-header.component.d.ts +15 -12
  44. package/lib/channel-list/channel-list.component.d.ts +14 -11
  45. package/lib/channel-preview/channel-preview.component.d.ts +3 -2
  46. package/lib/channel.service.d.ts +33 -38
  47. package/lib/chat-client.service.d.ts +12 -11
  48. package/lib/custom-templates.service.d.ts +132 -0
  49. package/lib/icon-placeholder/icon-placeholder.component.d.ts +22 -0
  50. package/lib/loading-indicator-placeholder/loading-indicator-placeholder.component.d.ts +21 -0
  51. package/lib/message/message.component.d.ts +42 -30
  52. package/lib/message-actions-box/message-actions-box.component.d.ts +22 -26
  53. package/lib/message-input/autocomplete-textarea/autocomplete-textarea.component.d.ts +7 -11
  54. package/lib/message-input/message-input-config.service.d.ts +0 -19
  55. package/lib/message-input/message-input.component.d.ts +40 -26
  56. package/lib/message-input/textarea.directive.d.ts +3 -6
  57. package/lib/message-input/textarea.interface.d.ts +1 -4
  58. package/lib/message-list/group-styles.d.ts +1 -1
  59. package/lib/message-list/message-list.component.d.ts +10 -34
  60. package/lib/message-preview.d.ts +2 -1
  61. package/lib/message-reactions/message-reactions.component.d.ts +4 -5
  62. package/lib/modal/modal.component.d.ts +7 -3
  63. package/lib/notification/notification.component.d.ts +6 -1
  64. package/lib/notification-list/notification-list.component.d.ts +4 -2
  65. package/lib/read-by.d.ts +2 -1
  66. package/lib/stream-avatar.module.d.ts +4 -3
  67. package/lib/stream-chat.module.d.ts +6 -4
  68. package/lib/thread/thread.component.d.ts +6 -3
  69. package/lib/types.d.ts +115 -9
  70. package/package.json +2 -3
  71. package/public-api.d.ts +4 -0
  72. package/src/assets/styles/assets/EmojiOneColor.woff2 +0 -0
  73. package/src/assets/styles/assets/NotoColorEmoji-flags.woff2 +0 -0
  74. package/src/assets/styles/assets/Poweredby_100px-White_VertText.png +0 -0
  75. package/src/assets/styles/assets/str-chat__reaction-list-sprite@1x.png +0 -0
  76. package/src/assets/styles/assets/str-chat__reaction-list-sprite@2x.png +0 -0
  77. package/src/assets/styles/assets/str-chat__reaction-list-sprite@3x.png +0 -0
  78. package/src/assets/styles/css/index.css +1 -0
  79. package/src/assets/styles/css/index.css.map +1 -0
  80. package/src/assets/styles/scss/ActionsBox.scss +56 -0
  81. package/src/assets/styles/scss/Attachment.scss +227 -0
  82. package/src/assets/styles/scss/AttachmentActions.scss +44 -0
  83. package/src/assets/styles/scss/Audio.scss +112 -0
  84. package/src/assets/styles/scss/Avatar.scss +79 -0
  85. package/src/assets/styles/scss/Card.scss +100 -0
  86. package/src/assets/styles/scss/ChannelHeader.scss +284 -0
  87. package/src/assets/styles/scss/ChannelList.scss +117 -0
  88. package/src/assets/styles/scss/ChannelListMessenger.scss +9 -0
  89. package/src/assets/styles/scss/ChannelPreview.scss +108 -0
  90. package/src/assets/styles/scss/ChannelSearch.scss +111 -0
  91. package/src/assets/styles/scss/ChatDown.scss +15 -0
  92. package/src/assets/styles/scss/DateSeparator.scss +51 -0
  93. package/src/assets/styles/scss/EditMessageForm.scss +112 -0
  94. package/src/assets/styles/scss/EventComponent.scss +48 -0
  95. package/src/assets/styles/scss/Gallery.scss +135 -0
  96. package/src/assets/styles/scss/InfiniteScrollPaginator.scss +6 -0
  97. package/src/assets/styles/scss/LoadMoreButton.scss +44 -0
  98. package/src/assets/styles/scss/LoadingChannels.scss +70 -0
  99. package/src/assets/styles/scss/LoadingIndicator.scss +38 -0
  100. package/src/assets/styles/scss/Message.scss +1261 -0
  101. package/src/assets/styles/scss/MessageActions.scss +112 -0
  102. package/src/assets/styles/scss/MessageCommerce.scss +564 -0
  103. package/src/assets/styles/scss/MessageInput.scss +385 -0
  104. package/src/assets/styles/scss/MessageInputFlat.scss +305 -0
  105. package/src/assets/styles/scss/MessageList.scss +203 -0
  106. package/src/assets/styles/scss/MessageLivestream.scss +325 -0
  107. package/src/assets/styles/scss/MessageNotification.scss +49 -0
  108. package/src/assets/styles/scss/MessageRepliesCountButton.scss +33 -0
  109. package/src/assets/styles/scss/MessageTeam.scss +617 -0
  110. package/src/assets/styles/scss/Modal.scss +77 -0
  111. package/src/assets/styles/scss/ReactionList.scss +183 -0
  112. package/src/assets/styles/scss/ReactionSelector.scss +212 -0
  113. package/src/assets/styles/scss/SendButton.scss +14 -0
  114. package/src/assets/styles/scss/SimpleReactionsList.scss +76 -0
  115. package/src/assets/styles/scss/SmallMessageInput.scss +172 -0
  116. package/src/assets/styles/scss/Thread.scss +306 -0
  117. package/src/assets/styles/scss/Tooltip.scss +38 -0
  118. package/src/assets/styles/scss/TypingIndicator.scss +75 -0
  119. package/src/assets/styles/scss/VirtualMessage.scss +291 -0
  120. package/src/assets/styles/scss/_base.scss +206 -0
  121. package/src/assets/styles/scss/_variables.scss +158 -0
  122. package/src/assets/styles/scss/index.scss +50 -0
  123. package/src/assets/styles/scss/vendor/emoji-mart.scss +495 -0
  124. package/src/assets/styles/scss/vendor/mml-react.scss +1749 -0
  125. package/src/assets/styles/scss/vendor/react-file-utils.scss +378 -0
  126. package/src/assets/styles/scss/vendor/react-image-gallery.scss +224 -0
  127. package/src/assets/version.ts +1 -1
@@ -1,8 +1,8 @@
1
1
  (function (global, factory) {
2
2
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('rxjs'), require('stream-chat'), require('rxjs/operators'), require('uuid'), require('@ngx-translate/core'), require('@angular/common'), require('pretty-bytes'), require('dayjs'), require('dayjs/plugin/calendar'), require('emoji-regex'), require('@stream-io/transliterate'), require('angular-mentions')) :
3
3
  typeof define === 'function' && define.amd ? define('stream-chat-angular', ['exports', '@angular/core', 'rxjs', 'stream-chat', 'rxjs/operators', 'uuid', '@ngx-translate/core', '@angular/common', 'pretty-bytes', 'dayjs', 'dayjs/plugin/calendar', 'emoji-regex', '@stream-io/transliterate', 'angular-mentions'], factory) :
4
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global['stream-chat-angular'] = {}, global.ng.core, global.rxjs, global.streamChat, global.rxjs.operators, global.uuid, global.i2, global.ng.common, global.prettybytes, global.Dayjs, global.calendar, global.emojiRegex, global.transliterate, global.i6$1));
5
- }(this, (function (exports, i0, rxjs, streamChat, operators, uuid, i2, i6, prettybytes, Dayjs, calendar, emojiRegex, transliterate, i6$1) { 'use strict';
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global['stream-chat-angular'] = {}, global.ng.core, global.rxjs, global.streamChat, global.rxjs.operators, global.uuid, global.i2, global.ng.common, global.prettybytes, global.Dayjs, global.calendar, global.emojiRegex, global.transliterate, global.i7));
5
+ }(this, (function (exports, i0, rxjs, streamChat, operators, uuid, i2, i3, prettybytes, Dayjs, calendar, emojiRegex, transliterate, i7) { 'use strict';
6
6
 
7
7
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
8
8
 
@@ -28,13 +28,13 @@
28
28
 
29
29
  var i0__namespace = /*#__PURE__*/_interopNamespace(i0);
30
30
  var i2__namespace = /*#__PURE__*/_interopNamespace(i2);
31
- var i6__namespace = /*#__PURE__*/_interopNamespace(i6);
31
+ var i3__namespace = /*#__PURE__*/_interopNamespace(i3);
32
32
  var prettybytes__default = /*#__PURE__*/_interopDefaultLegacy(prettybytes);
33
33
  var Dayjs__default = /*#__PURE__*/_interopDefaultLegacy(Dayjs);
34
34
  var calendar__default = /*#__PURE__*/_interopDefaultLegacy(calendar);
35
35
  var emojiRegex__default = /*#__PURE__*/_interopDefaultLegacy(emojiRegex);
36
36
  var transliterate__default = /*#__PURE__*/_interopDefaultLegacy(transliterate);
37
- var i6__namespace$1 = /*#__PURE__*/_interopNamespace(i6$1);
37
+ var i7__namespace = /*#__PURE__*/_interopNamespace(i7);
38
38
 
39
39
  /*! *****************************************************************************
40
40
  Copyright (c) Microsoft Corporation.
@@ -354,7 +354,7 @@
354
354
  return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
355
355
  }
356
356
 
357
- var version = '2.21.0';
357
+ var version = '3.0.0-beta.11';
358
358
 
359
359
  /**
360
360
  * The `NotificationService` can be used to add or remove notifications. By default the [`NotificationList`](../components/NotificationListComponent.mdx) component displays the currently active notifications.
@@ -449,7 +449,7 @@
449
449
  this.connectionStateSubject = new rxjs.ReplaySubject(1);
450
450
  this.appSettingsSubject = new rxjs.BehaviorSubject(undefined);
451
451
  this.pendingInvitesSubject = new rxjs.BehaviorSubject([]);
452
- this.notification$ = this.notificationSubject.asObservable();
452
+ this.events$ = this.notificationSubject.asObservable();
453
453
  this.connectionState$ = this.connectionStateSubject.asObservable();
454
454
  this.appSettings$ = this.appSettingsSubject.asObservable();
455
455
  this.pendingInvites$ = this.pendingInvitesSubject.asObservable();
@@ -486,7 +486,8 @@
486
486
  }); })];
487
487
  case 1:
488
488
  _d.sent();
489
- return [4 /*yield*/, this.chatClient.queryChannels({ invite: 'pending' }, {}, { user_id: (_a = this.chatClient.user) === null || _a === void 0 ? void 0 : _a.id })];
489
+ return [4 /*yield*/, this.chatClient.queryChannels({ invite: 'pending' }, // TODO: find out why we need this typecast
490
+ {}, { user_id: (_a = this.chatClient.user) === null || _a === void 0 ? void 0 : _a.id })];
490
491
  case 2:
491
492
  channels = _d.sent();
492
493
  this.pendingInvitesSubject.next(channels);
@@ -628,27 +629,13 @@
628
629
  }]
629
630
  }], ctorParameters: function () { return [{ type: i0__namespace.NgZone }, { type: NotificationService }]; } });
630
631
 
631
- var createMessagePreview = function (user, text, attachments, mentionedUsers, parentId, quotedMessageId) {
632
+ var createMessagePreview = function (user, text, attachments, mentionedUsers, parentId, quotedMessageId, customData) {
632
633
  if (attachments === void 0) { attachments = []; }
633
634
  if (mentionedUsers === void 0) { mentionedUsers = []; }
634
635
  if (parentId === void 0) { parentId = undefined; }
635
636
  if (quotedMessageId === void 0) { quotedMessageId = undefined; }
636
637
  var clientSideId = user.id + "-" + uuid.v4();
637
- return {
638
- __html: text,
639
- created_at: new Date(),
640
- html: text,
641
- id: clientSideId,
642
- reactions: [],
643
- status: 'sending',
644
- text: text,
645
- type: 'regular',
646
- user: user,
647
- attachments: attachments,
648
- mentioned_users: mentionedUsers,
649
- parent_id: parentId,
650
- quoted_message_id: quotedMessageId,
651
- };
638
+ return Object.assign({ __html: text, created_at: new Date(), html: text, id: clientSideId, reactions: [], status: 'sending', text: text, type: 'regular', user: user, attachments: attachments, mentioned_users: mentionedUsers, parent_id: parentId, quoted_message_id: quotedMessageId }, customData);
652
639
  };
653
640
 
654
641
  var getReadBy = function (message, channel) {
@@ -665,7 +652,7 @@
665
652
  };
666
653
 
667
654
  /**
668
- * The `ChannelService` provides data and interaction for the channel list and message list. TEST
655
+ * The `ChannelService` provides data and interaction for the channel list and message list.
669
656
  */
670
657
  var ChannelService = /** @class */ (function () {
671
658
  function ChannelService(chatClientService, ngZone) {
@@ -760,21 +747,6 @@
760
747
  this.activeThreadMessagesSubject.next([]);
761
748
  this.messageToQuoteSubject.next(undefined);
762
749
  };
763
- /**
764
- * Deselects the currently active (if any) channel
765
- */
766
- ChannelService.prototype.deselectActiveChannel = function () {
767
- var activeChannel = this.activeChannelSubject.getValue();
768
- if (!activeChannel) {
769
- return;
770
- }
771
- this.activeChannelMessagesSubject.next([]);
772
- this.activeChannelSubject.next(undefined);
773
- this.activeParentMessageIdSubject.next(undefined);
774
- this.activeThreadMessagesSubject.next([]);
775
- this.latestMessageDateByUserByChannelsSubject.next({});
776
- this.selectMessageToQuote(undefined);
777
- };
778
750
  /**
779
751
  * Sets the given `message` as an active parent message. If `undefined` is provided, it will deleselect the current parent message.
780
752
  * @param message
@@ -870,13 +842,9 @@
870
842
  * @param filters
871
843
  * @param sort
872
844
  * @param options
873
- * @param shouldSetActiveChannel Decides if the first channel in the result should be made as an active channel, or no channel should be marked as active
874
- * @returns the list of channels found by the query
875
845
  */
876
- ChannelService.prototype.init = function (filters, sort, options, shouldSetActiveChannel) {
877
- if (shouldSetActiveChannel === void 0) { shouldSetActiveChannel = true; }
846
+ ChannelService.prototype.init = function (filters, sort, options) {
878
847
  return __awaiter(this, void 0, void 0, function () {
879
- var result;
880
848
  var _this = this;
881
849
  return __generator(this, function (_h) {
882
850
  switch (_h.label) {
@@ -891,11 +859,11 @@
891
859
  message_limit: this.messagePageSize,
892
860
  };
893
861
  this.sort = sort || { last_message_at: -1, updated_at: -1 };
894
- return [4 /*yield*/, this.queryChannels(shouldSetActiveChannel)];
862
+ return [4 /*yield*/, this.queryChannels()];
895
863
  case 1:
896
- result = _h.sent();
897
- this.chatClientService.notification$.subscribe(function (notification) { return void _this.handleNotification(notification); });
898
- return [2 /*return*/, result];
864
+ _h.sent();
865
+ this.chatClientService.events$.subscribe(function (notification) { return void _this.handleNotification(notification); });
866
+ return [2 /*return*/];
899
867
  }
900
868
  });
901
869
  });
@@ -904,8 +872,13 @@
904
872
  * Resets the `activeChannel$`, `channels$` and `activeChannelMessages$` Observables. Useful when disconnecting a chat user, use in combination with [`disconnectUser`](./ChatClientService.mdx/#disconnectuser).
905
873
  */
906
874
  ChannelService.prototype.reset = function () {
907
- this.deselectActiveChannel();
875
+ this.activeChannelMessagesSubject.next([]);
876
+ this.activeChannelSubject.next(undefined);
877
+ this.activeParentMessageIdSubject.next(undefined);
878
+ this.activeThreadMessagesSubject.next([]);
908
879
  this.channelsSubject.next(undefined);
880
+ this.latestMessageDateByUserByChannelsSubject.next({});
881
+ this.selectMessageToQuote(undefined);
909
882
  };
910
883
  /**
911
884
  * Loads the next page of channels. The page size can be set in the [query option](https://getstream.io/chat/docs/javascript/query_channels/?language=javascript#query-options) object.
@@ -916,7 +889,7 @@
916
889
  switch (_h.label) {
917
890
  case 0:
918
891
  this.options.offset = this.channels.length;
919
- return [4 /*yield*/, this.queryChannels(false)];
892
+ return [4 /*yield*/, this.queryChannels()];
920
893
  case 1:
921
894
  _h.sent();
922
895
  return [2 /*return*/];
@@ -928,15 +901,14 @@
928
901
  * Adds a reaction to a message.
929
902
  * @param messageId The id of the message to add the reaction to
930
903
  * @param reactionType The type of the reaction
904
+ * @param customData
931
905
  */
932
- ChannelService.prototype.addReaction = function (messageId, reactionType) {
906
+ ChannelService.prototype.addReaction = function (messageId, reactionType, customData) {
933
907
  var _a;
934
908
  return __awaiter(this, void 0, void 0, function () {
935
909
  return __generator(this, function (_h) {
936
910
  switch (_h.label) {
937
- case 0: return [4 /*yield*/, ((_a = this.activeChannelSubject.getValue()) === null || _a === void 0 ? void 0 : _a.sendReaction(messageId, {
938
- type: reactionType,
939
- }))];
911
+ case 0: return [4 /*yield*/, ((_a = this.activeChannelSubject.getValue()) === null || _a === void 0 ? void 0 : _a.sendReaction(messageId, Object.assign({ type: reactionType }, customData)))];
940
912
  case 1:
941
913
  _h.sent();
942
914
  return [2 /*return*/];
@@ -970,22 +942,24 @@
970
942
  * @param mentionedUsers Mentioned users
971
943
  * @param parentId Id of the parent message (if sending a thread reply)
972
944
  * @param quotedMessageId Id of the message to quote (if sending a quote reply)
945
+ * @param customData
973
946
  */
974
- ChannelService.prototype.sendMessage = function (text, attachments, mentionedUsers, parentId, quotedMessageId) {
947
+ ChannelService.prototype.sendMessage = function (text, attachments, mentionedUsers, parentId, quotedMessageId, customData) {
975
948
  if (attachments === void 0) { attachments = []; }
976
949
  if (mentionedUsers === void 0) { mentionedUsers = []; }
977
950
  if (parentId === void 0) { parentId = undefined; }
978
951
  if (quotedMessageId === void 0) { quotedMessageId = undefined; }
952
+ if (customData === void 0) { customData = undefined; }
979
953
  return __awaiter(this, void 0, void 0, function () {
980
954
  var preview, channel;
981
955
  return __generator(this, function (_h) {
982
956
  switch (_h.label) {
983
957
  case 0:
984
- preview = createMessagePreview(this.chatClientService.chatClient.user, text, attachments, mentionedUsers, parentId, quotedMessageId);
958
+ preview = createMessagePreview(this.chatClientService.chatClient.user, text, attachments, mentionedUsers, parentId, quotedMessageId, customData);
985
959
  channel = this.activeChannelSubject.getValue();
986
960
  preview.readBy = [];
987
961
  channel.state.addMessageSorted(preview, true);
988
- return [4 /*yield*/, this.sendMessageRequest(preview)];
962
+ return [4 /*yield*/, this.sendMessageRequest(preview, customData)];
989
963
  case 1:
990
964
  _h.sent();
991
965
  return [2 /*return*/];
@@ -1184,7 +1158,7 @@
1184
1158
  ChannelService.prototype.selectMessageToQuote = function (message) {
1185
1159
  this.messageToQuoteSubject.next(message);
1186
1160
  };
1187
- ChannelService.prototype.sendMessageRequest = function (preview) {
1161
+ ChannelService.prototype.sendMessageRequest = function (preview, customData) {
1188
1162
  var _a;
1189
1163
  return __awaiter(this, void 0, void 0, function () {
1190
1164
  var channel, isThreadReply, response, error_1, stringError, parsedError;
@@ -1199,14 +1173,7 @@
1199
1173
  _h.label = 1;
1200
1174
  case 1:
1201
1175
  _h.trys.push([1, 3, , 4]);
1202
- return [4 /*yield*/, channel.sendMessage({
1203
- text: preview.text,
1204
- attachments: preview.attachments,
1205
- mentioned_users: (_a = preview.mentioned_users) === null || _a === void 0 ? void 0 : _a.map(function (u) { return u.id; }),
1206
- id: preview.id,
1207
- parent_id: preview.parent_id,
1208
- quoted_message_id: preview.quoted_message_id,
1209
- })];
1176
+ return [4 /*yield*/, channel.sendMessage(Object.assign({ id: preview.id, text: preview.text, attachments: preview.attachments, mentioned_users: (_a = preview.mentioned_users) === null || _a === void 0 ? void 0 : _a.map(function (u) { return u.id; }), parent_id: preview.parent_id, quoted_message_id: preview.quoted_message_id }, customData))];
1210
1177
  case 2:
1211
1178
  response = _h.sent();
1212
1179
  if (response === null || response === void 0 ? void 0 : response.message) {
@@ -1232,16 +1199,16 @@
1232
1199
  });
1233
1200
  });
1234
1201
  };
1235
- ChannelService.prototype.handleNotification = function (notification) {
1202
+ ChannelService.prototype.handleNotification = function (clientEvent) {
1236
1203
  var _this = this;
1237
- switch (notification.eventType) {
1204
+ switch (clientEvent.eventType) {
1238
1205
  case 'notification.message_new': {
1239
1206
  this.ngZone.run(function () {
1240
1207
  if (_this.customNewMessageNotificationHandler) {
1241
- _this.customNewMessageNotificationHandler(notification, _this.channelListSetter);
1208
+ _this.customNewMessageNotificationHandler(clientEvent, _this.channelListSetter);
1242
1209
  }
1243
1210
  else {
1244
- _this.handleNewMessageNotification(notification);
1211
+ _this.handleNewMessageNotification(clientEvent);
1245
1212
  }
1246
1213
  });
1247
1214
  break;
@@ -1249,10 +1216,10 @@
1249
1216
  case 'notification.added_to_channel': {
1250
1217
  this.ngZone.run(function () {
1251
1218
  if (_this.customAddedToChannelNotificationHandler) {
1252
- _this.customAddedToChannelNotificationHandler(notification, _this.channelListSetter);
1219
+ _this.customAddedToChannelNotificationHandler(clientEvent, _this.channelListSetter);
1253
1220
  }
1254
1221
  else {
1255
- _this.handleAddedToChannelNotification(notification);
1222
+ _this.handleAddedToChannelNotification(clientEvent);
1256
1223
  }
1257
1224
  });
1258
1225
  break;
@@ -1260,27 +1227,27 @@
1260
1227
  case 'notification.removed_from_channel': {
1261
1228
  this.ngZone.run(function () {
1262
1229
  if (_this.customRemovedFromChannelNotificationHandler) {
1263
- _this.customRemovedFromChannelNotificationHandler(notification, _this.channelListSetter);
1230
+ _this.customRemovedFromChannelNotificationHandler(clientEvent, _this.channelListSetter);
1264
1231
  }
1265
1232
  else {
1266
- _this.handleRemovedFromChannelNotification(notification);
1233
+ _this.handleRemovedFromChannelNotification(clientEvent);
1267
1234
  }
1268
1235
  });
1269
1236
  }
1270
1237
  }
1271
1238
  };
1272
- ChannelService.prototype.handleRemovedFromChannelNotification = function (notification) {
1273
- var channelIdToBeRemoved = notification.event.channel.cid;
1239
+ ChannelService.prototype.handleRemovedFromChannelNotification = function (clientEvent) {
1240
+ var channelIdToBeRemoved = clientEvent.event.channel.cid;
1274
1241
  this.removeChannelsFromChannelList([channelIdToBeRemoved]);
1275
1242
  };
1276
- ChannelService.prototype.handleNewMessageNotification = function (notification) {
1277
- if (notification.event.channel) {
1278
- this.addChannelsFromNotification([notification.event.channel]);
1243
+ ChannelService.prototype.handleNewMessageNotification = function (clientEvent) {
1244
+ if (clientEvent.event.channel) {
1245
+ this.addChannelsFromNotification([clientEvent.event.channel]);
1279
1246
  }
1280
1247
  };
1281
- ChannelService.prototype.handleAddedToChannelNotification = function (notification) {
1282
- if (notification.event.channel) {
1283
- this.addChannelsFromNotification([notification.event.channel]);
1248
+ ChannelService.prototype.handleAddedToChannelNotification = function (clientEvent) {
1249
+ if (clientEvent.event.channel) {
1250
+ this.addChannelsFromNotification([clientEvent.event.channel]);
1284
1251
  }
1285
1252
  };
1286
1253
  ChannelService.prototype.addChannelsFromNotification = function (channelResponses) {
@@ -1446,7 +1413,7 @@
1446
1413
  this.activeChannelSubscriptions.forEach(function (s) { return s.unsubscribe(); });
1447
1414
  this.activeChannelSubscriptions = [];
1448
1415
  };
1449
- ChannelService.prototype.queryChannels = function (shouldSetActiveChannel) {
1416
+ ChannelService.prototype.queryChannels = function () {
1450
1417
  return __awaiter(this, void 0, void 0, function () {
1451
1418
  var channels, prevChannels, error_2;
1452
1419
  var _this = this;
@@ -1460,17 +1427,15 @@
1460
1427
  channels.forEach(function (c) { return _this.watchForChannelEvents(c); });
1461
1428
  prevChannels = this.channelsSubject.getValue() || [];
1462
1429
  this.channelsSubject.next(__spreadArray(__spreadArray([], __read(prevChannels)), __read(channels)));
1463
- if (channels.length > 0 &&
1464
- !this.activeChannelSubject.getValue() &&
1465
- shouldSetActiveChannel) {
1430
+ if (channels.length > 0 && !this.activeChannelSubject.getValue()) {
1466
1431
  this.setAsActiveChannel(channels[0]);
1467
1432
  }
1468
1433
  this.hasMoreChannelsSubject.next(channels.length >= this.options.limit);
1469
- return [2 /*return*/, channels];
1434
+ return [3 /*break*/, 3];
1470
1435
  case 2:
1471
1436
  error_2 = _h.sent();
1472
1437
  this.channelsSubject.error(error_2);
1473
- throw error_2;
1438
+ return [3 /*break*/, 3];
1474
1439
  case 3: return [2 /*return*/];
1475
1440
  }
1476
1441
  });
@@ -1923,7 +1888,7 @@
1923
1888
  */
1924
1889
  AttachmentService.prototype.deleteAttachment = function (upload) {
1925
1890
  return __awaiter(this, void 0, void 0, function () {
1926
- var attachmentUploads, error_1;
1891
+ var attachmentUploads, result, index, error_1, index;
1927
1892
  return __generator(this, function (_d) {
1928
1893
  switch (_d.label) {
1929
1894
  case 0:
@@ -1935,18 +1900,23 @@
1935
1900
  return [4 /*yield*/, this.channelService.deleteAttachment(upload)];
1936
1901
  case 2:
1937
1902
  _d.sent();
1938
- attachmentUploads.splice(attachmentUploads.indexOf(upload), 1);
1903
+ result = __spreadArray([], __read(attachmentUploads));
1904
+ index = attachmentUploads.indexOf(upload);
1905
+ result.splice(index, 1);
1939
1906
  return [3 /*break*/, 4];
1940
1907
  case 3:
1941
1908
  error_1 = _d.sent();
1909
+ result = attachmentUploads;
1942
1910
  this.notificationService.addTemporaryNotification('streamChat.Error deleting attachment');
1943
1911
  return [3 /*break*/, 4];
1944
1912
  case 4: return [3 /*break*/, 6];
1945
1913
  case 5:
1946
- attachmentUploads.splice(attachmentUploads.indexOf(upload), 1);
1914
+ result = __spreadArray([], __read(attachmentUploads));
1915
+ index = attachmentUploads.indexOf(upload);
1916
+ result.splice(index, 1);
1947
1917
  _d.label = 6;
1948
1918
  case 6:
1949
- this.attachmentUploadsSubject.next(__spreadArray([], __read(attachmentUploads)));
1919
+ this.attachmentUploadsSubject.next(__spreadArray([], __read(result)));
1950
1920
  return [2 /*return*/];
1951
1921
  }
1952
1922
  });
@@ -2029,16 +1999,16 @@
2029
1999
  };
2030
2000
  AttachmentService.prototype.uploadAttachments = function (uploads) {
2031
2001
  return __awaiter(this, void 0, void 0, function () {
2032
- var attachmentUploads, result;
2002
+ var result, attachmentUploads;
2033
2003
  var _this = this;
2034
2004
  return __generator(this, function (_d) {
2035
2005
  switch (_d.label) {
2036
2006
  case 0:
2037
- attachmentUploads = this.attachmentUploadsSubject.getValue();
2038
2007
  this.attachmentUploadInProgressCounterSubject.next(this.attachmentUploadInProgressCounterSubject.getValue() + 1);
2039
2008
  return [4 /*yield*/, this.channelService.uploadAttachments(uploads)];
2040
2009
  case 1:
2041
2010
  result = _d.sent();
2011
+ attachmentUploads = this.attachmentUploadsSubject.getValue();
2042
2012
  result.forEach(function (r) {
2043
2013
  var upload = attachmentUploads.find(function (upload) { return upload.file === r.file; });
2044
2014
  if (!upload) {
@@ -2213,7 +2183,7 @@
2213
2183
  return AvatarComponent;
2214
2184
  }());
2215
2185
  AvatarComponent.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: AvatarComponent, deps: [], target: i0__namespace.ɵɵFactoryTarget.Component });
2216
- AvatarComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: AvatarComponent, selector: "stream-avatar", inputs: { name: "name", imageUrl: "imageUrl", size: "size" }, ngImport: i0__namespace, template: "<div\n class=\"str-chat__avatar str-chat__avatar--circle\"\n title=\"{{ name }}\"\n [style]=\"{\n flexBasis: size + 'px',\n fontSize: size / 2 + 'px',\n height: size + 'px',\n lineHeight: size + 'px',\n width: size + 'px'\n }\"\n>\n <img\n *ngIf=\"imageUrl && !isError; else fallback\"\n class=\"str-chat__avatar-image str-chat__avatar-image{{\n isLoaded ? ' str-chat__avatar-image--loaded' : ''\n }}\"\n src=\"{{ imageUrl }}\"\n alt=\"{{ initials }}\"\n data-testid=\"avatar-img\"\n (load)=\"isLoaded = true\"\n (error)=\"isError = true\"\n [style]=\"{\n flexBasis: size + 'px',\n height: size + 'px',\n objectFit: 'cover',\n width: size + 'px'\n }\"\n />\n <ng-template #fallback>\n <div data-testid=\"fallback-img\" class=\"str-chat__avatar-fallback\">\n {{ initials }}\n </div>\n </ng-template>\n</div>\n", styles: [""], directives: [{ type: i6__namespace.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
2186
+ AvatarComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: AvatarComponent, selector: "stream-avatar", inputs: { name: "name", imageUrl: "imageUrl", size: "size" }, ngImport: i0__namespace, template: "<div\n class=\"str-chat__avatar str-chat__avatar--circle\"\n title=\"{{ name }}\"\n [style]=\"{\n flexBasis: size + 'px',\n fontSize: size / 2 + 'px',\n height: size + 'px',\n lineHeight: size + 'px',\n width: size + 'px'\n }\"\n>\n <img\n *ngIf=\"imageUrl && !isError; else fallback\"\n class=\"str-chat__avatar-image str-chat__avatar-image{{\n isLoaded ? ' str-chat__avatar-image--loaded' : ''\n }}\"\n src=\"{{ imageUrl }}\"\n alt=\"{{ initials }}\"\n data-testid=\"avatar-img\"\n (load)=\"isLoaded = true\"\n (error)=\"isError = true\"\n [style]=\"{\n flexBasis: size + 'px',\n height: size + 'px',\n objectFit: 'cover',\n width: size + 'px'\n }\"\n />\n <ng-template #fallback>\n <div data-testid=\"fallback-img\" class=\"str-chat__avatar-fallback\">\n {{ initials }}\n </div>\n </ng-template>\n</div>\n", styles: [""], directives: [{ type: i3__namespace.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
2217
2187
  i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: AvatarComponent, decorators: [{
2218
2188
  type: i0.Component,
2219
2189
  args: [{
@@ -2229,6 +2199,180 @@
2229
2199
  type: i0.Input
2230
2200
  }] } });
2231
2201
 
2202
+ /**
2203
+ * A central location for registering your custom templates to override parts of the chat application.
2204
+ *
2205
+ * For code examples to the different customizations see our [customizations example application](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example), specifically the [AppComponent](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example/src/app) (see [README](https://github.com/GetStream/stream-chat-angular/blob/master/README.md#customization-examples) for instructions on how to start the application).
2206
+ */
2207
+ var CustomTemplatesService = /** @class */ (function () {
2208
+ function CustomTemplatesService() {
2209
+ /**
2210
+ * The autocomplete list item template for mentioning users (used in the [`AutocompleteTextareaComponent`](../components/AutocompleteTextareaComponent.mdx))
2211
+ */
2212
+ this.mentionAutocompleteItemTemplate$ = new rxjs.BehaviorSubject(undefined);
2213
+ /**
2214
+ * The autocomplete list item template for commands (used in the [`AutocompleteTextareaComponent`](../components/AutocompleteTextareaComponent.mdx))
2215
+ *
2216
+ * For code examples to the different customizations see our [customizations example application](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example), specifically the [AppComponent](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example/src/app) (see [README](https://github.com/GetStream/stream-chat-angular/blob/master/README.md#customization-examples) for instructions on how to start the application).
2217
+ */
2218
+ this.commandAutocompleteItemTemplate$ = new rxjs.BehaviorSubject(undefined);
2219
+ /**
2220
+ * Template used to display an item in the [channel list](../components/ChannelListComponent.mdx) (instead of the default [channal list item](../components/ChannelPreviewComponent.mdx))
2221
+ *
2222
+ * For code examples to the different customizations see our [customizations example application](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example), specifically the [AppComponent](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example/src/app) (see [README](https://github.com/GetStream/stream-chat-angular/blob/master/README.md#customization-examples) for instructions on how to start the application).
2223
+ */
2224
+ this.channelPreviewTemplate$ = new rxjs.BehaviorSubject(undefined);
2225
+ /**
2226
+ * The message input template used when editing a message (instead of the [default message input](../components/MessageInputComponent.mdx))
2227
+ *
2228
+ * For code examples to the different customizations see our [customizations example application](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example), specifically the [AppComponent](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example/src/app) (see [README](https://github.com/GetStream/stream-chat-angular/blob/master/README.md#customization-examples) for instructions on how to start the application).
2229
+ */
2230
+ this.messageInputTemplate$ = new rxjs.BehaviorSubject(undefined);
2231
+ /**
2232
+ * The template used for displaying a [mention inside a message](../code-examples/mention-actions.mdx)
2233
+ *
2234
+ * For code examples to the different customizations see our [customizations example application](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example), specifically the [AppComponent](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example/src/app) (see [README](https://github.com/GetStream/stream-chat-angular/blob/master/README.md#customization-examples) for instructions on how to start the application).
2235
+ */
2236
+ this.mentionTemplate$ = new rxjs.BehaviorSubject(undefined);
2237
+ /**
2238
+ * The template for [emoji picker](../code-examples/emoji-picker.mdx)
2239
+ *
2240
+ * For code examples to the different customizations see our [customizations example application](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example), specifically the [AppComponent](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example/src/app) (see [README](https://github.com/GetStream/stream-chat-angular/blob/master/README.md#customization-examples) for instructions on how to start the application).
2241
+ */
2242
+ this.emojiPickerTemplate$ = new rxjs.BehaviorSubject(undefined);
2243
+ /**
2244
+ * The typing indicator template used in the [message list](../components/MessageListComponent.mdx)
2245
+ *
2246
+ * For code examples to the different customizations see our [customizations example application](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example), specifically the [AppComponent](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example/src/app) (see [README](https://github.com/GetStream/stream-chat-angular/blob/master/README.md#customization-examples) for instructions on how to start the application).
2247
+ */
2248
+ this.typingIndicatorTemplate$ = new rxjs.BehaviorSubject(undefined);
2249
+ /**
2250
+ * The template used to display a message in the [message list](../components/MessageListComponent.mdx) (instead of the [default message component](../components/MessageComponent.mdx))
2251
+ *
2252
+ * For code examples to the different customizations see our [customizations example application](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example), specifically the [AppComponent](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example/src/app) (see [README](https://github.com/GetStream/stream-chat-angular/blob/master/README.md#customization-examples) for instructions on how to start the application).
2253
+ */
2254
+ this.messageTemplate$ = new rxjs.BehaviorSubject(undefined);
2255
+ /**
2256
+ * The template for channel actions displayed in the [channel header](../components/ChannelHeaderComponent.mdx) (by default no channel action is displayed)
2257
+ *
2258
+ * For code examples to the different customizations see our [customizations example application](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example), specifically the [AppComponent](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example/src/app) (see [README](https://github.com/GetStream/stream-chat-angular/blob/master/README.md#customization-examples) for instructions on how to start the application).
2259
+ */
2260
+ this.channelActionsTemplate$ = new rxjs.BehaviorSubject(undefined);
2261
+ /**
2262
+ * The template used to display attachments of a [message](../components/MessageComponent.mdx) (instead of the [default attachment list](../components/AttachmentListComponent.mdx))
2263
+ *
2264
+ * For code examples to the different customizations see our [customizations example application](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example), specifically the [AppComponent](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example/src/app) (see [README](https://github.com/GetStream/stream-chat-angular/blob/master/README.md#customization-examples) for instructions on how to start the application).
2265
+ */
2266
+ this.attachmentListTemplate$ = new rxjs.BehaviorSubject(undefined);
2267
+ /**
2268
+ * The template used to display attachments in the [message input](../components/MessageInputComponent.mdx) component (instead of the [default attachment preview](../components/AttachmentPreviewListComponent.mdx))
2269
+ *
2270
+ * For code examples to the different customizations see our [customizations example application](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example), specifically the [AppComponent](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example/src/app) (see [README](https://github.com/GetStream/stream-chat-angular/blob/master/README.md#customization-examples) for instructions on how to start the application).
2271
+ */
2272
+ this.attachmentPreviewListTemplate$ = new rxjs.BehaviorSubject(undefined);
2273
+ /**
2274
+ * The template used to display avatars for channels and users (instead of the [default avatar](../components/AvatarComponent.mdx))
2275
+ *
2276
+ * For code examples to the different customizations see our [customizations example application](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example), specifically the [AppComponent](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example/src/app) (see [README](https://github.com/GetStream/stream-chat-angular/blob/master/README.md#customization-examples) for instructions on how to start the application).
2277
+ */
2278
+ this.avatarTemplate$ = new rxjs.BehaviorSubject(undefined);
2279
+ /**
2280
+ * Template for displaying icons (instead of the [default icon component](../components/IconComponent.mdx))
2281
+ *
2282
+ * For code examples to the different customizations see our [customizations example application](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example), specifically the [AppComponent](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example/src/app) (see [README](https://github.com/GetStream/stream-chat-angular/blob/master/README.md#customization-examples) for instructions on how to start the application).
2283
+ */
2284
+ this.iconTemplate$ = new rxjs.BehaviorSubject(undefined);
2285
+ /**
2286
+ * Template for displaying the loading indicator (instead of the [default loading indicator](../components/LoadingIndicatorComponent.mdx))
2287
+ *
2288
+ * For code examples to the different customizations see our [customizations example application](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example), specifically the [AppComponent](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example/src/app) (see [README](https://github.com/GetStream/stream-chat-angular/blob/master/README.md#customization-examples) for instructions on how to start the application).
2289
+ */
2290
+ this.loadingIndicatorTemplate$ = new rxjs.BehaviorSubject(undefined);
2291
+ /**
2292
+ * Template for displaying the message actions box (instead of the [default message actions box](../components/MessageActionsBoxComponent.mdx))
2293
+ *
2294
+ * For code examples to the different customizations see our [customizations example application](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example), specifically the [AppComponent](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example/src/app) (see [README](https://github.com/GetStream/stream-chat-angular/blob/master/README.md#customization-examples) for instructions on how to start the application).
2295
+ */
2296
+ this.messageActionsBoxTemplate$ = new rxjs.BehaviorSubject(undefined);
2297
+ /**
2298
+ * The template used for displaying an item in the [message actions box](../components/MessageActionsBoxComponent.mdx)
2299
+ *
2300
+ * For code examples to the different customizations see our [customizations example application](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example), specifically the [AppComponent](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example/src/app) (see [README](https://github.com/GetStream/stream-chat-angular/blob/master/README.md#customization-examples) for instructions on how to start the application).
2301
+ */
2302
+ this.messageActionsBoxItemTemplate$ = new rxjs.BehaviorSubject(undefined);
2303
+ /**
2304
+ * The template used to display the reactions of a [message](../components/MessageComponent.mdx), and the selector to add a reaction to a message (instead of the [default message reactions component](../components/MessageReactionsComponent.mdx))
2305
+ *
2306
+ * For code examples to the different customizations see our [customizations example application](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example), specifically the [AppComponent](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example/src/app) (see [README](https://github.com/GetStream/stream-chat-angular/blob/master/README.md#customization-examples) for instructions on how to start the application).
2307
+ */
2308
+ this.messageReactionsTemplate$ = new rxjs.BehaviorSubject(undefined);
2309
+ /**
2310
+ * The template used to display a modal window (instead of the [default modal](../components/ModalComponent.mdx))
2311
+ *
2312
+ * For code examples to the different customizations see our [customizations example application](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example), specifically the [AppComponent](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example/src/app) (see [README](https://github.com/GetStream/stream-chat-angular/blob/master/README.md#customization-examples) for instructions on how to start the application).
2313
+ */
2314
+ this.modalTemplate$ = new rxjs.BehaviorSubject(undefined);
2315
+ /**
2316
+ * The template used to override the [default notification component](../components/NotificationComponent.mdx)
2317
+ *
2318
+ * For code examples to the different customizations see our [customizations example application](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example), specifically the [AppComponent](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example/src/app) (see [README](https://github.com/GetStream/stream-chat-angular/blob/master/README.md#customization-examples) for instructions on how to start the application).
2319
+ */
2320
+ this.notificationTemplate$ = new rxjs.BehaviorSubject(undefined);
2321
+ /**
2322
+ * The template used for header of a [thread](../components/ThreadComponent.mdx)
2323
+ *
2324
+ * For code examples to the different customizations see our [customizations example application](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example), specifically the [AppComponent](https://github.com/GetStream/stream-chat-angular/tree/master/projects/customizations-example/src/app) (see [README](https://github.com/GetStream/stream-chat-angular/blob/master/README.md#customization-examples) for instructions on how to start the application).
2325
+ */
2326
+ this.threadHeaderTemplate$ = new rxjs.BehaviorSubject(undefined);
2327
+ }
2328
+ return CustomTemplatesService;
2329
+ }());
2330
+ CustomTemplatesService.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: CustomTemplatesService, deps: [], target: i0__namespace.ɵɵFactoryTarget.Injectable });
2331
+ CustomTemplatesService.ɵprov = i0__namespace.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: CustomTemplatesService, providedIn: 'root' });
2332
+ i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: CustomTemplatesService, decorators: [{
2333
+ type: i0.Injectable,
2334
+ args: [{
2335
+ providedIn: 'root',
2336
+ }]
2337
+ }], ctorParameters: function () { return []; } });
2338
+
2339
+ /**
2340
+ * The `AvatarPlaceholder` component displays the [default avatar](./AvatarComponent.mdx) unless a [custom template](../services/CustomTemplatesService.mdx) is provided. This componet is used by the SDK internally, you likely won't need to use it.
2341
+ */
2342
+ var AvatarPlaceholderComponent = /** @class */ (function () {
2343
+ function AvatarPlaceholderComponent(customTemplatesService) {
2344
+ this.customTemplatesService = customTemplatesService;
2345
+ /**
2346
+ * The size in pixels of the avatar image.
2347
+ */
2348
+ this.size = 32;
2349
+ }
2350
+ AvatarPlaceholderComponent.prototype.getAvatarContext = function () {
2351
+ return {
2352
+ name: this.name,
2353
+ imageUrl: this.imageUrl,
2354
+ size: this.size,
2355
+ };
2356
+ };
2357
+ return AvatarPlaceholderComponent;
2358
+ }());
2359
+ AvatarPlaceholderComponent.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: AvatarPlaceholderComponent, deps: [{ token: CustomTemplatesService }], target: i0__namespace.ɵɵFactoryTarget.Component });
2360
+ AvatarPlaceholderComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: AvatarPlaceholderComponent, selector: "stream-avatar-placeholder", inputs: { name: "name", imageUrl: "imageUrl", size: "size" }, ngImport: i0__namespace, template: "<ng-template\n #defaultAvatar\n let-name=\"name\"\n let-imageUrl=\"imageUrl\"\n let-size=\"size\"\n>\n <stream-avatar\n [name]=\"name\"\n [imageUrl]=\"imageUrl\"\n [size]=\"size\"\n ></stream-avatar>\n</ng-template>\n<ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.avatarTemplate$ | async) || defaultAvatar;\n context: getAvatarContext()\n \"\n></ng-container>\n", components: [{ type: AvatarComponent, selector: "stream-avatar", inputs: ["name", "imageUrl", "size"] }], directives: [{ type: i3__namespace.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], pipes: { "async": i3__namespace.AsyncPipe } });
2361
+ i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: AvatarPlaceholderComponent, decorators: [{
2362
+ type: i0.Component,
2363
+ args: [{
2364
+ selector: 'stream-avatar-placeholder',
2365
+ templateUrl: './avatar-placeholder.component.html',
2366
+ styles: [],
2367
+ }]
2368
+ }], ctorParameters: function () { return [{ type: CustomTemplatesService }]; }, propDecorators: { name: [{
2369
+ type: i0.Input
2370
+ }], imageUrl: [{
2371
+ type: i0.Input
2372
+ }], size: [{
2373
+ type: i0.Input
2374
+ }] } });
2375
+
2232
2376
  /**
2233
2377
  * The `Icon` component can be used to display different icons (i. e. message delivered icon).
2234
2378
  */
@@ -2238,7 +2382,7 @@
2238
2382
  return IconComponent;
2239
2383
  }());
2240
2384
  IconComponent.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: IconComponent, deps: [], target: i0__namespace.ɵɵFactoryTarget.Component });
2241
- IconComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: IconComponent, selector: "stream-icon", inputs: { icon: "icon", size: "size" }, ngImport: i0__namespace, template: "<svg\n data-testid=\"action-icon\"\n *ngIf=\"icon === 'action-icon'\"\n height=\"4\"\n viewBox=\"0 0 11 4\"\n width=\"11\"\n xmlns=\"http://www.w3.org/2000/svg\"\n>\n <path\n d=\"M1.5 3a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm4 0a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm4 0a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3z\"\n fillRule=\"nonzero\"\n />\n</svg>\n<svg\n *ngIf=\"icon === 'delivered-icon'\"\n height=\"16\"\n width=\"16\"\n xmlns=\"http://www.w3.org/2000/svg\"\n data-testid=\"delivered-icon\"\n>\n <path\n d=\"M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0zm3.72 6.633a.955.955 0 1 0-1.352-1.352L6.986 8.663 5.633 7.31A.956.956 0 1 0 4.28 8.663l2.029 2.028a.956.956 0 0 0 1.353 0l4.058-4.058z\"\n fill=\"#006CFF\"\n fillRule=\"evenodd\"\n />\n</svg>\n<svg\n *ngIf=\"icon === 'reaction-icon'\"\n height=\"12\"\n viewBox=\"0 0 12 12\"\n width=\"12\"\n xmlns=\"http://www.w3.org/2000/svg\"\n data-testid=\"reaction-icon\"\n>\n <g clipRule=\"evenodd\" fillRule=\"evenodd\">\n <path\n d=\"M6 1.2C3.3 1.2 1.2 3.3 1.2 6c0 2.7 2.1 4.8 4.8 4.8 2.7 0 4.8-2.1 4.8-4.8 0-2.7-2.1-4.8-4.8-4.8zM0 6c0-3.3 2.7-6 6-6s6 2.7 6 6-2.7 6-6 6-6-2.7-6-6z\"\n ></path>\n <path\n d=\"M5.4 4.5c0 .5-.4.9-.9.9s-.9-.4-.9-.9.4-.9.9-.9.9.4.9.9zM8.4 4.5c0 .5-.4.9-.9.9s-.9-.4-.9-.9.4-.9.9-.9.9.4.9.9zM3.3 6.7c.3-.2.6-.1.8.1.3.4.8.9 1.5 1 .6.2 1.4.1 2.4-1 .2-.2.6-.3.8 0 .2.2.3.6 0 .8-1.1 1.3-2.4 1.7-3.5 1.5-1-.2-1.8-.9-2.2-1.5-.2-.3-.1-.7.2-.9z\"\n ></path>\n </g>\n</svg>\n<svg\n data-testid=\"connection-error\"\n *ngIf=\"icon === 'connection-error'\"\n width=\"78px\"\n height=\"78px\"\n viewBox=\"0 0 78 78\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n>\n <!-- Generator: Sketch 52.6 (67491) - http://www.bohemiancoding.com/sketch -->\n <title>Combined Shape</title>\n <desc>Created with Sketch.</desc>\n <g\n id=\"Interactions\"\n stroke=\"none\"\n stroke-width=\"1\"\n fill=\"none\"\n fill-rule=\"evenodd\"\n >\n <g\n id=\"Connection-Error-_-Connectivity\"\n transform=\"translate(-270.000000, -30.000000)\"\n fill=\"#CF1F25\"\n >\n <g\n id=\"109-network-connection\"\n transform=\"translate(270.000000, 30.000000)\"\n >\n <path\n d=\"M66.4609744,11.414231 C81.6225232,26.5757798 81.6225232,51.157545 66.4609744,66.3188467 C51.2994256,81.4803954 26.7176604,81.4803954 11.5563587,66.3188467 C-3.60519004,51.1572979 -3.60519004,26.5755327 11.5563587,11.414231 C26.7179075,-3.74731776 51.2996727,-3.74731776 66.4609744,11.414231 Z M54.7853215,45.8823776 L54.7853215,40.5882574 C54.7853215,39.613638 53.9952341,38.8235506 53.0206147,38.8235506 L44.9576695,38.8235506 L41.428256,42.3529641 L51.255555,42.3529641 L51.255555,45.8823776 L54.7853215,45.8823776 Z M40.6659027,43.1153174 L37.8988425,45.8823776 L40.6659027,45.8823776 L40.6659027,43.1153174 Z M51.1764962,56.4702653 L58.2353232,56.4702653 C59.2099355,56.4702653 60.00003,55.6801708 60.00003,54.7055585 L60.00003,51.176145 C60.00003,50.2015327 59.2099355,49.4114382 58.2353232,49.4114382 L51.1764962,49.4114382 C50.2018839,49.4114382 49.4117894,50.2015327 49.4117894,51.176145 L49.4117894,54.7055585 C49.4117894,55.6801708 50.2018839,56.4702653 51.1764962,56.4702653 Z M35.2941353,56.4702653 L42.3529624,56.4702653 C43.3275746,56.4702653 44.1176691,55.6801708 44.1176691,54.7055585 L44.1176691,51.176145 C44.1176691,50.2015327 43.3275746,49.4114382 42.3529624,49.4114382 L35.2941353,49.4114382 C34.319523,49.4114382 33.5294285,50.2015327 33.5294285,51.176145 L33.5294285,54.7055585 C33.5294285,55.6801708 34.319523,56.4702653 35.2941353,56.4702653 Z M56.6964989,19.0874231 C56.007381,18.3985134 54.8903216,18.3985134 54.2012036,19.087423 L45.882376,27.4062507 L45.882376,19.4117761 C45.882376,18.4371568 45.0922885,17.6470693 44.1176692,17.6470693 L33.5294286,17.6470693 C32.5548092,17.6470694 31.7647218,18.4371568 31.7647218,19.4117761 L31.7647218,30.0000167 C31.7647219,30.9746363 32.5548092,31.7647237 33.5294285,31.7647237 L41.5239031,31.7647237 L34.4650761,38.8235508 L24.7058947,38.8235508 C23.7312753,38.8235508 22.9411879,39.6136382 22.9411879,40.5882575 L22.9411879,45.8823778 L26.4706014,45.8823778 L26.4706014,42.3529643 L30.9356624,42.3529643 L23.8768354,49.4117914 L19.4117743,49.4117914 C18.4371549,49.4117914 17.6470675,50.2018788 17.6470675,51.1764981 L17.6470675,54.7059117 C17.6504049,54.9674302 17.7129076,55.2248042 17.8298886,55.4587302 L16.4456526,56.8429662 C15.7446193,57.5200453 15.7252005,58.6372282 16.4022825,59.3382615 C17.0793616,60.0392948 18.1965445,60.0587136 18.8975778,59.3816316 C18.9122847,59.3674273 18.9267436,59.3529684 18.940948,59.3382615 L56.6964963,21.5830662 C57.3856425,20.8939094 57.3856425,19.7765747 56.6964963,19.0874179 Z\"\n id=\"Combined-Shape\"\n ></path>\n </g>\n </g>\n </g>\n</svg>\n<svg\n *ngIf=\"icon === 'send'\"\n data-testid=\"send\"\n height=\"17\"\n viewBox=\"0 0 18 17\"\n width=\"18\"\n xmlns=\"http://www.w3.org/2000/svg\"\n>\n <title translate>streamChat.Send</title>\n <path\n d=\"M0 17.015l17.333-8.508L0 0v6.617l12.417 1.89L0 10.397z\"\n fill=\"#006cff\"\n fillRule=\"evenodd\"\n />\n</svg>\n<svg\n *ngIf=\"icon === 'file-upload'\"\n data-testid=\"file-upload\"\n height=\"14\"\n width=\"14\"\n xmlns=\"http://www.w3.org/2000/svg\"\n>\n <title translate>streamChat.Attach files</title>\n <path\n d=\"M1.667.333h10.666c.737 0 1.334.597 1.334 1.334v10.666c0 .737-.597 1.334-1.334 1.334H1.667a1.333 1.333 0 0 1-1.334-1.334V1.667C.333.93.93.333 1.667.333zm2 1.334a1.667 1.667 0 1 0 0 3.333 1.667 1.667 0 0 0 0-3.333zm-2 9.333v1.333h10.666v-4l-2-2-4 4-2-2L1.667 11z\"\n fillRule=\"nonzero\"\n />\n</svg>\n<svg\n data-testid=\"retry\"\n *ngIf=\"icon === 'retry'\"\n width=\"22\"\n height=\"20\"\n viewBox=\"0 0 22 20\"\n xmlns=\"http://www.w3.org/2000/svg\"\n>\n <path\n d=\"M20 5.535V2a1 1 0 0 1 2 0v6a1 1 0 0 1-1 1h-6a1 1 0 0 1 0-2h3.638l-2.975-2.653a8 8 0 1 0 1.884 8.32 1 1 0 1 1 1.886.666A10 10 0 1 1 5.175 1.245c3.901-2.15 8.754-1.462 11.88 1.667L20 5.535z\"\n fill=\"#FFF\"\n fill-rule=\"nonzero\"\n />\n</svg>\n<svg\n *ngIf=\"icon === 'close'\"\n data-testid=\"close\"\n width=\"28\"\n height=\"28\"\n viewBox=\"0 0 28 28\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n>\n <defs>\n <path\n d=\"M465 5c5.53 0 10 4.47 10 10s-4.47 10-10 10-10-4.47-10-10 4.47-10 10-10zm3.59 5L465 13.59 461.41 10 460 11.41l3.59 3.59-3.59 3.59 1.41 1.41 3.59-3.59 3.59 3.59 1.41-1.41-3.59-3.59 3.59-3.59-1.41-1.41z\"\n id=\"b\"\n />\n <filter\n x=\"-30%\"\n y=\"-30%\"\n width=\"160%\"\n height=\"160%\"\n filterUnits=\"objectBoundingBox\"\n id=\"a\"\n >\n <feOffset in=\"SourceAlpha\" result=\"shadowOffsetOuter1\" />\n <feGaussianBlur\n stdDeviation=\"2\"\n in=\"shadowOffsetOuter1\"\n result=\"shadowBlurOuter1\"\n />\n <feColorMatrix\n values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.5 0\"\n in=\"shadowBlurOuter1\"\n />\n </filter>\n </defs>\n <g transform=\"translate(-451 -1)\" fill-rule=\"nonzero\" fill=\"none\">\n <use fill=\"#000\" filter=\"url(#a)\" xlink:href=\"#b\" />\n <use fill=\"#FFF\" fill-rule=\"evenodd\" xlink:href=\"#b\" />\n </g>\n</svg>\n<svg\n *ngIf=\"icon === 'file'\"\n data-testid=\"file\"\n className=\"rfu-file-icon--small fa-file-fallback\"\n [attr.height]=\"size || 20\"\n [attr.width]=\"size || 20\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 384 512\"\n>\n <path\n d=\"M369.9 97.9L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM332.1 128H256V51.9l76.1 76.1zM48 464V48h160v104c0 13.3 10.7 24 24 24h104v288H48z\"\n fill=\"#414D54\"\n />\n</svg>\n<svg\n *ngIf=\"icon === 'reply'\"\n data-testid=\"reply\"\n height=\"15\"\n width=\"18\"\n xmlns=\"http://www.w3.org/2000/svg\"\n>\n <path\n d=\"M.56 10.946H.06l-.002-.498L.025.92a.5.5 0 1 1 1-.004l.032 9.029H9.06v-4l9 4.5-9 4.5v-4H.56z\"\n fillRule=\"nonzero\"\n />\n</svg>\n<svg\n height=\"10\"\n width=\"10\"\n xmlns=\"http://www.w3.org/2000/svg\"\n data-testid=\"close-no-outline\"\n *ngIf=\"icon === 'close-no-outline'\"\n>\n <path\n d=\"M9.916 1.027L8.973.084 5 4.058 1.027.084l-.943.943L4.058 5 .084 8.973l.943.943L5 5.942l3.973 3.974.943-.943L5.942 5z\"\n fillRule=\"evenodd\"\n />\n</svg>\n<svg\n height=\"10\"\n width=\"14\"\n xmlns=\"http://www.w3.org/2000/svg\"\n data-testid=\"reply-in-thread\"\n *ngIf=\"icon === 'reply-in-thread'\"\n>\n <path\n d=\"M8.516 3c4.78 0 4.972 6.5 4.972 6.5-1.6-2.906-2.847-3.184-4.972-3.184v2.872L3.772 4.994 8.516.5V3zM.484 5l4.5-4.237v1.78L2.416 5l2.568 2.125v1.828L.484 5z\"\n fillRule=\"evenodd\"\n />\n</svg>\n<svg\n *ngIf=\"icon === 'arrow-left'\"\n data-testid=\"arrow-left\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n>\n <path\n d=\"M15.7049 7.41L14.2949 6L8.29492 12L14.2949 18L15.7049 16.59L11.1249 12L15.7049 7.41Z\"\n fill=\"var(--black)\"\n />\n</svg>\n\n<svg\n *ngIf=\"icon === 'arrow-right'\"\n data-testid=\"arrow-right\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n>\n <path\n d=\"M9.70492 6L8.29492 7.41L12.8749 12L8.29492 16.59L9.70492 18L15.7049 12L9.70492 6Z\"\n fill=\"var(--black)\"\n />\n</svg>\n<svg\n *ngIf=\"icon === 'menu'\"\n data-testid=\"menu\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n>\n <path\n fill-rule=\"evenodd\"\n clip-rule=\"evenodd\"\n d=\"M3 8V6H21V8H3ZM3 13H21V11H3V13ZM3 18H21V16H3V18Z\"\n fill=\"black\"\n />\n</svg>\n", directives: [{ type: i6__namespace.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2__namespace.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }] });
2385
+ IconComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: IconComponent, selector: "stream-icon", inputs: { icon: "icon", size: "size" }, ngImport: i0__namespace, template: "<svg\n data-testid=\"action-icon\"\n *ngIf=\"icon === 'action-icon'\"\n height=\"4\"\n viewBox=\"0 0 11 4\"\n width=\"11\"\n xmlns=\"http://www.w3.org/2000/svg\"\n>\n <path\n d=\"M1.5 3a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm4 0a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm4 0a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3z\"\n fillRule=\"nonzero\"\n />\n</svg>\n<svg\n *ngIf=\"icon === 'delivered-icon'\"\n height=\"16\"\n width=\"16\"\n xmlns=\"http://www.w3.org/2000/svg\"\n data-testid=\"delivered-icon\"\n>\n <path\n d=\"M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0zm3.72 6.633a.955.955 0 1 0-1.352-1.352L6.986 8.663 5.633 7.31A.956.956 0 1 0 4.28 8.663l2.029 2.028a.956.956 0 0 0 1.353 0l4.058-4.058z\"\n fill=\"#006CFF\"\n fillRule=\"evenodd\"\n />\n</svg>\n<svg\n *ngIf=\"icon === 'reaction-icon'\"\n height=\"12\"\n viewBox=\"0 0 12 12\"\n width=\"12\"\n xmlns=\"http://www.w3.org/2000/svg\"\n data-testid=\"reaction-icon\"\n>\n <g clipRule=\"evenodd\" fillRule=\"evenodd\">\n <path\n d=\"M6 1.2C3.3 1.2 1.2 3.3 1.2 6c0 2.7 2.1 4.8 4.8 4.8 2.7 0 4.8-2.1 4.8-4.8 0-2.7-2.1-4.8-4.8-4.8zM0 6c0-3.3 2.7-6 6-6s6 2.7 6 6-2.7 6-6 6-6-2.7-6-6z\"\n ></path>\n <path\n d=\"M5.4 4.5c0 .5-.4.9-.9.9s-.9-.4-.9-.9.4-.9.9-.9.9.4.9.9zM8.4 4.5c0 .5-.4.9-.9.9s-.9-.4-.9-.9.4-.9.9-.9.9.4.9.9zM3.3 6.7c.3-.2.6-.1.8.1.3.4.8.9 1.5 1 .6.2 1.4.1 2.4-1 .2-.2.6-.3.8 0 .2.2.3.6 0 .8-1.1 1.3-2.4 1.7-3.5 1.5-1-.2-1.8-.9-2.2-1.5-.2-.3-.1-.7.2-.9z\"\n ></path>\n </g>\n</svg>\n<svg\n data-testid=\"connection-error\"\n *ngIf=\"icon === 'connection-error'\"\n width=\"78px\"\n height=\"78px\"\n viewBox=\"0 0 78 78\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n>\n <!-- Generator: Sketch 52.6 (67491) - http://www.bohemiancoding.com/sketch -->\n <title>Combined Shape</title>\n <desc>Created with Sketch.</desc>\n <g\n id=\"Interactions\"\n stroke=\"none\"\n stroke-width=\"1\"\n fill=\"none\"\n fill-rule=\"evenodd\"\n >\n <g\n id=\"Connection-Error-_-Connectivity\"\n transform=\"translate(-270.000000, -30.000000)\"\n fill=\"#CF1F25\"\n >\n <g\n id=\"109-network-connection\"\n transform=\"translate(270.000000, 30.000000)\"\n >\n <path\n d=\"M66.4609744,11.414231 C81.6225232,26.5757798 81.6225232,51.157545 66.4609744,66.3188467 C51.2994256,81.4803954 26.7176604,81.4803954 11.5563587,66.3188467 C-3.60519004,51.1572979 -3.60519004,26.5755327 11.5563587,11.414231 C26.7179075,-3.74731776 51.2996727,-3.74731776 66.4609744,11.414231 Z M54.7853215,45.8823776 L54.7853215,40.5882574 C54.7853215,39.613638 53.9952341,38.8235506 53.0206147,38.8235506 L44.9576695,38.8235506 L41.428256,42.3529641 L51.255555,42.3529641 L51.255555,45.8823776 L54.7853215,45.8823776 Z M40.6659027,43.1153174 L37.8988425,45.8823776 L40.6659027,45.8823776 L40.6659027,43.1153174 Z M51.1764962,56.4702653 L58.2353232,56.4702653 C59.2099355,56.4702653 60.00003,55.6801708 60.00003,54.7055585 L60.00003,51.176145 C60.00003,50.2015327 59.2099355,49.4114382 58.2353232,49.4114382 L51.1764962,49.4114382 C50.2018839,49.4114382 49.4117894,50.2015327 49.4117894,51.176145 L49.4117894,54.7055585 C49.4117894,55.6801708 50.2018839,56.4702653 51.1764962,56.4702653 Z M35.2941353,56.4702653 L42.3529624,56.4702653 C43.3275746,56.4702653 44.1176691,55.6801708 44.1176691,54.7055585 L44.1176691,51.176145 C44.1176691,50.2015327 43.3275746,49.4114382 42.3529624,49.4114382 L35.2941353,49.4114382 C34.319523,49.4114382 33.5294285,50.2015327 33.5294285,51.176145 L33.5294285,54.7055585 C33.5294285,55.6801708 34.319523,56.4702653 35.2941353,56.4702653 Z M56.6964989,19.0874231 C56.007381,18.3985134 54.8903216,18.3985134 54.2012036,19.087423 L45.882376,27.4062507 L45.882376,19.4117761 C45.882376,18.4371568 45.0922885,17.6470693 44.1176692,17.6470693 L33.5294286,17.6470693 C32.5548092,17.6470694 31.7647218,18.4371568 31.7647218,19.4117761 L31.7647218,30.0000167 C31.7647219,30.9746363 32.5548092,31.7647237 33.5294285,31.7647237 L41.5239031,31.7647237 L34.4650761,38.8235508 L24.7058947,38.8235508 C23.7312753,38.8235508 22.9411879,39.6136382 22.9411879,40.5882575 L22.9411879,45.8823778 L26.4706014,45.8823778 L26.4706014,42.3529643 L30.9356624,42.3529643 L23.8768354,49.4117914 L19.4117743,49.4117914 C18.4371549,49.4117914 17.6470675,50.2018788 17.6470675,51.1764981 L17.6470675,54.7059117 C17.6504049,54.9674302 17.7129076,55.2248042 17.8298886,55.4587302 L16.4456526,56.8429662 C15.7446193,57.5200453 15.7252005,58.6372282 16.4022825,59.3382615 C17.0793616,60.0392948 18.1965445,60.0587136 18.8975778,59.3816316 C18.9122847,59.3674273 18.9267436,59.3529684 18.940948,59.3382615 L56.6964963,21.5830662 C57.3856425,20.8939094 57.3856425,19.7765747 56.6964963,19.0874179 Z\"\n id=\"Combined-Shape\"\n ></path>\n </g>\n </g>\n </g>\n</svg>\n<svg\n *ngIf=\"icon === 'send'\"\n data-testid=\"send\"\n height=\"17\"\n viewBox=\"0 0 18 17\"\n width=\"18\"\n xmlns=\"http://www.w3.org/2000/svg\"\n>\n <title translate>streamChat.Send</title>\n <path\n d=\"M0 17.015l17.333-8.508L0 0v6.617l12.417 1.89L0 10.397z\"\n fill=\"#006cff\"\n fillRule=\"evenodd\"\n />\n</svg>\n<svg\n *ngIf=\"icon === 'file-upload'\"\n data-testid=\"file-upload\"\n height=\"14\"\n width=\"14\"\n xmlns=\"http://www.w3.org/2000/svg\"\n>\n <title translate>streamChat.Attach files</title>\n <path\n d=\"M1.667.333h10.666c.737 0 1.334.597 1.334 1.334v10.666c0 .737-.597 1.334-1.334 1.334H1.667a1.333 1.333 0 0 1-1.334-1.334V1.667C.333.93.93.333 1.667.333zm2 1.334a1.667 1.667 0 1 0 0 3.333 1.667 1.667 0 0 0 0-3.333zm-2 9.333v1.333h10.666v-4l-2-2-4 4-2-2L1.667 11z\"\n fillRule=\"nonzero\"\n />\n</svg>\n<svg\n data-testid=\"retry\"\n *ngIf=\"icon === 'retry'\"\n width=\"22\"\n height=\"20\"\n viewBox=\"0 0 22 20\"\n xmlns=\"http://www.w3.org/2000/svg\"\n>\n <path\n d=\"M20 5.535V2a1 1 0 0 1 2 0v6a1 1 0 0 1-1 1h-6a1 1 0 0 1 0-2h3.638l-2.975-2.653a8 8 0 1 0 1.884 8.32 1 1 0 1 1 1.886.666A10 10 0 1 1 5.175 1.245c3.901-2.15 8.754-1.462 11.88 1.667L20 5.535z\"\n fill=\"#FFF\"\n fill-rule=\"nonzero\"\n />\n</svg>\n<svg\n *ngIf=\"icon === 'close'\"\n data-testid=\"close\"\n width=\"28\"\n height=\"28\"\n viewBox=\"0 0 28 28\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n>\n <defs>\n <path\n d=\"M465 5c5.53 0 10 4.47 10 10s-4.47 10-10 10-10-4.47-10-10 4.47-10 10-10zm3.59 5L465 13.59 461.41 10 460 11.41l3.59 3.59-3.59 3.59 1.41 1.41 3.59-3.59 3.59 3.59 1.41-1.41-3.59-3.59 3.59-3.59-1.41-1.41z\"\n id=\"b\"\n />\n <filter\n x=\"-30%\"\n y=\"-30%\"\n width=\"160%\"\n height=\"160%\"\n filterUnits=\"objectBoundingBox\"\n id=\"a\"\n >\n <feOffset in=\"SourceAlpha\" result=\"shadowOffsetOuter1\" />\n <feGaussianBlur\n stdDeviation=\"2\"\n in=\"shadowOffsetOuter1\"\n result=\"shadowBlurOuter1\"\n />\n <feColorMatrix\n values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.5 0\"\n in=\"shadowBlurOuter1\"\n />\n </filter>\n </defs>\n <g transform=\"translate(-451 -1)\" fill-rule=\"nonzero\" fill=\"none\">\n <use fill=\"#000\" filter=\"url(#a)\" xlink:href=\"#b\" />\n <use fill=\"#FFF\" fill-rule=\"evenodd\" xlink:href=\"#b\" />\n </g>\n</svg>\n<svg\n *ngIf=\"icon === 'file'\"\n data-testid=\"file\"\n className=\"rfu-file-icon--small fa-file-fallback\"\n [attr.height]=\"size || 20\"\n [attr.width]=\"size || 20\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 384 512\"\n>\n <path\n d=\"M369.9 97.9L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM332.1 128H256V51.9l76.1 76.1zM48 464V48h160v104c0 13.3 10.7 24 24 24h104v288H48z\"\n fill=\"#414D54\"\n />\n</svg>\n<svg\n *ngIf=\"icon === 'reply'\"\n data-testid=\"reply\"\n height=\"15\"\n width=\"18\"\n xmlns=\"http://www.w3.org/2000/svg\"\n>\n <path\n d=\"M.56 10.946H.06l-.002-.498L.025.92a.5.5 0 1 1 1-.004l.032 9.029H9.06v-4l9 4.5-9 4.5v-4H.56z\"\n fillRule=\"nonzero\"\n />\n</svg>\n<svg\n height=\"10\"\n width=\"10\"\n xmlns=\"http://www.w3.org/2000/svg\"\n data-testid=\"close-no-outline\"\n *ngIf=\"icon === 'close-no-outline'\"\n>\n <path\n d=\"M9.916 1.027L8.973.084 5 4.058 1.027.084l-.943.943L4.058 5 .084 8.973l.943.943L5 5.942l3.973 3.974.943-.943L5.942 5z\"\n fillRule=\"evenodd\"\n />\n</svg>\n<svg\n height=\"10\"\n width=\"14\"\n xmlns=\"http://www.w3.org/2000/svg\"\n data-testid=\"reply-in-thread\"\n *ngIf=\"icon === 'reply-in-thread'\"\n>\n <path\n d=\"M8.516 3c4.78 0 4.972 6.5 4.972 6.5-1.6-2.906-2.847-3.184-4.972-3.184v2.872L3.772 4.994 8.516.5V3zM.484 5l4.5-4.237v1.78L2.416 5l2.568 2.125v1.828L.484 5z\"\n fillRule=\"evenodd\"\n />\n</svg>\n<svg\n *ngIf=\"icon === 'arrow-left'\"\n data-testid=\"arrow-left\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n>\n <path\n d=\"M15.7049 7.41L14.2949 6L8.29492 12L14.2949 18L15.7049 16.59L11.1249 12L15.7049 7.41Z\"\n fill=\"var(--black)\"\n />\n</svg>\n\n<svg\n *ngIf=\"icon === 'arrow-right'\"\n data-testid=\"arrow-right\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n>\n <path\n d=\"M9.70492 6L8.29492 7.41L12.8749 12L8.29492 16.59L9.70492 18L15.7049 12L9.70492 6Z\"\n fill=\"var(--black)\"\n />\n</svg>\n<svg\n *ngIf=\"icon === 'menu'\"\n data-testid=\"menu\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n>\n <path\n fill-rule=\"evenodd\"\n clip-rule=\"evenodd\"\n d=\"M3 8V6H21V8H3ZM3 13H21V11H3V13ZM3 18H21V16H3V18Z\"\n fill=\"black\"\n />\n</svg>\n", directives: [{ type: i3__namespace.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2__namespace.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }] });
2242
2386
  i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: IconComponent, decorators: [{
2243
2387
  type: i0.Component,
2244
2388
  args: [{
@@ -2252,6 +2396,36 @@
2252
2396
  type: i0.Input
2253
2397
  }] } });
2254
2398
 
2399
+ /**
2400
+ * The `IconPlaceholder` component displays the [default icons](./IconComponent.mdx) unless a [custom template](../services/CustomTemplatesService.mdx) is provided. This componet is used by the SDK internally, you likely won't need to use it.
2401
+ */
2402
+ var IconPlaceholderComponent = /** @class */ (function () {
2403
+ function IconPlaceholderComponent(customTemplatesService) {
2404
+ this.customTemplatesService = customTemplatesService;
2405
+ }
2406
+ IconPlaceholderComponent.prototype.getIconContext = function () {
2407
+ return {
2408
+ icon: this.icon,
2409
+ size: this.size,
2410
+ };
2411
+ };
2412
+ return IconPlaceholderComponent;
2413
+ }());
2414
+ IconPlaceholderComponent.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: IconPlaceholderComponent, deps: [{ token: CustomTemplatesService }], target: i0__namespace.ɵɵFactoryTarget.Component });
2415
+ IconPlaceholderComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: { icon: "icon", size: "size" }, ngImport: i0__namespace, template: "<ng-template #defaultIcon let-icon=\"icon\" let-size=\"size\">\n <stream-icon [icon]=\"icon\" [size]=\"size\"></stream-icon>\n</ng-template>\n<ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.iconTemplate$ | async) || defaultIcon;\n context: getIconContext()\n \"\n></ng-container>\n", components: [{ type: IconComponent, selector: "stream-icon", inputs: ["icon", "size"] }], directives: [{ type: i3__namespace.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], pipes: { "async": i3__namespace.AsyncPipe } });
2416
+ i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: IconPlaceholderComponent, decorators: [{
2417
+ type: i0.Component,
2418
+ args: [{
2419
+ selector: 'stream-icon-placeholder',
2420
+ templateUrl: './icon-placeholder.component.html',
2421
+ styles: [],
2422
+ }]
2423
+ }], ctorParameters: function () { return [{ type: CustomTemplatesService }]; }, propDecorators: { icon: [{
2424
+ type: i0.Input
2425
+ }], size: [{
2426
+ type: i0.Input
2427
+ }] } });
2428
+
2255
2429
  /**
2256
2430
  * The `LoadingIndicator` component displays a spinner to indicate that an action is in progress.
2257
2431
  */
@@ -2269,7 +2443,7 @@
2269
2443
  return LoadingIndicatorComponent;
2270
2444
  }());
2271
2445
  LoadingIndicatorComponent.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: LoadingIndicatorComponent, deps: [], target: i0__namespace.ɵɵFactoryTarget.Component });
2272
- LoadingIndicatorComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: LoadingIndicatorComponent, selector: "stream-loading-indicator", inputs: { size: "size", color: "color" }, ngImport: i0__namespace, template: "<div class=\"str-chat__loading-indicator\">\n <svg\n [attr.height]=\"size\"\n viewBox=\"0 0 30 30\"\n [attr.width]=\"size\"\n data-testid=\"loading-indicator\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <defs>\n <linearGradient id=\"a\" x1=\"50%\" x2=\"50%\" y1=\"0%\" y2=\"100%\">\n <stop offset=\"0%\" stop-color=\"#FFF\" stop-opacity=\"0\" />\n <stop\n data-testid=\"stop-color\"\n offset=\"100%\"\n [attr.stop-color]=\"color\"\n stop-opacity=\"1\"\n [ngStyle]=\"{ stopColor: color }\"\n />\n </linearGradient>\n </defs>\n <path\n d=\"M2.518 23.321l1.664-1.11A12.988 12.988 0 0 0 15 28c7.18 0 13-5.82 13-13S22.18 2 15 2V0c8.284 0 15 6.716 15 15 0 8.284-6.716 15-15 15-5.206 0-9.792-2.652-12.482-6.679z\"\n fill=\"url(#a)\"\n fillRule=\"evenodd\"\n />\n </svg>\n</div>\n", directives: [{ type: i6__namespace.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] });
2446
+ LoadingIndicatorComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: LoadingIndicatorComponent, selector: "stream-loading-indicator", inputs: { size: "size", color: "color" }, ngImport: i0__namespace, template: "<div class=\"str-chat__loading-indicator\">\n <svg\n [attr.height]=\"size\"\n viewBox=\"0 0 30 30\"\n [attr.width]=\"size\"\n data-testid=\"loading-indicator\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <defs>\n <linearGradient id=\"a\" x1=\"50%\" x2=\"50%\" y1=\"0%\" y2=\"100%\">\n <stop offset=\"0%\" stop-color=\"#FFF\" stop-opacity=\"0\" />\n <stop\n data-testid=\"stop-color\"\n offset=\"100%\"\n [attr.stop-color]=\"color\"\n stop-opacity=\"1\"\n [ngStyle]=\"{ stopColor: color }\"\n />\n </linearGradient>\n </defs>\n <path\n d=\"M2.518 23.321l1.664-1.11A12.988 12.988 0 0 0 15 28c7.18 0 13-5.82 13-13S22.18 2 15 2V0c8.284 0 15 6.716 15 15 0 8.284-6.716 15-15 15-5.206 0-9.792-2.652-12.482-6.679z\"\n fill=\"url(#a)\"\n fillRule=\"evenodd\"\n />\n </svg>\n</div>\n", directives: [{ type: i3__namespace.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] });
2273
2447
  i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: LoadingIndicatorComponent, decorators: [{
2274
2448
  type: i0.Component,
2275
2449
  args: [{
@@ -2283,6 +2457,117 @@
2283
2457
  type: i0.Input
2284
2458
  }] } });
2285
2459
 
2460
+ /**
2461
+ * The `LoadingInficatorPlaceholder` component displays the [default loading indicator](./LoadingIndicatorComponent.mdx) unless a [custom template](../services/CustomTemplatesService.mdx) is provided. This componet is used by the SDK internally, you likely won't need to use it.
2462
+ */
2463
+ var LoadingIndicatorPlaceholderComponent = /** @class */ (function () {
2464
+ function LoadingIndicatorPlaceholderComponent(customTemplatesService) {
2465
+ this.customTemplatesService = customTemplatesService;
2466
+ /**
2467
+ * The size of the indicator (in pixels)
2468
+ */
2469
+ this.size = 15;
2470
+ /**
2471
+ * The color of the indicator
2472
+ */
2473
+ this.color = '#006CFF';
2474
+ }
2475
+ LoadingIndicatorPlaceholderComponent.prototype.getLoadingIndicatorContext = function () {
2476
+ return {
2477
+ size: this.size,
2478
+ color: this.color,
2479
+ };
2480
+ };
2481
+ return LoadingIndicatorPlaceholderComponent;
2482
+ }());
2483
+ LoadingIndicatorPlaceholderComponent.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: LoadingIndicatorPlaceholderComponent, deps: [{ token: CustomTemplatesService }], target: i0__namespace.ɵɵFactoryTarget.Component });
2484
+ LoadingIndicatorPlaceholderComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: LoadingIndicatorPlaceholderComponent, selector: "stream-loading-indicator-placeholder", inputs: { size: "size", color: "color" }, ngImport: i0__namespace, template: "<ng-template #defaultLoadingIndicator let-size=\"size\" let-color=\"color\">\n <stream-loading-indicator\n [size]=\"size\"\n [color]=\"color\"\n ></stream-loading-indicator>\n</ng-template>\n<ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.loadingIndicatorTemplate$ | async) ||\n defaultLoadingIndicator;\n context: getLoadingIndicatorContext()\n \"\n></ng-container>\n", components: [{ type: LoadingIndicatorComponent, selector: "stream-loading-indicator", inputs: ["size", "color"] }], directives: [{ type: i3__namespace.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], pipes: { "async": i3__namespace.AsyncPipe } });
2485
+ i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: LoadingIndicatorPlaceholderComponent, decorators: [{
2486
+ type: i0.Component,
2487
+ args: [{
2488
+ selector: 'stream-loading-indicator-placeholder',
2489
+ templateUrl: './loading-indicator-placeholder.component.html',
2490
+ styles: [],
2491
+ }]
2492
+ }], ctorParameters: function () { return [{ type: CustomTemplatesService }]; }, propDecorators: { size: [{
2493
+ type: i0.Input
2494
+ }], color: [{
2495
+ type: i0.Input
2496
+ }] } });
2497
+
2498
+ /**
2499
+ * 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.
2500
+ */
2501
+ var ModalComponent = /** @class */ (function () {
2502
+ function ModalComponent() {
2503
+ var _this = this;
2504
+ /**
2505
+ * If `true` the modal will be displayed, if `false` the modal will be hidden
2506
+ */
2507
+ this.isOpen = false;
2508
+ /**
2509
+ * Emits `true` if the modal becomes visible, and `false` if the modal is closed.
2510
+ */
2511
+ this.isOpenChange = new i0.EventEmitter();
2512
+ this.watchForEscPress = function (event) {
2513
+ if (event.key === 'Escape') {
2514
+ _this.close();
2515
+ }
2516
+ };
2517
+ this.stopWatchForEscPress = function () {
2518
+ window.removeEventListener('keyup', _this.watchForEscPress);
2519
+ };
2520
+ this.watchForOutsideClicks = function (event) {
2521
+ var _a;
2522
+ if (!((_a = _this.innerContainer) === null || _a === void 0 ? void 0 : _a.nativeElement.contains(event.target))) {
2523
+ _this.close();
2524
+ }
2525
+ };
2526
+ }
2527
+ ModalComponent.prototype.ngOnChanges = function (changes) {
2528
+ var _this = this;
2529
+ if (changes.isOpen) {
2530
+ if (this.isOpen) {
2531
+ window.addEventListener('keyup', this.watchForEscPress);
2532
+ setTimeout(function () { return window.addEventListener('click', _this.watchForOutsideClicks); }, 0);
2533
+ }
2534
+ else {
2535
+ this.stopWatchForOutsideClicks();
2536
+ this.stopWatchForEscPress();
2537
+ }
2538
+ }
2539
+ };
2540
+ ModalComponent.prototype.close = function () {
2541
+ this.isOpen = false;
2542
+ this.isOpenChange.emit(false);
2543
+ this.stopWatchForOutsideClicks();
2544
+ this.stopWatchForEscPress();
2545
+ };
2546
+ ModalComponent.prototype.stopWatchForOutsideClicks = function () {
2547
+ window.removeEventListener('click', this.watchForOutsideClicks);
2548
+ };
2549
+ return ModalComponent;
2550
+ }());
2551
+ ModalComponent.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: ModalComponent, deps: [], target: i0__namespace.ɵɵFactoryTarget.Component });
2552
+ ModalComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: ModalComponent, selector: "stream-modal", inputs: { isOpen: "isOpen", content: "content" }, outputs: { isOpenChange: "isOpenChange" }, viewQueries: [{ propertyName: "innerContainer", first: true, predicate: ["modalInner"], descendants: true }], usesOnChanges: true, ngImport: i0__namespace, template: "<div\n data-testid=\"modal\"\n class=\"str-chat__modal str-chat__modal--{{ isOpen ? 'open' : 'close' }}\"\n>\n <div\n data-testid=\"close\"\n class=\"str-chat__modal__close-button\"\n (click)=\"close()\"\n (keyup.enter)=\"close()\"\n translate\n >\n streamChat.Close\n <stream-icon-placeholder icon=\"close\"></stream-icon-placeholder>\n </div>\n <div class=\"str-chat__modal__inner\" #modalInner>\n <ng-container *ngIf=\"content; else elseContent\">\n <ng-container *ngTemplateOutlet=\"content\"></ng-container>\n </ng-container>\n <ng-template #elseContent>\n <ng-content></ng-content>\n </ng-template>\n </div>\n</div>\n", components: [{ type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon", "size"] }], directives: [{ type: i2__namespace.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { type: i3__namespace.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3__namespace.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }] });
2553
+ i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: ModalComponent, decorators: [{
2554
+ type: i0.Component,
2555
+ args: [{
2556
+ selector: 'stream-modal',
2557
+ templateUrl: './modal.component.html',
2558
+ styles: [],
2559
+ }]
2560
+ }], ctorParameters: function () { return []; }, propDecorators: { isOpen: [{
2561
+ type: i0.Input
2562
+ }], content: [{
2563
+ type: i0.Input
2564
+ }], isOpenChange: [{
2565
+ type: i0.Output
2566
+ }], innerContainer: [{
2567
+ type: i0.ViewChild,
2568
+ args: ['modalInner']
2569
+ }] } });
2570
+
2286
2571
  var textareaInjectionToken = new i0.InjectionToken('textareaInjectionToken');
2287
2572
 
2288
2573
  var TextareaDirective = /** @class */ (function () {
@@ -2310,10 +2595,6 @@
2310
2595
  this.subscriptions.push(this.componentRef.instance.userMentions.subscribe(function (value) { return _this.userMentions.next(value); }));
2311
2596
  }
2312
2597
  this.componentRef.instance.areMentionsEnabled = this.areMentionsEnabled;
2313
- this.componentRef.instance.mentionAutocompleteItemTemplate =
2314
- this.mentionAutocompleteItemTemplate;
2315
- this.componentRef.instance.commandAutocompleteItemTemplate =
2316
- this.commandAutocompleteItemTemplate;
2317
2598
  this.componentRef.instance.mentionScope = this.mentionScope;
2318
2599
  this.componentRef.instance.value = this.value;
2319
2600
  }
@@ -2321,14 +2602,6 @@
2321
2602
  if (changes.areMentionsEnabled) {
2322
2603
  this.componentRef.instance.areMentionsEnabled = this.areMentionsEnabled;
2323
2604
  }
2324
- if (changes.mentionAutocompleteItemTemplate) {
2325
- this.componentRef.instance.mentionAutocompleteItemTemplate =
2326
- this.mentionAutocompleteItemTemplate;
2327
- }
2328
- if (changes.commandAutocompleteItemTemplate) {
2329
- this.componentRef.instance.commandAutocompleteItemTemplate =
2330
- this.commandAutocompleteItemTemplate;
2331
- }
2332
2605
  if (changes.mentionScope) {
2333
2606
  this.componentRef.instance.mentionScope = this.mentionScope;
2334
2607
  }
@@ -2345,7 +2618,7 @@
2345
2618
  return TextareaDirective;
2346
2619
  }());
2347
2620
  TextareaDirective.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: TextareaDirective, deps: [{ token: i0__namespace.ViewContainerRef }], target: i0__namespace.ɵɵFactoryTarget.Directive });
2348
- TextareaDirective.ɵdir = i0__namespace.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "12.2.5", type: TextareaDirective, selector: "[streamTextarea]", inputs: { componentRef: "componentRef", areMentionsEnabled: "areMentionsEnabled", mentionAutocompleteItemTemplate: "mentionAutocompleteItemTemplate", mentionScope: "mentionScope", commandAutocompleteItemTemplate: "commandAutocompleteItemTemplate", value: "value" }, outputs: { valueChange: "valueChange", send: "send", userMentions: "userMentions" }, usesOnChanges: true, ngImport: i0__namespace });
2621
+ TextareaDirective.ɵdir = i0__namespace.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "12.2.5", type: TextareaDirective, selector: "[streamTextarea]", inputs: { componentRef: "componentRef", areMentionsEnabled: "areMentionsEnabled", mentionScope: "mentionScope", value: "value" }, outputs: { valueChange: "valueChange", send: "send", userMentions: "userMentions" }, usesOnChanges: true, ngImport: i0__namespace });
2349
2622
  i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: TextareaDirective, decorators: [{
2350
2623
  type: i0.Directive,
2351
2624
  args: [{
@@ -2355,12 +2628,8 @@
2355
2628
  type: i0.Input
2356
2629
  }], areMentionsEnabled: [{
2357
2630
  type: i0.Input
2358
- }], mentionAutocompleteItemTemplate: [{
2359
- type: i0.Input
2360
2631
  }], mentionScope: [{
2361
2632
  type: i0.Input
2362
- }], commandAutocompleteItemTemplate: [{
2363
- type: i0.Input
2364
2633
  }], value: [{
2365
2634
  type: i0.Input
2366
2635
  }], valueChange: [{
@@ -2446,82 +2715,12 @@
2446
2715
  }]
2447
2716
  }], ctorParameters: function () { return []; } });
2448
2717
 
2449
- /**
2450
- * 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.
2451
- */
2452
- var ModalComponent = /** @class */ (function () {
2453
- function ModalComponent() {
2454
- var _this = this;
2455
- /**
2456
- * If `true` the modal will be displayed, if `false` the modal will be hidden
2457
- */
2458
- this.isOpen = false;
2459
- /**
2460
- * Emits `true` if the modal becomes visible, and `false` if the modal is closed.
2461
- */
2462
- this.isOpenChange = new i0.EventEmitter();
2463
- this.watchForEscPress = function (event) {
2464
- if (event.key === 'Escape') {
2465
- _this.close();
2466
- }
2467
- };
2468
- this.stopWatchForEscPress = function () {
2469
- window.removeEventListener('keyup', _this.watchForEscPress);
2470
- };
2471
- this.watchForOutsideClicks = function (event) {
2472
- var _a;
2473
- if (!((_a = _this.content) === null || _a === void 0 ? void 0 : _a.nativeElement.contains(event.target))) {
2474
- _this.close();
2475
- }
2476
- };
2477
- }
2478
- ModalComponent.prototype.ngOnChanges = function (changes) {
2479
- var _this = this;
2480
- if (changes.isOpen) {
2481
- if (this.isOpen) {
2482
- window.addEventListener('keyup', this.watchForEscPress);
2483
- setTimeout(function () { return window.addEventListener('click', _this.watchForOutsideClicks); }, 0);
2484
- }
2485
- else {
2486
- this.stopWatchForOutsideClicks();
2487
- this.stopWatchForEscPress();
2488
- }
2489
- }
2490
- };
2491
- ModalComponent.prototype.close = function () {
2492
- this.isOpen = false;
2493
- this.isOpenChange.emit(false);
2494
- this.stopWatchForOutsideClicks();
2495
- this.stopWatchForEscPress();
2496
- };
2497
- ModalComponent.prototype.stopWatchForOutsideClicks = function () {
2498
- window.removeEventListener('click', this.watchForOutsideClicks);
2499
- };
2500
- return ModalComponent;
2501
- }());
2502
- ModalComponent.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: ModalComponent, deps: [], target: i0__namespace.ɵɵFactoryTarget.Component });
2503
- ModalComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: ModalComponent, selector: "stream-modal", inputs: { isOpen: "isOpen" }, outputs: { isOpenChange: "isOpenChange" }, viewQueries: [{ propertyName: "content", first: true, predicate: ["content"], descendants: true }], usesOnChanges: true, ngImport: i0__namespace, template: "<div\n data-testid=\"modal\"\n class=\"str-chat__modal str-chat__modal--{{ isOpen ? 'open' : 'close' }}\"\n>\n <div\n data-testid=\"close\"\n class=\"str-chat__modal__close-button\"\n (click)=\"close()\"\n (keyup.enter)=\"close()\"\n translate\n >\n streamChat.Close\n <stream-icon icon=\"close\"></stream-icon>\n </div>\n <div class=\"str-chat__modal__inner\" #content>\n <ng-content></ng-content>\n </div>\n</div>\n", components: [{ type: IconComponent, selector: "stream-icon", inputs: ["icon", "size"] }], directives: [{ type: i2__namespace.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }] });
2504
- i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: ModalComponent, decorators: [{
2505
- type: i0.Component,
2506
- args: [{
2507
- selector: 'stream-modal',
2508
- templateUrl: './modal.component.html',
2509
- styles: [],
2510
- }]
2511
- }], ctorParameters: function () { return []; }, propDecorators: { isOpen: [{
2512
- type: i0.Input
2513
- }], isOpenChange: [{
2514
- type: i0.Output
2515
- }], content: [{
2516
- type: i0.ViewChild,
2517
- args: ['content']
2518
- }] } });
2519
-
2520
2718
  /**
2521
2719
  * The `AttachmentList` compontent displays the attachments of a message
2522
2720
  */
2523
2721
  var AttachmentListComponent = /** @class */ (function () {
2524
- function AttachmentListComponent(imageLoadService, channelService) {
2722
+ function AttachmentListComponent(customTemplatesService, imageLoadService, channelService) {
2723
+ this.customTemplatesService = customTemplatesService;
2525
2724
  this.imageLoadService = imageLoadService;
2526
2725
  this.channelService = channelService;
2527
2726
  /**
@@ -2564,6 +2763,14 @@
2564
2763
  AttachmentListComponent.prototype.getFileSize = function (attachment) {
2565
2764
  return prettybytes__default['default'](Number(attachment.file_size));
2566
2765
  };
2766
+ AttachmentListComponent.prototype.getModalContext = function () {
2767
+ var _this = this;
2768
+ return {
2769
+ isOpen: this.imagesToView && this.imagesToView.length > 0,
2770
+ isOpenChangeHandler: function (isOpen) { return (isOpen ? null : _this.closeImageModal()); },
2771
+ content: this.modalContent,
2772
+ };
2773
+ };
2567
2774
  AttachmentListComponent.prototype.trimUrl = function (url) {
2568
2775
  if (url !== undefined && url !== null) {
2569
2776
  var _a = __read(url
@@ -2587,9 +2794,6 @@
2587
2794
  this.imagesToView = attachments;
2588
2795
  this.imagesToViewCurrentIndex = selectedIndex;
2589
2796
  };
2590
- AttachmentListComponent.prototype.closeImageModal = function () {
2591
- this.imagesToView = [];
2592
- };
2593
2797
  AttachmentListComponent.prototype.stepImages = function (dir) {
2594
2798
  this.imagesToViewCurrentIndex += dir * 1;
2595
2799
  };
@@ -2618,10 +2822,13 @@
2618
2822
  },
2619
2823
  ];
2620
2824
  };
2825
+ AttachmentListComponent.prototype.closeImageModal = function () {
2826
+ this.imagesToView = [];
2827
+ };
2621
2828
  return AttachmentListComponent;
2622
2829
  }());
2623
- AttachmentListComponent.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: AttachmentListComponent, deps: [{ token: ImageLoadService }, { token: ChannelService }], target: i0__namespace.ɵɵFactoryTarget.Component });
2624
- AttachmentListComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: AttachmentListComponent, selector: "stream-attachment-list", inputs: { messageId: "messageId", attachments: "attachments" }, usesOnChanges: true, ngImport: i0__namespace, template: "<ng-container *ngFor=\"let attachment of orderedAttachments; trackBy: trackById\">\n <div\n data-testclass=\"attachment-container\"\n class=\"str-chat__message-attachment str-chat__message-attachment--{{\n attachment.type\n }}\"\n [class.str-chat__message-attachment--card]=\"isCard(attachment)\"\n [class.str-chat-angular__message-attachment-file-single]=\"\n isFile(attachment)\n \"\n >\n <img\n *ngIf=\"isImage(attachment)\"\n class=\"str-chat__message-attachment--img\"\n data-testclass=\"image\"\n [src]=\"attachment.img_url || attachment.thumb_url || attachment.image_url\"\n [alt]=\"attachment?.fallback\"\n (load)=\"imageLoaded()\"\n (click)=\"openImageModal([attachment])\"\n (keyup.enter)=\"openImageModal([attachment])\"\n />\n <div\n class=\"str-chat__gallery\"\n data-testid=\"image-gallery\"\n *ngIf=\"isGallery(attachment)\"\n [class.str-chat__gallery--square]=\"(attachment?.images)!.length > 3\"\n >\n <ng-container\n *ngFor=\"\n let galleryImage of attachment.images;\n let index = index;\n let isLast = last;\n trackBy: trackByImageUrl\n \"\n >\n <button\n *ngIf=\"index < 3 || (index === 3 && isLast)\"\n class=\"str-chat__gallery-image\"\n data-testclass=\"gallery-image\"\n (click)=\"openImageModal(attachment.images!, index)\"\n (keyup.enter)=\"openImageModal(attachment.images!, index)\"\n >\n <img\n [src]=\"\n galleryImage.img_url ||\n galleryImage.thumb_url ||\n galleryImage.image_url\n \"\n [alt]=\"galleryImage.fallback\"\n (load)=\"imageLoaded()\"\n />\n </button>\n <button\n *ngIf=\"index === 3 && !isLast\"\n class=\"str-chat__gallery-placeholder\"\n data-testclass=\"gallery-image\"\n (click)=\"openImageModal(attachment.images!, index)\"\n (keyup.enter)=\"openImageModal(attachment.images!, index)\"\n [ngStyle]=\"{\n 'background-image':\n 'url(' +\n (galleryImage.img_url ||\n galleryImage.thumb_url ||\n galleryImage.image_url) +\n ')'\n }\"\n >\n <p\n [innerHTML]=\"\n 'streamChat.{{ imageCount }} more'\n | translate: { imageCount: attachment!.images!.length - 4 }\n \"\n ></p>\n </button>\n </ng-container>\n </div>\n <div\n *ngIf=\"isFile(attachment)\"\n class=\"\n str-chat__message-attachment-file--item\n str-chat-angular__message-attachment-file-single\n \"\n >\n <stream-icon icon=\"file\" [size]=\"30\"></stream-icon>\n <div class=\"str-chat__message-attachment-file--item-text\">\n <a\n data-testclass=\"file-link\"\n download\n href=\"{{ attachment.asset_url }}\"\n target=\"_blank\"\n >\n {{ attachment.title }}\n </a>\n <span data-testclass=\"size\" *ngIf=\"hasFileSize(attachment)\">{{\n getFileSize(attachment)\n }}</span>\n </div>\n </div>\n <div\n *ngIf=\"isCard(attachment)\"\n class=\"str-chat__message-attachment-card str-chat__message-attachment-card--{{\n attachment.type\n }}\"\n >\n <div\n *ngIf=\"attachment.image_url || attachment.thumb_url\"\n class=\"str-chat__message-attachment-card--header\"\n >\n <img\n data-testclass=\"card-img\"\n alt=\"{{ attachment.image_url || attachment.thumb_url }}\"\n src=\"{{ attachment.image_url || attachment.thumb_url }}\"\n />\n </div>\n <div class=\"str-chat__message-attachment-card--content\">\n <div class=\"str-chat__message-attachment-card--flex\">\n <div\n *ngIf=\"attachment.title\"\n data-testclass=\"card-title\"\n class=\"str-chat__message-attachment-card--title\"\n >\n {{ attachment.title }}\n </div>\n <div\n *ngIf=\"attachment.text\"\n class=\"str-chat__message-attachment-card--text\"\n data-testclass=\"card-text\"\n >\n {{ attachment.text }}\n </div>\n <a\n class=\"str-chat__message-attachment-card--url\"\n *ngIf=\"attachment.title_link || attachment.og_scrape_url\"\n data-testclass=\"url-link\"\n noopener\n noreferrer\n href=\"{{ attachment.title_link || attachment.og_scrape_url }}\"\n target=\"_blank\"\n >\n {{ trimUrl(attachment.title_link || attachment.og_scrape_url) }}\n </a>\n </div>\n </div>\n </div>\n <div\n class=\"str-chat__message-attachment-actions\"\n *ngIf=\"attachment.actions && attachment.actions.length > 0\"\n >\n <div class=\"str-chat__message-attachment-actions-form\">\n <button\n *ngFor=\"let action of attachment.actions; trackBy: trackByActionValue\"\n class=\"str-chat__message-attachment-actions-button str-chat__message-attachment-actions-button--{{\n action.style\n }}\"\n data-testclass=\"attachment-action\"\n (click)=\"sendAction(action)\"\n (keyup.enter)=\"sendAction(action)\"\n >\n {{ action.text }}\n </button>\n </div>\n </div>\n </div>\n</ng-container>\n\n<stream-modal\n *ngIf=\"imagesToView && imagesToView.length > 0\"\n [isOpen]=\"imagesToView && imagesToView.length > 0\"\n (isOpenChange)=\"$event ? null : closeImageModal()\"\n>\n <div class=\"stream-chat-angular__image-modal\">\n <button\n class=\"stream-chat-angular__image-modal-stepper\"\n [ngStyle]=\"{\n visibility: isImageModalPrevButtonVisible ? 'visible' : 'hidden'\n }\"\n data-testid=\"image-modal-prev\"\n type=\"button\"\n (click)=\"stepImages(-1)\"\n (keyup.enter)=\"stepImages(-1)\"\n >\n <stream-icon icon=\"arrow-left\"></stream-icon>\n </button>\n <img\n class=\"stream-chat-angular__image-modal-image\"\n data-testid=\"modal-image\"\n [src]=\"\n imagesToView[imagesToViewCurrentIndex].img_url ||\n imagesToView[imagesToViewCurrentIndex].thumb_url ||\n imagesToView[imagesToViewCurrentIndex].image_url\n \"\n [alt]=\"imagesToView[imagesToViewCurrentIndex].fallback\"\n />\n <button\n class=\"stream-chat-angular__image-modal-stepper\"\n type=\"button\"\n [ngStyle]=\"{\n visibility: isImageModalNextButtonVisible ? 'visible' : 'hidden'\n }\"\n data-testid=\"image-modal-next\"\n (click)=\"stepImages(1)\"\n (keyup.enter)=\"stepImages(1)\"\n >\n <stream-icon icon=\"arrow-right\"></stream-icon>\n </button>\n </div>\n</stream-modal>\n", components: [{ type: IconComponent, selector: "stream-icon", inputs: ["icon", "size"] }, { type: ModalComponent, selector: "stream-modal", inputs: ["isOpen"], outputs: ["isOpenChange"] }], directives: [{ type: i6__namespace.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i6__namespace.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i6__namespace.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }], pipes: { "translate": i2__namespace.TranslatePipe } });
2830
+ AttachmentListComponent.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: AttachmentListComponent, deps: [{ token: CustomTemplatesService }, { token: ImageLoadService }, { token: ChannelService }], target: i0__namespace.ɵɵFactoryTarget.Component });
2831
+ AttachmentListComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: AttachmentListComponent, selector: "stream-attachment-list", inputs: { messageId: "messageId", attachments: "attachments" }, viewQueries: [{ propertyName: "modalContent", first: true, predicate: ["modalContent"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0__namespace, template: "<ng-container *ngFor=\"let attachment of orderedAttachments; trackBy: trackById\">\n <div\n data-testclass=\"attachment-container\"\n class=\"str-chat__message-attachment str-chat__message-attachment--{{\n attachment.type\n }}\"\n [class.str-chat__message-attachment--card]=\"isCard(attachment)\"\n [class.str-chat-angular__message-attachment-file-single]=\"\n isFile(attachment)\n \"\n >\n <img\n *ngIf=\"isImage(attachment)\"\n class=\"str-chat__message-attachment--img\"\n data-testclass=\"image\"\n [src]=\"attachment.img_url || attachment.thumb_url || attachment.image_url\"\n [alt]=\"attachment?.fallback\"\n (load)=\"imageLoaded()\"\n (click)=\"openImageModal([attachment])\"\n (keyup.enter)=\"openImageModal([attachment])\"\n />\n <div\n class=\"str-chat__gallery\"\n data-testid=\"image-gallery\"\n *ngIf=\"isGallery(attachment)\"\n [class.str-chat__gallery--square]=\"(attachment?.images)!.length > 3\"\n >\n <ng-container\n *ngFor=\"\n let galleryImage of attachment.images;\n let index = index;\n let isLast = last;\n trackBy: trackByImageUrl\n \"\n >\n <button\n *ngIf=\"index < 3 || (index === 3 && isLast)\"\n class=\"str-chat__gallery-image\"\n data-testclass=\"gallery-image\"\n (click)=\"openImageModal(attachment.images!, index)\"\n (keyup.enter)=\"openImageModal(attachment.images!, index)\"\n >\n <img\n [src]=\"\n galleryImage.img_url ||\n galleryImage.thumb_url ||\n galleryImage.image_url\n \"\n [alt]=\"galleryImage.fallback\"\n (load)=\"imageLoaded()\"\n />\n </button>\n <button\n *ngIf=\"index === 3 && !isLast\"\n class=\"str-chat__gallery-placeholder\"\n data-testclass=\"gallery-image\"\n (click)=\"openImageModal(attachment.images!, index)\"\n (keyup.enter)=\"openImageModal(attachment.images!, index)\"\n [ngStyle]=\"{\n 'background-image':\n 'url(' +\n (galleryImage.img_url ||\n galleryImage.thumb_url ||\n galleryImage.image_url) +\n ')'\n }\"\n >\n <p\n [innerHTML]=\"\n 'streamChat.{{ imageCount }} more'\n | translate: { imageCount: attachment!.images!.length - 4 }\n \"\n ></p>\n </button>\n </ng-container>\n </div>\n <div\n *ngIf=\"isFile(attachment)\"\n class=\"\n str-chat__message-attachment-file--item\n str-chat-angular__message-attachment-file-single\n \"\n >\n <stream-icon-placeholder\n icon=\"file\"\n [size]=\"30\"\n ></stream-icon-placeholder>\n <div class=\"str-chat__message-attachment-file--item-text\">\n <a\n data-testclass=\"file-link\"\n download\n href=\"{{ attachment.asset_url }}\"\n target=\"_blank\"\n >\n {{ attachment.title }}\n </a>\n <span data-testclass=\"size\" *ngIf=\"hasFileSize(attachment)\">{{\n getFileSize(attachment)\n }}</span>\n </div>\n </div>\n <div\n *ngIf=\"isCard(attachment)\"\n class=\"str-chat__message-attachment-card str-chat__message-attachment-card--{{\n attachment.type\n }}\"\n >\n <div\n *ngIf=\"attachment.image_url || attachment.thumb_url\"\n class=\"str-chat__message-attachment-card--header\"\n >\n <img\n data-testclass=\"card-img\"\n alt=\"{{ attachment.image_url || attachment.thumb_url }}\"\n src=\"{{ attachment.image_url || attachment.thumb_url }}\"\n />\n </div>\n <div class=\"str-chat__message-attachment-card--content\">\n <div class=\"str-chat__message-attachment-card--flex\">\n <div\n *ngIf=\"attachment.title\"\n data-testclass=\"card-title\"\n class=\"str-chat__message-attachment-card--title\"\n >\n {{ attachment.title }}\n </div>\n <div\n *ngIf=\"attachment.text\"\n class=\"str-chat__message-attachment-card--text\"\n data-testclass=\"card-text\"\n >\n {{ attachment.text }}\n </div>\n <a\n class=\"str-chat__message-attachment-card--url\"\n *ngIf=\"attachment.title_link || attachment.og_scrape_url\"\n data-testclass=\"url-link\"\n noopener\n noreferrer\n href=\"{{ attachment.title_link || attachment.og_scrape_url }}\"\n target=\"_blank\"\n >\n {{ trimUrl(attachment.title_link || attachment.og_scrape_url) }}\n </a>\n </div>\n </div>\n </div>\n <div\n class=\"str-chat__message-attachment-actions\"\n *ngIf=\"attachment.actions && attachment.actions.length > 0\"\n >\n <div class=\"str-chat__message-attachment-actions-form\">\n <button\n *ngFor=\"let action of attachment.actions; trackBy: trackByActionValue\"\n class=\"str-chat__message-attachment-actions-button str-chat__message-attachment-actions-button--{{\n action.style\n }}\"\n data-testclass=\"attachment-action\"\n (click)=\"sendAction(action)\"\n (keyup.enter)=\"sendAction(action)\"\n >\n {{ action.text }}\n </button>\n </div>\n </div>\n </div>\n</ng-container>\n\n<ng-container *ngIf=\"imagesToView && imagesToView.length > 0\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.modalTemplate$ | async) || defaultModal;\n context: getModalContext()\n \"\n ></ng-container>\n</ng-container>\n\n<ng-template\n #defaultModal\n let-isOpen=\"isOpen\"\n let-isOpenChangeHandler=\"isOpenChangeHandler\"\n let-content=\"content\"\n>\n <stream-modal\n [isOpen]=\"isOpen\"\n (isOpenChange)=\"isOpenChangeHandler($event)\"\n [content]=\"content\"\n >\n </stream-modal>\n</ng-template>\n\n<ng-template #modalContent>\n <div class=\"stream-chat-angular__image-modal\">\n <button\n class=\"stream-chat-angular__image-modal-stepper\"\n [ngStyle]=\"{\n visibility: isImageModalPrevButtonVisible ? 'visible' : 'hidden'\n }\"\n data-testid=\"image-modal-prev\"\n type=\"button\"\n (click)=\"stepImages(-1)\"\n (keyup.enter)=\"stepImages(-1)\"\n >\n <stream-icon-placeholder icon=\"arrow-left\"></stream-icon-placeholder>\n </button>\n <img\n class=\"stream-chat-angular__image-modal-image\"\n data-testid=\"modal-image\"\n [src]=\"\n imagesToView[imagesToViewCurrentIndex].img_url ||\n imagesToView[imagesToViewCurrentIndex].thumb_url ||\n imagesToView[imagesToViewCurrentIndex].image_url\n \"\n [alt]=\"imagesToView[imagesToViewCurrentIndex].fallback\"\n />\n <button\n class=\"stream-chat-angular__image-modal-stepper\"\n type=\"button\"\n [ngStyle]=\"{\n visibility: isImageModalNextButtonVisible ? 'visible' : 'hidden'\n }\"\n data-testid=\"image-modal-next\"\n (click)=\"stepImages(1)\"\n (keyup.enter)=\"stepImages(1)\"\n >\n <stream-icon-placeholder icon=\"arrow-right\"></stream-icon-placeholder>\n </button>\n </div>\n</ng-template>\n", components: [{ type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon", "size"] }, { type: ModalComponent, selector: "stream-modal", inputs: ["isOpen", "content"], outputs: ["isOpenChange"] }], directives: [{ type: i3__namespace.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i3__namespace.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3__namespace.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { type: i3__namespace.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], pipes: { "translate": i2__namespace.TranslatePipe, "async": i3__namespace.AsyncPipe } });
2625
2832
  i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: AttachmentListComponent, decorators: [{
2626
2833
  type: i0.Component,
2627
2834
  args: [{
@@ -2629,51 +2836,42 @@
2629
2836
  templateUrl: './attachment-list.component.html',
2630
2837
  styles: [],
2631
2838
  }]
2632
- }], ctorParameters: function () { return [{ type: ImageLoadService }, { type: ChannelService }]; }, propDecorators: { messageId: [{
2839
+ }], ctorParameters: function () { return [{ type: CustomTemplatesService }, { type: ImageLoadService }, { type: ChannelService }]; }, propDecorators: { messageId: [{
2633
2840
  type: i0.Input
2634
2841
  }], attachments: [{
2635
2842
  type: i0.Input
2843
+ }], modalContent: [{
2844
+ type: i0.ViewChild,
2845
+ args: ['modalContent', { static: true }]
2636
2846
  }] } });
2637
2847
 
2638
2848
  /**
2639
2849
  * The `AttachmentPreviewList` compontent displays a preview of the attachments uploaded to a message. Users can delete attachments using the preview component, or retry upload if it failed previously.
2640
2850
  */
2641
2851
  var AttachmentPreviewListComponent = /** @class */ (function () {
2642
- function AttachmentPreviewListComponent(attachmentService) {
2643
- this.attachmentService = attachmentService;
2644
- this.attachmentUploads$ = this.attachmentService.attachmentUploads$;
2645
- }
2646
- AttachmentPreviewListComponent.prototype.retryAttachmentUpload = function (file) {
2647
- return __awaiter(this, void 0, void 0, function () {
2648
- return __generator(this, function (_a) {
2649
- switch (_a.label) {
2650
- case 0: return [4 /*yield*/, this.attachmentService.retryAttachmentUpload(file)];
2651
- case 1:
2652
- _a.sent();
2653
- return [2 /*return*/];
2654
- }
2655
- });
2656
- });
2852
+ function AttachmentPreviewListComponent() {
2853
+ /**
2854
+ * An output to notify the parent component if the user tries to retry a failed upload
2855
+ */
2856
+ this.retryAttachmentUpload = new i0.EventEmitter();
2857
+ /**
2858
+ * An output to notify the parent component if the user wants to delete a file
2859
+ */
2860
+ this.deleteAttachment = new i0.EventEmitter();
2861
+ }
2862
+ AttachmentPreviewListComponent.prototype.attachmentUploadRetried = function (file) {
2863
+ this.retryAttachmentUpload.emit(file);
2657
2864
  };
2658
- AttachmentPreviewListComponent.prototype.deleteAttachment = function (upload) {
2659
- return __awaiter(this, void 0, void 0, function () {
2660
- return __generator(this, function (_a) {
2661
- switch (_a.label) {
2662
- case 0: return [4 /*yield*/, this.attachmentService.deleteAttachment(upload)];
2663
- case 1:
2664
- _a.sent();
2665
- return [2 /*return*/];
2666
- }
2667
- });
2668
- });
2865
+ AttachmentPreviewListComponent.prototype.attachmentDeleted = function (upload) {
2866
+ this.deleteAttachment.emit(upload);
2669
2867
  };
2670
2868
  AttachmentPreviewListComponent.prototype.trackByFile = function (_, item) {
2671
2869
  return item.file;
2672
2870
  };
2673
2871
  return AttachmentPreviewListComponent;
2674
2872
  }());
2675
- AttachmentPreviewListComponent.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: AttachmentPreviewListComponent, deps: [{ token: AttachmentService }], target: i0__namespace.ɵɵFactoryTarget.Component });
2676
- AttachmentPreviewListComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: AttachmentPreviewListComponent, selector: "stream-attachment-preview-list", ngImport: i0__namespace, template: "<div class=\"rfu-image-previewer\" *ngIf=\"(attachmentUploads$ | async)?.length\">\n <ng-container\n *ngFor=\"\n let attachmentUpload of attachmentUploads$ | async;\n trackBy: trackByFile\n \"\n >\n <div\n *ngIf=\"attachmentUpload.type === 'image'\"\n class=\"rfu-image-previewer__image\"\n [class.rfu-image-previewer__image--loaded]=\"\n attachmentUpload.state === 'success'\n \"\n data-testclass=\"attachment-image-preview\"\n >\n <div\n *ngIf=\"attachmentUpload.state === 'error'\"\n class=\"rfu-image-previewer__retry\"\n (click)=\"retryAttachmentUpload(attachmentUpload.file)\"\n (keyup.enter)=\"retryAttachmentUpload(attachmentUpload.file)\"\n data-testclass=\"upload-error\"\n >\n <stream-icon icon=\"retry\"></stream-icon>\n </div>\n <div class=\"rfu-thumbnail__wrapper\" style=\"width: 100; height: 100\">\n <div class=\"rfu-thumbnail__overlay\">\n <div\n class=\"rfu-icon-button\"\n data-testclass=\"delete-attachment\"\n role=\"button\"\n (click)=\"deleteAttachment(attachmentUpload)\"\n (keyup.enter)=\"deleteAttachment(attachmentUpload)\"\n >\n <stream-icon icon=\"close\"></stream-icon>\n </div>\n </div>\n <img\n *ngIf=\"attachmentUpload.url || attachmentUpload.previewUri\"\n src=\"{{\n attachmentUpload.url\n ? attachmentUpload.url\n : attachmentUpload.previewUri\n }}\"\n alt=\"attachmentUpload.file.name\"\n class=\"rfu-thumbnail__image\"\n data-testclass=\"attachment-image\"\n />\n </div>\n <stream-loading-indicator\n data-testclass=\"loading-indicator\"\n color=\"rgba(255,255,255,0.7)\"\n *ngIf=\"attachmentUpload.state === 'uploading'\"\n ></stream-loading-indicator>\n </div>\n <div\n class=\"rfu-file-previewer\"\n *ngIf=\"attachmentUpload.type === 'file'\"\n data-testclass=\"attachment-file-preview\"\n >\n <ol>\n <li\n class=\"rfu-file-previewer__file\"\n [class.rfu-file-previewer__file--uploading]=\"\n attachmentUpload.state === 'uploading'\n \"\n [class.rfu-file-previewer__file--failed]=\"\n attachmentUpload.state === 'error'\n \"\n >\n <stream-icon icon=\"file\"></stream-icon>\n\n <a\n data-testclass=\"file-download-link\"\n href=\"{{ attachmentUpload.url }}\"\n (click)=\"attachmentUpload.url ? null : $event.preventDefault()\"\n (keyup.enter)=\"\n attachmentUpload.url ? null : $event.preventDefault()\n \"\n download\n >\n {{ attachmentUpload.file.name }}\n <ng-container *ngIf=\"attachmentUpload.state === 'error'\">\n <div\n data-testclass=\"file-upload-retry\"\n class=\"rfu-file-previewer__failed\"\n (click)=\"retryAttachmentUpload(attachmentUpload.file)\"\n (keyup.enter)=\"retryAttachmentUpload(attachmentUpload.file)\"\n translate\n >\n streamChat.failed\n </div>\n <div\n class=\"rfu-file-previewer__retry\"\n (click)=\"retryAttachmentUpload(attachmentUpload.file)\"\n (keyup.enter)=\"retryAttachmentUpload(attachmentUpload.file)\"\n translate\n >\n streamChat.retry\n </div>\n </ng-container>\n </a>\n\n <span\n data-testclass=\"file-delete\"\n class=\"rfu-file-previewer__close-button\"\n (click)=\"deleteAttachment(attachmentUpload)\"\n (keyup.enter)=\"deleteAttachment(attachmentUpload)\"\n >\n \u2718\n </span>\n <div\n *ngIf=\"attachmentUpload.state === 'uploading'\"\n class=\"rfu-file-previewer__loading-indicator\"\n >\n <stream-loading-indicator></stream-loading-indicator>\n </div>\n </li>\n </ol>\n </div>\n </ng-container>\n</div>\n", components: [{ type: IconComponent, selector: "stream-icon", inputs: ["icon", "size"] }, { type: LoadingIndicatorComponent, selector: "stream-loading-indicator", inputs: ["size", "color"] }], directives: [{ type: i6__namespace.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i6__namespace.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2__namespace.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }], pipes: { "async": i6__namespace.AsyncPipe } });
2873
+ AttachmentPreviewListComponent.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: AttachmentPreviewListComponent, deps: [], target: i0__namespace.ɵɵFactoryTarget.Component });
2874
+ AttachmentPreviewListComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: AttachmentPreviewListComponent, selector: "stream-attachment-preview-list", inputs: { attachmentUploads$: "attachmentUploads$" }, outputs: { retryAttachmentUpload: "retryAttachmentUpload", deleteAttachment: "deleteAttachment" }, ngImport: i0__namespace, template: "<div class=\"rfu-image-previewer\" *ngIf=\"(attachmentUploads$ | async)?.length\">\n <ng-container\n *ngFor=\"\n let attachmentUpload of attachmentUploads$ | async;\n trackBy: trackByFile\n \"\n >\n <div\n *ngIf=\"attachmentUpload.type === 'image'\"\n class=\"rfu-image-previewer__image\"\n [class.rfu-image-previewer__image--loaded]=\"\n attachmentUpload.state === 'success'\n \"\n data-testclass=\"attachment-image-preview\"\n >\n <div\n *ngIf=\"attachmentUpload.state === 'error'\"\n class=\"rfu-image-previewer__retry\"\n (click)=\"attachmentUploadRetried(attachmentUpload.file)\"\n (keyup.enter)=\"attachmentUploadRetried(attachmentUpload.file)\"\n data-testclass=\"upload-error\"\n >\n <stream-icon-placeholder icon=\"retry\"></stream-icon-placeholder>\n </div>\n <div class=\"rfu-thumbnail__wrapper\" style=\"width: 100; height: 100\">\n <div class=\"rfu-thumbnail__overlay\">\n <div\n class=\"rfu-icon-button\"\n data-testclass=\"delete-attachment\"\n role=\"button\"\n (click)=\"attachmentDeleted(attachmentUpload)\"\n (keyup.enter)=\"attachmentDeleted(attachmentUpload)\"\n >\n <stream-icon-placeholder icon=\"close\"></stream-icon-placeholder>\n </div>\n </div>\n <img\n *ngIf=\"attachmentUpload.url || attachmentUpload.previewUri\"\n src=\"{{\n attachmentUpload.url\n ? attachmentUpload.url\n : attachmentUpload.previewUri\n }}\"\n alt=\"attachmentUpload.file.name\"\n class=\"rfu-thumbnail__image\"\n data-testclass=\"attachment-image\"\n />\n </div>\n <stream-loading-indicator-placeholder\n data-testclass=\"loading-indicator\"\n color=\"rgba(255,255,255,0.7)\"\n *ngIf=\"attachmentUpload.state === 'uploading'\"\n ></stream-loading-indicator-placeholder>\n </div>\n <div\n class=\"rfu-file-previewer\"\n *ngIf=\"attachmentUpload.type === 'file'\"\n data-testclass=\"attachment-file-preview\"\n >\n <ol>\n <li\n class=\"rfu-file-previewer__file\"\n [class.rfu-file-previewer__file--uploading]=\"\n attachmentUpload.state === 'uploading'\n \"\n [class.rfu-file-previewer__file--failed]=\"\n attachmentUpload.state === 'error'\n \"\n >\n <stream-icon-placeholder icon=\"file\"></stream-icon-placeholder>\n\n <a\n data-testclass=\"file-download-link\"\n href=\"{{ attachmentUpload.url }}\"\n (click)=\"attachmentUpload.url ? null : $event.preventDefault()\"\n (keyup.enter)=\"\n attachmentUpload.url ? null : $event.preventDefault()\n \"\n download\n >\n {{ attachmentUpload.file.name }}\n <ng-container *ngIf=\"attachmentUpload.state === 'error'\">\n <div\n data-testclass=\"file-upload-retry\"\n class=\"rfu-file-previewer__failed\"\n (click)=\"attachmentUploadRetried(attachmentUpload.file)\"\n (keyup.enter)=\"attachmentUploadRetried(attachmentUpload.file)\"\n translate\n >\n streamChat.failed\n </div>\n <div\n class=\"rfu-file-previewer__retry\"\n (click)=\"attachmentUploadRetried(attachmentUpload.file)\"\n (keyup.enter)=\"attachmentUploadRetried(attachmentUpload.file)\"\n translate\n >\n streamChat.retry\n </div>\n </ng-container>\n </a>\n\n <span\n data-testclass=\"file-delete\"\n class=\"rfu-file-previewer__close-button\"\n (click)=\"attachmentDeleted(attachmentUpload)\"\n (keyup.enter)=\"attachmentDeleted(attachmentUpload)\"\n >\n \u2718\n </span>\n <div\n *ngIf=\"attachmentUpload.state === 'uploading'\"\n class=\"rfu-file-previewer__loading-indicator\"\n >\n <stream-loading-indicator-placeholder></stream-loading-indicator-placeholder>\n </div>\n </li>\n </ol>\n </div>\n </ng-container>\n</div>\n", components: [{ type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon", "size"] }, { type: LoadingIndicatorPlaceholderComponent, selector: "stream-loading-indicator-placeholder", inputs: ["size", "color"] }], directives: [{ type: i3__namespace.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3__namespace.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2__namespace.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }], pipes: { "async": i3__namespace.AsyncPipe } });
2677
2875
  i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: AttachmentPreviewListComponent, decorators: [{
2678
2876
  type: i0.Component,
2679
2877
  args: [{
@@ -2681,13 +2879,19 @@
2681
2879
  templateUrl: './attachment-preview-list.component.html',
2682
2880
  styles: [],
2683
2881
  }]
2684
- }], ctorParameters: function () { return [{ type: AttachmentService }]; } });
2882
+ }], ctorParameters: function () { return []; }, propDecorators: { attachmentUploads$: [{
2883
+ type: i0.Input
2884
+ }], retryAttachmentUpload: [{
2885
+ type: i0.Output
2886
+ }], deleteAttachment: [{
2887
+ type: i0.Output
2888
+ }] } });
2685
2889
 
2686
2890
  /**
2687
2891
  * The `MessageInput` component displays an input where users can type their messages and upload files, and sends the message to the active channel. The component can be used to compose new messages or update existing ones. To send messages, the chat user needs to have the necessary [channel capability](https://getstream.io/chat/docs/javascript/channel_capabilities/?language=javascript).
2688
2892
  */
2689
2893
  var MessageInputComponent = /** @class */ (function () {
2690
- function MessageInputComponent(channelService, notificationService, attachmentService, configService, textareaType, componentFactoryResolver, cdRef, chatClient, emojiInputService) {
2894
+ function MessageInputComponent(channelService, notificationService, attachmentService, configService, textareaType, componentFactoryResolver, cdRef, chatClient, emojiInputService, customTemplatesService) {
2691
2895
  var _this = this;
2692
2896
  this.channelService = channelService;
2693
2897
  this.notificationService = notificationService;
@@ -2698,6 +2902,7 @@
2698
2902
  this.cdRef = cdRef;
2699
2903
  this.chatClient = chatClient;
2700
2904
  this.emojiInputService = emojiInputService;
2905
+ this.customTemplatesService = customTemplatesService;
2701
2906
  /**
2702
2907
  * Determines if the message is being dispalyed in a channel or in a [thread](https://getstream.io/chat/docs/javascript/threads/?language=javascript).
2703
2908
  */
@@ -2742,16 +2947,10 @@
2742
2947
  }));
2743
2948
  this.attachmentUploads$ = this.attachmentService.attachmentUploads$;
2744
2949
  this.isFileUploadEnabled = this.configService.isFileUploadEnabled;
2745
- this.acceptedFileTypes = this.configService.acceptedFileTypes;
2746
2950
  this.isMultipleFileUploadEnabled =
2747
2951
  this.configService.isMultipleFileUploadEnabled;
2748
2952
  this.areMentionsEnabled = this.configService.areMentionsEnabled;
2749
- this.mentionAutocompleteItemTemplate =
2750
- this.configService.mentionAutocompleteItemTemplate;
2751
2953
  this.mentionScope = this.configService.mentionScope;
2752
- this.commandAutocompleteItemTemplate =
2753
- this.configService.commandAutocompleteItemTemplate;
2754
- this.emojiPickerTemplate = this.configService.emojiPickerTemplate;
2755
2954
  this.subscriptions.push(this.typingStart$.subscribe(function () { return void _this.channelService.typingStarted(_this.parentMessageId); }));
2756
2955
  this.subscriptions.push(rxjs.combineLatest([
2757
2956
  this.channelService.latestMessageDateByUserByChannels$,
@@ -2778,11 +2977,23 @@
2778
2977
  }
2779
2978
  }));
2780
2979
  }
2980
+ MessageInputComponent.prototype.ngOnInit = function () {
2981
+ var _this = this;
2982
+ this.subscriptions.push(this.customTemplatesService.emojiPickerTemplate$.subscribe(function (template) {
2983
+ _this.emojiPickerTemplate = template;
2984
+ _this.cdRef.detectChanges();
2985
+ }));
2986
+ this.subscriptions.push(this.customTemplatesService.attachmentPreviewListTemplate$.subscribe(function (template) {
2987
+ _this.attachmentPreviewListTemplate = template;
2988
+ _this.cdRef.detectChanges();
2989
+ }));
2990
+ };
2781
2991
  MessageInputComponent.prototype.ngAfterViewInit = function () {
2782
2992
  this.isViewInited = true;
2783
2993
  this.initTextarea();
2784
2994
  };
2785
2995
  MessageInputComponent.prototype.ngOnChanges = function (changes) {
2996
+ var _this = this;
2786
2997
  if (changes.message) {
2787
2998
  this.attachmentService.resetAttachmentUploads();
2788
2999
  if (this.isUpdate) {
@@ -2793,9 +3004,6 @@
2793
3004
  if (changes.isFileUploadEnabled) {
2794
3005
  this.configService.isFileUploadEnabled = this.isFileUploadEnabled;
2795
3006
  }
2796
- if (changes.acceptedFileTypes) {
2797
- this.configService.acceptedFileTypes = this.acceptedFileTypes;
2798
- }
2799
3007
  if (changes.isMultipleFileUploadEnabled) {
2800
3008
  this.configService.isMultipleFileUploadEnabled =
2801
3009
  this.isMultipleFileUploadEnabled;
@@ -2803,25 +3011,25 @@
2803
3011
  if (changes.areMentionsEnabled) {
2804
3012
  this.configService.areMentionsEnabled = this.areMentionsEnabled;
2805
3013
  }
2806
- if (changes.mentionAutocompleteItemTemplate) {
2807
- this.configService.mentionAutocompleteItemTemplate =
2808
- this.mentionAutocompleteItemTemplate;
2809
- }
2810
- if (changes.commandAutocompleteItemTemplate) {
2811
- this.configService.commandAutocompleteItemTemplate =
2812
- this.commandAutocompleteItemTemplate;
2813
- }
2814
3014
  if (changes.mentionScope) {
2815
3015
  this.configService.mentionScope = this.mentionScope;
2816
3016
  }
2817
- if (changes.emojiPickerTemplate) {
2818
- this.configService.emojiPickerTemplate = this.emojiPickerTemplate;
2819
- }
2820
3017
  if (changes.mode) {
2821
3018
  this.setCanSendMessages();
2822
3019
  }
3020
+ if (changes.sendMessage$) {
3021
+ if (this.sendMessageSubcription) {
3022
+ this.sendMessageSubcription.unsubscribe();
3023
+ }
3024
+ if (this.sendMessage$) {
3025
+ this.sendMessageSubcription = this.sendMessage$.subscribe(function () { return void _this.messageSent(); });
3026
+ }
3027
+ }
2823
3028
  };
2824
3029
  MessageInputComponent.prototype.ngOnDestroy = function () {
3030
+ if (this.sendMessageSubcription) {
3031
+ this.sendMessageSubcription.unsubscribe();
3032
+ }
2825
3033
  this.subscriptions.forEach(function (s) { return s.unsubscribe(); });
2826
3034
  };
2827
3035
  MessageInputComponent.prototype.messageSent = function () {
@@ -2889,14 +3097,6 @@
2889
3097
  enumerable: false,
2890
3098
  configurable: true
2891
3099
  });
2892
- Object.defineProperty(MessageInputComponent.prototype, "accept", {
2893
- get: function () {
2894
- var _a;
2895
- return this.acceptedFileTypes ? (_a = this.acceptedFileTypes) === null || _a === void 0 ? void 0 : _a.join(',') : '';
2896
- },
2897
- enumerable: false,
2898
- configurable: true
2899
- });
2900
3100
  Object.defineProperty(MessageInputComponent.prototype, "quotedMessageAttachments", {
2901
3101
  get: function () {
2902
3102
  var _a;
@@ -2944,6 +3144,24 @@
2944
3144
  MessageInputComponent.prototype.deselectMessageToQuote = function () {
2945
3145
  this.channelService.selectMessageToQuote(undefined);
2946
3146
  };
3147
+ MessageInputComponent.prototype.getEmojiPickerContext = function () {
3148
+ return {
3149
+ emojiInput$: this.emojiInputService.emojiInput$,
3150
+ };
3151
+ };
3152
+ MessageInputComponent.prototype.getAttachmentPreviewListContext = function () {
3153
+ return {
3154
+ attachmentUploads$: this.attachmentService.attachmentUploads$,
3155
+ deleteUploadHandler: this.deleteUpload.bind(this),
3156
+ retryUploadHandler: this.retryUpload.bind(this),
3157
+ };
3158
+ };
3159
+ MessageInputComponent.prototype.deleteUpload = function (upload) {
3160
+ void this.attachmentService.deleteAttachment(upload);
3161
+ };
3162
+ MessageInputComponent.prototype.retryUpload = function (file) {
3163
+ void this.attachmentService.retryAttachmentUpload(file);
3164
+ };
2947
3165
  MessageInputComponent.prototype.clearFileInput = function () {
2948
3166
  this.fileInput.nativeElement.value = '';
2949
3167
  };
@@ -2970,7 +3188,7 @@
2970
3188
  return __generator(this, function (_12) {
2971
3189
  switch (_12.label) {
2972
3190
  case 0:
2973
- if (!fileList || this.acceptedFileTypes) {
3191
+ if (!fileList) {
2974
3192
  return [2 /*return*/, true];
2975
3193
  }
2976
3194
  if (!!this.appSettings) return [3 /*break*/, 2];
@@ -3071,8 +3289,8 @@
3071
3289
  };
3072
3290
  return MessageInputComponent;
3073
3291
  }());
3074
- MessageInputComponent.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: MessageInputComponent, deps: [{ token: ChannelService }, { token: NotificationService }, { token: AttachmentService }, { token: MessageInputConfigService }, { token: textareaInjectionToken }, { token: i0__namespace.ComponentFactoryResolver }, { token: i0__namespace.ChangeDetectorRef }, { token: ChatClientService }, { token: EmojiInputService }], target: i0__namespace.ɵɵFactoryTarget.Component });
3075
- MessageInputComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: MessageInputComponent, selector: "stream-message-input", inputs: { isFileUploadEnabled: "isFileUploadEnabled", areMentionsEnabled: "areMentionsEnabled", mentionScope: "mentionScope", mentionAutocompleteItemTemplate: "mentionAutocompleteItemTemplate", commandAutocompleteItemTemplate: "commandAutocompleteItemTemplate", emojiPickerTemplate: "emojiPickerTemplate", mode: "mode", acceptedFileTypes: "acceptedFileTypes", isMultipleFileUploadEnabled: "isMultipleFileUploadEnabled", message: "message" }, outputs: { messageUpdate: "messageUpdate" }, providers: [AttachmentService, EmojiInputService], viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true }, { propertyName: "textareaAnchor", first: true, predicate: TextareaDirective, descendants: true }], usesOnChanges: true, ngImport: i0__namespace, template: "<div\n class=\"{{\n mode === 'main' ? 'str-chat__input-flat' : 'str-chat__small-message-input'\n }}\"\n [class.str-chat__input-flat-has-attachments]=\"\n (attachmentUploads$ | async)!.length > 0\n \"\n [class.str-chat__input-flat-quoted]=\"!!quotedMessage\"\n>\n <div\n data-testid=\"quoted-message-container\"\n class=\"quoted-message-preview\"\n *ngIf=\"quotedMessage\"\n >\n <div class=\"quoted-message-preview-header\">\n <div>{{ \"streamChat.Reply to Message\" | translate }}</div>\n <button\n class=\"str-chat__square-button\"\n data-testid=\"remove-quote\"\n (click)=\"deselectMessageToQuote()\"\n (keyup.enter)=\"deselectMessageToQuote()\"\n >\n <stream-icon\n icon=\"close-no-outline\"\n style=\"font-size: 10px; line-height: 10px\"\n ></stream-icon>\n </button>\n </div>\n <div class=\"quoted-message-preview-content\">\n <stream-avatar\n data-testid=\"qouted-message-avatar\"\n class=\"str-chat-angular__avatar-host\"\n [imageUrl]=\"quotedMessage?.user?.image\"\n [name]=\"quotedMessage?.user?.name || quotedMessage?.user?.id\"\n [size]=\"20\"\n ></stream-avatar>\n <div class=\"quoted-message-preview-content-inner\">\n <stream-attachment-list\n *ngIf=\"\n quotedMessage?.attachments && quotedMessage?.attachments?.length\n \"\n [attachments]=\"quotedMessageAttachments\"\n [messageId]=\"quotedMessage?.id\"\n ></stream-attachment-list>\n <div\n data-testid=\"quoted-message-text\"\n [innerHTML]=\"quotedMessage?.html || quotedMessage?.text\"\n ></div>\n </div>\n </div>\n </div>\n <div class=\"str-chat__input-flat-wrapper\" style=\"width: 100%\">\n <div\n class=\"{{\n mode === 'main'\n ? 'str-chat__input-flat--textarea-wrapper'\n : 'str-chat__small-message-input--textarea-wrapper'\n }}\"\n >\n <stream-attachment-preview-list\n class=\"rfu-image-previewer-angular-host\"\n ></stream-attachment-preview-list>\n <div class=\"rta str-chat__textarea str-chat-angular__textarea\">\n <ng-container\n *ngIf=\"emojiPickerTemplate && !isCooldownInProgress\"\n data-testid=\"emoji-picker\"\n >\n <div\n class=\"\n str-chat__input-flat-emojiselect\n str-chat-angular__emojiselect\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n emojiPickerTemplate;\n context: { emojiInput$: emojiInputService.emojiInput$ }\n \"\n ></ng-container>\n </div>\n </ng-container>\n <div\n class=\"str-chat__input-flat-cooldown str-chat-angular__cooldown\"\n *ngIf=\"isCooldownInProgress\"\n data-testid=\"cooldown-timer\"\n >\n {{ cooldown$ | async }}\n </div>\n <ng-template\n *ngIf=\"canSendMessages && !isCooldownInProgress; else notAllowed\"\n streamTextarea\n [(value)]=\"textareaValue\"\n (valueChange)=\"typingStart$.next()\"\n (send)=\"messageSent()\"\n [componentRef]=\"textareaRef\"\n (userMentions)=\"mentionedUsers = $event\"\n [areMentionsEnabled]=\"areMentionsEnabled\"\n [mentionAutocompleteItemTemplate]=\"mentionAutocompleteItemTemplate\"\n [commandAutocompleteItemTemplate]=\"commandAutocompleteItemTemplate\"\n [mentionScope]=\"mentionScope\"\n ></ng-template>\n <ng-template #notAllowed>\n <textarea\n disabled\n rows=\"1\"\n [value]=\"disabledTextareaText | translate\"\n class=\"rta__textarea str-chat__textarea__textarea\"\n data-testid=\"disabled-textarea\"\n ></textarea>\n </ng-template>\n </div>\n <div\n *ngIf=\"\n isFileUploadEnabled &&\n isFileUploadAuthorized &&\n canSendMessages &&\n !isCooldownInProgress\n \"\n class=\"str-chat__fileupload-wrapper\"\n data-testid=\"file-upload-button\"\n >\n <div class=\"str-chat__tooltip\">\n {{ \"streamChat.Attach files\" | translate }}\n </div>\n <div class=\"rfu-file-upload-button\">\n <label>\n <input\n #fileInput\n type=\"file\"\n class=\"rfu-file-input\"\n data-testid=\"file-input\"\n [accept]=\"accept\"\n [multiple]=\"isMultipleFileUploadEnabled\"\n (change)=\"filesSelected(fileInput.files)\"\n />\n <span class=\"str-chat__input-flat-fileupload\">\n <stream-icon icon=\"file-upload\"></stream-icon>\n </span>\n </label>\n </div>\n </div>\n </div>\n <button\n *ngIf=\"canSendMessages\"\n data-testid=\"send-button\"\n class=\"str-chat__send-button\"\n (click)=\"messageSent()\"\n (keyup.enter)=\"messageSent()\"\n >\n <stream-icon icon=\"send\"></stream-icon>\n </button>\n </div>\n</div>\n", components: [{ type: IconComponent, selector: "stream-icon", inputs: ["icon", "size"] }, { type: AvatarComponent, selector: "stream-avatar", inputs: ["name", "imageUrl", "size"] }, { type: AttachmentListComponent, selector: "stream-attachment-list", inputs: ["messageId", "attachments"] }, { type: AttachmentPreviewListComponent, selector: "stream-attachment-preview-list" }], directives: [{ type: i6__namespace.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i6__namespace.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: TextareaDirective, selector: "[streamTextarea]", inputs: ["componentRef", "areMentionsEnabled", "mentionAutocompleteItemTemplate", "mentionScope", "commandAutocompleteItemTemplate", "value"], outputs: ["valueChange", "send", "userMentions"] }], pipes: { "async": i6__namespace.AsyncPipe, "translate": i2__namespace.TranslatePipe } });
3292
+ MessageInputComponent.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: MessageInputComponent, deps: [{ token: ChannelService }, { token: NotificationService }, { token: AttachmentService }, { token: MessageInputConfigService }, { token: textareaInjectionToken }, { token: i0__namespace.ComponentFactoryResolver }, { token: i0__namespace.ChangeDetectorRef }, { token: ChatClientService }, { token: EmojiInputService }, { token: CustomTemplatesService }], target: i0__namespace.ɵɵFactoryTarget.Component });
3293
+ MessageInputComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: MessageInputComponent, selector: "stream-message-input", inputs: { isFileUploadEnabled: "isFileUploadEnabled", areMentionsEnabled: "areMentionsEnabled", mentionScope: "mentionScope", mode: "mode", isMultipleFileUploadEnabled: "isMultipleFileUploadEnabled", message: "message", sendMessage$: "sendMessage$" }, outputs: { messageUpdate: "messageUpdate" }, providers: [AttachmentService, EmojiInputService], viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true }, { propertyName: "textareaAnchor", first: true, predicate: TextareaDirective, descendants: true }], usesOnChanges: true, ngImport: i0__namespace, template: "<div\n class=\"{{\n mode === 'main' ? 'str-chat__input-flat' : 'str-chat__small-message-input'\n }}\"\n [class.str-chat__input-flat-has-attachments]=\"\n (attachmentUploads$ | async)!.length > 0\n \"\n [class.str-chat__input-flat-quoted]=\"!!quotedMessage\"\n>\n <div\n data-testid=\"quoted-message-container\"\n class=\"quoted-message-preview\"\n *ngIf=\"quotedMessage\"\n >\n <div class=\"quoted-message-preview-header\">\n <div>{{ \"streamChat.Reply to Message\" | translate }}</div>\n <button\n class=\"str-chat__square-button\"\n data-testid=\"remove-quote\"\n (click)=\"deselectMessageToQuote()\"\n (keyup.enter)=\"deselectMessageToQuote()\"\n >\n <stream-icon-placeholder\n icon=\"close-no-outline\"\n style=\"font-size: 10px; line-height: 10px\"\n ></stream-icon-placeholder>\n </button>\n </div>\n <div class=\"quoted-message-preview-content\">\n <stream-avatar-placeholder\n data-testid=\"qouted-message-avatar\"\n class=\"str-chat-angular__avatar-host\"\n [imageUrl]=\"quotedMessage?.user?.image\"\n [name]=\"quotedMessage?.user?.name || quotedMessage?.user?.id\"\n [size]=\"20\"\n ></stream-avatar-placeholder>\n <div class=\"quoted-message-preview-content-inner\">\n <stream-attachment-list\n *ngIf=\"\n quotedMessage?.attachments && quotedMessage?.attachments?.length\n \"\n [attachments]=\"quotedMessageAttachments\"\n [messageId]=\"quotedMessage?.id\"\n ></stream-attachment-list>\n <div\n data-testid=\"quoted-message-text\"\n [innerHTML]=\"quotedMessage?.html || quotedMessage?.text\"\n ></div>\n </div>\n </div>\n </div>\n <div class=\"str-chat__input-flat-wrapper\" style=\"width: 100%\">\n <div\n class=\"{{\n mode === 'main'\n ? 'str-chat__input-flat--textarea-wrapper'\n : 'str-chat__small-message-input--textarea-wrapper'\n }}\"\n >\n <ng-template\n #defaultAttachmentsPreview\n let-attachmentUploads$=\"attachmentUploads$\"\n let-retryUploadHandler=\"retryUploadHandler\"\n let-deleteUploadHandler=\"deleteUploadHandler\"\n >\n <stream-attachment-preview-list\n [attachmentUploads$]=\"attachmentUploads$\"\n (retryAttachmentUpload)=\"retryUploadHandler($event)\"\n (deleteAttachment)=\"deleteUploadHandler($event)\"\n class=\"rfu-image-previewer-angular-host\"\n ></stream-attachment-preview-list>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n attachmentPreviewListTemplate || defaultAttachmentsPreview;\n context: getAttachmentPreviewListContext()\n \"\n ></ng-container>\n <div class=\"rta str-chat__textarea str-chat-angular__textarea\">\n <ng-container\n *ngIf=\"emojiPickerTemplate && !isCooldownInProgress\"\n data-testid=\"emoji-picker\"\n >\n <div\n class=\"\n str-chat__input-flat-emojiselect\n str-chat-angular__emojiselect\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n emojiPickerTemplate;\n context: getEmojiPickerContext()\n \"\n ></ng-container>\n </div>\n </ng-container>\n <div\n class=\"str-chat__input-flat-cooldown str-chat-angular__cooldown\"\n *ngIf=\"isCooldownInProgress\"\n data-testid=\"cooldown-timer\"\n >\n {{ cooldown$ | async }}\n </div>\n <ng-template\n *ngIf=\"canSendMessages && !isCooldownInProgress; else notAllowed\"\n streamTextarea\n [(value)]=\"textareaValue\"\n (valueChange)=\"typingStart$.next()\"\n (send)=\"messageSent()\"\n [componentRef]=\"textareaRef\"\n (userMentions)=\"mentionedUsers = $event\"\n [areMentionsEnabled]=\"areMentionsEnabled\"\n [mentionScope]=\"mentionScope\"\n ></ng-template>\n <ng-template #notAllowed>\n <textarea\n disabled\n rows=\"1\"\n [value]=\"disabledTextareaText | translate\"\n class=\"rta__textarea str-chat__textarea__textarea\"\n data-testid=\"disabled-textarea\"\n ></textarea>\n </ng-template>\n </div>\n <div\n *ngIf=\"\n isFileUploadEnabled &&\n isFileUploadAuthorized &&\n canSendMessages &&\n !isCooldownInProgress\n \"\n class=\"str-chat__fileupload-wrapper\"\n data-testid=\"file-upload-button\"\n >\n <div class=\"str-chat__tooltip\">\n {{ \"streamChat.Attach files\" | translate }}\n </div>\n <div class=\"rfu-file-upload-button\">\n <label>\n <input\n #fileInput\n type=\"file\"\n class=\"rfu-file-input\"\n data-testid=\"file-input\"\n [multiple]=\"isMultipleFileUploadEnabled\"\n (change)=\"filesSelected(fileInput.files)\"\n />\n <span class=\"str-chat__input-flat-fileupload\">\n <stream-icon-placeholder\n icon=\"file-upload\"\n ></stream-icon-placeholder>\n </span>\n </label>\n </div>\n </div>\n </div>\n <button\n *ngIf=\"canSendMessages\"\n data-testid=\"send-button\"\n class=\"str-chat__send-button\"\n (click)=\"messageSent()\"\n (keyup.enter)=\"messageSent()\"\n >\n <stream-icon-placeholder icon=\"send\"></stream-icon-placeholder>\n </button>\n </div>\n</div>\n", components: [{ type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon", "size"] }, { type: AvatarPlaceholderComponent, selector: "stream-avatar-placeholder", inputs: ["name", "imageUrl", "size"] }, { type: AttachmentListComponent, selector: "stream-attachment-list", inputs: ["messageId", "attachments"] }, { type: AttachmentPreviewListComponent, selector: "stream-attachment-preview-list", inputs: ["attachmentUploads$"], outputs: ["retryAttachmentUpload", "deleteAttachment"] }], directives: [{ type: i3__namespace.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3__namespace.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: TextareaDirective, selector: "[streamTextarea]", inputs: ["componentRef", "areMentionsEnabled", "mentionScope", "value"], outputs: ["valueChange", "send", "userMentions"] }], pipes: { "async": i3__namespace.AsyncPipe, "translate": i2__namespace.TranslatePipe } });
3076
3294
  i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: MessageInputComponent, decorators: [{
3077
3295
  type: i0.Component,
3078
3296
  args: [{
@@ -3085,27 +3303,21 @@
3085
3303
  return [{ type: ChannelService }, { type: NotificationService }, { type: AttachmentService }, { type: MessageInputConfigService }, { type: i0__namespace.Type, decorators: [{
3086
3304
  type: i0.Inject,
3087
3305
  args: [textareaInjectionToken]
3088
- }] }, { type: i0__namespace.ComponentFactoryResolver }, { type: i0__namespace.ChangeDetectorRef }, { type: ChatClientService }, { type: EmojiInputService }];
3306
+ }] }, { type: i0__namespace.ComponentFactoryResolver }, { type: i0__namespace.ChangeDetectorRef }, { type: ChatClientService }, { type: EmojiInputService }, { type: CustomTemplatesService }];
3089
3307
  }, propDecorators: { isFileUploadEnabled: [{
3090
3308
  type: i0.Input
3091
3309
  }], areMentionsEnabled: [{
3092
3310
  type: i0.Input
3093
3311
  }], mentionScope: [{
3094
3312
  type: i0.Input
3095
- }], mentionAutocompleteItemTemplate: [{
3096
- type: i0.Input
3097
- }], commandAutocompleteItemTemplate: [{
3098
- type: i0.Input
3099
- }], emojiPickerTemplate: [{
3100
- type: i0.Input
3101
3313
  }], mode: [{
3102
3314
  type: i0.Input
3103
- }], acceptedFileTypes: [{
3104
- type: i0.Input
3105
3315
  }], isMultipleFileUploadEnabled: [{
3106
3316
  type: i0.Input
3107
3317
  }], message: [{
3108
3318
  type: i0.Input
3319
+ }], sendMessage$: [{
3320
+ type: i0.Input
3109
3321
  }], messageUpdate: [{
3110
3322
  type: i0.Output
3111
3323
  }], fileInput: [{
@@ -3125,7 +3337,7 @@
3125
3337
  return NotificationComponent;
3126
3338
  }());
3127
3339
  NotificationComponent.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: NotificationComponent, deps: [], target: i0__namespace.ɵɵFactoryTarget.Component });
3128
- NotificationComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: NotificationComponent, selector: "stream-notification", inputs: { type: "type" }, ngImport: i0__namespace, template: "<div\n class=\"str-chat__custom-notification notification-{{ type }}\"\n data-testid=\"custom-notification\"\n>\n <ng-content></ng-content>\n</div>\n" });
3340
+ NotificationComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: NotificationComponent, selector: "stream-notification", inputs: { type: "type", content: "content" }, ngImport: i0__namespace, template: "<div\n class=\"str-chat__custom-notification notification-{{ type }}\"\n data-testid=\"custom-notification\"\n>\n <ng-container *ngIf=\"content; else elseContent\">\n <ng-container *ngTemplateOutlet=\"content\"></ng-container>\n </ng-container>\n <ng-template #elseContent>\n <ng-content></ng-content>\n </ng-template>\n</div>\n", directives: [{ type: i3__namespace.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3__namespace.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }] });
3129
3341
  i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: NotificationComponent, decorators: [{
3130
3342
  type: i0.Component,
3131
3343
  args: [{
@@ -3135,26 +3347,29 @@
3135
3347
  }]
3136
3348
  }], ctorParameters: function () { return []; }, propDecorators: { type: [{
3137
3349
  type: i0.Input
3350
+ }], content: [{
3351
+ type: i0.Input
3138
3352
  }] } });
3139
3353
 
3140
3354
  /**
3141
3355
  * The `NotificationList` component displays the list of active notifications.
3142
3356
  */
3143
3357
  var NotificationListComponent = /** @class */ (function () {
3144
- function NotificationListComponent(notificationService) {
3358
+ function NotificationListComponent(customTemplatesService, notificationService) {
3359
+ this.customTemplatesService = customTemplatesService;
3145
3360
  this.notificationService = notificationService;
3146
3361
  this.notifications$ = this.notificationService.notifications$;
3147
3362
  }
3148
3363
  NotificationListComponent.prototype.trackById = function (_, item) {
3149
3364
  return item.id;
3150
3365
  };
3151
- NotificationListComponent.prototype.getTemplateContext = function (notification) {
3366
+ NotificationListComponent.prototype.getNotificationContentContext = function (notification) {
3152
3367
  return Object.assign(Object.assign({}, notification.templateContext), { dismissFn: notification.dismissFn });
3153
3368
  };
3154
3369
  return NotificationListComponent;
3155
3370
  }());
3156
- NotificationListComponent.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: NotificationListComponent, deps: [{ token: NotificationService }], target: i0__namespace.ɵɵFactoryTarget.Component });
3157
- NotificationListComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: NotificationListComponent, selector: "stream-notification-list", ngImport: i0__namespace, template: "<div class=\"str-chat__list-notifications\">\n <stream-notification\n *ngFor=\"let notification of notifications$ | async; trackBy: trackById\"\n [type]=\"notification.type\"\n >\n <div\n *ngIf=\"notification.text !== undefined\"\n data-testclass=\"notification-content\"\n >\n {{ notification.text | translate: notification.translateParams }}\n </div>\n <ng-container *ngIf=\"notification.template !== undefined\">\n <ng-container\n *ngTemplateOutlet=\"\n notification.template;\n context: getTemplateContext(notification)\n \"\n ></ng-container>\n </ng-container>\n </stream-notification>\n</div>\n", components: [{ type: NotificationComponent, selector: "stream-notification", inputs: ["type"] }], directives: [{ type: i6__namespace.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i6__namespace.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i6__namespace.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], pipes: { "async": i6__namespace.AsyncPipe, "translate": i2__namespace.TranslatePipe } });
3371
+ NotificationListComponent.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: NotificationListComponent, deps: [{ token: CustomTemplatesService }, { token: NotificationService }], target: i0__namespace.ɵɵFactoryTarget.Component });
3372
+ NotificationListComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: NotificationListComponent, selector: "stream-notification-list", ngImport: i0__namespace, template: "<div class=\"str-chat__list-notifications\">\n <ng-container\n *ngFor=\"let notification of notifications$ | async; trackBy: trackById\"\n >\n <ng-template #notificationContent>\n <div\n *ngIf=\"notification.text !== undefined\"\n data-testclass=\"notification-content\"\n >\n {{ notification.text | translate: notification.translateParams }}\n </div>\n <ng-container *ngIf=\"notification.template !== undefined\">\n <ng-container\n *ngTemplateOutlet=\"\n notification.template;\n context: getNotificationContentContext(notification)\n \"\n ></ng-container>\n </ng-container>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.notificationTemplate$ | async) ||\n defaultNotification;\n context: { type: notification.type, content: notificationContent }\n \"\n ></ng-container>\n </ng-container>\n</div>\n\n<ng-template #defaultNotification let-type=\"type\" let-content=\"content\">\n <stream-notification [type]=\"type\" [content]=\"content\"></stream-notification>\n</ng-template>\n", components: [{ type: NotificationComponent, selector: "stream-notification", inputs: ["type", "content"] }], directives: [{ type: i3__namespace.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i3__namespace.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3__namespace.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], pipes: { "async": i3__namespace.AsyncPipe, "translate": i2__namespace.TranslatePipe } });
3158
3373
  i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: NotificationListComponent, decorators: [{
3159
3374
  type: i0.Component,
3160
3375
  args: [{
@@ -3162,17 +3377,18 @@
3162
3377
  templateUrl: './notification-list.component.html',
3163
3378
  styles: [],
3164
3379
  }]
3165
- }], ctorParameters: function () { return [{ type: NotificationService }]; } });
3380
+ }], ctorParameters: function () { return [{ type: CustomTemplatesService }, { type: NotificationService }]; } });
3166
3381
 
3167
3382
  /**
3168
3383
  * 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.
3169
3384
  */
3170
3385
  var MessageActionsBoxComponent = /** @class */ (function () {
3171
- function MessageActionsBoxComponent(chatClientService, notificationService, channelService) {
3386
+ function MessageActionsBoxComponent(chatClientService, notificationService, channelService, customTemplatesService) {
3172
3387
  var _this = this;
3173
3388
  this.chatClientService = chatClientService;
3174
3389
  this.notificationService = notificationService;
3175
3390
  this.channelService = channelService;
3391
+ this.customTemplatesService = customTemplatesService;
3176
3392
  /**
3177
3393
  * 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.
3178
3394
  */
@@ -3194,152 +3410,145 @@
3194
3410
  */
3195
3411
  this.isEditing = new i0.EventEmitter();
3196
3412
  this.isEditModalOpen = false;
3413
+ this.subscriptions = [];
3414
+ this.visibleMessageActionItems = [];
3415
+ this.sendMessageSubject = new rxjs.Subject();
3197
3416
  this.modalClosed = function () {
3198
3417
  _this.isEditModalOpen = false;
3199
3418
  _this.isEditing.emit(false);
3200
3419
  };
3420
+ this.subscriptions.push(this.customTemplatesService.messageInputTemplate$.subscribe(function (template) { return (_this.messageInputTemplate = template); }));
3421
+ this.subscriptions.push(this.customTemplatesService.messageActionsBoxItemTemplate$.subscribe(function (template) { return (_this.messageActionItemTemplate = template); }));
3422
+ this.subscriptions.push(this.customTemplatesService.modalTemplate$.subscribe(function (template) { return (_this.modalTemplate = template); }));
3423
+ this.messageActionItems = [
3424
+ {
3425
+ actionName: 'quote',
3426
+ actionLabelOrTranslationKey: 'streamChat.Reply',
3427
+ actionHandler: function (message) { return _this.channelService.selectMessageToQuote(message); },
3428
+ isVisible: function (enabledActions, isMine, message) { return enabledActions.indexOf('quote-message') !== -1 &&
3429
+ !(message === null || message === void 0 ? void 0 : message.quoted_message); },
3430
+ },
3431
+ {
3432
+ actionName: 'pin',
3433
+ actionLabelOrTranslationKey: function () { var _a; return ((_a = _this.message) === null || _a === void 0 ? void 0 : _a.pinned) ? 'streamChat.Unpin' : 'streamChat.Pin'; },
3434
+ actionHandler: function () { return alert('Feature not yet implemented'); },
3435
+ isVisible: function () { return false; },
3436
+ },
3437
+ {
3438
+ actionName: 'flag',
3439
+ actionLabelOrTranslationKey: 'streamChat.Flag',
3440
+ actionHandler: function (message) { return __awaiter(_this, void 0, void 0, function () {
3441
+ var err_1;
3442
+ return __generator(this, function (_b) {
3443
+ switch (_b.label) {
3444
+ case 0:
3445
+ _b.trys.push([0, 2, , 3]);
3446
+ return [4 /*yield*/, this.chatClientService.flagMessage(message.id)];
3447
+ case 1:
3448
+ _b.sent();
3449
+ this.notificationService.addTemporaryNotification('streamChat.Message has been successfully flagged', 'success');
3450
+ return [3 /*break*/, 3];
3451
+ case 2:
3452
+ err_1 = _b.sent();
3453
+ this.notificationService.addTemporaryNotification('streamChat.Error adding flag');
3454
+ return [3 /*break*/, 3];
3455
+ case 3: return [2 /*return*/];
3456
+ }
3457
+ });
3458
+ }); },
3459
+ isVisible: function (enabledActions, isMine) { return enabledActions.indexOf('flag-message') !== -1 && !isMine; },
3460
+ },
3461
+ {
3462
+ actionName: 'edit',
3463
+ actionLabelOrTranslationKey: 'streamChat.Edit Message',
3464
+ actionHandler: function () {
3465
+ _this.isEditing.emit(true);
3466
+ _this.isEditModalOpen = true;
3467
+ },
3468
+ isVisible: function (enabledActions, isMine) { return (enabledActions.indexOf('update-own-message') !== -1 && isMine) ||
3469
+ enabledActions.indexOf('update-any-message') !== -1; },
3470
+ },
3471
+ {
3472
+ actionName: 'delete',
3473
+ actionLabelOrTranslationKey: 'streamChat.Delete',
3474
+ actionHandler: function (message) { return __awaiter(_this, void 0, void 0, function () {
3475
+ var error_1;
3476
+ return __generator(this, function (_b) {
3477
+ switch (_b.label) {
3478
+ case 0:
3479
+ _b.trys.push([0, 2, , 3]);
3480
+ return [4 /*yield*/, this.channelService.deleteMessage(message)];
3481
+ case 1:
3482
+ _b.sent();
3483
+ return [3 /*break*/, 3];
3484
+ case 2:
3485
+ error_1 = _b.sent();
3486
+ this.notificationService.addTemporaryNotification('streamChat.Error deleting message');
3487
+ return [3 /*break*/, 3];
3488
+ case 3: return [2 /*return*/];
3489
+ }
3490
+ });
3491
+ }); },
3492
+ isVisible: function (enabledActions, isMine) { return ((enabledActions.indexOf('delete') !== -1 ||
3493
+ enabledActions.indexOf('delete-own-message') !== -1) &&
3494
+ isMine) ||
3495
+ enabledActions.indexOf('delete-any') !== -1 ||
3496
+ enabledActions.indexOf('delete-any-message') !== -1; },
3497
+ },
3498
+ ];
3499
+ this.sendMessage$ = this.sendMessageSubject.asObservable();
3201
3500
  }
3202
3501
  MessageActionsBoxComponent.prototype.ngOnChanges = function (changes) {
3203
- if (changes.isMine || changes.enabledActions) {
3204
- var displayedActionsCount = 0;
3205
- if (this.isQuoteVisible) {
3206
- displayedActionsCount++;
3207
- }
3208
- if (this.isEditVisible) {
3209
- displayedActionsCount++;
3210
- }
3211
- if (this.isDeleteVisible) {
3212
- displayedActionsCount++;
3213
- }
3214
- if (this.isMuteVisible) {
3215
- displayedActionsCount++;
3216
- }
3217
- if (this.isFlagVisible) {
3218
- displayedActionsCount++;
3219
- }
3220
- if (this.isPinVisible) {
3221
- displayedActionsCount++;
3222
- }
3223
- this.displayedActionsCount.next(displayedActionsCount);
3502
+ var _this = this;
3503
+ if (changes.isMine || changes.enabledActions || changes.message) {
3504
+ this.messageActionItems.forEach(function (i) { return (i.actionHandler = i.actionHandler.bind(_this, _this.message, _this.isMine)); });
3505
+ this.visibleMessageActionItems = this.messageActionItems.filter(function (item) { return item.isVisible(_this.enabledActions, _this.isMine, _this.message); });
3506
+ this.displayedActionsCount.emit(this.visibleMessageActionItems.length);
3224
3507
  }
3225
3508
  };
3226
- Object.defineProperty(MessageActionsBoxComponent.prototype, "isQuoteVisible", {
3227
- get: function () {
3228
- var _a;
3229
- return ((this.enabledActions.indexOf('quote') !== -1 ||
3230
- this.enabledActions.indexOf('quote-message') !== -1) &&
3231
- !((_a = this.message) === null || _a === void 0 ? void 0 : _a.quoted_message));
3232
- },
3233
- enumerable: false,
3234
- configurable: true
3235
- });
3236
- Object.defineProperty(MessageActionsBoxComponent.prototype, "isEditVisible", {
3237
- get: function () {
3238
- return (((this.enabledActions.indexOf('edit') !== -1 ||
3239
- this.enabledActions.indexOf('update-own-message') !== -1) &&
3240
- this.isMine) ||
3241
- this.enabledActions.indexOf('edit-any') !== -1 ||
3242
- this.enabledActions.indexOf('update-any-message') !== -1);
3243
- },
3244
- enumerable: false,
3245
- configurable: true
3246
- });
3247
- Object.defineProperty(MessageActionsBoxComponent.prototype, "isDeleteVisible", {
3248
- get: function () {
3249
- return (((this.enabledActions.indexOf('delete') !== -1 ||
3250
- this.enabledActions.indexOf('delete-own-message') !== -1) &&
3251
- this.isMine) ||
3252
- this.enabledActions.indexOf('delete-any') !== -1 ||
3253
- this.enabledActions.indexOf('delete-any-message') !== -1);
3254
- },
3255
- enumerable: false,
3256
- configurable: true
3257
- });
3258
- Object.defineProperty(MessageActionsBoxComponent.prototype, "isMuteVisible", {
3259
- get: function () {
3260
- return this.enabledActions.indexOf('mute') !== -1;
3261
- },
3262
- enumerable: false,
3263
- configurable: true
3264
- });
3265
- Object.defineProperty(MessageActionsBoxComponent.prototype, "isFlagVisible", {
3266
- get: function () {
3267
- return ((this.enabledActions.indexOf('flag') !== -1 ||
3268
- this.enabledActions.indexOf('flag-message') !== -1) &&
3269
- !this.isMine);
3270
- },
3271
- enumerable: false,
3272
- configurable: true
3273
- });
3274
- Object.defineProperty(MessageActionsBoxComponent.prototype, "isPinVisible", {
3275
- get: function () {
3276
- return this.enabledActions.indexOf('pin') !== -1;
3277
- },
3278
- enumerable: false,
3279
- configurable: true
3280
- });
3281
- MessageActionsBoxComponent.prototype.pinClicked = function () {
3282
- alert('Feature not yet implemented');
3283
- };
3284
- MessageActionsBoxComponent.prototype.flagClicked = function () {
3285
- return __awaiter(this, void 0, void 0, function () {
3286
- var err_1;
3287
- return __generator(this, function (_b) {
3288
- switch (_b.label) {
3289
- case 0:
3290
- _b.trys.push([0, 2, , 3]);
3291
- return [4 /*yield*/, this.chatClientService.flagMessage(this.message.id)];
3292
- case 1:
3293
- _b.sent();
3294
- this.notificationService.addTemporaryNotification('streamChat.Message has been successfully flagged', 'success');
3295
- return [3 /*break*/, 3];
3296
- case 2:
3297
- err_1 = _b.sent();
3298
- this.notificationService.addTemporaryNotification('streamChat.Error adding flag');
3299
- return [3 /*break*/, 3];
3300
- case 3: return [2 /*return*/];
3301
- }
3302
- });
3303
- });
3304
- };
3305
- MessageActionsBoxComponent.prototype.muteClicked = function () {
3306
- alert('Feature not yet implemented');
3307
- };
3308
- MessageActionsBoxComponent.prototype.quoteClicked = function () {
3309
- this.channelService.selectMessageToQuote(this.message);
3509
+ MessageActionsBoxComponent.prototype.ngOnDestroy = function () {
3510
+ this.subscriptions.forEach(function (s) { return s.unsubscribe(); });
3310
3511
  };
3311
- MessageActionsBoxComponent.prototype.editClicked = function () {
3312
- this.isEditing.emit(true);
3313
- this.isEditModalOpen = true;
3512
+ MessageActionsBoxComponent.prototype.getActionLabel = function (actionLabelOrTranslationKey) {
3513
+ return typeof actionLabelOrTranslationKey === 'string'
3514
+ ? actionLabelOrTranslationKey
3515
+ : actionLabelOrTranslationKey();
3314
3516
  };
3315
3517
  MessageActionsBoxComponent.prototype.sendClicked = function () {
3316
- var _a;
3317
- (_a = this.messageInput) === null || _a === void 0 ? void 0 : _a.messageSent();
3518
+ this.sendMessageSubject.next();
3318
3519
  };
3319
- MessageActionsBoxComponent.prototype.deleteClicked = function () {
3320
- return __awaiter(this, void 0, void 0, function () {
3321
- var error_1;
3322
- return __generator(this, function (_b) {
3323
- switch (_b.label) {
3324
- case 0:
3325
- _b.trys.push([0, 2, , 3]);
3326
- return [4 /*yield*/, this.channelService.deleteMessage(this.message)];
3327
- case 1:
3328
- _b.sent();
3329
- return [3 /*break*/, 3];
3330
- case 2:
3331
- error_1 = _b.sent();
3332
- this.notificationService.addTemporaryNotification('streamChat.Error deleting message');
3333
- return [3 /*break*/, 3];
3334
- case 3: return [2 /*return*/];
3520
+ MessageActionsBoxComponent.prototype.getMessageInputContext = function () {
3521
+ return {
3522
+ message: this.message,
3523
+ messageUpdateHandler: this.modalClosed,
3524
+ isFileUploadEnabled: undefined,
3525
+ areMentionsEnabled: undefined,
3526
+ isMultipleFileUploadEnabled: undefined,
3527
+ mentionScope: undefined,
3528
+ mode: undefined,
3529
+ sendMessage$: this.sendMessage$,
3530
+ };
3531
+ };
3532
+ MessageActionsBoxComponent.prototype.getEditModalContext = function () {
3533
+ var _this = this;
3534
+ return {
3535
+ isOpen: this.isEditModalOpen,
3536
+ isOpenChangeHandler: function (isOpen) {
3537
+ _this.isEditModalOpen = isOpen;
3538
+ if (!_this.isEditModalOpen) {
3539
+ _this.modalClosed();
3335
3540
  }
3336
- });
3337
- });
3541
+ },
3542
+ content: this.modalContent,
3543
+ };
3544
+ };
3545
+ MessageActionsBoxComponent.prototype.trackByActionName = function (_, item) {
3546
+ return item.actionName;
3338
3547
  };
3339
3548
  return MessageActionsBoxComponent;
3340
3549
  }());
3341
- MessageActionsBoxComponent.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: MessageActionsBoxComponent, deps: [{ token: ChatClientService }, { token: NotificationService }, { token: ChannelService }], target: i0__namespace.ɵɵFactoryTarget.Component });
3342
- MessageActionsBoxComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: MessageActionsBoxComponent, selector: "stream-message-actions-box", inputs: { messageInputTemplate: "messageInputTemplate", isOpen: "isOpen", isMine: "isMine", message: "message", enabledActions: "enabledActions" }, outputs: { displayedActionsCount: "displayedActionsCount", isEditing: "isEditing" }, viewQueries: [{ propertyName: "messageInput", first: true, predicate: MessageInputComponent, descendants: true }], usesOnChanges: true, ngImport: i0__namespace, template: "<div\n data-testid=\"action-box\"\n class=\"str-chat__message-actions-box\"\n [class.str-chat__message-actions-box--open]=\"isOpen\"\n [class.str-chat__message-actions-box--mine]=\"isMine\"\n>\n <ul class=\"str-chat__message-actions-list\">\n <button\n data-testid=\"quote-action\"\n *ngIf=\"isQuoteVisible\"\n (click)=\"quoteClicked()\"\n >\n <li class=\"str-chat__message-actions-list-item\">\n {{ \"streamChat.Reply\" | translate }}\n </li>\n </button>\n <button\n data-testid=\"pin-action\"\n *ngIf=\"isPinVisible\"\n (click)=\"pinClicked()\"\n >\n <li class=\"str-chat__message-actions-list-item\">\n {{\n (message?.pinned ? \"streamChat.Unpin\" : \"streamChat.Pin\") | translate\n }}\n </li>\n </button>\n <button\n data-testid=\"flag-action\"\n *ngIf=\"isFlagVisible\"\n (click)=\"flagClicked()\"\n >\n <li class=\"str-chat__message-actions-list-item\">\n {{ \"streamChat.Flag\" | translate }}\n </li>\n </button>\n <button\n data-testid=\"mute-action\"\n *ngIf=\"isMuteVisible\"\n (click)=\"muteClicked()\"\n >\n <li class=\"str-chat__message-actions-list-item\">\n {{ \"streamChat.Mute\" | translate }}\n </li>\n </button>\n <button\n data-testid=\"edit-action\"\n *ngIf=\"isEditVisible\"\n (click)=\"editClicked()\"\n >\n <li class=\"str-chat__message-actions-list-item\">\n {{ \"streamChat.Edit Message\" | translate }}\n </li>\n </button>\n <button\n data-testid=\"delete-action\"\n *ngIf=\"isDeleteVisible\"\n (click)=\"deleteClicked()\"\n >\n <li class=\"str-chat__message-actions-list-item\">\n {{ \"streamChat.Delete\" | translate }}\n </li>\n </button>\n </ul>\n</div>\n\n<stream-modal\n [isOpen]=\"isEditModalOpen\"\n (isOpenChange)=\"\n isEditModalOpen = $event; isEditModalOpen ? '' : modalClosed()\n \"\n>\n <div class=\"str-chat__edit-message-form\" *ngIf=\"isEditModalOpen\">\n <ng-container *ngIf=\"messageInputTemplate; else defaultInput\">\n <ng-container\n *ngTemplateOutlet=\"\n messageInputTemplate;\n context: {\n message: message,\n messageUpdateHandler: modalClosed\n }\n \"\n ></ng-container>\n </ng-container>\n <ng-template #defaultInput>\n <stream-message-input\n [message]=\"message\"\n (messageUpdate)=\"modalClosed()\"\n ></stream-message-input>\n </ng-template>\n <stream-notification-list></stream-notification-list>\n <div\n class=\"\n str-chat__message-team-form-footer\n str-chat__message-team-form-footer-angular\n \"\n >\n <div class=\"str-chat__edit-message-form-options\">\n <button translate data-testid=\"cancel-button\" (click)=\"modalClosed()\">\n streamChat.Cancel\n </button>\n <button\n type=\"submit\"\n translate\n data-testid=\"send-button\"\n (click)=\"sendClicked()\"\n (keyup.enter)=\"sendClicked()\"\n >\n streamChat.Send\n </button>\n </div>\n </div>\n </div>\n</stream-modal>\n", components: [{ type: ModalComponent, selector: "stream-modal", inputs: ["isOpen"], outputs: ["isOpenChange"] }, { type: MessageInputComponent, selector: "stream-message-input", inputs: ["isFileUploadEnabled", "areMentionsEnabled", "mentionScope", "mentionAutocompleteItemTemplate", "commandAutocompleteItemTemplate", "emojiPickerTemplate", "mode", "acceptedFileTypes", "isMultipleFileUploadEnabled", "message"], outputs: ["messageUpdate"] }, { type: NotificationListComponent, selector: "stream-notification-list" }], directives: [{ type: i6__namespace.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i6__namespace.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i2__namespace.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }], pipes: { "translate": i2__namespace.TranslatePipe } });
3550
+ MessageActionsBoxComponent.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: MessageActionsBoxComponent, deps: [{ token: ChatClientService }, { token: NotificationService }, { token: ChannelService }, { token: CustomTemplatesService }], target: i0__namespace.ɵɵFactoryTarget.Component });
3551
+ MessageActionsBoxComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: MessageActionsBoxComponent, selector: "stream-message-actions-box", inputs: { isOpen: "isOpen", isMine: "isMine", message: "message", enabledActions: "enabledActions" }, outputs: { displayedActionsCount: "displayedActionsCount", isEditing: "isEditing" }, viewQueries: [{ propertyName: "modalContent", first: true, predicate: ["modalContent"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0__namespace, template: "<div\n data-testid=\"action-box\"\n class=\"str-chat__message-actions-box\"\n [class.str-chat__message-actions-box--open]=\"isOpen\"\n [class.str-chat__message-actions-box--mine]=\"isMine\"\n>\n <ul class=\"str-chat__message-actions-list\">\n <ng-container\n *ngFor=\"let item of visibleMessageActionItems; trackBy: trackByActionName\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n messageActionItemTemplate || defaultMessageActionItem;\n context: item\n \"\n ></ng-container>\n </ng-container>\n </ul>\n</div>\n\n<ng-template\n #defaultMessageActionItem\n let-actionName=\"actionName\"\n let-actionHandler=\"actionHandler\"\n let-actionLabelOrTranslationKey=\"actionLabelOrTranslationKey\"\n>\n <button [attr.data-testid]=\"actionName + '-action'\" (click)=\"actionHandler()\">\n <li class=\"str-chat__message-actions-list-item\">\n {{ getActionLabel(actionLabelOrTranslationKey) | translate }}\n </li>\n </button>\n</ng-template>\n\n<ng-container\n *ngTemplateOutlet=\"\n modalTemplate || defaultModal;\n context: getEditModalContext()\n \"\n></ng-container>\n\n<ng-template\n #defaultModal\n let-isOpen=\"isOpen\"\n let-isOpenChangeHandler=\"isOpenChangeHandler\"\n let-content=\"content\"\n>\n <stream-modal\n [isOpen]=\"isOpen\"\n (isOpenChange)=\"isOpenChangeHandler($event)\"\n [content]=\"content\"\n >\n </stream-modal>\n</ng-template>\n\n<ng-template #modalContent>\n <div class=\"str-chat__edit-message-form\" *ngIf=\"isEditModalOpen\">\n <ng-template\n #defaultInput\n let-messageInput=\"message\"\n let-messageUpdateHandler=\"messageUpdateHandler\"\n let-sendMessage$Input=\"sendMessage$\"\n >\n <stream-message-input\n [message]=\"messageInput\"\n (messageUpdate)=\"messageUpdateHandler()\"\n [sendMessage$]=\"sendMessage$Input\"\n ></stream-message-input>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n messageInputTemplate || defaultInput;\n context: getMessageInputContext()\n \"\n >\n </ng-container>\n\n <stream-notification-list></stream-notification-list>\n <div\n class=\"\n str-chat__message-team-form-footer\n str-chat__message-team-form-footer-angular\n \"\n >\n <div class=\"str-chat__edit-message-form-options\">\n <button translate data-testid=\"cancel-button\" (click)=\"modalClosed()\">\n streamChat.Cancel\n </button>\n <button\n type=\"submit\"\n translate\n data-testid=\"send-button\"\n (click)=\"sendClicked()\"\n (keyup.enter)=\"sendClicked()\"\n >\n streamChat.Send\n </button>\n </div>\n </div>\n </div>\n</ng-template>\n", components: [{ type: ModalComponent, selector: "stream-modal", inputs: ["isOpen", "content"], outputs: ["isOpenChange"] }, { type: MessageInputComponent, selector: "stream-message-input", inputs: ["isFileUploadEnabled", "areMentionsEnabled", "mentionScope", "mode", "isMultipleFileUploadEnabled", "message", "sendMessage$"], outputs: ["messageUpdate"] }, { type: NotificationListComponent, selector: "stream-notification-list" }], directives: [{ type: i3__namespace.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i3__namespace.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i3__namespace.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2__namespace.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }], pipes: { "translate": i2__namespace.TranslatePipe } });
3343
3552
  i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: MessageActionsBoxComponent, decorators: [{
3344
3553
  type: i0.Component,
3345
3554
  args: [{
@@ -3347,9 +3556,7 @@
3347
3556
  templateUrl: './message-actions-box.component.html',
3348
3557
  styles: [],
3349
3558
  }]
3350
- }], ctorParameters: function () { return [{ type: ChatClientService }, { type: NotificationService }, { type: ChannelService }]; }, propDecorators: { messageInputTemplate: [{
3351
- type: i0.Input
3352
- }], isOpen: [{
3559
+ }], ctorParameters: function () { return [{ type: ChatClientService }, { type: NotificationService }, { type: ChannelService }, { type: CustomTemplatesService }]; }, propDecorators: { isOpen: [{
3353
3560
  type: i0.Input
3354
3561
  }], isMine: [{
3355
3562
  type: i0.Input
@@ -3361,9 +3568,9 @@
3361
3568
  type: i0.Output
3362
3569
  }], isEditing: [{
3363
3570
  type: i0.Output
3364
- }], messageInput: [{
3571
+ }], modalContent: [{
3365
3572
  type: i0.ViewChild,
3366
- args: [MessageInputComponent]
3573
+ args: ['modalContent', { static: true }]
3367
3574
  }] } });
3368
3575
 
3369
3576
  /**
@@ -3380,7 +3587,7 @@
3380
3587
  return ChannelComponent;
3381
3588
  }());
3382
3589
  ChannelComponent.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: ChannelComponent, deps: [{ token: ChannelService }], target: i0__namespace.ɵɵFactoryTarget.Component });
3383
- ChannelComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: ChannelComponent, selector: "stream-channel", ngImport: i0__namespace, template: "<div\n *ngIf=\"(isError$ | async) === false && (isInitializing$ | async) === false\"\n class=\"str-chat str-chat-channel messaging\"\n>\n <div class=\"str-chat__container\">\n <div class=\"str-chat__main-panel\">\n <ng-content></ng-content>\n </div>\n <ng-content\n *ngIf=\"isActiveThread$ | async\"\n select='[name=\"thread\"]'\n ></ng-content>\n </div>\n</div>\n", directives: [{ type: i6__namespace.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], pipes: { "async": i6__namespace.AsyncPipe } });
3590
+ ChannelComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: ChannelComponent, selector: "stream-channel", ngImport: i0__namespace, template: "<div\n *ngIf=\"(isError$ | async) === false && (isInitializing$ | async) === false\"\n class=\"str-chat str-chat-channel messaging\"\n>\n <div class=\"str-chat__container\">\n <div class=\"str-chat__main-panel\">\n <ng-content></ng-content>\n </div>\n <ng-content\n *ngIf=\"isActiveThread$ | async\"\n select='[name=\"thread\"]'\n ></ng-content>\n </div>\n</div>\n", directives: [{ type: i3__namespace.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], pipes: { "async": i3__namespace.AsyncPipe } });
3384
3591
  i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: ChannelComponent, decorators: [{
3385
3592
  type: i0.Component,
3386
3593
  args: [{
@@ -3477,10 +3684,13 @@
3477
3684
  * The `ChannelHeader` component displays the avatar and name of the currently active channel along with member and watcher information. You can read about [the difference between members and watchers](https://getstream.io/chat/docs/javascript/watch_channel/?language=javascript#watchers-vs-members) in the platform documentation. Please note that number of watchers is only displayed if the user has [`connect-events` capability](https://getstream.io/chat/docs/javascript/channel_capabilities/?language=javascript)
3478
3685
  */
3479
3686
  var ChannelHeaderComponent = /** @class */ (function () {
3480
- function ChannelHeaderComponent(channelService, channelListToggleService) {
3687
+ function ChannelHeaderComponent(channelService, channelListToggleService, customTemplatesService, cdRef) {
3481
3688
  var _this = this;
3482
3689
  this.channelService = channelService;
3483
3690
  this.channelListToggleService = channelListToggleService;
3691
+ this.customTemplatesService = customTemplatesService;
3692
+ this.cdRef = cdRef;
3693
+ this.subscriptions = [];
3484
3694
  this.channelService.activeChannel$.subscribe(function (c) {
3485
3695
  var _a, _b;
3486
3696
  _this.activeChannel = c;
@@ -3492,10 +3702,23 @@
3492
3702
  capabilities.indexOf('connect-events') !== -1;
3493
3703
  });
3494
3704
  }
3705
+ ChannelHeaderComponent.prototype.ngOnInit = function () {
3706
+ var _this = this;
3707
+ this.subscriptions.push(this.customTemplatesService.channelActionsTemplate$.subscribe(function (template) {
3708
+ _this.channelActionsTemplate = template;
3709
+ _this.cdRef.detectChanges();
3710
+ }));
3711
+ };
3712
+ ChannelHeaderComponent.prototype.ngOnDestroy = function () {
3713
+ this.subscriptions.forEach(function (s) { return s.unsubscribe(); });
3714
+ };
3495
3715
  ChannelHeaderComponent.prototype.toggleMenu = function (event) {
3496
3716
  event.stopPropagation();
3497
3717
  this.channelListToggleService.toggle();
3498
3718
  };
3719
+ ChannelHeaderComponent.prototype.getChannelActionsContext = function () {
3720
+ return { channel: this.activeChannel };
3721
+ };
3499
3722
  Object.defineProperty(ChannelHeaderComponent.prototype, "memberCountParam", {
3500
3723
  get: function () {
3501
3724
  var _a, _b;
@@ -3514,8 +3737,8 @@
3514
3737
  });
3515
3738
  return ChannelHeaderComponent;
3516
3739
  }());
3517
- ChannelHeaderComponent.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: ChannelHeaderComponent, deps: [{ token: ChannelService }, { token: ChannelListToggleService }], target: i0__namespace.ɵɵFactoryTarget.Component });
3518
- ChannelHeaderComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: ChannelHeaderComponent, selector: "stream-channel-header", inputs: { channelActionsTemplate: "channelActionsTemplate" }, ngImport: i0__namespace, template: "<div class=\"str-chat__header-livestream\">\n <div\n class=\"str-chat__header-hamburger\"\n (click)=\"toggleMenu($event)\"\n (keyup.enter)=\"toggleMenu($event)\"\n >\n <stream-icon icon=\"menu\"></stream-icon>\n </div>\n <stream-avatar\n imageUrl=\"{{ activeChannel?.data?.image }}\"\n name=\"{{ activeChannel?.data?.name }}\"\n ></stream-avatar>\n <div class=\"str-chat__header-livestream-left\">\n <p data-testid=\"name\" class=\"str-chat__header-livestream-left--title\">\n {{ activeChannel?.data?.name }}\n </p>\n <p data-testid=\"info\" class=\"str-chat__header-livestream-left--members\">\n {{'streamChat.{{ memberCount }} members' | translate:memberCountParam}}\n {{canReceiveConnectEvents ? ('streamChat.{{ watcherCount }} online' |\n translate:watcherCountParam) : ''}}\n </p>\n </div>\n <ng-container *ngIf=\"channelActionsTemplate\">\n <ng-container\n *ngTemplateOutlet=\"\n channelActionsTemplate;\n context: { channel: activeChannel }\n \"\n ></ng-container>\n </ng-container>\n</div>\n", components: [{ type: IconComponent, selector: "stream-icon", inputs: ["icon", "size"] }, { type: AvatarComponent, selector: "stream-avatar", inputs: ["name", "imageUrl", "size"] }], directives: [{ type: i6__namespace.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i6__namespace.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], pipes: { "translate": i2__namespace.TranslatePipe } });
3740
+ ChannelHeaderComponent.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: ChannelHeaderComponent, deps: [{ token: ChannelService }, { token: ChannelListToggleService }, { token: CustomTemplatesService }, { token: i0__namespace.ChangeDetectorRef }], target: i0__namespace.ɵɵFactoryTarget.Component });
3741
+ ChannelHeaderComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: ChannelHeaderComponent, selector: "stream-channel-header", ngImport: i0__namespace, template: "<div class=\"str-chat__header-livestream\">\n <div\n class=\"str-chat__header-hamburger\"\n (click)=\"toggleMenu($event)\"\n (keyup.enter)=\"toggleMenu($event)\"\n >\n <stream-icon-placeholder icon=\"menu\"></stream-icon-placeholder>\n </div>\n <stream-avatar-placeholder\n imageUrl=\"{{ activeChannel?.data?.image }}\"\n name=\"{{ activeChannel?.data?.name }}\"\n ></stream-avatar-placeholder>\n <div class=\"str-chat__header-livestream-left\">\n <p data-testid=\"name\" class=\"str-chat__header-livestream-left--title\">\n {{ activeChannel?.data?.name }}\n </p>\n <p data-testid=\"info\" class=\"str-chat__header-livestream-left--members\">\n {{'streamChat.{{ memberCount }} members' | translate:memberCountParam}}\n {{canReceiveConnectEvents ? ('streamChat.{{ watcherCount }} online' |\n translate:watcherCountParam) : ''}}\n </p>\n </div>\n <ng-container *ngIf=\"channelActionsTemplate\">\n <ng-container\n *ngTemplateOutlet=\"\n channelActionsTemplate;\n context: getChannelActionsContext()\n \"\n ></ng-container>\n </ng-container>\n</div>\n", components: [{ type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon", "size"] }, { type: AvatarPlaceholderComponent, selector: "stream-avatar-placeholder", inputs: ["name", "imageUrl", "size"] }], directives: [{ type: i3__namespace.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3__namespace.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], pipes: { "translate": i2__namespace.TranslatePipe } });
3519
3742
  i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: ChannelHeaderComponent, decorators: [{
3520
3743
  type: i0.Component,
3521
3744
  args: [{
@@ -3523,9 +3746,7 @@
3523
3746
  templateUrl: './channel-header.component.html',
3524
3747
  styles: [],
3525
3748
  }]
3526
- }], ctorParameters: function () { return [{ type: ChannelService }, { type: ChannelListToggleService }]; }, propDecorators: { channelActionsTemplate: [{
3527
- type: i0.Input
3528
- }] } });
3749
+ }], ctorParameters: function () { return [{ type: ChannelService }, { type: ChannelListToggleService }, { type: CustomTemplatesService }, { type: i0__namespace.ChangeDetectorRef }]; } });
3529
3750
 
3530
3751
  /**
3531
3752
  * The `ChannelPreview` component displays a channel preview in the channel list, it consists of the image, name and latest message of the channel.
@@ -3620,7 +3841,7 @@
3620
3841
  return ChannelPreviewComponent;
3621
3842
  }());
3622
3843
  ChannelPreviewComponent.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: ChannelPreviewComponent, deps: [{ token: ChannelService }, { token: i0__namespace.NgZone }], target: i0__namespace.ɵɵFactoryTarget.Component });
3623
- ChannelPreviewComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: ChannelPreviewComponent, selector: "stream-channel-preview", inputs: { channel: "channel" }, ngImport: i0__namespace, template: "<button\n class=\"str-chat__channel-preview-messenger\"\n [class.str-chat__channel-preview-messenger--active]=\"isActive\"\n [class.str-chat__channel-preview-messenger--unread]=\"isUnread\"\n (click)=\"setAsActiveChannel()\"\n data-testid=\"channel-preview-container\"\n>\n <div class=\"str-chat__channel-preview-messenger--left\">\n <stream-avatar\n imageUrl=\"{{ avatarImage }}\"\n name=\"{{ avatarName }}\"\n [size]=\"40\"\n ></stream-avatar>\n </div>\n <div class=\"str-chat__channel-preview-messenger--right\">\n <div class=\"str-chat__channel-preview-messenger--name\">\n <span data-testid=\"channel-preview-title\">{{ title }}</span>\n </div>\n <div\n data-testid=\"latest-message\"\n class=\"str-chat__channel-preview-messenger--last-message\"\n >\n {{ latestMessage | translate }}\n </div>\n </div>\n</button>\n", components: [{ type: AvatarComponent, selector: "stream-avatar", inputs: ["name", "imageUrl", "size"] }], pipes: { "translate": i2__namespace.TranslatePipe } });
3844
+ ChannelPreviewComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: ChannelPreviewComponent, selector: "stream-channel-preview", inputs: { channel: "channel" }, ngImport: i0__namespace, template: "<button\n class=\"str-chat__channel-preview-messenger\"\n [class.str-chat__channel-preview-messenger--active]=\"isActive\"\n [class.str-chat__channel-preview-messenger--unread]=\"isUnread\"\n (click)=\"setAsActiveChannel()\"\n data-testid=\"channel-preview-container\"\n>\n <div class=\"str-chat__channel-preview-messenger--left\">\n <stream-avatar-placeholder\n imageUrl=\"{{ avatarImage }}\"\n name=\"{{ avatarName }}\"\n [size]=\"40\"\n ></stream-avatar-placeholder>\n </div>\n <div class=\"str-chat__channel-preview-messenger--right\">\n <div class=\"str-chat__channel-preview-messenger--name\">\n <span data-testid=\"channel-preview-title\">{{ title }}</span>\n </div>\n <div\n data-testid=\"latest-message\"\n class=\"str-chat__channel-preview-messenger--last-message\"\n >\n {{ latestMessage | translate }}\n </div>\n </div>\n</button>\n", components: [{ type: AvatarPlaceholderComponent, selector: "stream-avatar-placeholder", inputs: ["name", "imageUrl", "size"] }], pipes: { "translate": i2__namespace.TranslatePipe } });
3624
3845
  i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: ChannelPreviewComponent, decorators: [{
3625
3846
  type: i0.Component,
3626
3847
  args: [{
@@ -3636,19 +3857,26 @@
3636
3857
  * The `ChannelList` component renders the list of channels.
3637
3858
  */
3638
3859
  var ChannelListComponent = /** @class */ (function () {
3639
- function ChannelListComponent(channelService, channelListToggleService) {
3860
+ function ChannelListComponent(channelService, channelListToggleService, customTemplatesService) {
3861
+ var _this = this;
3640
3862
  this.channelService = channelService;
3641
3863
  this.channelListToggleService = channelListToggleService;
3864
+ this.customTemplatesService = customTemplatesService;
3642
3865
  this.isLoadingMoreChannels = false;
3866
+ this.subscriptions = [];
3643
3867
  this.isOpen$ = this.channelListToggleService.isOpen$;
3644
3868
  this.channels$ = this.channelService.channels$;
3645
3869
  this.hasMoreChannels$ = this.channelService.hasMoreChannels$;
3646
3870
  this.isError$ = this.channels$.pipe(operators.map(function () { return false; }), operators.catchError(function () { return rxjs.of(true); }), operators.startWith(false));
3647
3871
  this.isInitializing$ = this.channels$.pipe(operators.map(function (channels) { return !channels; }), operators.catchError(function () { return rxjs.of(false); }));
3872
+ this.subscriptions.push(this.customTemplatesService.channelPreviewTemplate$.subscribe(function (template) { return (_this.customChannelPreviewTemplate = template); }));
3648
3873
  }
3649
3874
  ChannelListComponent.prototype.ngAfterViewInit = function () {
3650
3875
  this.channelListToggleService.setMenuElement(this.container.nativeElement);
3651
3876
  };
3877
+ ChannelListComponent.prototype.ngOnDestroy = function () {
3878
+ this.subscriptions.forEach(function (s) { return s.unsubscribe(); });
3879
+ };
3652
3880
  ChannelListComponent.prototype.loadMoreChannels = function () {
3653
3881
  return __awaiter(this, void 0, void 0, function () {
3654
3882
  return __generator(this, function (_a) {
@@ -3670,10 +3898,15 @@
3670
3898
  ChannelListComponent.prototype.channelSelected = function () {
3671
3899
  this.channelListToggleService.channelSelected();
3672
3900
  };
3901
+ ChannelListComponent.prototype.getChannelPreviewContext = function (channel) {
3902
+ return {
3903
+ channel: channel,
3904
+ };
3905
+ };
3673
3906
  return ChannelListComponent;
3674
3907
  }());
3675
- ChannelListComponent.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: ChannelListComponent, deps: [{ token: ChannelService }, { token: ChannelListToggleService }], target: i0__namespace.ɵɵFactoryTarget.Component });
3676
- ChannelListComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: ChannelListComponent, selector: "stream-channel-list", inputs: { customChannelPreviewTemplate: "customChannelPreviewTemplate" }, viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true }], ngImport: i0__namespace, template: "<div\n #container\n data-testid=\"channel-list-container\"\n class=\"str-chat str-chat-channel-list messaging\"\n [class.str-chat-channel-list--open]=\"(isOpen$ | async) === true\"\n>\n <div\n *ngIf=\"\n (isError$ | async) === false && (isInitializing$ | async) === false;\n else statusIndicator\n \"\n class=\"str-chat__channel-list-messenger\"\n >\n <div class=\"str-chat__channel-list-messenger__main\">\n <p\n data-testid=\"empty-channel-list-indicator\"\n *ngIf=\"!(channels$ | async)?.length\"\n >\n {{ \"streamChat.You have no channels currently\" | translate }}\n </p>\n <ng-container\n *ngFor=\"let channel of channels$ | async; trackBy: trackByChannelId\"\n >\n <ng-container\n *ngIf=\"customChannelPreviewTemplate; else defaultTemplate\"\n >\n <div (click)=\"channelSelected()\" (keyup.enter)=\"channelSelected()\">\n <ng-container\n *ngTemplateOutlet=\"\n customChannelPreviewTemplate;\n context: { channel: channel }\n \"\n ></ng-container>\n </div>\n </ng-container>\n <ng-template #defaultTemplate>\n <stream-channel-preview\n data-testclass=\"channel-preview\"\n [channel]=\"channel\"\n (click)=\"channelSelected()\"\n (keyup.enter)=\"channelSelected()\"\n ></stream-channel-preview>\n </ng-template>\n </ng-container>\n <div\n *ngIf=\"hasMoreChannels$ | async\"\n class=\"str-chat__load-more-button\"\n (click)=\"loadMoreChannels()\"\n (keyup.enter)=\"loadMoreChannels()\"\n data-testid=\"load-more\"\n >\n <button\n class=\"str-chat__load-more-button__button\"\n data-testid=\"load-more-button\"\n [disabled]=\"isLoadingMoreChannels\"\n >\n <span *ngIf=\"!isLoadingMoreChannels; else loadingIndicator\">{{\n \"Load more\" | translate\n }}</span>\n <ng-template #loadingIndicator\n ><stream-loading-indicator></stream-loading-indicator\n ></ng-template>\n </button>\n </div>\n </div>\n </div>\n</div>\n\n<ng-template #statusIndicator>\n <ng-container *ngIf=\"isError$ | async\">\n <ng-container *ngTemplateOutlet=\"chatDown\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"isInitializing$ | async\">\n <ng-container *ngTemplateOutlet=\"loadingChannels\"></ng-container>\n </ng-container>\n</ng-template>\n\n<ng-template #chatDown>\n <div data-testid=\"chatdown-container\" class=\"str-chat__down\">\n <ng-container *ngTemplateOutlet=\"loadingChannels\"></ng-container>\n <div class=\"str-chat__down-main\">\n <stream-icon icon=\"connection-error\"></stream-icon>\n <h1>{{ \"streamChat.Connection error\" | translate }}</h1>\n <h3>\n {{\n \"streamChat.Error connecting to chat, refresh the page to try again.\"\n | translate\n }}\n </h3>\n </div>\n </div>\n</ng-template>\n\n<ng-template #loadingChannels>\n <div data-testid=\"loading-indicator\" class=\"str-chat__loading-channels\">\n <ng-container *ngTemplateOutlet=\"loadingChannel\"></ng-container>\n <ng-container *ngTemplateOutlet=\"loadingChannel\"></ng-container>\n <ng-container *ngTemplateOutlet=\"loadingChannel\"></ng-container>\n </div>\n</ng-template>\n\n<ng-template #loadingChannel>\n <div class=\"str-chat__loading-channels-item\">\n <div class=\"str-chat__loading-channels-avatar\"></div>\n <div class=\"str-chat__loading-channels-meta\">\n <div class=\"str-chat__loading-channels-username\"></div>\n <div class=\"str-chat__loading-channels-status\"></div>\n </div>\n </div>\n</ng-template>\n", components: [{ type: ChannelPreviewComponent, selector: "stream-channel-preview", inputs: ["channel"] }, { type: LoadingIndicatorComponent, selector: "stream-loading-indicator", inputs: ["size", "color"] }, { type: IconComponent, selector: "stream-icon", inputs: ["icon", "size"] }], directives: [{ type: i6__namespace.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i6__namespace.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i6__namespace.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], pipes: { "async": i6__namespace.AsyncPipe, "translate": i2__namespace.TranslatePipe } });
3908
+ ChannelListComponent.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: ChannelListComponent, deps: [{ token: ChannelService }, { token: ChannelListToggleService }, { token: CustomTemplatesService }], target: i0__namespace.ɵɵFactoryTarget.Component });
3909
+ ChannelListComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: ChannelListComponent, selector: "stream-channel-list", viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true }], ngImport: i0__namespace, template: "<div\n #container\n data-testid=\"channel-list-container\"\n class=\"str-chat str-chat-channel-list messaging\"\n [class.str-chat-channel-list--open]=\"(isOpen$ | async) === true\"\n>\n <div\n *ngIf=\"\n (isError$ | async) === false && (isInitializing$ | async) === false;\n else statusIndicator\n \"\n class=\"str-chat__channel-list-messenger\"\n >\n <div class=\"str-chat__channel-list-messenger__main\">\n <p\n data-testid=\"empty-channel-list-indicator\"\n *ngIf=\"!(channels$ | async)?.length\"\n >\n {{ \"streamChat.You have no channels currently\" | translate }}\n </p>\n <ng-container\n *ngFor=\"let channel of channels$ | async; trackBy: trackByChannelId\"\n >\n <ng-template #defaultTemplate let-channelInput=\"channel\">\n <stream-channel-preview\n data-testclass=\"channel-preview\"\n [channel]=\"channelInput\"\n ></stream-channel-preview>\n </ng-template>\n <div (click)=\"channelSelected()\" (keyup.enter)=\"channelSelected()\">\n <ng-container\n *ngTemplateOutlet=\"\n customChannelPreviewTemplate || defaultTemplate;\n context: getChannelPreviewContext(channel)\n \"\n ></ng-container>\n </div>\n </ng-container>\n <div\n *ngIf=\"hasMoreChannels$ | async\"\n class=\"str-chat__load-more-button\"\n (click)=\"loadMoreChannels()\"\n (keyup.enter)=\"loadMoreChannels()\"\n data-testid=\"load-more\"\n >\n <button\n class=\"str-chat__load-more-button__button\"\n data-testid=\"load-more-button\"\n [disabled]=\"isLoadingMoreChannels\"\n >\n <span *ngIf=\"!isLoadingMoreChannels; else loadingIndicator\">{{\n \"Load more\" | translate\n }}</span>\n <ng-template #loadingIndicator\n ><stream-loading-indicator-placeholder></stream-loading-indicator-placeholder\n ></ng-template>\n </button>\n </div>\n </div>\n </div>\n</div>\n\n<ng-template #statusIndicator>\n <ng-container *ngIf=\"isError$ | async\">\n <ng-container *ngTemplateOutlet=\"chatDown\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"isInitializing$ | async\">\n <ng-container *ngTemplateOutlet=\"loadingChannels\"></ng-container>\n </ng-container>\n</ng-template>\n\n<ng-template #chatDown>\n <div data-testid=\"chatdown-container\" class=\"str-chat__down\">\n <ng-container *ngTemplateOutlet=\"loadingChannels\"></ng-container>\n <div class=\"str-chat__down-main\">\n <stream-icon-placeholder\n icon=\"connection-error\"\n ></stream-icon-placeholder>\n <h1>{{ \"streamChat.Connection error\" | translate }}</h1>\n <h3>\n {{\n \"streamChat.Error connecting to chat, refresh the page to try again.\"\n | translate\n }}\n </h3>\n </div>\n </div>\n</ng-template>\n\n<ng-template #loadingChannels>\n <div data-testid=\"loading-indicator\" class=\"str-chat__loading-channels\">\n <ng-container *ngTemplateOutlet=\"loadingChannel\"></ng-container>\n <ng-container *ngTemplateOutlet=\"loadingChannel\"></ng-container>\n <ng-container *ngTemplateOutlet=\"loadingChannel\"></ng-container>\n </div>\n</ng-template>\n\n<ng-template #loadingChannel>\n <div class=\"str-chat__loading-channels-item\">\n <div class=\"str-chat__loading-channels-avatar\"></div>\n <div class=\"str-chat__loading-channels-meta\">\n <div class=\"str-chat__loading-channels-username\"></div>\n <div class=\"str-chat__loading-channels-status\"></div>\n </div>\n </div>\n</ng-template>\n", components: [{ type: ChannelPreviewComponent, selector: "stream-channel-preview", inputs: ["channel"] }, { type: LoadingIndicatorPlaceholderComponent, selector: "stream-loading-indicator-placeholder", inputs: ["size", "color"] }, { type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon", "size"] }], directives: [{ type: i3__namespace.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3__namespace.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i3__namespace.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], pipes: { "async": i3__namespace.AsyncPipe, "translate": i2__namespace.TranslatePipe } });
3677
3910
  i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: ChannelListComponent, decorators: [{
3678
3911
  type: i0.Component,
3679
3912
  args: [{
@@ -3681,9 +3914,7 @@
3681
3914
  templateUrl: './channel-list.component.html',
3682
3915
  styles: [],
3683
3916
  }]
3684
- }], ctorParameters: function () { return [{ type: ChannelService }, { type: ChannelListToggleService }]; }, propDecorators: { customChannelPreviewTemplate: [{
3685
- type: i0.Input
3686
- }], container: [{
3917
+ }], ctorParameters: function () { return [{ type: ChannelService }, { type: ChannelListToggleService }, { type: CustomTemplatesService }]; }, propDecorators: { container: [{
3687
3918
  type: i0.ViewChild,
3688
3919
  args: ['container']
3689
3920
  }] } });
@@ -3858,7 +4089,7 @@
3858
4089
  return MessageReactionsComponent;
3859
4090
  }());
3860
4091
  MessageReactionsComponent.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: MessageReactionsComponent, deps: [{ token: i0__namespace.ChangeDetectorRef }, { token: ChannelService }], target: i0__namespace.ɵɵFactoryTarget.Component });
3861
- MessageReactionsComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: MessageReactionsComponent, selector: "stream-message-reactions", inputs: { messageId: "messageId", messageReactionCounts: "messageReactionCounts", isSelectorOpen: "isSelectorOpen", latestReactions: "latestReactions", ownReactions: "ownReactions" }, outputs: { isSelectorOpenChange: "isSelectorOpenChange" }, viewQueries: [{ propertyName: "selectorContainer", first: true, predicate: ["selectorContainer"], descendants: true }, { propertyName: "selectorTooltip", first: true, predicate: ["selectorTooltip"], descendants: true }], usesOnChanges: true, ngImport: i0__namespace, template: "<div\n *ngIf=\"existingReactions.length > 0 && !isSelectorOpen\"\n class=\"str-chat__reaction-list\"\n [class.str-chat__reaction-list--reverse]=\"true\"\n data-testid=\"reaction-list\"\n>\n <ul>\n <li\n *ngFor=\"\n let reactionType of existingReactions;\n trackBy: trackByMessageReaction\n \"\n data-testclass=\"emoji\"\n >\n <span class=\"emoji\">\n {{ getEmojiByReaction(reactionType) }}\n </span>\n &nbsp;\n </li>\n <li>\n <span\n data-testid=\"reactions-count\"\n class=\"str-chat__reaction-list--counter\"\n >{{ reactionsCount }}</span\n >\n </li>\n </ul>\n</div>\n\n<div\n #selectorContainer\n class=\"str-chat__reaction-selector\"\n *ngIf=\"isSelectorOpen\"\n data-testid=\"reaction-selector\"\n>\n <div\n *ngIf=\"tooltipText\"\n data-testid=\"tooltip\"\n #selectorTooltip\n class=\"str-chat__reaction-selector-tooltip\"\n [ngStyle]=\"{\n left: tooltipPositions?.tooltip + 'px',\n visibility: tooltipPositions ? 'visible' : 'hidden'\n }\"\n >\n <div\n class=\"arrow\"\n [ngStyle]=\"{ left: tooltipPositions?.arrow + 'px' }\"\n ></div>\n <span class=\"latest-user-username\">\n {{ tooltipText }}\n </span>\n </div>\n <ul class=\"str-chat__message-reactions-list\">\n <li\n class=\"str-chat__message-reactions-list-item str-chat__emoji\"\n *ngFor=\"\n let reactionType of reactionOptions;\n trackBy: trackByMessageReaction\n \"\n data-testclass=\"emoji-option\"\n (click)=\"react(reactionType)\"\n (keyup.enter)=\"react(reactionType)\"\n >\n <div\n *ngIf=\"getLatestUserByReaction(reactionType) as user\"\n class=\"latest-user\"\n (click)=\"hideTooltip()\"\n (keyup.enter)=\"hideTooltip()\"\n (mouseenter)=\"showTooltip($event, reactionType)\"\n (mouseleave)=\"hideTooltip()\"\n attr.data-testid=\"{{ reactionType }}-last-user\"\n >\n <stream-avatar\n attr.data-testid=\"{{ reactionType }}-avatar\"\n [imageUrl]=\"user.image\"\n [name]=\"user.name || user.id\"\n [size]=\"20\"\n ></stream-avatar>\n </div>\n <span class=\"emoji\" style=\"width: 20px; height: 20px; top: 10px\">\n {{ getEmojiByReaction(reactionType) }}\n </span>\n <span\n *ngIf=\"\n messageReactionCounts[reactionType] &&\n messageReactionCounts[reactionType]! > 0\n \"\n class=\"str-chat__message-reactions-list-item__count\"\n attr.data-testid=\"{{ reactionType }}-reaction-count\"\n >\n {{ messageReactionCounts[reactionType] }}\n </span>\n </li>\n </ul>\n</div>\n", styles: [".emoji {position: relative; display: inline-block; }"], components: [{ type: AvatarComponent, selector: "stream-avatar", inputs: ["name", "imageUrl", "size"] }], directives: [{ type: i6__namespace.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i6__namespace.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i6__namespace.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] });
4092
+ MessageReactionsComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: MessageReactionsComponent, selector: "stream-message-reactions", inputs: { messageId: "messageId", messageReactionCounts: "messageReactionCounts", isSelectorOpen: "isSelectorOpen", latestReactions: "latestReactions", ownReactions: "ownReactions" }, outputs: { isSelectorOpenChange: "isSelectorOpenChange" }, viewQueries: [{ propertyName: "selectorContainer", first: true, predicate: ["selectorContainer"], descendants: true }, { propertyName: "selectorTooltip", first: true, predicate: ["selectorTooltip"], descendants: true }], usesOnChanges: true, ngImport: i0__namespace, template: "<div\n *ngIf=\"existingReactions.length > 0 && !isSelectorOpen\"\n class=\"str-chat__reaction-list\"\n [class.str-chat__reaction-list--reverse]=\"true\"\n data-testid=\"reaction-list\"\n>\n <ul>\n <li\n *ngFor=\"\n let reactionType of existingReactions;\n trackBy: trackByMessageReaction\n \"\n data-testclass=\"emoji\"\n >\n <span class=\"emoji\">\n {{ getEmojiByReaction(reactionType) }}\n </span>\n &nbsp;\n </li>\n <li>\n <span\n data-testid=\"reactions-count\"\n class=\"str-chat__reaction-list--counter\"\n >{{ reactionsCount }}</span\n >\n </li>\n </ul>\n</div>\n\n<div\n #selectorContainer\n class=\"str-chat__reaction-selector\"\n *ngIf=\"isSelectorOpen\"\n data-testid=\"reaction-selector\"\n>\n <div\n *ngIf=\"tooltipText\"\n data-testid=\"tooltip\"\n #selectorTooltip\n class=\"str-chat__reaction-selector-tooltip\"\n [ngStyle]=\"{\n left: tooltipPositions?.tooltip + 'px',\n visibility: tooltipPositions ? 'visible' : 'hidden'\n }\"\n >\n <div\n class=\"arrow\"\n [ngStyle]=\"{ left: tooltipPositions?.arrow + 'px' }\"\n ></div>\n <span class=\"latest-user-username\">\n {{ tooltipText }}\n </span>\n </div>\n <ul class=\"str-chat__message-reactions-list\">\n <li\n class=\"str-chat__message-reactions-list-item str-chat__emoji\"\n *ngFor=\"\n let reactionType of reactionOptions;\n trackBy: trackByMessageReaction\n \"\n data-testclass=\"emoji-option\"\n (click)=\"react(reactionType)\"\n (keyup.enter)=\"react(reactionType)\"\n >\n <div\n *ngIf=\"getLatestUserByReaction(reactionType) as user\"\n class=\"latest-user\"\n (click)=\"hideTooltip()\"\n (keyup.enter)=\"hideTooltip()\"\n (mouseenter)=\"showTooltip($event, reactionType)\"\n (mouseleave)=\"hideTooltip()\"\n attr.data-testid=\"{{ reactionType }}-last-user\"\n >\n <stream-avatar-placeholder\n attr.data-testid=\"{{ reactionType }}-avatar\"\n [imageUrl]=\"user.image\"\n [name]=\"user.name || user.id\"\n [size]=\"20\"\n ></stream-avatar-placeholder>\n </div>\n <span class=\"emoji\" style=\"width: 20px; height: 20px; top: 10px\">\n {{ getEmojiByReaction(reactionType) }}\n </span>\n <span\n *ngIf=\"\n messageReactionCounts[reactionType] &&\n messageReactionCounts[reactionType]! > 0\n \"\n class=\"str-chat__message-reactions-list-item__count\"\n attr.data-testid=\"{{ reactionType }}-reaction-count\"\n >\n {{ messageReactionCounts[reactionType] }}\n </span>\n </li>\n </ul>\n</div>\n", styles: [".emoji {position: relative; display: inline-block; }"], components: [{ type: AvatarPlaceholderComponent, selector: "stream-avatar-placeholder", inputs: ["name", "imageUrl", "size"] }], directives: [{ type: i3__namespace.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3__namespace.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i3__namespace.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] });
3862
4093
  i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: MessageReactionsComponent, decorators: [{
3863
4094
  type: i0.Component,
3864
4095
  args: [{
@@ -3890,9 +4121,11 @@
3890
4121
  * The `Message` component displays a message with additional information such as sender and date, and enables [interaction with the message (i.e. edit or react)](../concepts/message-interactions.mdx).
3891
4122
  */
3892
4123
  var MessageComponent = /** @class */ (function () {
3893
- function MessageComponent(chatClientService, channelService) {
4124
+ function MessageComponent(chatClientService, channelService, customTemplatesService, cdRef) {
3894
4125
  this.chatClientService = chatClientService;
3895
4126
  this.channelService = channelService;
4127
+ this.customTemplatesService = customTemplatesService;
4128
+ this.cdRef = cdRef;
3896
4129
  /**
3897
4130
  * The list of [channel capabilities](https://getstream.io/chat/docs/javascript/channel_capabilities/?language=javascript) that are enabled for the current user, the list of [supported interactions](../concepts/message-interactions.mdx) can be found in our message interaction guide. Unathorized actions won't be displayed on the UI. The [`MessageList`](./MessageListComponent.mdx) component automatically sets this based on [channel capabilities](https://getstream.io/chat/docs/javascript/channel_capabilities/?language=javascript).
3898
4131
  */
@@ -3906,12 +4139,29 @@
3906
4139
  this.isPressedOnMobile = false;
3907
4140
  this.visibleMessageActionsCount = 0;
3908
4141
  this.messageTextParts = [];
4142
+ this.subscriptions = [];
3909
4143
  this.user = this.chatClientService.chatClient.user;
3910
4144
  }
4145
+ MessageComponent.prototype.ngOnInit = function () {
4146
+ var _this = this;
4147
+ this.subscriptions.push(this.customTemplatesService.mentionTemplate$.subscribe(function (template) { return (_this.mentionTemplate = template); }));
4148
+ this.subscriptions.push(this.customTemplatesService.attachmentListTemplate$.subscribe(function (template) { return (_this.attachmentListTemplate = template); }));
4149
+ this.subscriptions.push(this.customTemplatesService.messageActionsBoxTemplate$.subscribe(function (template) { return (_this.messageActionsBoxTemplate = template); }));
4150
+ this.subscriptions.push(this.customTemplatesService.messageReactionsTemplate$.subscribe(function (template) { return (_this.messageReactionsTemplate = template); }));
4151
+ };
3911
4152
  MessageComponent.prototype.ngOnChanges = function (changes) {
3912
4153
  if (changes.message) {
3913
4154
  this.createMessageParts();
3914
4155
  }
4156
+ if (changes.enabledMessageActions) {
4157
+ this.canReactToMessage =
4158
+ this.enabledMessageActions.indexOf('send-reaction') !== -1;
4159
+ this.canReceiveReadEvents =
4160
+ this.enabledMessageActions.indexOf('read-events') !== -1;
4161
+ }
4162
+ };
4163
+ MessageComponent.prototype.ngOnDestroy = function () {
4164
+ this.subscriptions.forEach(function (s) { return s.unsubscribe(); });
3915
4165
  };
3916
4166
  Object.defineProperty(MessageComponent.prototype, "isSentByCurrentUser", {
3917
4167
  get: function () {
@@ -4032,6 +4282,25 @@
4032
4282
  enumerable: false,
4033
4283
  configurable: true
4034
4284
  });
4285
+ MessageComponent.prototype.getAttachmentListContext = function () {
4286
+ var _a, _b;
4287
+ return {
4288
+ messageId: ((_a = this.message) === null || _a === void 0 ? void 0 : _a.id) || '',
4289
+ attachments: ((_b = this.message) === null || _b === void 0 ? void 0 : _b.attachments) || [],
4290
+ };
4291
+ };
4292
+ MessageComponent.prototype.getMessageReactionsContext = function () {
4293
+ var _this = this;
4294
+ var _a, _b, _c, _d;
4295
+ return {
4296
+ messageReactionCounts: ((_a = this.message) === null || _a === void 0 ? void 0 : _a.reaction_counts) || {},
4297
+ latestReactions: ((_b = this.message) === null || _b === void 0 ? void 0 : _b.latest_reactions) || [],
4298
+ isSelectorOpen: this.isReactionSelectorOpen,
4299
+ isSelectorOpenChangeHandler: function (isOpen) { return (_this.isReactionSelectorOpen = isOpen); },
4300
+ messageId: (_c = this.message) === null || _c === void 0 ? void 0 : _c.id,
4301
+ ownReactions: ((_d = this.message) === null || _d === void 0 ? void 0 : _d.own_reactions) || [],
4302
+ };
4303
+ };
4035
4304
  MessageComponent.prototype.resendMessage = function () {
4036
4305
  void this.channelService.resendMessage(this.message);
4037
4306
  };
@@ -4057,6 +4326,30 @@
4057
4326
  MessageComponent.prototype.setAsActiveParentMessage = function () {
4058
4327
  void this.channelService.setAsActiveParentMessage(this.message);
4059
4328
  };
4329
+ MessageComponent.prototype.getMentionContext = function (messagePart) {
4330
+ return {
4331
+ content: messagePart.content,
4332
+ user: messagePart.user,
4333
+ };
4334
+ };
4335
+ MessageComponent.prototype.getMessageActionsBoxContext = function () {
4336
+ var _this = this;
4337
+ return {
4338
+ isOpen: this.isActionBoxOpen,
4339
+ isMine: this.isSentByCurrentUser,
4340
+ enabledActions: this.enabledMessageActions,
4341
+ message: this.message,
4342
+ displayedActionsCountChaneHanler: function (count) {
4343
+ _this.visibleMessageActionsCount = count;
4344
+ // message action box changes UI bindings in parent, so we'll have to rerun change detection
4345
+ _this.cdRef.detectChanges();
4346
+ },
4347
+ isEditingChangeHandler: function (isEditing) {
4348
+ _this.isEditing = isEditing;
4349
+ _this.isActionBoxOpen = !_this.isEditing;
4350
+ },
4351
+ };
4352
+ };
4060
4353
  MessageComponent.prototype.createMessageParts = function () {
4061
4354
  var _this = this;
4062
4355
  var _a, _b;
@@ -4076,12 +4369,7 @@
4076
4369
  this.message.mentioned_users.length === 0) {
4077
4370
  // Wrap emojis in span to display emojis correctly in Chrome https://bugs.chromium.org/p/chromium/issues/detail?id=596223
4078
4371
  var regex = new RegExp(emojiRegex__default['default'](), 'g');
4079
- // Based on this: https://stackoverflow.com/questions/4565112/javascript-how-to-find-out-if-the-user-browser-is-chrome
4080
- /* eslint-disable @typescript-eslint/no-unsafe-member-access */
4081
- var isChrome_1 = !!window.chrome &&
4082
- typeof window.opr === 'undefined';
4083
- /* eslint-enable @typescript-eslint/no-unsafe-member-access */
4084
- content = content.replace(regex, function (match) { return "<span " + (isChrome_1 ? 'class="str-chat__emoji-display-fix"' : '') + ">" + match + "</span>"; });
4372
+ content = content.replace(regex, function (match) { return "<span class=\"str-chat__emoji-display-fix\">" + match + "</span>"; });
4085
4373
  this.messageTextParts = [{ content: content, type: 'text' }];
4086
4374
  }
4087
4375
  else {
@@ -4109,8 +4397,8 @@
4109
4397
  };
4110
4398
  return MessageComponent;
4111
4399
  }());
4112
- MessageComponent.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: MessageComponent, deps: [{ token: ChatClientService }, { token: ChannelService }], target: i0__namespace.ɵɵFactoryTarget.Component });
4113
- MessageComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: MessageComponent, selector: "stream-message", inputs: { messageInputTemplate: "messageInputTemplate", mentionTemplate: "mentionTemplate", message: "message", enabledMessageActions: "enabledMessageActions", areReactionsEnabled: "areReactionsEnabled", canReactToMessage: "canReactToMessage", isLastSentMessage: "isLastSentMessage", canReceiveReadEvents: "canReceiveReadEvents", mode: "mode" }, viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true }], usesOnChanges: true, ngImport: i0__namespace, template: "<div\n #container\n class=\"str-chat__message-simple str-chat__message str-chat__message--{{\n message?.type\n }} str-chat__message--{{ message?.status }} {{\n message?.text ? 'str-chat__message--has-text' : 'has-no-text'\n }}\"\n [class.str-chat__message--me]=\"isSentByCurrentUser\"\n [class.str-chat__message-simple--me]=\"isSentByCurrentUser\"\n [class.mobile-press]=\"isPressedOnMobile\"\n [class.str-chat__message--has-attachment]=\"hasAttachment\"\n [class.str-chat__message--with-reactions]=\"\n areReactionsEnabled !== false && hasReactions\n \"\n data-testid=\"message-container\"\n (mouseleave)=\"isActionBoxOpen = false\"\n>\n <ng-container *ngIf=\"!message?.deleted_at; else deletedMessage\">\n <ng-container *ngIf=\"message?.type !== 'system'; else systemMessage\">\n <ng-container\n *ngIf=\"\n isSentByCurrentUser &&\n ((isLastSentMessage && message?.status === 'received') ||\n message?.status === 'sending')\n \"\n >\n <ng-container *ngIf=\"message?.status === 'sending'; else sentStatus\">\n <ng-container *ngTemplateOutlet=\"sendingStatus\"></ng-container>\n </ng-container>\n <ng-template #sentStatus>\n <ng-container\n *ngIf=\"\n mode === 'main' &&\n isMessageDeliveredAndRead &&\n canDisplayReadStatus;\n else deliveredStatus\n \"\n >\n <ng-container *ngTemplateOutlet=\"readStatus\"></ng-container>\n </ng-container>\n </ng-template>\n </ng-container>\n <stream-avatar\n data-testid=\"avatar\"\n class=\"str-chat-angular__avatar-host\"\n [imageUrl]=\"message?.user?.image\"\n [name]=\"message?.user?.name || message?.user?.id\"\n ></stream-avatar>\n <div class=\"str-chat__message-inner\">\n <div\n class=\"str-chat__message-simple__actions\"\n data-testid=\"message-options\"\n *ngIf=\"areOptionsVisible\"\n >\n <div\n data-testid=\"message-actions-container\"\n class=\"\n str-chat__message-simple__actions__action\n str-chat__message-simple__actions__action--options\n \"\n [class.str-chat-angular__message-simple__actions__action--options--editing]=\"\n isEditing\n \"\n >\n <stream-message-actions-box\n [isOpen]=\"isActionBoxOpen\"\n [isMine]=\"isSentByCurrentUser\"\n [enabledActions]=\"enabledMessageActions\"\n [message]=\"message\"\n (displayedActionsCount)=\"visibleMessageActionsCount = $event\"\n (isEditing)=\"isEditing = $event; isActionBoxOpen = !isEditing\"\n [messageInputTemplate]=\"messageInputTemplate\"\n ></stream-message-actions-box>\n <stream-icon\n *ngIf=\"visibleMessageActionsCount > 0\"\n data-testid=\"action-icon\"\n icon=\"action-icon\"\n (keyup.enter)=\"isActionBoxOpen = !isActionBoxOpen\"\n (click)=\"isActionBoxOpen = !isActionBoxOpen\"\n ></stream-icon>\n </div>\n <!-- eslint-disable @angular-eslint/template/conditional-complexity -->\n <div\n *ngIf=\"\n enabledMessageActions.indexOf('send-reply') !== -1 &&\n mode === 'main'\n \"\n class=\"\n str-chat__message-simple__actions__action\n str-chat__message-simple__actions__action--thread\n \"\n data-testid=\"reply-in-thread\"\n (click)=\"setAsActiveParentMessage()\"\n (keyup.enter)=\"setAsActiveParentMessage()\"\n >\n <stream-icon icon=\"reply-in-thread\"></stream-icon>\n </div>\n <div\n *ngIf=\"\n areReactionsEnabled !== false &&\n canReactToMessage !== false &&\n enabledMessageActions.indexOf('send-reaction') !== -1\n \"\n class=\"\n str-chat__message-simple__actions__action\n str-chat__message-simple__actions__action--reactions\n \"\n data-testid=\"reaction-icon\"\n (click)=\"isReactionSelectorOpen = !isReactionSelectorOpen\"\n (keyup.enter)=\"isReactionSelectorOpen = !isReactionSelectorOpen\"\n >\n <stream-icon icon=\"reaction-icon\"></stream-icon>\n </div>\n </div>\n <!-- eslint-enable @angular-eslint/template/conditional-complexity -->\n <stream-message-reactions\n *ngIf=\"areReactionsEnabled !== false\"\n [messageReactionCounts]=\"message?.reaction_counts || {}\"\n [latestReactions]=\"message?.latest_reactions || []\"\n [(isSelectorOpen)]=\"isReactionSelectorOpen\"\n [messageId]=\"message?.id\"\n [ownReactions]=\"message?.own_reactions || []\"\n ></stream-message-reactions>\n <stream-attachment-list\n *ngIf=\"hasAttachment && !message?.quoted_message\"\n [attachments]=\"message!.attachments!\"\n [messageId]=\"message!.id\"\n ></stream-attachment-list>\n <div class=\"str-chat__message-text\" *ngIf=\"message?.text\">\n <div\n data-testid=\"inner-message\"\n class=\"\n str-chat__message-text-inner str-chat__message-simple-text-inner\n \"\n [class.str-chat__message-light-text-inner--has-attachment]=\"\n hasAttachment\n \"\n (click)=\"\n message?.status === 'failed' && message?.errorStatusCode !== 403\n ? resendMessage()\n : undefined\n \"\n (keyup.enter)=\"\n message?.status === 'failed' && message?.errorStatusCode !== 403\n ? resendMessage()\n : undefined\n \"\n >\n <ng-container *ngTemplateOutlet=\"quotedMessage\"></ng-container>\n <stream-attachment-list\n *ngIf=\"hasAttachment && message?.quoted_message\"\n [attachments]=\"message!.attachments!\"\n [messageId]=\"message!.id\"\n ></stream-attachment-list>\n <div\n data-testid=\"client-error-message\"\n *ngIf=\"message?.type === 'error'\"\n class=\"str-chat__simple-message--error-message\"\n >\n {{ \"streamChat.Error \u00B7 Unsent\" | translate }}\n </div>\n <div\n data-testid=\"error-message\"\n *ngIf=\"message?.status === 'failed'\"\n class=\"str-chat__simple-message--error-message\"\n >\n {{\n (message?.errorStatusCode === 403\n ? \"streamChat.Message Failed \u00B7 Unauthorized\"\n : \"streamChat.Message Failed \u00B7 Click to try again\"\n ) | translate\n }}\n </div>\n <div\n (click)=\"textClicked()\"\n (keyup.enter)=\"textClicked()\"\n data-testid=\"text\"\n >\n <p>\n <!-- eslint-disable-next-line @angular-eslint/template/use-track-by-function -->\n <ng-container *ngFor=\"let part of messageTextParts\">\n <span\n *ngIf=\"part.type === 'text'; else mention\"\n [innerHTML]=\"part.content\"\n ></span>\n <ng-template #mention>\n <ng-container *ngIf=\"mentionTemplate; else defaultMention\">\n <ng-container\n *ngTemplateOutlet=\"\n mentionTemplate;\n context: { user: part.user! }\n \"\n ></ng-container>\n </ng-container>\n <ng-template #defaultMention>\n <b>{{ part.content }}</b>\n </ng-template>\n </ng-template>\n </ng-container>\n </p>\n </div>\n </div>\n </div>\n <div class=\"str-chat__message-simple-reply-button\">\n <button\n *ngIf=\"\n !!message?.reply_count &&\n mode !== 'thread' &&\n enabledMessageActions.indexOf('send-reply') !== -1\n \"\n class=\"str-chat__message-replies-count-button\"\n data-testid=\"reply-count-button\"\n (click)=\"setAsActiveParentMessage()\"\n >\n <stream-icon icon=\"reply\"></stream-icon>\n {{message?.reply_count === 1 ? ('streamChat.1 reply' | translate) : ('streamChat.{{ replyCount }}\n replies' | translate:replyCountParam)}}\n </button>\n </div>\n <div class=\"str-chat__message-data str-chat__message-simple-data\">\n <span\n data-testid=\"sender\"\n *ngIf=\"!isSentByCurrentUser\"\n class=\"str-chat__message-simple-name\"\n >\n {{ message?.user?.name ? message?.user?.name : message?.user?.id }}\n </span>\n <span data-testid=\"date\" class=\"str-chat__message-simple-timestamp\">\n {{ parsedDate }}\n </span>\n </div>\n </div>\n </ng-container>\n </ng-container>\n</div>\n\n<ng-template #sendingStatus>\n <span\n class=\"\n str-chat__message-simple-status str-chat__message-simple-status-angular\n \"\n data-testid=\"sending-indicator\"\n >\n <div class=\"str-chat__tooltip\">\n {{ \"streamChat.Sending...\" | translate }}\n </div>\n <stream-loading-indicator\n data-testid=\"loading-indicator\"\n ></stream-loading-indicator>\n </span>\n</ng-template>\n<ng-template #readStatus>\n <span\n class=\"\n str-chat__message-simple-status str-chat__message-simple-status-angular\n \"\n data-testid=\"read-indicator\"\n >\n <div class=\"str-chat__tooltip\" data-testid=\"read-by-tooltip\">\n {{ readByText }}\n </div>\n <stream-avatar\n class=\"str-chat-angular__avatar-host\"\n data-test-id=\"last-read-user-avatar\"\n [size]=\"15\"\n [imageUrl]=\"lastReadUser?.image\"\n [name]=\"lastReadUser?.name || lastReadUser?.id\"\n ></stream-avatar>\n <span\n data-test-id=\"read-by-length\"\n *ngIf=\"isReadByMultipleUsers\"\n class=\"str-chat__message-simple-status-number\"\n >\n {{ (message?.readBy)!.length }}\n </span>\n </span>\n</ng-template>\n<ng-template #deliveredStatus>\n <span\n *ngIf=\"mode === 'main'\"\n class=\"\n str-chat__message-simple-status str-chat__message-simple-status-angular\n \"\n data-testid=\"delivered-indicator\"\n >\n <div class=\"str-chat__tooltip\">\n {{ \"streamChat.Delivered\" | translate }}\n </div>\n <stream-icon\n data-testid=\"delivered-icon\"\n icon=\"delivered-icon\"\n ></stream-icon>\n </span>\n</ng-template>\n\n<ng-template #deletedMessage>\n <div data-testid=\"message-deleted-component\">\n <div class=\"str-chat__message--deleted-inner\" translate>\n streamChat.This message was deleted...\n </div>\n </div>\n</ng-template>\n\n<ng-template #systemMessage>\n <div data-testid=\"system-message\" class=\"str-chat__message--system\">\n <div class=\"str-chat__message--system__text\">\n <div class=\"str-chat__message--system__line\"></div>\n <p>{{ message?.text }}</p>\n <div class=\"str-chat__message--system__line\"></div>\n </div>\n <div class=\"str-chat__message--system__date\">\n {{ parsedDate }}\n </div>\n </div>\n</ng-template>\n\n<ng-template #quotedMessage>\n <div\n *ngIf=\"message?.quoted_message\"\n class=\"quoted-message\"\n data-testid=\"quoted-message-container\"\n [class.mine]=\"isSentByCurrentUser\"\n >\n <stream-avatar\n data-testid=\"qouted-message-avatar\"\n class=\"str-chat-angular__avatar-host\"\n [imageUrl]=\"message?.quoted_message?.user?.image\"\n [name]=\"\n message?.quoted_message?.user?.name || message?.quoted_message?.user?.id\n \"\n [size]=\"20\"\n ></stream-avatar>\n <div class=\"quoted-message-inner\">\n <stream-attachment-list\n *ngIf=\"\n message?.quoted_message?.attachments &&\n message?.quoted_message?.attachments?.length\n \"\n [attachments]=\"quotedMessageAttachments\"\n [messageId]=\"message?.quoted_message?.id\"\n ></stream-attachment-list>\n <div\n data-testid=\"quoted-message-text\"\n [innerHTML]=\"\n message?.quoted_message?.html || message?.quoted_message?.text\n \"\n ></div>\n </div>\n </div>\n</ng-template>\n", components: [{ type: AvatarComponent, selector: "stream-avatar", inputs: ["name", "imageUrl", "size"] }, { type: MessageActionsBoxComponent, selector: "stream-message-actions-box", inputs: ["messageInputTemplate", "isOpen", "isMine", "message", "enabledActions"], outputs: ["displayedActionsCount", "isEditing"] }, { type: IconComponent, selector: "stream-icon", inputs: ["icon", "size"] }, { type: MessageReactionsComponent, selector: "stream-message-reactions", inputs: ["messageId", "messageReactionCounts", "isSelectorOpen", "latestReactions", "ownReactions"], outputs: ["isSelectorOpenChange"] }, { type: AttachmentListComponent, selector: "stream-attachment-list", inputs: ["messageId", "attachments"] }, { type: LoadingIndicatorComponent, selector: "stream-loading-indicator", inputs: ["size", "color"] }], directives: [{ type: i6__namespace.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i6__namespace.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i6__namespace.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2__namespace.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }], pipes: { "translate": i2__namespace.TranslatePipe } });
4400
+ MessageComponent.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: MessageComponent, deps: [{ token: ChatClientService }, { token: ChannelService }, { token: CustomTemplatesService }, { token: i0__namespace.ChangeDetectorRef }], target: i0__namespace.ɵɵFactoryTarget.Component });
4401
+ MessageComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: MessageComponent, selector: "stream-message", inputs: { message: "message", enabledMessageActions: "enabledMessageActions", isLastSentMessage: "isLastSentMessage", mode: "mode" }, viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true }], usesOnChanges: true, ngImport: i0__namespace, template: "<div\n #container\n class=\"str-chat__message-simple str-chat__message str-chat__message--{{\n message?.type\n }} str-chat__message--{{ message?.status }} {{\n message?.text ? 'str-chat__message--has-text' : 'has-no-text'\n }}\"\n [class.str-chat__message--me]=\"isSentByCurrentUser\"\n [class.str-chat__message-simple--me]=\"isSentByCurrentUser\"\n [class.mobile-press]=\"isPressedOnMobile\"\n [class.str-chat__message--has-attachment]=\"hasAttachment\"\n [class.str-chat__message--with-reactions]=\"hasReactions\"\n data-testid=\"message-container\"\n (mouseleave)=\"isActionBoxOpen = false\"\n>\n <ng-container *ngIf=\"!message?.deleted_at; else deletedMessage\">\n <ng-container *ngIf=\"message?.type !== 'system'; else systemMessage\">\n <ng-container\n *ngIf=\"\n isSentByCurrentUser &&\n ((isLastSentMessage && message?.status === 'received') ||\n message?.status === 'sending')\n \"\n >\n <ng-container *ngIf=\"message?.status === 'sending'; else sentStatus\">\n <ng-container *ngTemplateOutlet=\"sendingStatus\"></ng-container>\n </ng-container>\n <ng-template #sentStatus>\n <ng-container\n *ngIf=\"\n mode === 'main' &&\n isMessageDeliveredAndRead &&\n canDisplayReadStatus;\n else deliveredStatus\n \"\n >\n <ng-container *ngTemplateOutlet=\"readStatus\"></ng-container>\n </ng-container>\n </ng-template>\n </ng-container>\n <stream-avatar-placeholder\n data-testid=\"avatar\"\n class=\"str-chat-angular__avatar-host\"\n [imageUrl]=\"message?.user?.image\"\n [name]=\"message?.user?.name || message?.user?.id\"\n ></stream-avatar-placeholder>\n <div class=\"str-chat__message-inner\">\n <div\n class=\"str-chat__message-simple__actions\"\n data-testid=\"message-options\"\n *ngIf=\"areOptionsVisible\"\n >\n <div\n data-testid=\"message-actions-container\"\n class=\"\n str-chat__message-simple__actions__action\n str-chat__message-simple__actions__action--options\n \"\n [class.str-chat-angular__message-simple__actions__action--options--editing]=\"\n isEditing\n \"\n >\n <ng-template\n #defaultMessageActionsBox\n let-isOpen=\"isOpen\"\n let-isMine=\"isMine\"\n let-enabledActions=\"enabledActions\"\n let-messageInput=\"message\"\n let-displayedActionsCountChaneHanler=\"displayedActionsCountChaneHanler\"\n let-isEditingChangeHandler=\"isEditingChangeHandler\"\n >\n <stream-message-actions-box\n [isOpen]=\"isOpen\"\n [isMine]=\"isMine\"\n [enabledActions]=\"enabledActions\"\n [message]=\"messageInput\"\n (displayedActionsCount)=\"\n displayedActionsCountChaneHanler($event)\n \"\n (isEditing)=\"isEditingChangeHandler($event)\"\n ></stream-message-actions-box>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n messageActionsBoxTemplate || defaultMessageActionsBox;\n context: getMessageActionsBoxContext()\n \"\n ></ng-container>\n <stream-icon-placeholder\n *ngIf=\"visibleMessageActionsCount > 0\"\n data-testid=\"action-icon\"\n icon=\"action-icon\"\n (keyup.enter)=\"isActionBoxOpen = !isActionBoxOpen\"\n (click)=\"isActionBoxOpen = !isActionBoxOpen\"\n ></stream-icon-placeholder>\n </div>\n <!-- eslint-disable @angular-eslint/template/conditional-complexity -->\n <div\n *ngIf=\"\n enabledMessageActions.indexOf('send-reply') !== -1 &&\n mode === 'main'\n \"\n class=\"\n str-chat__message-simple__actions__action\n str-chat__message-simple__actions__action--thread\n \"\n data-testid=\"reply-in-thread\"\n (click)=\"setAsActiveParentMessage()\"\n (keyup.enter)=\"setAsActiveParentMessage()\"\n >\n <stream-icon-placeholder\n icon=\"reply-in-thread\"\n ></stream-icon-placeholder>\n </div>\n <div\n *ngIf=\"canReactToMessage\"\n class=\"\n str-chat__message-simple__actions__action\n str-chat__message-simple__actions__action--reactions\n \"\n data-testid=\"reaction-icon\"\n (click)=\"isReactionSelectorOpen = !isReactionSelectorOpen\"\n (keyup.enter)=\"isReactionSelectorOpen = !isReactionSelectorOpen\"\n >\n <stream-icon-placeholder\n icon=\"reaction-icon\"\n ></stream-icon-placeholder>\n </div>\n </div>\n <!-- eslint-enable @angular-eslint/template/conditional-complexity -->\n <ng-template\n #defaultMessageReactions\n let-messageReactionCounts=\"messageReactionCounts\"\n let-latestReactions=\"latestReactions\"\n let-isSelectorOpen=\"isSelectorOpen\"\n let-isSelectorOpenChangeHandler=\"isSelectorOpenChangeHandler\"\n let-messageId=\"messageId\"\n let-ownReactions=\"ownReactions\"\n >\n <stream-message-reactions\n [messageReactionCounts]=\"messageReactionCounts\"\n [latestReactions]=\"latestReactions\"\n [isSelectorOpen]=\"isSelectorOpen\"\n (isSelectorOpenChange)=\"isSelectorOpenChangeHandler($event)\"\n [messageId]=\"messageId\"\n [ownReactions]=\"ownReactions\"\n ></stream-message-reactions>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n messageReactionsTemplate || defaultMessageReactions;\n context: getMessageReactionsContext()\n \"\n ></ng-container>\n <ng-container *ngIf=\"hasAttachment && !message?.quoted_message\">\n <ng-template\n #defaultAttachments\n let-messageId=\"messageId\"\n let-attachments=\"attachments\"\n >\n <stream-attachment-list\n [messageId]=\"messageId\"\n [attachments]=\"attachments\"\n ></stream-attachment-list>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n attachmentListTemplate || defaultAttachments;\n context: getAttachmentListContext()\n \"\n ></ng-container>\n </ng-container>\n <div class=\"str-chat__message-text\" *ngIf=\"message?.text\">\n <div\n data-testid=\"inner-message\"\n class=\"\n str-chat__message-text-inner str-chat__message-simple-text-inner\n \"\n [class.str-chat__message-light-text-inner--has-attachment]=\"\n hasAttachment\n \"\n (click)=\"\n message?.status === 'failed' && message?.errorStatusCode !== 403\n ? resendMessage()\n : undefined\n \"\n (keyup.enter)=\"\n message?.status === 'failed' && message?.errorStatusCode !== 403\n ? resendMessage()\n : undefined\n \"\n >\n <ng-container *ngTemplateOutlet=\"quotedMessage\"></ng-container>\n <stream-attachment-list\n *ngIf=\"hasAttachment && message?.quoted_message\"\n [attachments]=\"message!.attachments!\"\n [messageId]=\"message!.id\"\n ></stream-attachment-list>\n <div\n data-testid=\"client-error-message\"\n *ngIf=\"message?.type === 'error'\"\n class=\"str-chat__simple-message--error-message\"\n >\n {{ \"streamChat.Error \u00B7 Unsent\" | translate }}\n </div>\n <div\n data-testid=\"error-message\"\n *ngIf=\"message?.status === 'failed'\"\n class=\"str-chat__simple-message--error-message\"\n >\n {{\n (message?.errorStatusCode === 403\n ? \"streamChat.Message Failed \u00B7 Unauthorized\"\n : \"streamChat.Message Failed \u00B7 Click to try again\"\n ) | translate\n }}\n </div>\n <div\n (click)=\"textClicked()\"\n (keyup.enter)=\"textClicked()\"\n data-testid=\"text\"\n >\n <p>\n <!-- eslint-disable-next-line @angular-eslint/template/use-track-by-function -->\n <ng-container *ngFor=\"let part of messageTextParts\">\n <span\n *ngIf=\"part.type === 'text'; else mention\"\n [innerHTML]=\"part.content\"\n ></span>\n <ng-template #mention>\n <ng-template #defaultMention let-content=\"content\">\n <b>{{ content }}</b>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n mentionTemplate || defaultMention;\n context: getMentionContext(part)\n \"\n ></ng-container>\n </ng-template>\n </ng-container>\n </p>\n </div>\n </div>\n </div>\n <div class=\"str-chat__message-simple-reply-button\">\n <button\n *ngIf=\"\n !!message?.reply_count &&\n mode !== 'thread' &&\n enabledMessageActions.indexOf('send-reply') !== -1\n \"\n class=\"str-chat__message-replies-count-button\"\n data-testid=\"reply-count-button\"\n (click)=\"setAsActiveParentMessage()\"\n >\n <stream-icon-placeholder icon=\"reply\"></stream-icon-placeholder>\n {{message?.reply_count === 1 ? ('streamChat.1 reply' | translate) : ('streamChat.{{ replyCount }}\n replies' | translate:replyCountParam)}}\n </button>\n </div>\n <div class=\"str-chat__message-data str-chat__message-simple-data\">\n <span\n data-testid=\"sender\"\n *ngIf=\"!isSentByCurrentUser\"\n class=\"str-chat__message-simple-name\"\n >\n {{ message?.user?.name ? message?.user?.name : message?.user?.id }}\n </span>\n <span data-testid=\"date\" class=\"str-chat__message-simple-timestamp\">\n {{ parsedDate }}\n </span>\n </div>\n </div>\n </ng-container>\n </ng-container>\n</div>\n\n<ng-template #sendingStatus>\n <span\n class=\"\n str-chat__message-simple-status str-chat__message-simple-status-angular\n \"\n data-testid=\"sending-indicator\"\n >\n <div class=\"str-chat__tooltip\">\n {{ \"streamChat.Sending...\" | translate }}\n </div>\n <stream-loading-indicator-placeholder\n data-testid=\"loading-indicator\"\n ></stream-loading-indicator-placeholder>\n </span>\n</ng-template>\n<ng-template #readStatus>\n <span\n class=\"\n str-chat__message-simple-status str-chat__message-simple-status-angular\n \"\n data-testid=\"read-indicator\"\n >\n <div class=\"str-chat__tooltip\" data-testid=\"read-by-tooltip\">\n {{ readByText }}\n </div>\n <stream-avatar-placeholder\n class=\"str-chat-angular__avatar-host\"\n data-test-id=\"last-read-user-avatar\"\n [size]=\"15\"\n [imageUrl]=\"lastReadUser?.image\"\n [name]=\"lastReadUser?.name || lastReadUser?.id\"\n ></stream-avatar-placeholder>\n <span\n data-test-id=\"read-by-length\"\n *ngIf=\"isReadByMultipleUsers\"\n class=\"str-chat__message-simple-status-number\"\n >\n {{ (message?.readBy)!.length }}\n </span>\n </span>\n</ng-template>\n<ng-template #deliveredStatus>\n <span\n *ngIf=\"mode === 'main'\"\n class=\"\n str-chat__message-simple-status str-chat__message-simple-status-angular\n \"\n data-testid=\"delivered-indicator\"\n >\n <div class=\"str-chat__tooltip\">\n {{ \"streamChat.Delivered\" | translate }}\n </div>\n <stream-icon-placeholder\n data-testid=\"delivered-icon\"\n icon=\"delivered-icon\"\n ></stream-icon-placeholder>\n </span>\n</ng-template>\n\n<ng-template #deletedMessage>\n <div data-testid=\"message-deleted-component\">\n <div class=\"str-chat__message--deleted-inner\" translate>\n streamChat.This message was deleted...\n </div>\n </div>\n</ng-template>\n\n<ng-template #systemMessage>\n <div data-testid=\"system-message\" class=\"str-chat__message--system\">\n <div class=\"str-chat__message--system__text\">\n <div class=\"str-chat__message--system__line\"></div>\n <p>{{ message?.text }}</p>\n <div class=\"str-chat__message--system__line\"></div>\n </div>\n <div class=\"str-chat__message--system__date\">\n {{ parsedDate }}\n </div>\n </div>\n</ng-template>\n\n<ng-template #quotedMessage>\n <div\n *ngIf=\"message?.quoted_message\"\n class=\"quoted-message\"\n data-testid=\"quoted-message-container\"\n [class.mine]=\"isSentByCurrentUser\"\n >\n <stream-avatar-placeholder\n data-testid=\"qouted-message-avatar\"\n class=\"str-chat-angular__avatar-host\"\n [imageUrl]=\"message?.quoted_message?.user?.image\"\n [name]=\"\n message?.quoted_message?.user?.name || message?.quoted_message?.user?.id\n \"\n [size]=\"20\"\n ></stream-avatar-placeholder>\n <div class=\"quoted-message-inner\">\n <stream-attachment-list\n *ngIf=\"\n message?.quoted_message?.attachments &&\n message?.quoted_message?.attachments?.length\n \"\n [attachments]=\"quotedMessageAttachments\"\n [messageId]=\"message?.quoted_message?.id\"\n ></stream-attachment-list>\n <div\n data-testid=\"quoted-message-text\"\n [innerHTML]=\"\n message?.quoted_message?.html || message?.quoted_message?.text\n \"\n ></div>\n </div>\n </div>\n</ng-template>\n", components: [{ type: AvatarPlaceholderComponent, selector: "stream-avatar-placeholder", inputs: ["name", "imageUrl", "size"] }, { type: MessageActionsBoxComponent, selector: "stream-message-actions-box", inputs: ["isOpen", "isMine", "message", "enabledActions"], outputs: ["displayedActionsCount", "isEditing"] }, { type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon", "size"] }, { type: MessageReactionsComponent, selector: "stream-message-reactions", inputs: ["messageId", "messageReactionCounts", "isSelectorOpen", "latestReactions", "ownReactions"], outputs: ["isSelectorOpenChange"] }, { type: AttachmentListComponent, selector: "stream-attachment-list", inputs: ["messageId", "attachments"] }, { type: LoadingIndicatorPlaceholderComponent, selector: "stream-loading-indicator-placeholder", inputs: ["size", "color"] }], directives: [{ type: i3__namespace.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3__namespace.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i3__namespace.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2__namespace.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }], pipes: { "translate": i2__namespace.TranslatePipe } });
4114
4402
  i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: MessageComponent, decorators: [{
4115
4403
  type: i0.Component,
4116
4404
  args: [{
@@ -4118,22 +4406,12 @@
4118
4406
  templateUrl: './message.component.html',
4119
4407
  styles: [],
4120
4408
  }]
4121
- }], ctorParameters: function () { return [{ type: ChatClientService }, { type: ChannelService }]; }, propDecorators: { messageInputTemplate: [{
4122
- type: i0.Input
4123
- }], mentionTemplate: [{
4124
- type: i0.Input
4125
- }], message: [{
4409
+ }], ctorParameters: function () { return [{ type: ChatClientService }, { type: ChannelService }, { type: CustomTemplatesService }, { type: i0__namespace.ChangeDetectorRef }]; }, propDecorators: { message: [{
4126
4410
  type: i0.Input
4127
4411
  }], enabledMessageActions: [{
4128
4412
  type: i0.Input
4129
- }], areReactionsEnabled: [{
4130
- type: i0.Input
4131
- }], canReactToMessage: [{
4132
- type: i0.Input
4133
4413
  }], isLastSentMessage: [{
4134
4414
  type: i0.Input
4135
- }], canReceiveReadEvents: [{
4136
- type: i0.Input
4137
4415
  }], mode: [{
4138
4416
  type: i0.Input
4139
4417
  }], container: [{
@@ -4236,12 +4514,13 @@
4236
4514
  * The `AutocompleteTextarea` component is used by the [`MessageInput`](./MessageInputComponent.mdx) component to display the input HTML element where users can type their message.
4237
4515
  */
4238
4516
  var AutocompleteTextareaComponent = /** @class */ (function () {
4239
- function AutocompleteTextareaComponent(channelService, chatClientService, transliterationService, emojiInputService) {
4517
+ function AutocompleteTextareaComponent(channelService, chatClientService, transliterationService, emojiInputService, customTemplatesService) {
4240
4518
  var _this = this;
4241
4519
  this.channelService = channelService;
4242
4520
  this.chatClientService = chatClientService;
4243
4521
  this.transliterationService = transliterationService;
4244
4522
  this.emojiInputService = emojiInputService;
4523
+ this.customTemplatesService = customTemplatesService;
4245
4524
  this.class = 'str-chat__textarea';
4246
4525
  /**
4247
4526
  * The value of the input HTML element.
@@ -4320,6 +4599,8 @@
4320
4599
  selectionStart + emoji.length;
4321
4600
  _this.inputChanged();
4322
4601
  }));
4602
+ this.subscriptions.push(this.customTemplatesService.mentionAutocompleteItemTemplate$.subscribe(function (template) { return (_this.mentionAutocompleteItemTemplate = template); }));
4603
+ this.subscriptions.push(this.customTemplatesService.commandAutocompleteItemTemplate$.subscribe(function (template) { return (_this.commandAutocompleteItemTemplate = template); }));
4323
4604
  this.autocompleteConfig.mentions = [
4324
4605
  this.userMentionConfig,
4325
4606
  this.slashCommandConfig,
@@ -4432,8 +4713,8 @@
4432
4713
  };
4433
4714
  return AutocompleteTextareaComponent;
4434
4715
  }());
4435
- AutocompleteTextareaComponent.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: AutocompleteTextareaComponent, deps: [{ token: ChannelService }, { token: ChatClientService }, { token: TransliterationService }, { token: EmojiInputService }], target: i0__namespace.ɵɵFactoryTarget.Component });
4436
- AutocompleteTextareaComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: AutocompleteTextareaComponent, selector: "stream-autocomplete-textarea", inputs: { value: "value", areMentionsEnabled: "areMentionsEnabled", mentionAutocompleteItemTemplate: "mentionAutocompleteItemTemplate", commandAutocompleteItemTemplate: "commandAutocompleteItemTemplate", mentionScope: "mentionScope" }, outputs: { valueChange: "valueChange", send: "send", userMentions: "userMentions" }, host: { properties: { "class": "this.class" } }, viewQueries: [{ propertyName: "messageInput", first: true, predicate: ["input"], descendants: true }], usesOnChanges: true, ngImport: i0__namespace, template: "<textarea\n [value]=\"value || ''\"\n autofocus\n data-testid=\"textarea\"\n #input\n placeholder=\"{{ 'streamChat.Type your message' | translate }}\"\n class=\"rta__textarea str-chat__textarea__textarea str-chat__angular-textarea\"\n rows=\"1\"\n (input)=\"inputChanged()\"\n (keydown.enter)=\"sent($event)\"\n [mentionConfig]=\"autocompleteConfig\"\n (searchTerm)=\"autcompleteSearchTermChanged($event)\"\n [mentionListTemplate]=\"autocompleteItem\"\n (blur)=\"inputLeft()\"\n></textarea>\n<ng-template #autocompleteItem let-item=\"item\">\n <div class=\"rta rta__item str-chat__emojisearch__item\" [ngSwitch]=\"item.type\">\n <div class=\"rta__entity\" *ngSwitchCase=\"'mention'\">\n <ng-container\n *ngTemplateOutlet=\"\n mentionAutocompleteItemTemplate || defaultMentionTemplate;\n context: { item: item }\n \"\n ></ng-container>\n </div>\n <div class=\"rta__entity\" *ngSwitchCase=\"'command'\">\n <ng-container\n *ngTemplateOutlet=\"\n commandAutocompleteItemTemplate || defaultCommandTemplate;\n context: { item: item }\n \"\n ></ng-container>\n </div>\n </div>\n</ng-template>\n\n<ng-template #defaultCommandTemplate let-item=\"item\">\n <div class=\"str-chat__slash-command\">\n <span class=\"str-chat__slash-command-header\">\n <strong data-testclass=\"command-name\">{{ item.name }}</strong>\n {{ item.args }}\n </span>\n <br />\n <span class=\"str-chat__slash-command-description\">{{\n item.description\n }}</span>\n </div>\n</ng-template>\n\n<ng-template #defaultMentionTemplate let-item=\"item\">\n <div class=\"str-chat__user-item\">\n <stream-avatar\n data-testclass=\"avatar\"\n class=\"str-chat__avatar str-chat__avatar--circle\"\n style=\"height: 20px\"\n [size]=\"20\"\n [imageUrl]=\"item.image || item.user?.image\"\n [name]=\"item.autocompleteLabel\"\n ></stream-avatar>\n <span data-testclass=\"username\" class=\"str-chat__user-item--name\">{{\n item.autocompleteLabel\n }}</span>\n </div>\n</ng-template>\n", components: [{ type: AvatarComponent, selector: "stream-avatar", inputs: ["name", "imageUrl", "size"] }], directives: [{ type: i6__namespace$1.MentionDirective, selector: "[mention], [mentionConfig]", inputs: ["mentionConfig", "mention", "mentionListTemplate"], outputs: ["searchTerm", "itemSelected", "opened", "closed"] }, { type: i6__namespace.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { type: i6__namespace.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { type: i6__namespace.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], pipes: { "translate": i2__namespace.TranslatePipe } });
4716
+ AutocompleteTextareaComponent.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: AutocompleteTextareaComponent, deps: [{ token: ChannelService }, { token: ChatClientService }, { token: TransliterationService }, { token: EmojiInputService }, { token: CustomTemplatesService }], target: i0__namespace.ɵɵFactoryTarget.Component });
4717
+ AutocompleteTextareaComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: AutocompleteTextareaComponent, selector: "stream-autocomplete-textarea", inputs: { value: "value", areMentionsEnabled: "areMentionsEnabled", mentionScope: "mentionScope" }, outputs: { valueChange: "valueChange", send: "send", userMentions: "userMentions" }, host: { properties: { "class": "this.class" } }, viewQueries: [{ propertyName: "messageInput", first: true, predicate: ["input"], descendants: true }], usesOnChanges: true, ngImport: i0__namespace, template: "<textarea\n [value]=\"value || ''\"\n autofocus\n data-testid=\"textarea\"\n #input\n placeholder=\"{{ 'streamChat.Type your message' | translate }}\"\n class=\"rta__textarea str-chat__textarea__textarea str-chat__angular-textarea\"\n rows=\"1\"\n (input)=\"inputChanged()\"\n (keydown.enter)=\"sent($event)\"\n [mentionConfig]=\"autocompleteConfig\"\n (searchTerm)=\"autcompleteSearchTermChanged($event)\"\n [mentionListTemplate]=\"autocompleteItem\"\n (blur)=\"inputLeft()\"\n></textarea>\n<ng-template #autocompleteItem let-item=\"item\">\n <div class=\"rta rta__item str-chat__emojisearch__item\" [ngSwitch]=\"item.type\">\n <div class=\"rta__entity\" *ngSwitchCase=\"'mention'\">\n <ng-container\n *ngTemplateOutlet=\"\n mentionAutocompleteItemTemplate || defaultMentionTemplate;\n context: { item: item }\n \"\n ></ng-container>\n </div>\n <div class=\"rta__entity\" *ngSwitchCase=\"'command'\">\n <ng-container\n *ngTemplateOutlet=\"\n commandAutocompleteItemTemplate || defaultCommandTemplate;\n context: { item: item }\n \"\n ></ng-container>\n </div>\n </div>\n</ng-template>\n\n<ng-template #defaultCommandTemplate let-item=\"item\">\n <div class=\"str-chat__slash-command\">\n <span class=\"str-chat__slash-command-header\">\n <strong data-testclass=\"command-name\">{{ item.name }}</strong>\n {{ item.args }}\n </span>\n <br />\n <span class=\"str-chat__slash-command-description\">{{\n item.description\n }}</span>\n </div>\n</ng-template>\n\n<ng-template #defaultMentionTemplate let-item=\"item\">\n <div class=\"str-chat__user-item\">\n <stream-avatar-placeholder\n data-testclass=\"avatar\"\n class=\"str-chat__avatar str-chat__avatar--circle\"\n style=\"height: 20px\"\n [size]=\"20\"\n [imageUrl]=\"item.image || item.user?.image\"\n [name]=\"item.autocompleteLabel\"\n ></stream-avatar-placeholder>\n <span data-testclass=\"username\" class=\"str-chat__user-item--name\">{{\n item.autocompleteLabel\n }}</span>\n </div>\n</ng-template>\n", components: [{ type: AvatarPlaceholderComponent, selector: "stream-avatar-placeholder", inputs: ["name", "imageUrl", "size"] }], directives: [{ type: i7__namespace.MentionDirective, selector: "[mention], [mentionConfig]", inputs: ["mentionConfig", "mention", "mentionListTemplate"], outputs: ["searchTerm", "itemSelected", "opened", "closed"] }, { type: i3__namespace.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { type: i3__namespace.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { type: i3__namespace.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], pipes: { "translate": i2__namespace.TranslatePipe } });
4437
4718
  i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: AutocompleteTextareaComponent, decorators: [{
4438
4719
  type: i0.Component,
4439
4720
  args: [{
@@ -4441,16 +4722,12 @@
4441
4722
  templateUrl: './autocomplete-textarea.component.html',
4442
4723
  styles: [],
4443
4724
  }]
4444
- }], ctorParameters: function () { return [{ type: ChannelService }, { type: ChatClientService }, { type: TransliterationService }, { type: EmojiInputService }]; }, propDecorators: { class: [{
4725
+ }], ctorParameters: function () { return [{ type: ChannelService }, { type: ChatClientService }, { type: TransliterationService }, { type: EmojiInputService }, { type: CustomTemplatesService }]; }, propDecorators: { class: [{
4445
4726
  type: i0.HostBinding
4446
4727
  }], value: [{
4447
4728
  type: i0.Input
4448
4729
  }], areMentionsEnabled: [{
4449
4730
  type: i0.Input
4450
- }], mentionAutocompleteItemTemplate: [{
4451
- type: i0.Input
4452
- }], commandAutocompleteItemTemplate: [{
4453
- type: i0.Input
4454
4731
  }], mentionScope: [{
4455
4732
  type: i0.Input
4456
4733
  }], valueChange: [{
@@ -4509,20 +4786,12 @@
4509
4786
  * The `MessageList` component renders a scrollable list of messages.
4510
4787
  */
4511
4788
  var MessageListComponent = /** @class */ (function () {
4512
- function MessageListComponent(channelService, chatClientService, imageLoadService) {
4789
+ function MessageListComponent(channelService, chatClientService, imageLoadService, customTemplatesService) {
4513
4790
  var _this = this;
4514
4791
  this.channelService = channelService;
4515
4792
  this.chatClientService = chatClientService;
4516
4793
  this.imageLoadService = imageLoadService;
4517
- /**
4518
- * @deprecated use [channel capabilities](https://getstream.io/chat/docs/javascript/channel_capabilities/?language=javascript) instead. If true, the message reactions are displayed. Users can also react to messages if they have the necessary [channel capability](https://getstream.io/chat/docs/javascript/channel_capabilities/?language=javascript).
4519
- */
4520
- this.areReactionsEnabled = undefined;
4521
- /**
4522
- * @deprecated use [channel capabilities](https://getstream.io/chat/docs/javascript/channel_capabilities/?language=javascript) instead. The list of [actions that are enabled](./MessageActionsBoxComponent.mdx), please note that the user also has to have the necessary [channel capabilities](https://getstream.io/chat/docs/javascript/channel_capabilities/?language=javascript) for actions to work. Unathorized actions won't be displayed on the UI. The `MessgaeList` component makes the necessary checks before passing the actions to the `Message` component.
4523
- */
4524
- /* eslint-disable-next-line @angular-eslint/no-input-rename */
4525
- this.enabledMessageActionsInput = undefined;
4794
+ this.customTemplatesService = customTemplatesService;
4526
4795
  /**
4527
4796
  * Determines if the message list should display channel messages or [thread messages](https://getstream.io/chat/docs/javascript/threads/?language=javascript).
4528
4797
  */
@@ -4531,7 +4800,6 @@
4531
4800
  this.class = 'str-chat-angular__main-panel-inner str-chat-angular__message-list-host';
4532
4801
  this.unreadMessageCount = 0;
4533
4802
  this.groupStyles = [];
4534
- this.authorizedMessageActions = ['flag'];
4535
4803
  this.isUserScrolledUpThreshold = 300;
4536
4804
  this.subscriptions = [];
4537
4805
  this.subscriptions.push(this.channelService.activeChannel$.subscribe(function (channel) {
@@ -4539,39 +4807,7 @@
4539
4807
  _this.resetScrollState();
4540
4808
  var capabilites = (_a = channel === null || channel === void 0 ? void 0 : channel.data) === null || _a === void 0 ? void 0 : _a.own_capabilities;
4541
4809
  if (capabilites) {
4542
- _this.canReactToMessage = capabilites.indexOf('send-reaction') !== -1;
4543
- _this.canReceiveReadEvents = capabilites.indexOf('read-events') !== -1;
4544
- _this.authorizedMessageActions = [];
4545
- if (_this.canReactToMessage) {
4546
- _this.authorizedMessageActions.push('send-reaction');
4547
- }
4548
- if (_this.canReceiveReadEvents) {
4549
- _this.authorizedMessageActions.push('read-events');
4550
- }
4551
- if (capabilites.indexOf('flag-message') !== -1) {
4552
- _this.authorizedMessageActions.push('flag');
4553
- }
4554
- if (capabilites.indexOf('update-own-message') !== -1) {
4555
- _this.authorizedMessageActions.push('edit');
4556
- }
4557
- if (capabilites.indexOf('update-any-message') !== -1) {
4558
- _this.authorizedMessageActions.push('edit');
4559
- _this.authorizedMessageActions.push('edit-any');
4560
- }
4561
- if (capabilites.indexOf('delete-own-message') !== -1) {
4562
- _this.authorizedMessageActions.push('delete');
4563
- }
4564
- if (capabilites.indexOf('delete-any-message') !== -1) {
4565
- _this.authorizedMessageActions.push('delete');
4566
- _this.authorizedMessageActions.push('delete-any');
4567
- }
4568
- if (capabilites.indexOf('send-reply') !== -1) {
4569
- _this.authorizedMessageActions.push('send-reply');
4570
- }
4571
- if (capabilites.indexOf('quote-message') !== -1) {
4572
- _this.authorizedMessageActions.push('quote-message');
4573
- }
4574
- _this.setEnabledActions();
4810
+ _this.enabledMessageActions = capabilites;
4575
4811
  }
4576
4812
  }));
4577
4813
  this.subscriptions.push(this.imageLoadService.imageLoad$.subscribe(function () {
@@ -4592,6 +4828,8 @@
4592
4828
  }
4593
4829
  _this.parentMessage = message;
4594
4830
  }));
4831
+ this.subscriptions.push(this.customTemplatesService.messageTemplate$.subscribe(function (template) { return (_this.messageTemplate = template); }));
4832
+ this.subscriptions.push(this.customTemplatesService.typingIndicatorTemplate$.subscribe(function (template) { return (_this.typingIndicatorTemplate = template); }));
4595
4833
  this.usersTypingInChannel$ = this.channelService.usersTypingInChannel$;
4596
4834
  this.usersTypingInThread$ = this.channelService.usersTypingInThread$;
4597
4835
  }
@@ -4599,9 +4837,6 @@
4599
4837
  this.setMessages$();
4600
4838
  };
4601
4839
  MessageListComponent.prototype.ngOnChanges = function (changes) {
4602
- if (changes.enabledMessageActionsInput) {
4603
- this.setEnabledActions();
4604
- }
4605
4840
  if (changes.mode) {
4606
4841
  this.setMessages$();
4607
4842
  }
@@ -4634,15 +4869,6 @@
4634
4869
  MessageListComponent.prototype.ngOnDestroy = function () {
4635
4870
  this.subscriptions.forEach(function (s) { return s.unsubscribe(); });
4636
4871
  };
4637
- Object.defineProperty(MessageListComponent.prototype, "usersTyping$", {
4638
- get: function () {
4639
- return this.mode === 'thread'
4640
- ? this.usersTypingInThread$
4641
- : this.usersTypingInChannel$;
4642
- },
4643
- enumerable: false,
4644
- configurable: true
4645
- });
4646
4872
  MessageListComponent.prototype.trackByMessageId = function (index, item) {
4647
4873
  return item.id;
4648
4874
  };
@@ -4675,31 +4901,24 @@
4675
4901
  }
4676
4902
  this.prevScrollTop = this.scrollContainer.nativeElement.scrollTop;
4677
4903
  };
4904
+ MessageListComponent.prototype.getTypingIndicatorContext = function () {
4905
+ return {
4906
+ usersTyping$: this.usersTyping$,
4907
+ };
4908
+ };
4909
+ MessageListComponent.prototype.getMessageContext = function (message) {
4910
+ return {
4911
+ message: message,
4912
+ isLastSentMessage: !!(this.lastSentMessageId && (message === null || message === void 0 ? void 0 : message.id) === this.lastSentMessageId),
4913
+ enabledMessageActions: this.enabledMessageActions,
4914
+ mode: this.mode,
4915
+ };
4916
+ };
4678
4917
  MessageListComponent.prototype.preserveScrollbarPosition = function () {
4679
4918
  this.scrollContainer.nativeElement.scrollTop =
4680
4919
  (this.prevScrollTop || 0) +
4681
4920
  (this.scrollContainer.nativeElement.scrollHeight - this.containerHeight);
4682
4921
  };
4683
- MessageListComponent.prototype.setEnabledActions = function () {
4684
- var _this = this;
4685
- this.enabledMessageActions = [];
4686
- if (!this.enabledMessageActionsInput) {
4687
- this.enabledMessageActions = this.authorizedMessageActions;
4688
- return;
4689
- }
4690
- this.enabledMessageActionsInput = __spreadArray(__spreadArray([], __read(this.enabledMessageActionsInput)), [
4691
- 'send-reaction',
4692
- 'read-events',
4693
- 'send-reply',
4694
- 'quote-message',
4695
- ]);
4696
- this.enabledMessageActionsInput.forEach(function (action) {
4697
- var isAuthorized = _this.authorizedMessageActions.indexOf(action) !== -1;
4698
- if (isAuthorized) {
4699
- _this.enabledMessageActions.push(action);
4700
- }
4701
- });
4702
- };
4703
4922
  MessageListComponent.prototype.setMessages$ = function () {
4704
4923
  var _this = this;
4705
4924
  this.messages$ = (this.mode === 'main'
@@ -4752,10 +4971,19 @@
4752
4971
  this.prevScrollTop = undefined;
4753
4972
  this.isNewMessageSentByUser = undefined;
4754
4973
  };
4974
+ Object.defineProperty(MessageListComponent.prototype, "usersTyping$", {
4975
+ get: function () {
4976
+ return this.mode === 'thread'
4977
+ ? this.usersTypingInThread$
4978
+ : this.usersTypingInChannel$;
4979
+ },
4980
+ enumerable: false,
4981
+ configurable: true
4982
+ });
4755
4983
  return MessageListComponent;
4756
4984
  }());
4757
- MessageListComponent.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: MessageListComponent, deps: [{ token: ChannelService }, { token: ChatClientService }, { token: ImageLoadService }], target: i0__namespace.ɵɵFactoryTarget.Component });
4758
- MessageListComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: MessageListComponent, selector: "stream-message-list", inputs: { messageTemplate: "messageTemplate", messageInputTemplate: "messageInputTemplate", mentionTemplate: "mentionTemplate", typingIndicatorTemplate: "typingIndicatorTemplate", areReactionsEnabled: "areReactionsEnabled", enabledMessageActionsInput: ["enabledMessageActions", "enabledMessageActionsInput"], mode: "mode" }, host: { properties: { "class": "this.class" } }, viewQueries: [{ propertyName: "scrollContainer", first: true, predicate: ["scrollContainer"], descendants: true }, { propertyName: "parentMessageElement", first: true, predicate: ["parentMessageElement"], descendants: true }], usesOnChanges: true, ngImport: i0__namespace, template: "<div\n #scrollContainer\n data-testid=\"scroll-container\"\n class=\"str-chat__list\"\n (scroll)=\"scrolled()\"\n>\n <div class=\"str-chat__reverse-infinite-scroll\">\n <ul class=\"str-chat__ul\">\n <li\n #parentMessageElement\n *ngIf=\"mode === 'thread'\"\n data-testid=\"parent-message\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n messageTemplateContainer;\n context: { message: parentMessage }\n \"\n ></ng-container>\n <div class=\"str-chat__thread-start\" translate>\n streamChat.Start of a new thread\n </div>\n </li>\n <li\n data-testclass=\"message\"\n *ngFor=\"\n let message of messages$ | async;\n let i = index;\n trackBy: trackByMessageId\n \"\n class=\"str-chat__li str-chat__li--{{ groupStyles[i] }}\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n messageTemplateContainer;\n context: { message: message }\n \"\n ></ng-container>\n </li>\n </ul>\n <ng-container *ngIf=\"typingIndicatorTemplate; else defaultTypingIndicator\">\n <ng-container\n *ngTemplateOutlet=\"\n typingIndicatorTemplate;\n context: { usersTyping$: usersTyping$ }\n \"\n ></ng-container>\n </ng-container>\n <ng-template #defaultTypingIndicator>\n <div\n *ngIf=\"(usersTyping$ | async)?.length\"\n data-testid=\"typing-indicator\"\n class=\"str-chat__typing-indicator str-chat__typing-indicator--typing\"\n >\n <stream-avatar\n *ngFor=\"let user of usersTyping$ | async; trackBy: trackByUserId\"\n [name]=\"user.name || user.id\"\n [imageUrl]=\"user.image\"\n ></stream-avatar>\n <div class=\"str-chat__typing-indicator__dots\">\n <span class=\"str-chat__typing-indicator__dot\"></span>\n <span class=\"str-chat__typing-indicator__dot\"></span>\n <span class=\"str-chat__typing-indicator__dot\"></span>\n </div>\n </div>\n </ng-template>\n </div>\n</div>\n<div class=\"str-chat__list-notifications\">\n <button\n data-testid=\"scroll-to-bottom\"\n *ngIf=\"isUserScrolledUp\"\n class=\"\n str-chat__message-notification\n str-chat__message-notification-right\n str-chat__message-notification-scroll-down\n \"\n (keyup.enter)=\"scrollToBottom()\"\n (click)=\"scrollToBottom()\"\n >\n <div\n *ngIf=\"unreadMessageCount > 0\"\n class=\"\n str-chat__message-notification\n str-chat__message-notification-scroll-down-unread-count\n \"\n >\n {{ unreadMessageCount }}\n </div>\n </button>\n</div>\n\n<ng-template #messageTemplateContainer let-message=\"message\">\n <ng-container *ngIf=\"messageTemplate; else defaultMessageTemplate\">\n <ng-container\n *ngTemplateOutlet=\"\n messageTemplate;\n context: {\n message: message,\n areReactionsEnabled: areReactionsEnabled,\n canReactToMessage: canReactToMessage,\n lastSentMessageId: !!(\n lastSentMessageId && message?.id === lastSentMessageId\n ),\n canReceiveReadEvents: canReceiveReadEvents,\n messageInputTemplate: messageInputTemplate,\n mentionTemplate: mentionTemplate,\n mode: mode,\n enabledMessageActions: enabledMessageActions\n }\n \"\n ></ng-container>\n </ng-container>\n <ng-template #defaultMessageTemplate>\n <stream-message\n [message]=\"message\"\n [areReactionsEnabled]=\"areReactionsEnabled\"\n [canReactToMessage]=\"canReactToMessage\"\n [isLastSentMessage]=\"\n !!(lastSentMessageId && message?.id === lastSentMessageId)\n \"\n [enabledMessageActions]=\"enabledMessageActions\"\n [canReceiveReadEvents]=\"canReceiveReadEvents\"\n [messageInputTemplate]=\"messageInputTemplate\"\n [mentionTemplate]=\"mentionTemplate\"\n [mode]=\"mode\"\n ></stream-message>\n </ng-template>\n</ng-template>\n", components: [{ type: AvatarComponent, selector: "stream-avatar", inputs: ["name", "imageUrl", "size"] }, { type: MessageComponent, selector: "stream-message", inputs: ["messageInputTemplate", "mentionTemplate", "message", "enabledMessageActions", "areReactionsEnabled", "canReactToMessage", "isLastSentMessage", "canReceiveReadEvents", "mode"] }], directives: [{ type: i6__namespace.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i6__namespace.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i2__namespace.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { type: i6__namespace.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], pipes: { "async": i6__namespace.AsyncPipe } });
4985
+ MessageListComponent.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: MessageListComponent, deps: [{ token: ChannelService }, { token: ChatClientService }, { token: ImageLoadService }, { token: CustomTemplatesService }], target: i0__namespace.ɵɵFactoryTarget.Component });
4986
+ MessageListComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: MessageListComponent, selector: "stream-message-list", inputs: { mode: "mode" }, host: { properties: { "class": "this.class" } }, viewQueries: [{ propertyName: "scrollContainer", first: true, predicate: ["scrollContainer"], descendants: true }, { propertyName: "parentMessageElement", first: true, predicate: ["parentMessageElement"], descendants: true }], usesOnChanges: true, ngImport: i0__namespace, template: "<div\n #scrollContainer\n data-testid=\"scroll-container\"\n class=\"str-chat__list\"\n (scroll)=\"scrolled()\"\n>\n <div class=\"str-chat__reverse-infinite-scroll\">\n <ul class=\"str-chat__ul\">\n <li\n #parentMessageElement\n *ngIf=\"mode === 'thread'\"\n data-testid=\"parent-message\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n messageTemplateContainer;\n context: { message: parentMessage }\n \"\n ></ng-container>\n <div class=\"str-chat__thread-start\" translate>\n streamChat.Start of a new thread\n </div>\n </li>\n <li\n data-testclass=\"message\"\n *ngFor=\"\n let message of messages$ | async;\n let i = index;\n trackBy: trackByMessageId\n \"\n class=\"str-chat__li str-chat__li--{{ groupStyles[i] }}\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n messageTemplateContainer;\n context: { message: message }\n \"\n ></ng-container>\n </li>\n </ul>\n <ng-template #defaultTypingIndicator let-usersTyping$=\"usersTyping$\">\n <div\n *ngIf=\"$any(usersTyping$ | async)?.length\"\n data-testid=\"typing-indicator\"\n class=\"str-chat__typing-indicator str-chat__typing-indicator--typing\"\n >\n <stream-avatar-placeholder\n *ngFor=\"let user of usersTyping$ | async; trackBy: trackByUserId\"\n [name]=\"user.name || user.id\"\n [imageUrl]=\"user.image\"\n ></stream-avatar-placeholder>\n <div class=\"str-chat__typing-indicator__dots\">\n <span class=\"str-chat__typing-indicator__dot\"></span>\n <span class=\"str-chat__typing-indicator__dot\"></span>\n <span class=\"str-chat__typing-indicator__dot\"></span>\n </div>\n </div>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n typingIndicatorTemplate || defaultTypingIndicator;\n context: getTypingIndicatorContext()\n \"\n ></ng-container>\n </div>\n</div>\n<div class=\"str-chat__list-notifications\">\n <button\n data-testid=\"scroll-to-bottom\"\n *ngIf=\"isUserScrolledUp\"\n class=\"\n str-chat__message-notification\n str-chat__message-notification-right\n str-chat__message-notification-scroll-down\n \"\n (keyup.enter)=\"scrollToBottom()\"\n (click)=\"scrollToBottom()\"\n >\n <div\n *ngIf=\"unreadMessageCount > 0\"\n class=\"\n str-chat__message-notification\n str-chat__message-notification-scroll-down-unread-count\n \"\n >\n {{ unreadMessageCount }}\n </div>\n </button>\n</div>\n\n<ng-template #messageTemplateContainer let-message=\"message\">\n <ng-template\n #defaultMessageTemplate\n let-messageInput=\"message\"\n let-isLastSentMessage=\"isLastSentMessage\"\n let-enabledMessageActions=\"enabledMessageActions\"\n let-mode=\"mode\"\n >\n <stream-message\n [message]=\"messageInput\"\n [isLastSentMessage]=\"isLastSentMessage\"\n [enabledMessageActions]=\"enabledMessageActions\"\n [mode]=\"mode\"\n ></stream-message>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n messageTemplate || defaultMessageTemplate;\n context: getMessageContext(message)\n \"\n ></ng-container>\n</ng-template>\n", components: [{ type: AvatarPlaceholderComponent, selector: "stream-avatar-placeholder", inputs: ["name", "imageUrl", "size"] }, { type: MessageComponent, selector: "stream-message", inputs: ["message", "enabledMessageActions", "isLastSentMessage", "mode"] }], directives: [{ type: i3__namespace.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3__namespace.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i2__namespace.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { type: i3__namespace.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], pipes: { "async": i3__namespace.AsyncPipe } });
4759
4987
  i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: MessageListComponent, decorators: [{
4760
4988
  type: i0.Component,
4761
4989
  args: [{
@@ -4763,20 +4991,7 @@
4763
4991
  templateUrl: './message-list.component.html',
4764
4992
  styles: [],
4765
4993
  }]
4766
- }], ctorParameters: function () { return [{ type: ChannelService }, { type: ChatClientService }, { type: ImageLoadService }]; }, propDecorators: { messageTemplate: [{
4767
- type: i0.Input
4768
- }], messageInputTemplate: [{
4769
- type: i0.Input
4770
- }], mentionTemplate: [{
4771
- type: i0.Input
4772
- }], typingIndicatorTemplate: [{
4773
- type: i0.Input
4774
- }], areReactionsEnabled: [{
4775
- type: i0.Input
4776
- }], enabledMessageActionsInput: [{
4777
- type: i0.Input,
4778
- args: ['enabledMessageActions']
4779
- }], mode: [{
4994
+ }], ctorParameters: function () { return [{ type: ChannelService }, { type: ChatClientService }, { type: ImageLoadService }, { type: CustomTemplatesService }]; }, propDecorators: { mode: [{
4780
4995
  type: i0.Input
4781
4996
  }], class: [{
4782
4997
  type: i0.HostBinding,
@@ -4793,8 +5008,9 @@
4793
5008
  * The `Thread` component represents a [message thread](https://getstream.io/chat/docs/javascript/threads/?language=javascript), it is a container component that displays a thread with a header, [`MessageList`](./MessageListComponent.mdx) and [`MessageInput`](./MessageInputComponent.mdx) components.
4794
5009
  */
4795
5010
  var ThreadComponent = /** @class */ (function () {
4796
- function ThreadComponent(channelService) {
5011
+ function ThreadComponent(customTemplatesService, channelService) {
4797
5012
  var _this = this;
5013
+ this.customTemplatesService = customTemplatesService;
4798
5014
  this.channelService = channelService;
4799
5015
  this.class = 'str-chat__thread';
4800
5016
  this.subscriptions = [];
@@ -4803,21 +5019,23 @@
4803
5019
  ThreadComponent.prototype.ngOnDestroy = function () {
4804
5020
  this.subscriptions.forEach(function (s) { return s.unsubscribe(); });
4805
5021
  };
4806
- Object.defineProperty(ThreadComponent.prototype, "replyCountParam", {
4807
- get: function () {
4808
- var _a;
4809
- return { replyCount: (_a = this.parentMessage) === null || _a === void 0 ? void 0 : _a.reply_count };
4810
- },
4811
- enumerable: false,
4812
- configurable: true
4813
- });
5022
+ ThreadComponent.prototype.getThreadHeaderContext = function () {
5023
+ var _this = this;
5024
+ return {
5025
+ parentMessage: this.parentMessage,
5026
+ closeThreadHandler: function () { return _this.closeThread(); },
5027
+ };
5028
+ };
5029
+ ThreadComponent.prototype.getReplyCountParam = function (parentMessage) {
5030
+ return { replyCount: parentMessage === null || parentMessage === void 0 ? void 0 : parentMessage.reply_count };
5031
+ };
4814
5032
  ThreadComponent.prototype.closeThread = function () {
4815
5033
  void this.channelService.setAsActiveParentMessage(undefined);
4816
5034
  };
4817
5035
  return ThreadComponent;
4818
5036
  }());
4819
- ThreadComponent.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: ThreadComponent, deps: [{ token: ChannelService }], target: i0__namespace.ɵɵFactoryTarget.Component });
4820
- ThreadComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: ThreadComponent, selector: "stream-thread", host: { properties: { "class": "this.class" } }, ngImport: i0__namespace, template: "<div class=\"str-chat__thread-header\">\n <div class=\"str-chat__thread-header-details\">\n <strong translate>streamChat.Thread</strong>\n <small data-testid=\"reply-count\">\n {{parentMessage?.reply_count === 1 ? ('streamChat.1 reply' | translate) : ('streamChat.{{ replyCount }}\n replies' | translate:replyCountParam)}}\n </small>\n </div>\n <button\n class=\"str-chat__square-button\"\n data-testid=\"close-button\"\n (click)=\"closeThread()\"\n >\n <stream-icon icon=\"close-no-outline\"></stream-icon>\n </button>\n</div>\n<ng-content select='[name=\"thread-message-list\"]'></ng-content>\n<div class=\"str-chat__small-message-input__wrapper\">\n <ng-content select='[name=\"thread-message-input\"]'></ng-content>\n</div>\n", components: [{ type: IconComponent, selector: "stream-icon", inputs: ["icon", "size"] }], directives: [{ type: i2__namespace.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }], pipes: { "translate": i2__namespace.TranslatePipe } });
5037
+ ThreadComponent.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: ThreadComponent, deps: [{ token: CustomTemplatesService }, { token: ChannelService }], target: i0__namespace.ɵɵFactoryTarget.Component });
5038
+ ThreadComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: ThreadComponent, selector: "stream-thread", host: { properties: { "class": "this.class" } }, ngImport: i0__namespace, template: "<ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.threadHeaderTemplate$ | async) ||\n defaultThreadHeader;\n context: getThreadHeaderContext()\n \"\n></ng-container>\n<ng-content select='[name=\"thread-message-list\"]'></ng-content>\n<div class=\"str-chat__small-message-input__wrapper\">\n <ng-content select='[name=\"thread-message-input\"]'></ng-content>\n</div>\n\n<ng-template\n #defaultThreadHeader\n let-parentMessage=\"parentMessage\"\n let-closeThreadHandler=\"closeThreadHandler\"\n>\n <div class=\"str-chat__thread-header\">\n <div class=\"str-chat__thread-header-details\">\n <strong translate>streamChat.Thread</strong>\n <small data-testid=\"reply-count\">\n {{parentMessage?.reply_count === 1 ? ('streamChat.1 reply' | translate) : ('streamChat.{{ replyCount }}\n replies' | translate:getReplyCountParam(parentMessage))}}\n </small>\n </div>\n <button\n class=\"str-chat__square-button\"\n data-testid=\"close-button\"\n (click)=\"closeThreadHandler()\"\n >\n <stream-icon-placeholder\n icon=\"close-no-outline\"\n ></stream-icon-placeholder>\n </button>\n </div>\n</ng-template>\n", components: [{ type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon", "size"] }], directives: [{ type: i3__namespace.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i2__namespace.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }], pipes: { "async": i3__namespace.AsyncPipe, "translate": i2__namespace.TranslatePipe } });
4821
5039
  i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: ThreadComponent, decorators: [{
4822
5040
  type: i0.Component,
4823
5041
  args: [{
@@ -4825,7 +5043,7 @@
4825
5043
  templateUrl: './thread.component.html',
4826
5044
  styles: [],
4827
5045
  }]
4828
- }], ctorParameters: function () { return [{ type: ChannelService }]; }, propDecorators: { class: [{
5046
+ }], ctorParameters: function () { return [{ type: CustomTemplatesService }, { type: ChannelService }]; }, propDecorators: { class: [{
4829
5047
  type: i0.HostBinding,
4830
5048
  args: ['class']
4831
5049
  }] } });
@@ -4836,14 +5054,14 @@
4836
5054
  return StreamAvatarModule;
4837
5055
  }());
4838
5056
  StreamAvatarModule.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: StreamAvatarModule, deps: [], target: i0__namespace.ɵɵFactoryTarget.NgModule });
4839
- StreamAvatarModule.ɵmod = i0__namespace.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: StreamAvatarModule, declarations: [AvatarComponent], imports: [i6.CommonModule, i2.TranslateModule], exports: [AvatarComponent] });
4840
- StreamAvatarModule.ɵinj = i0__namespace.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: StreamAvatarModule, imports: [[i6.CommonModule, i2.TranslateModule]] });
5057
+ StreamAvatarModule.ɵmod = i0__namespace.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: StreamAvatarModule, declarations: [AvatarComponent, AvatarPlaceholderComponent], imports: [i3.CommonModule, i2.TranslateModule], exports: [AvatarComponent, AvatarPlaceholderComponent] });
5058
+ StreamAvatarModule.ɵinj = i0__namespace.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: StreamAvatarModule, imports: [[i3.CommonModule, i2.TranslateModule]] });
4841
5059
  i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: StreamAvatarModule, decorators: [{
4842
5060
  type: i0.NgModule,
4843
5061
  args: [{
4844
- declarations: [AvatarComponent],
4845
- imports: [i6.CommonModule, i2.TranslateModule],
4846
- exports: [AvatarComponent],
5062
+ declarations: [AvatarComponent, AvatarPlaceholderComponent],
5063
+ imports: [i3.CommonModule, i2.TranslateModule],
5064
+ exports: [AvatarComponent, AvatarPlaceholderComponent],
4847
5065
  }]
4848
5066
  }] });
4849
5067
 
@@ -4870,7 +5088,9 @@
4870
5088
  AttachmentPreviewListComponent,
4871
5089
  ModalComponent,
4872
5090
  TextareaDirective,
4873
- ThreadComponent], imports: [i6.CommonModule, i2.TranslateModule, StreamAvatarModule], exports: [ChannelComponent,
5091
+ ThreadComponent,
5092
+ IconPlaceholderComponent,
5093
+ LoadingIndicatorPlaceholderComponent], imports: [i3.CommonModule, i2.TranslateModule, StreamAvatarModule], exports: [ChannelComponent,
4874
5094
  ChannelHeaderComponent,
4875
5095
  ChannelListComponent,
4876
5096
  ChannelPreviewComponent,
@@ -4887,8 +5107,10 @@
4887
5107
  AttachmentPreviewListComponent,
4888
5108
  ModalComponent,
4889
5109
  StreamAvatarModule,
4890
- ThreadComponent] });
4891
- StreamChatModule.ɵinj = i0__namespace.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: StreamChatModule, imports: [[i6.CommonModule, i2.TranslateModule, StreamAvatarModule], StreamAvatarModule] });
5110
+ ThreadComponent,
5111
+ IconPlaceholderComponent,
5112
+ LoadingIndicatorPlaceholderComponent] });
5113
+ StreamChatModule.ɵinj = i0__namespace.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: StreamChatModule, imports: [[i3.CommonModule, i2.TranslateModule, StreamAvatarModule], StreamAvatarModule] });
4892
5114
  i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: StreamChatModule, decorators: [{
4893
5115
  type: i0.NgModule,
4894
5116
  args: [{
@@ -4911,8 +5133,10 @@
4911
5133
  ModalComponent,
4912
5134
  TextareaDirective,
4913
5135
  ThreadComponent,
5136
+ IconPlaceholderComponent,
5137
+ LoadingIndicatorPlaceholderComponent,
4914
5138
  ],
4915
- imports: [i6.CommonModule, i2.TranslateModule, StreamAvatarModule],
5139
+ imports: [i3.CommonModule, i2.TranslateModule, StreamAvatarModule],
4916
5140
  exports: [
4917
5141
  ChannelComponent,
4918
5142
  ChannelHeaderComponent,
@@ -4932,6 +5156,8 @@
4932
5156
  ModalComponent,
4933
5157
  StreamAvatarModule,
4934
5158
  ThreadComponent,
5159
+ IconPlaceholderComponent,
5160
+ LoadingIndicatorPlaceholderComponent,
4935
5161
  ],
4936
5162
  }]
4937
5163
  }] });
@@ -4942,18 +5168,18 @@
4942
5168
  return StreamAutocompleteTextareaModule;
4943
5169
  }());
4944
5170
  StreamAutocompleteTextareaModule.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: StreamAutocompleteTextareaModule, deps: [], target: i0__namespace.ɵɵFactoryTarget.NgModule });
4945
- StreamAutocompleteTextareaModule.ɵmod = i0__namespace.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: StreamAutocompleteTextareaModule, declarations: [AutocompleteTextareaComponent], imports: [i6.CommonModule, i2.TranslateModule, i6$1.MentionModule, StreamAvatarModule], exports: [AutocompleteTextareaComponent] });
5171
+ StreamAutocompleteTextareaModule.ɵmod = i0__namespace.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: StreamAutocompleteTextareaModule, declarations: [AutocompleteTextareaComponent], imports: [i3.CommonModule, i2.TranslateModule, i7.MentionModule, StreamAvatarModule], exports: [AutocompleteTextareaComponent] });
4946
5172
  StreamAutocompleteTextareaModule.ɵinj = i0__namespace.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: StreamAutocompleteTextareaModule, providers: [
4947
5173
  {
4948
5174
  provide: textareaInjectionToken,
4949
5175
  useValue: AutocompleteTextareaComponent,
4950
5176
  },
4951
- ], imports: [[i6.CommonModule, i2.TranslateModule, i6$1.MentionModule, StreamAvatarModule]] });
5177
+ ], imports: [[i3.CommonModule, i2.TranslateModule, i7.MentionModule, StreamAvatarModule]] });
4952
5178
  i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: StreamAutocompleteTextareaModule, decorators: [{
4953
5179
  type: i0.NgModule,
4954
5180
  args: [{
4955
5181
  declarations: [AutocompleteTextareaComponent],
4956
- imports: [i6.CommonModule, i2.TranslateModule, i6$1.MentionModule, StreamAvatarModule],
5182
+ imports: [i3.CommonModule, i2.TranslateModule, i7.MentionModule, StreamAvatarModule],
4957
5183
  exports: [AutocompleteTextareaComponent],
4958
5184
  providers: [
4959
5185
  {
@@ -4970,18 +5196,18 @@
4970
5196
  return StreamTextareaModule;
4971
5197
  }());
4972
5198
  StreamTextareaModule.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: StreamTextareaModule, deps: [], target: i0__namespace.ɵɵFactoryTarget.NgModule });
4973
- StreamTextareaModule.ɵmod = i0__namespace.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: StreamTextareaModule, declarations: [TextareaComponent], imports: [i6.CommonModule, i2.TranslateModule], exports: [TextareaComponent] });
5199
+ StreamTextareaModule.ɵmod = i0__namespace.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: StreamTextareaModule, declarations: [TextareaComponent], imports: [i3.CommonModule, i2.TranslateModule], exports: [TextareaComponent] });
4974
5200
  StreamTextareaModule.ɵinj = i0__namespace.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: StreamTextareaModule, providers: [
4975
5201
  {
4976
5202
  provide: textareaInjectionToken,
4977
5203
  useValue: TextareaComponent,
4978
5204
  },
4979
- ], imports: [[i6.CommonModule, i2.TranslateModule]] });
5205
+ ], imports: [[i3.CommonModule, i2.TranslateModule]] });
4980
5206
  i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: StreamTextareaModule, decorators: [{
4981
5207
  type: i0.NgModule,
4982
5208
  args: [{
4983
5209
  declarations: [TextareaComponent],
4984
- imports: [i6.CommonModule, i2.TranslateModule],
5210
+ imports: [i3.CommonModule, i2.TranslateModule],
4985
5211
  exports: [TextareaComponent],
4986
5212
  providers: [
4987
5213
  {
@@ -5005,6 +5231,7 @@
5005
5231
  exports.AttachmentService = AttachmentService;
5006
5232
  exports.AutocompleteTextareaComponent = AutocompleteTextareaComponent;
5007
5233
  exports.AvatarComponent = AvatarComponent;
5234
+ exports.AvatarPlaceholderComponent = AvatarPlaceholderComponent;
5008
5235
  exports.ChannelComponent = ChannelComponent;
5009
5236
  exports.ChannelHeaderComponent = ChannelHeaderComponent;
5010
5237
  exports.ChannelListComponent = ChannelListComponent;
@@ -5012,10 +5239,13 @@
5012
5239
  exports.ChannelPreviewComponent = ChannelPreviewComponent;
5013
5240
  exports.ChannelService = ChannelService;
5014
5241
  exports.ChatClientService = ChatClientService;
5242
+ exports.CustomTemplatesService = CustomTemplatesService;
5015
5243
  exports.EmojiInputService = EmojiInputService;
5016
5244
  exports.IconComponent = IconComponent;
5245
+ exports.IconPlaceholderComponent = IconPlaceholderComponent;
5017
5246
  exports.ImageLoadService = ImageLoadService;
5018
5247
  exports.LoadingIndicatorComponent = LoadingIndicatorComponent;
5248
+ exports.LoadingIndicatorPlaceholderComponent = LoadingIndicatorPlaceholderComponent;
5019
5249
  exports.MessageActionsBoxComponent = MessageActionsBoxComponent;
5020
5250
  exports.MessageComponent = MessageComponent;
5021
5251
  exports.MessageInputComponent = MessageInputComponent;