stream-chat-angular 6.2.0 → 6.3.0-beta.2

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 (106) hide show
  1. package/assets/i18n/en.d.ts +42 -0
  2. package/assets/version.d.ts +1 -1
  3. package/esm2020/assets/i18n/en.mjs +43 -1
  4. package/esm2020/assets/version.mjs +2 -2
  5. package/esm2020/lib/channel-list/channel-list.component.mjs +3 -3
  6. package/esm2020/lib/channel-preview/channel-preview.component.mjs +4 -1
  7. package/esm2020/lib/channel.service.mjs +6 -3
  8. package/esm2020/lib/custom-templates.service.mjs +9 -1
  9. package/esm2020/lib/icon/icon.component.mjs +1 -1
  10. package/esm2020/lib/message/message.component.mjs +21 -6
  11. package/esm2020/lib/message-actions.service.mjs +5 -1
  12. package/esm2020/lib/message-input/message-input.component.mjs +30 -5
  13. package/esm2020/lib/message-preview.mjs +3 -2
  14. package/esm2020/lib/modal/modal.component.mjs +3 -3
  15. package/esm2020/lib/modal/stream-modal.module.mjs +19 -0
  16. package/esm2020/lib/notification-list/stream-notification.module.mjs +20 -0
  17. package/esm2020/lib/paginated-list/stream-paginated-list.module.mjs +20 -0
  18. package/esm2020/lib/polls/base-poll.component.mjs +87 -0
  19. package/esm2020/lib/polls/poll/poll.component.mjs +34 -0
  20. package/esm2020/lib/polls/poll-actions/add-option/add-option.component.mjs +67 -0
  21. package/esm2020/lib/polls/poll-actions/poll-actions.component.mjs +137 -0
  22. package/esm2020/lib/polls/poll-actions/poll-answers-list/poll-answers-list.component.mjs +82 -0
  23. package/esm2020/lib/polls/poll-actions/poll-results/poll-results-list/poll-results-list.component.mjs +63 -0
  24. package/esm2020/lib/polls/poll-actions/poll-results/poll-vote/poll-vote.component.mjs +33 -0
  25. package/esm2020/lib/polls/poll-actions/poll-results/poll-vote-results-list/poll-vote-results-list.component.mjs +82 -0
  26. package/esm2020/lib/polls/poll-actions/upsert-answer/upsert-answer.component.mjs +60 -0
  27. package/esm2020/lib/polls/poll-composer/poll-composer.component.mjs +134 -0
  28. package/esm2020/lib/polls/poll-composer/validators.mjs +18 -0
  29. package/esm2020/lib/polls/poll-header/poll-header.component.mjs +80 -0
  30. package/esm2020/lib/polls/poll-option-selector/poll-option-selector.component.mjs +137 -0
  31. package/esm2020/lib/polls/poll-options-list/poll-options-list.component.mjs +39 -0
  32. package/esm2020/lib/polls/poll-preview/poll-preview.component.mjs +31 -0
  33. package/esm2020/lib/polls/stream-polls.module.mjs +108 -0
  34. package/esm2020/lib/polls/unique.validator.mjs +13 -0
  35. package/esm2020/lib/stream-chat.module.mjs +26 -19
  36. package/esm2020/lib/types.mjs +1 -1
  37. package/esm2020/public-api.mjs +18 -1
  38. package/fesm2015/stream-chat-angular.mjs +1333 -61
  39. package/fesm2015/stream-chat-angular.mjs.map +1 -1
  40. package/fesm2020/stream-chat-angular.mjs +1291 -59
  41. package/fesm2020/stream-chat-angular.mjs.map +1 -1
  42. package/lib/channel.service.d.ts +2 -1
  43. package/lib/custom-templates.service.d.ts +14 -0
  44. package/lib/icon/icon.component.d.ts +1 -1
  45. package/lib/message/message.component.d.ts +1 -1
  46. package/lib/message-actions.service.d.ts +4 -0
  47. package/lib/message-input/message-input.component.d.ts +11 -1
  48. package/lib/message-preview.d.ts +1 -1
  49. package/lib/modal/stream-modal.module.d.ts +9 -0
  50. package/lib/notification-list/stream-notification.module.d.ts +10 -0
  51. package/lib/paginated-list/stream-paginated-list.module.d.ts +10 -0
  52. package/lib/polls/base-poll.component.d.ts +43 -0
  53. package/lib/polls/poll/poll.component.d.ts +12 -0
  54. package/lib/polls/poll-actions/add-option/add-option.component.d.ts +22 -0
  55. package/lib/polls/poll-actions/poll-actions.component.d.ts +50 -0
  56. package/lib/polls/poll-actions/poll-answers-list/poll-answers-list.component.d.ts +25 -0
  57. package/lib/polls/poll-actions/poll-results/poll-results-list/poll-results-list.component.d.ts +22 -0
  58. package/lib/polls/poll-actions/poll-results/poll-vote/poll-vote.component.d.ts +20 -0
  59. package/lib/polls/poll-actions/poll-results/poll-vote-results-list/poll-vote-results-list.component.d.ts +24 -0
  60. package/lib/polls/poll-actions/upsert-answer/upsert-answer.component.d.ts +27 -0
  61. package/lib/polls/poll-composer/poll-composer.component.d.ts +43 -0
  62. package/lib/polls/poll-composer/validators.d.ts +3 -0
  63. package/lib/polls/poll-header/poll-header.component.d.ts +19 -0
  64. package/lib/polls/poll-option-selector/poll-option-selector.component.d.ts +27 -0
  65. package/lib/polls/poll-options-list/poll-options-list.component.d.ts +17 -0
  66. package/lib/polls/poll-preview/poll-preview.component.d.ts +13 -0
  67. package/lib/polls/stream-polls.module.d.ts +26 -0
  68. package/lib/polls/unique.validator.d.ts +2 -0
  69. package/lib/stream-chat.module.d.ts +20 -19
  70. package/lib/types.d.ts +2 -1
  71. package/package.json +6 -2
  72. package/public-api.d.ts +17 -0
  73. package/src/assets/i18n/en.ts +46 -0
  74. package/src/assets/styles/css/index.css +1 -1
  75. package/src/assets/styles/css/index.layout.css +1 -1
  76. package/src/assets/styles/scss/AttachmentList/AttachmentList-layout.scss +50 -0
  77. package/src/assets/styles/scss/AttachmentList/AttachmentList-theme.scss +56 -0
  78. package/src/assets/styles/scss/AttachmentPreviewList/AttachmentPreviewList-layout.scss +4 -1
  79. package/src/assets/styles/scss/AttachmentPreviewList/AttachmentPreviewList-theme.scss +11 -0
  80. package/src/assets/styles/scss/Autocomplete/Autocomplete-layout.scss +14 -0
  81. package/src/assets/styles/scss/Autocomplete/Autocomplete-theme.scss +11 -0
  82. package/src/assets/styles/scss/Dialog/Dialog-layout.scss +13 -5
  83. package/src/assets/styles/scss/DropzoneContainer/DropzoneContainer-layout.scss +14 -0
  84. package/src/assets/styles/scss/DropzoneContainer/DropzoneContainer-theme.scss +17 -0
  85. package/src/assets/styles/scss/Form/Form-layout.scss +40 -0
  86. package/src/assets/styles/scss/Form/Form-theme.scss +75 -10
  87. package/src/assets/styles/scss/Icon/Icon-layout.scss +6 -0
  88. package/src/assets/styles/scss/Icon/Icon-theme.scss +4 -0
  89. package/src/assets/styles/scss/LinkPreview/LinkPreview-layout.scss +18 -0
  90. package/src/assets/styles/scss/LinkPreview/LinkPreview-theme.scss +15 -0
  91. package/src/assets/styles/scss/Location/Location-layout.scss +52 -0
  92. package/src/assets/styles/scss/Location/Location-theme.scss +32 -0
  93. package/src/assets/styles/scss/Message/Message-layout.scss +37 -2
  94. package/src/assets/styles/scss/Message/Message-theme.scss +40 -1
  95. package/src/assets/styles/scss/MessageActionsBox/MessageActionsBox-theme.scss +8 -0
  96. package/src/assets/styles/scss/MessageInput/MessageInput-layout.scss +32 -13
  97. package/src/assets/styles/scss/MessageInput/MessageInput-theme.scss +28 -20
  98. package/src/assets/styles/scss/Modal/Modal-layout.scss +2 -0
  99. package/src/assets/styles/scss/Modal/Modal-theme.scss +21 -6
  100. package/src/assets/styles/scss/Poll/Poll-layout.scss +45 -44
  101. package/src/assets/styles/scss/Poll/Poll-theme.scss +8 -36
  102. package/src/assets/styles/scss/_icons.scss +1 -0
  103. package/src/assets/styles/scss/index.layout.scss +3 -1
  104. package/src/assets/styles/scss/index.scss +2 -0
  105. package/src/assets/version.ts +1 -1
  106. /package/src/assets/styles/scss/DragAndDropContainer/{DragAmdDropContainer-layout.scss → DragAndDropContainer-layout.scss} +0 -0
@@ -1,13 +1,13 @@
1
1
  import { __awaiter } from 'tslib';
2
2
  import * as i0 from '@angular/core';
3
3
  import { Injectable, Component, Input, EventEmitter, Output, ViewChild, HostBinding, TemplateRef, ContentChild, ChangeDetectionStrategy, InjectionToken, Directive, NgModule, Inject, Optional } from '@angular/core';
4
- import { BehaviorSubject, ReplaySubject, combineLatest, map as map$1, shareReplay as shareReplay$1, take as take$1, Subject, timer, merge, switchMap, distinctUntilChanged, pairwise, filter as filter$1, of } from 'rxjs';
5
- import { StreamChat } from 'stream-chat';
4
+ import { BehaviorSubject, ReplaySubject, combineLatest, map as map$1, shareReplay as shareReplay$1, take as take$1, pairwise, Subject, timer, merge, switchMap, distinctUntilChanged, filter as filter$1, of } from 'rxjs';
5
+ import { StreamChat, VotingVisibility, isVoteAnswer } from 'stream-chat';
6
6
  import { take, shareReplay, map, first, filter, tap, debounceTime, throttleTime } from 'rxjs/operators';
7
7
  import { v4 } from 'uuid';
8
8
  import * as i6 from '@ngx-translate/core';
9
9
  import { TranslateModule } from '@ngx-translate/core';
10
- import * as i3 from '@angular/common';
10
+ import * as i1 from '@angular/common';
11
11
  import { CommonModule } from '@angular/common';
12
12
  import Dayjs from 'dayjs';
13
13
  import calendar from 'dayjs/plugin/calendar';
@@ -20,8 +20,10 @@ import fixWebmDuration from 'fix-webm-duration';
20
20
  import transliterate from '@stream-io/transliterate';
21
21
  import * as i8$1 from 'angular-mentions';
22
22
  import { MentionModule } from 'angular-mentions';
23
+ import * as i1$1 from '@angular/forms';
24
+ import { FormGroup, FormControl, Validators, FormArray, ReactiveFormsModule } from '@angular/forms';
23
25
 
24
- const version = '6.2.0';
26
+ const version = '6.3.0-beta.2';
25
27
 
26
28
  /**
27
29
  * The `NotificationService` can be used to add or remove notifications. By default the [`NotificationList`](/chat/docs/sdk/angular/components/NotificationListComponent/) component displays the currently active notifications.
@@ -342,10 +344,10 @@ const getMessageTranslation = (message, channel, user) => {
342
344
  }
343
345
  };
344
346
 
345
- const createMessagePreview = (user, text, attachments = [], mentionedUsers = [], parentId = undefined, quotedMessageId = undefined, customData) => {
347
+ const createMessagePreview = (user, text, attachments = [], mentionedUsers = [], parentId = undefined, quotedMessageId = undefined, customData, pollId = undefined) => {
346
348
  const clientSideId = `${user.id}-${v4()}`;
347
349
  return Object.assign({ __html: text, created_at: new Date(), html: text, id: clientSideId, reactions: [], status: 'sending', text, type: 'regular', user,
348
- attachments, mentioned_users: mentionedUsers, parent_id: parentId, quoted_message_id: quotedMessageId }, customData);
350
+ attachments, mentioned_users: mentionedUsers, parent_id: parentId, quoted_message_id: quotedMessageId, poll_id: pollId }, customData);
349
351
  };
350
352
 
351
353
  const getReadBy = (message, channel) => {
@@ -833,8 +835,9 @@ class ChannelService {
833
835
  * @param parentId Id of the parent message (if sending a thread reply)
834
836
  * @param quotedMessageId Id of the message to quote (if sending a quote reply)
835
837
  * @param customData
838
+ * @param pollId Id of the poll (if sending a poll message)
836
839
  */
837
- sendMessage(text, attachments = [], mentionedUsers = [], parentId = undefined, quotedMessageId = undefined, customData = undefined) {
840
+ sendMessage(text, attachments = [], mentionedUsers = [], parentId = undefined, quotedMessageId = undefined, customData = undefined, pollId = undefined) {
838
841
  return __awaiter(this, void 0, void 0, function* () {
839
842
  let input = {
840
843
  text,
@@ -843,11 +846,12 @@ class ChannelService {
843
846
  parentId,
844
847
  quotedMessageId,
845
848
  customData,
849
+ pollId,
846
850
  };
847
851
  if (this.beforeSendMessage) {
848
852
  input = yield this.beforeSendMessage(input);
849
853
  }
850
- const preview = createMessagePreview(this.chatClientService.chatClient.user, input.text, input.attachments, input.mentionedUsers, input.parentId, input.quotedMessageId, input.customData);
854
+ const preview = createMessagePreview(this.chatClientService.chatClient.user, input.text, input.attachments, input.mentionedUsers, input.parentId, input.quotedMessageId, input.customData, input.pollId);
851
855
  const channel = this.activeChannelSubject.getValue();
852
856
  channel.state.addMessageSorted(preview, true);
853
857
  const response = yield this.sendMessageRequest(preview, input.customData);
@@ -1137,7 +1141,7 @@ class ChannelService {
1137
1141
  ])
1138
1142
  : this.activeChannelMessagesSubject.next([...channel.state.messages]);
1139
1143
  try {
1140
- const response = 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((u) => u.id), parent_id: preview.parent_id, quoted_message_id: preview.quoted_message_id }, customData)); // TODO: find out why we need typecast here
1144
+ const response = 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((u) => u.id), parent_id: preview.parent_id, quoted_message_id: preview.quoted_message_id, poll_id: preview.poll_id }, customData)); // TODO: find out why we need typecast here
1141
1145
  channel.state.addMessageSorted(Object.assign(Object.assign({}, response.message), { status: 'received' }), true);
1142
1146
  isThreadReply
1143
1147
  ? this.activeThreadMessagesSubject.next([
@@ -2901,6 +2905,48 @@ const en = {
2901
2905
  'You currently have {{count}} attachments, the maximum is {{max}}': 'You currently have {{count}} attachments, the maximum is {{max}}',
2902
2906
  'and others': 'and others',
2903
2907
  'Message was blocked by moderation policies': 'Message was blocked by moderation policies',
2908
+ 'Vote ended': 'Vote ended',
2909
+ 'Select one': 'Select one',
2910
+ 'Select up to {{count}}': 'Select up to {{count}}',
2911
+ 'Select one or more': 'Select one or more',
2912
+ 'See all options ({{count}})': 'See all options ({{count}})',
2913
+ 'Suggest an option': 'Suggest an option',
2914
+ 'Add a comment': 'Add a comment',
2915
+ 'Update your comment': 'Update your comment',
2916
+ 'View {{ count }} comments': 'View {{ count }} comments',
2917
+ 'View {{ count }} comment': 'View {{ count }} comment',
2918
+ 'View results': 'View results',
2919
+ 'End vote': 'End vote',
2920
+ 'After a poll is closed, no more votes can be cast': 'After a poll is closed, no more votes can be cast',
2921
+ 'Failed to end vote': 'Failed to end vote',
2922
+ 'Failed to cast vote': 'Failed to cast vote',
2923
+ Anonymous: 'Anonymous',
2924
+ '{{ count }} votes': '{{ count }} votes',
2925
+ 'Show all': 'Show all',
2926
+ 'Poll results': 'Poll results',
2927
+ 'Error loading votes': 'Error loading votes',
2928
+ 'Poll comments': 'Poll comments',
2929
+ 'Error loading answers': 'Error loading answers',
2930
+ Comment: 'Comment',
2931
+ 'Failed to add comment': 'Failed to add comment',
2932
+ 'Failed to add option ({{ message }})': 'Failed to add option ({{ message }})',
2933
+ 'Option already exists': 'Option already exists',
2934
+ 'You have reached the maximum number of votes allowed': 'You have reached the maximum number of votes allowed',
2935
+ 'Create poll': 'Create poll',
2936
+ Create: 'Create',
2937
+ Question: 'Question',
2938
+ 'Ask a question': 'Ask a question',
2939
+ 'Question is required': 'Question is required',
2940
+ Options: 'Options',
2941
+ 'Add an option': 'Add an option',
2942
+ 'Multiple answers': 'Multiple answers',
2943
+ 'Maximum number of votes': 'Maximum number of votes',
2944
+ 'Provide a value between {{ min }} and {{ max }}': 'Provide a value between {{ min }} and {{ max }}',
2945
+ 'Anonymous poll': 'Anonymous poll',
2946
+ 'Allow option suggestions': 'Allow option suggestions',
2947
+ 'Allow comments': 'Allow comments',
2948
+ 'Failed to create poll': 'Failed to create poll',
2949
+ 'Provide at least one option': 'Provide at least one option',
2904
2950
  },
2905
2951
  };
2906
2952
 
@@ -3080,7 +3126,7 @@ class AvatarComponent {
3080
3126
  }
3081
3127
  }
3082
3128
  AvatarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: AvatarComponent, deps: [{ token: ChatClientService }, { token: i0.NgZone }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
3083
- AvatarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: AvatarComponent, selector: "stream-avatar", inputs: { name: "name", imageUrl: "imageUrl", location: "location", channel: "channel", user: "user", type: "type", showOnlineIndicator: "showOnlineIndicator", initialsType: "initialsType" }, usesOnChanges: true, ngImport: i0, template: "<div\n class=\"str-chat__avatar str-chat-angular__avatar str-chat__avatar--circle stream-chat__avatar--{{\n location\n }} stream-chat__avatar--{{\n initialsType === 'first-letter-of-first-word'\n ? 'one-letter'\n : 'multiple-letters'\n }}\"\n title=\"{{ name }}\"\n>\n <img\n *ngIf=\"(imageUrl || fallbackChannelImage) && !isError; else fallback\"\n class=\"str-chat__avatar-image\"\n data-testid=\"avatar-img\"\n fetchpriority=\"high\"\n src=\"{{ imageUrl || fallbackChannelImage }}\"\n alt=\"{{ initials }}\"\n (error)=\"isError = true\"\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 *ngIf=\"isOnline && showOnlineIndicator\"\n data-testid=\"online-indicator\"\n class=\"str-chat__avatar--online-indicator\"\n ></div>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
3129
+ AvatarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: AvatarComponent, selector: "stream-avatar", inputs: { name: "name", imageUrl: "imageUrl", location: "location", channel: "channel", user: "user", type: "type", showOnlineIndicator: "showOnlineIndicator", initialsType: "initialsType" }, usesOnChanges: true, ngImport: i0, template: "<div\n class=\"str-chat__avatar str-chat-angular__avatar str-chat__avatar--circle stream-chat__avatar--{{\n location\n }} stream-chat__avatar--{{\n initialsType === 'first-letter-of-first-word'\n ? 'one-letter'\n : 'multiple-letters'\n }}\"\n title=\"{{ name }}\"\n>\n <img\n *ngIf=\"(imageUrl || fallbackChannelImage) && !isError; else fallback\"\n class=\"str-chat__avatar-image\"\n data-testid=\"avatar-img\"\n fetchpriority=\"high\"\n src=\"{{ imageUrl || fallbackChannelImage }}\"\n alt=\"{{ initials }}\"\n (error)=\"isError = true\"\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 *ngIf=\"isOnline && showOnlineIndicator\"\n data-testid=\"online-indicator\"\n class=\"str-chat__avatar--online-indicator\"\n ></div>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
3084
3130
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: AvatarComponent, decorators: [{
3085
3131
  type: Component,
3086
3132
  args: [{ selector: 'stream-avatar', template: "<div\n class=\"str-chat__avatar str-chat-angular__avatar str-chat__avatar--circle stream-chat__avatar--{{\n location\n }} stream-chat__avatar--{{\n initialsType === 'first-letter-of-first-word'\n ? 'one-letter'\n : 'multiple-letters'\n }}\"\n title=\"{{ name }}\"\n>\n <img\n *ngIf=\"(imageUrl || fallbackChannelImage) && !isError; else fallback\"\n class=\"str-chat__avatar-image\"\n data-testid=\"avatar-img\"\n fetchpriority=\"high\"\n src=\"{{ imageUrl || fallbackChannelImage }}\"\n alt=\"{{ initials }}\"\n (error)=\"isError = true\"\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 *ngIf=\"isOnline && showOnlineIndicator\"\n data-testid=\"online-indicator\"\n class=\"str-chat__avatar--online-indicator\"\n ></div>\n</div>\n" }]
@@ -3338,6 +3384,14 @@ class CustomTemplatesService {
3338
3384
  * The template has no effect if you're using a custom `messageTemplate$`
3339
3385
  */
3340
3386
  this.messageBlockedTemplate$ = new BehaviorSubject(undefined);
3387
+ /**
3388
+ * Template to display polls inside [message component](/chat/docs/sdk/angular/components/MessageComponent/). There is no default template, but the `PollsModule` contains default components.
3389
+ */
3390
+ this.pollTemplate$ = new BehaviorSubject(undefined);
3391
+ /**
3392
+ * Template to display poll composer inside [message input component](/chat/docs/sdk/angular/components/MessageInputComponent/). There is no default template, but the `PollsModule` contains default components.
3393
+ */
3394
+ this.pollComposerTemplate$ = new BehaviorSubject(undefined);
3341
3395
  }
3342
3396
  }
3343
3397
  CustomTemplatesService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: CustomTemplatesService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
@@ -3388,7 +3442,7 @@ class AvatarPlaceholderComponent {
3388
3442
  }
3389
3443
  }
3390
3444
  AvatarPlaceholderComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: AvatarPlaceholderComponent, deps: [{ token: CustomTemplatesService }], target: i0.ɵɵFactoryTarget.Component });
3391
- AvatarPlaceholderComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: AvatarPlaceholderComponent, selector: "stream-avatar-placeholder", inputs: { name: "name", imageUrl: "imageUrl", location: "location", channel: "channel", user: "user", type: "type", initialsType: "initialsType", showOnlineIndicator: "showOnlineIndicator" }, usesOnChanges: true, ngImport: i0, template: "<ng-template\n #defaultAvatar\n let-name=\"name\"\n let-imageUrl=\"imageUrl\"\n let-type=\"type\"\n let-channel=\"channel\"\n let-user=\"user\"\n let-location=\"location\"\n let-initialsType=\"initialsType\"\n let-showOnlineIndicator=\"showOnlineIndicator\"\n>\n <stream-avatar\n [name]=\"name\"\n [imageUrl]=\"imageUrl\"\n [type]=\"type\"\n [channel]=\"channel\"\n [user]=\"user\"\n [location]=\"location\"\n [initialsType]=\"initialsType\"\n [showOnlineIndicator]=\"showOnlineIndicator\"\n ></stream-avatar>\n</ng-template>\n<ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.avatarTemplate$ | async) || defaultAvatar;\n context: context\n \"\n></ng-container>\n", dependencies: [{ kind: "directive", type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: AvatarComponent, selector: "stream-avatar", inputs: ["name", "imageUrl", "location", "channel", "user", "type", "showOnlineIndicator", "initialsType"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }] });
3445
+ AvatarPlaceholderComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: AvatarPlaceholderComponent, selector: "stream-avatar-placeholder", inputs: { name: "name", imageUrl: "imageUrl", location: "location", channel: "channel", user: "user", type: "type", initialsType: "initialsType", showOnlineIndicator: "showOnlineIndicator" }, usesOnChanges: true, ngImport: i0, template: "<ng-template\n #defaultAvatar\n let-name=\"name\"\n let-imageUrl=\"imageUrl\"\n let-type=\"type\"\n let-channel=\"channel\"\n let-user=\"user\"\n let-location=\"location\"\n let-initialsType=\"initialsType\"\n let-showOnlineIndicator=\"showOnlineIndicator\"\n>\n <stream-avatar\n [name]=\"name\"\n [imageUrl]=\"imageUrl\"\n [type]=\"type\"\n [channel]=\"channel\"\n [user]=\"user\"\n [location]=\"location\"\n [initialsType]=\"initialsType\"\n [showOnlineIndicator]=\"showOnlineIndicator\"\n ></stream-avatar>\n</ng-template>\n<ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.avatarTemplate$ | async) || defaultAvatar;\n context: context\n \"\n></ng-container>\n", dependencies: [{ kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: AvatarComponent, selector: "stream-avatar", inputs: ["name", "imageUrl", "location", "channel", "user", "type", "showOnlineIndicator", "initialsType"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }] });
3392
3446
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: AvatarPlaceholderComponent, decorators: [{
3393
3447
  type: Component,
3394
3448
  args: [{ selector: 'stream-avatar-placeholder', template: "<ng-template\n #defaultAvatar\n let-name=\"name\"\n let-imageUrl=\"imageUrl\"\n let-type=\"type\"\n let-channel=\"channel\"\n let-user=\"user\"\n let-location=\"location\"\n let-initialsType=\"initialsType\"\n let-showOnlineIndicator=\"showOnlineIndicator\"\n>\n <stream-avatar\n [name]=\"name\"\n [imageUrl]=\"imageUrl\"\n [type]=\"type\"\n [channel]=\"channel\"\n [user]=\"user\"\n [location]=\"location\"\n [initialsType]=\"initialsType\"\n [showOnlineIndicator]=\"showOnlineIndicator\"\n ></stream-avatar>\n</ng-template>\n<ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.avatarTemplate$ | async) || defaultAvatar;\n context: context\n \"\n></ng-container>\n" }]
@@ -3440,7 +3494,7 @@ class IconPlaceholderComponent {
3440
3494
  }
3441
3495
  }
3442
3496
  IconPlaceholderComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: IconPlaceholderComponent, deps: [{ token: CustomTemplatesService }], target: i0.ɵɵFactoryTarget.Component });
3443
- IconPlaceholderComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: { icon: "icon" }, usesOnChanges: true, ngImport: i0, template: "<ng-template #defaultIcon let-icon=\"icon\">\n <stream-icon [icon]=\"icon\"></stream-icon>\n</ng-template>\n<ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.iconTemplate$ | async) || defaultIcon;\n context: iconContext\n \"\n></ng-container>\n", dependencies: [{ kind: "directive", type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: IconComponent, selector: "stream-icon", inputs: ["icon"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }] });
3497
+ IconPlaceholderComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: { icon: "icon" }, usesOnChanges: true, ngImport: i0, template: "<ng-template #defaultIcon let-icon=\"icon\">\n <stream-icon [icon]=\"icon\"></stream-icon>\n</ng-template>\n<ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.iconTemplate$ | async) || defaultIcon;\n context: iconContext\n \"\n></ng-container>\n", dependencies: [{ kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: IconComponent, selector: "stream-icon", inputs: ["icon"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }] });
3444
3498
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: IconPlaceholderComponent, decorators: [{
3445
3499
  type: Component,
3446
3500
  args: [{ selector: 'stream-icon-placeholder', template: "<ng-template #defaultIcon let-icon=\"icon\">\n <stream-icon [icon]=\"icon\"></stream-icon>\n</ng-template>\n<ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.iconTemplate$ | async) || defaultIcon;\n context: iconContext\n \"\n></ng-container>\n" }]
@@ -3470,7 +3524,7 @@ class LoadingIndicatorPlaceholderComponent {
3470
3524
  }
3471
3525
  }
3472
3526
  LoadingIndicatorPlaceholderComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: LoadingIndicatorPlaceholderComponent, deps: [{ token: CustomTemplatesService }], target: i0.ɵɵFactoryTarget.Component });
3473
- LoadingIndicatorPlaceholderComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: LoadingIndicatorPlaceholderComponent, selector: "stream-loading-indicator-placeholder", ngImport: i0, template: "<ng-template #defaultLoadingIndicator>\n <stream-loading-indicator></stream-loading-indicator>\n</ng-template>\n<ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.loadingIndicatorTemplate$ | async) ||\n defaultLoadingIndicator\n \"\n></ng-container>\n", dependencies: [{ kind: "directive", type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: LoadingIndicatorComponent, selector: "stream-loading-indicator" }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }] });
3527
+ LoadingIndicatorPlaceholderComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: LoadingIndicatorPlaceholderComponent, selector: "stream-loading-indicator-placeholder", ngImport: i0, template: "<ng-template #defaultLoadingIndicator>\n <stream-loading-indicator></stream-loading-indicator>\n</ng-template>\n<ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.loadingIndicatorTemplate$ | async) ||\n defaultLoadingIndicator\n \"\n></ng-container>\n", dependencies: [{ kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: LoadingIndicatorComponent, selector: "stream-loading-indicator" }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }] });
3474
3528
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: LoadingIndicatorPlaceholderComponent, decorators: [{
3475
3529
  type: Component,
3476
3530
  args: [{ selector: 'stream-loading-indicator-placeholder', template: "<ng-template #defaultLoadingIndicator>\n <stream-loading-indicator></stream-loading-indicator>\n</ng-template>\n<ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.loadingIndicatorTemplate$ | async) ||\n defaultLoadingIndicator\n \"\n></ng-container>\n" }]
@@ -3615,6 +3669,10 @@ class MessageActionsService {
3615
3669
  * @internal
3616
3670
  */
3617
3671
  this.messageMenuOpenedFor$ = new BehaviorSubject(undefined);
3672
+ /**
3673
+ * @internal
3674
+ */
3675
+ this.modalOpenedForMessage = new BehaviorSubject(undefined);
3618
3676
  this.hasDisplayedClipboardWarning = false;
3619
3677
  combineLatest([
3620
3678
  this.messageToEdit$,
@@ -3775,7 +3833,7 @@ class MessageReactionsSelectorComponent {
3775
3833
  }
3776
3834
  }
3777
3835
  MessageReactionsSelectorComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: MessageReactionsSelectorComponent, deps: [{ token: ChannelService }, { token: MessageReactionsService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
3778
- MessageReactionsSelectorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: MessageReactionsSelectorComponent, selector: "stream-message-reactions-selector", inputs: { ownReactions: "ownReactions", messageId: "messageId" }, ngImport: i0, template: "<div\n #selectorContainer\n data-testid=\"reaction-selector\"\n class=\"str-chat__reaction-selector str-chat-angular-v5__reaction-selector str-chat__message-reaction-selector\"\n>\n <ul\n class=\"str-chat__message-reactions-list str-chat__message-reactions-options\"\n >\n <li\n *ngFor=\"\n let reactionType of reactionOptions;\n trackBy: trackByMessageReaction\n \"\n class=\"str-chat__message-reactions-option str-chat__message-reactions-list-item str-chat__emoji\"\n data-testclass=\"emoji-option\"\n [attr.data-testid]=\"reactionType\"\n [class.str-chat__message-reactions-option-selected]=\"\n isOwnReaction(reactionType)\n \"\n (click)=\"react(reactionType)\"\n (keyup.enter)=\"react(reactionType)\"\n >\n <span\n class=\"emoji str-chat__emoji-selector-emoji-angular str-chat__message-reaction-emoji\"\n >\n {{ getEmojiByReaction(reactionType) }}\n </span>\n </li>\n </ul>\n</div>\n", dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }] });
3836
+ MessageReactionsSelectorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: MessageReactionsSelectorComponent, selector: "stream-message-reactions-selector", inputs: { ownReactions: "ownReactions", messageId: "messageId" }, ngImport: i0, template: "<div\n #selectorContainer\n data-testid=\"reaction-selector\"\n class=\"str-chat__reaction-selector str-chat-angular-v5__reaction-selector str-chat__message-reaction-selector\"\n>\n <ul\n class=\"str-chat__message-reactions-list str-chat__message-reactions-options\"\n >\n <li\n *ngFor=\"\n let reactionType of reactionOptions;\n trackBy: trackByMessageReaction\n \"\n class=\"str-chat__message-reactions-option str-chat__message-reactions-list-item str-chat__emoji\"\n data-testclass=\"emoji-option\"\n [attr.data-testid]=\"reactionType\"\n [class.str-chat__message-reactions-option-selected]=\"\n isOwnReaction(reactionType)\n \"\n (click)=\"react(reactionType)\"\n (keyup.enter)=\"react(reactionType)\"\n >\n <span\n class=\"emoji str-chat__emoji-selector-emoji-angular str-chat__message-reaction-emoji\"\n >\n {{ getEmojiByReaction(reactionType) }}\n </span>\n </li>\n </ul>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }] });
3779
3837
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: MessageReactionsSelectorComponent, decorators: [{
3780
3838
  type: Component,
3781
3839
  args: [{ selector: 'stream-message-reactions-selector', template: "<div\n #selectorContainer\n data-testid=\"reaction-selector\"\n class=\"str-chat__reaction-selector str-chat-angular-v5__reaction-selector str-chat__message-reaction-selector\"\n>\n <ul\n class=\"str-chat__message-reactions-list str-chat__message-reactions-options\"\n >\n <li\n *ngFor=\"\n let reactionType of reactionOptions;\n trackBy: trackByMessageReaction\n \"\n class=\"str-chat__message-reactions-option str-chat__message-reactions-list-item str-chat__emoji\"\n data-testclass=\"emoji-option\"\n [attr.data-testid]=\"reactionType\"\n [class.str-chat__message-reactions-option-selected]=\"\n isOwnReaction(reactionType)\n \"\n (click)=\"react(reactionType)\"\n (keyup.enter)=\"react(reactionType)\"\n >\n <span\n class=\"emoji str-chat__emoji-selector-emoji-angular str-chat__message-reaction-emoji\"\n >\n {{ getEmojiByReaction(reactionType) }}\n </span>\n </li>\n </ul>\n</div>\n" }]
@@ -3889,7 +3947,7 @@ class MessageActionsBoxComponent {
3889
3947
  }
3890
3948
  }
3891
3949
  MessageActionsBoxComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: MessageActionsBoxComponent, deps: [{ token: CustomTemplatesService }, { token: MessageActionsService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
3892
- MessageActionsBoxComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: MessageActionsBoxComponent, selector: "stream-message-actions-box", inputs: { isMine: "isMine", message: "message", messageTextHtmlElement: "messageTextHtmlElement", enabledActions: "enabledActions" }, usesOnChanges: true, ngImport: i0, template: "<div\n #actionBox\n data-testid=\"action-box\"\n class=\"str-chat__message-actions-box str-chat__message-actions-box-angular str-chat__message-actions-box--open\"\n>\n <ul class=\"str-chat__message-actions-list\">\n <ng-container\n *ngFor=\"let item of visibleMessageActionItems; trackBy: trackByActionName\"\n >\n <ng-container [ngSwitch]=\"item.actionName\">\n <ng-container *ngSwitchCase=\"'react'\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.messageReactionsSelectorTemplate$\n | async) || defaultReactionSelector;\n context: getReactionSelectorTemplateContext()\n \"\n ></ng-container>\n </ng-container>\n <ng-container *ngSwitchDefault>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.messageActionsBoxItemTemplate$ | async) ||\n defaultMessageActionItem;\n context: getMessageActionTemplateContext(item)\n \"\n ></ng-container>\n </ng-container>\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 let-actionHandlerExtraParams=\"actionHandlerExtraParams\"\n>\n <button\n class=\"str-chat__message-actions-list-item-button\"\n [attr.data-testid]=\"actionName + '-action'\"\n (click)=\"actionHandler(message, actionHandlerExtraParams)\"\n >\n <li class=\"str-chat__message-actions-list-item\">\n {{ getActionLabel(actionLabelOrTranslationKey) | translate }}\n </li>\n </button>\n</ng-template>\n\n<ng-template\n #defaultReactionSelector\n let-messageId=\"messageId\"\n let-ownReactions=\"ownReactions\"\n>\n <stream-message-reactions-selector\n [messageId]=\"message?.id\"\n [ownReactions]=\"message?.own_reactions || []\"\n ></stream-message-reactions-selector>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i3.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i3.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i3.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "component", type: MessageReactionsSelectorComponent, selector: "stream-message-reactions-selector", inputs: ["ownReactions", "messageId"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.TranslatePipe, name: "translate" }] });
3950
+ MessageActionsBoxComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: MessageActionsBoxComponent, selector: "stream-message-actions-box", inputs: { isMine: "isMine", message: "message", messageTextHtmlElement: "messageTextHtmlElement", enabledActions: "enabledActions" }, usesOnChanges: true, ngImport: i0, template: "<div\n #actionBox\n data-testid=\"action-box\"\n class=\"str-chat__message-actions-box str-chat__message-actions-box-angular str-chat__message-actions-box--open\"\n>\n <ul class=\"str-chat__message-actions-list\">\n <ng-container\n *ngFor=\"let item of visibleMessageActionItems; trackBy: trackByActionName\"\n >\n <ng-container [ngSwitch]=\"item.actionName\">\n <ng-container *ngSwitchCase=\"'react'\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.messageReactionsSelectorTemplate$\n | async) || defaultReactionSelector;\n context: getReactionSelectorTemplateContext()\n \"\n ></ng-container>\n </ng-container>\n <ng-container *ngSwitchDefault>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.messageActionsBoxItemTemplate$ | async) ||\n defaultMessageActionItem;\n context: getMessageActionTemplateContext(item)\n \"\n ></ng-container>\n </ng-container>\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 let-actionHandlerExtraParams=\"actionHandlerExtraParams\"\n>\n <button\n class=\"str-chat__message-actions-list-item-button\"\n [attr.data-testid]=\"actionName + '-action'\"\n (click)=\"actionHandler(message, actionHandlerExtraParams)\"\n >\n <li class=\"str-chat__message-actions-list-item\">\n {{ getActionLabel(actionLabelOrTranslationKey) | translate }}\n </li>\n </button>\n</ng-template>\n\n<ng-template\n #defaultReactionSelector\n let-messageId=\"messageId\"\n let-ownReactions=\"ownReactions\"\n>\n <stream-message-reactions-selector\n [messageId]=\"message?.id\"\n [ownReactions]=\"message?.own_reactions || []\"\n ></stream-message-reactions-selector>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i1.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "component", type: MessageReactionsSelectorComponent, selector: "stream-message-reactions-selector", inputs: ["ownReactions", "messageId"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.TranslatePipe, name: "translate" }] });
3893
3951
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: MessageActionsBoxComponent, decorators: [{
3894
3952
  type: Component,
3895
3953
  args: [{ selector: 'stream-message-actions-box', template: "<div\n #actionBox\n data-testid=\"action-box\"\n class=\"str-chat__message-actions-box str-chat__message-actions-box-angular str-chat__message-actions-box--open\"\n>\n <ul class=\"str-chat__message-actions-list\">\n <ng-container\n *ngFor=\"let item of visibleMessageActionItems; trackBy: trackByActionName\"\n >\n <ng-container [ngSwitch]=\"item.actionName\">\n <ng-container *ngSwitchCase=\"'react'\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.messageReactionsSelectorTemplate$\n | async) || defaultReactionSelector;\n context: getReactionSelectorTemplateContext()\n \"\n ></ng-container>\n </ng-container>\n <ng-container *ngSwitchDefault>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.messageActionsBoxItemTemplate$ | async) ||\n defaultMessageActionItem;\n context: getMessageActionTemplateContext(item)\n \"\n ></ng-container>\n </ng-container>\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 let-actionHandlerExtraParams=\"actionHandlerExtraParams\"\n>\n <button\n class=\"str-chat__message-actions-list-item-button\"\n [attr.data-testid]=\"actionName + '-action'\"\n (click)=\"actionHandler(message, actionHandlerExtraParams)\"\n >\n <li class=\"str-chat__message-actions-list-item\">\n {{ getActionLabel(actionLabelOrTranslationKey) | translate }}\n </li>\n </button>\n</ng-template>\n\n<ng-template\n #defaultReactionSelector\n let-messageId=\"messageId\"\n let-ownReactions=\"ownReactions\"\n>\n <stream-message-reactions-selector\n [messageId]=\"message?.id\"\n [ownReactions]=\"message?.own_reactions || []\"\n ></stream-message-reactions-selector>\n</ng-template>\n" }]
@@ -3910,7 +3968,7 @@ class NotificationComponent {
3910
3968
  constructor() { }
3911
3969
  }
3912
3970
  NotificationComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: NotificationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3913
- NotificationComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: NotificationComponent, selector: "stream-notification", inputs: { type: "type", content: "content" }, ngImport: i0, template: "<div\n data-testid=\"custom-notification\"\n class=\"str-chat__custom-notification notification-{{\n type\n }} str-chat__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", dependencies: [{ kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
3971
+ NotificationComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: NotificationComponent, selector: "stream-notification", inputs: { type: "type", content: "content" }, ngImport: i0, template: "<div\n data-testid=\"custom-notification\"\n class=\"str-chat__custom-notification notification-{{\n type\n }} str-chat__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", dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
3914
3972
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: NotificationComponent, decorators: [{
3915
3973
  type: Component,
3916
3974
  args: [{ selector: 'stream-notification', template: "<div\n data-testid=\"custom-notification\"\n class=\"str-chat__custom-notification notification-{{\n type\n }} str-chat__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" }]
@@ -3939,7 +3997,7 @@ class NotificationListComponent {
3939
3997
  }
3940
3998
  }
3941
3999
  NotificationListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: NotificationListComponent, deps: [{ token: CustomTemplatesService }, { token: NotificationService }, { token: ThemeService }], target: i0.ɵɵFactoryTarget.Component });
3942
- NotificationListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: NotificationListComponent, selector: "stream-notification-list", ngImport: i0, template: "<div\n data-testid=\"notification-list\"\n class=\"str-chat str-chat__theme-{{\n theme$ | async\n }} str-chat__list-notifications\"\n>\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", dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: NotificationComponent, selector: "stream-notification", inputs: ["type", "content"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.TranslatePipe, name: "translate" }] });
4000
+ NotificationListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: NotificationListComponent, selector: "stream-notification-list", ngImport: i0, template: "<div\n data-testid=\"notification-list\"\n class=\"str-chat str-chat__theme-{{\n theme$ | async\n }} str-chat__list-notifications\"\n>\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", dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: NotificationComponent, selector: "stream-notification", inputs: ["type", "content"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.TranslatePipe, name: "translate" }] });
3943
4001
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: NotificationListComponent, decorators: [{
3944
4002
  type: Component,
3945
4003
  args: [{ selector: 'stream-notification-list', template: "<div\n data-testid=\"notification-list\"\n class=\"str-chat str-chat__theme-{{\n theme$ | async\n }} str-chat__list-notifications\"\n>\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" }]
@@ -3996,10 +4054,10 @@ class ModalComponent {
3996
4054
  }
3997
4055
  }
3998
4056
  ModalComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: ModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3999
- ModalComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", 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, 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 >\n <stream-icon-placeholder icon=\"close\"></stream-icon-placeholder>\n </div>\n <div #modalInner class=\"str-chat__modal__inner\">\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", dependencies: [{ kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon"] }] });
4057
+ ModalComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", 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, 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 >\n <stream-icon-placeholder icon=\"close\"></stream-icon-placeholder>\n </div>\n <div\n #modalInner\n class=\"str-chat__modal__inner\"\n (click)=\"$event.stopPropagation()\"\n (keyup.enter)=\"$event.stopPropagation()\"\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</div>\n", dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon"] }] });
4000
4058
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: ModalComponent, decorators: [{
4001
4059
  type: Component,
4002
- args: [{ selector: 'stream-modal', 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 >\n <stream-icon-placeholder icon=\"close\"></stream-icon-placeholder>\n </div>\n <div #modalInner class=\"str-chat__modal__inner\">\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" }]
4060
+ args: [{ selector: 'stream-modal', 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 >\n <stream-icon-placeholder icon=\"close\"></stream-icon-placeholder>\n </div>\n <div\n #modalInner\n class=\"str-chat__modal__inner\"\n (click)=\"$event.stopPropagation()\"\n (keyup.enter)=\"$event.stopPropagation()\"\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</div>\n" }]
4003
4061
  }], ctorParameters: function () { return []; }, propDecorators: { isOpen: [{
4004
4062
  type: Input
4005
4063
  }], content: [{
@@ -4070,7 +4128,7 @@ class MessageBouncePromptComponent {
4070
4128
  }
4071
4129
  }
4072
4130
  MessageBouncePromptComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: MessageBouncePromptComponent, deps: [{ token: ChannelService }, { token: CustomTemplatesService }, { token: MessageActionsService }], target: i0.ɵɵFactoryTarget.Component });
4073
- MessageBouncePromptComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: MessageBouncePromptComponent, selector: "stream-message-bounce-prompt", host: { properties: { "class": "this.class" } }, ngImport: i0, template: "<ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.modalTemplate$ | async) || defaultModal;\n context: {\n message: message,\n isOpen: isModalOpen,\n isOpenChangeHandler: messageBounceModalOpenChanged,\n content: modalContent\n }\n \"\n></ng-container>\n\n<ng-template\n #defaultModal\n let-isOpen=\"isOpen\"\n let-isOpenChangeHandler=\"isOpenChangeHandler\"\n let-content=\"content\"\n>\n <stream-modal\n *ngIf=\"isOpen\"\n [isOpen]=\"isOpen\"\n [content]=\"content\"\n (isOpenChange)=\"isOpenChangeHandler($event)\"\n >\n </stream-modal>\n</ng-template>\n\n<ng-template #modalContent>\n <div\n class=\"str-chat__message-bounce-prompt\"\n data-testid=\"message-bounce-prompt\"\n >\n <div class=\"str-chat__message-bounce-prompt-header\">\n {{\n \"streamChat.This message did not meet our content guidelines\"\n | translate\n }}\n </div>\n <div class=\"str-chat__message-bounce-actions\">\n <button\n class=\"str-chat__message-bounce-edit\"\n data-testid=\"message-bounce-edit\"\n type=\"button\"\n (click)=\"editMessage()\"\n (keyup.enter)=\"editMessage()\"\n >\n {{ \"streamChat.Edit Message\" | translate }}\n </button>\n <button\n class=\"str-chat__message-bounce-send\"\n data-testid=\"message-bounce-send\"\n (click)=\"resendMessage()\"\n (keyup.enter)=\"resendMessage()\"\n >\n {{ \"streamChat.Send Anyway\" | translate }}\n </button>\n <button\n class=\"str-chat__message-bounce-delete\"\n data-testid=\"message-bounce-delete\"\n (click)=\"deleteMessage()\"\n (keyup.enter)=\"deleteMessage()\"\n >\n {{ \"streamChat.Delete\" | translate }}\n </button>\n </div>\n </div>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ModalComponent, selector: "stream-modal", inputs: ["isOpen", "content"], outputs: ["isOpenChange"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.TranslatePipe, name: "translate" }] });
4131
+ MessageBouncePromptComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: MessageBouncePromptComponent, selector: "stream-message-bounce-prompt", host: { properties: { "class": "this.class" } }, ngImport: i0, template: "<ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.modalTemplate$ | async) || defaultModal;\n context: {\n message: message,\n isOpen: isModalOpen,\n isOpenChangeHandler: messageBounceModalOpenChanged,\n content: modalContent\n }\n \"\n></ng-container>\n\n<ng-template\n #defaultModal\n let-isOpen=\"isOpen\"\n let-isOpenChangeHandler=\"isOpenChangeHandler\"\n let-content=\"content\"\n>\n <stream-modal\n *ngIf=\"isOpen\"\n [isOpen]=\"isOpen\"\n [content]=\"content\"\n (isOpenChange)=\"isOpenChangeHandler($event)\"\n >\n </stream-modal>\n</ng-template>\n\n<ng-template #modalContent>\n <div\n class=\"str-chat__message-bounce-prompt\"\n data-testid=\"message-bounce-prompt\"\n >\n <div class=\"str-chat__message-bounce-prompt-header\">\n {{\n \"streamChat.This message did not meet our content guidelines\"\n | translate\n }}\n </div>\n <div class=\"str-chat__message-bounce-actions\">\n <button\n class=\"str-chat__message-bounce-edit\"\n data-testid=\"message-bounce-edit\"\n type=\"button\"\n (click)=\"editMessage()\"\n (keyup.enter)=\"editMessage()\"\n >\n {{ \"streamChat.Edit Message\" | translate }}\n </button>\n <button\n class=\"str-chat__message-bounce-send\"\n data-testid=\"message-bounce-send\"\n (click)=\"resendMessage()\"\n (keyup.enter)=\"resendMessage()\"\n >\n {{ \"streamChat.Send Anyway\" | translate }}\n </button>\n <button\n class=\"str-chat__message-bounce-delete\"\n data-testid=\"message-bounce-delete\"\n (click)=\"deleteMessage()\"\n (keyup.enter)=\"deleteMessage()\"\n >\n {{ \"streamChat.Delete\" | translate }}\n </button>\n </div>\n </div>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ModalComponent, selector: "stream-modal", inputs: ["isOpen", "content"], outputs: ["isOpenChange"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.TranslatePipe, name: "translate" }] });
4074
4132
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: MessageBouncePromptComponent, decorators: [{
4075
4133
  type: Component,
4076
4134
  args: [{ selector: 'stream-message-bounce-prompt', template: "<ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.modalTemplate$ | async) || defaultModal;\n context: {\n message: message,\n isOpen: isModalOpen,\n isOpenChangeHandler: messageBounceModalOpenChanged,\n content: modalContent\n }\n \"\n></ng-container>\n\n<ng-template\n #defaultModal\n let-isOpen=\"isOpen\"\n let-isOpenChangeHandler=\"isOpenChangeHandler\"\n let-content=\"content\"\n>\n <stream-modal\n *ngIf=\"isOpen\"\n [isOpen]=\"isOpen\"\n [content]=\"content\"\n (isOpenChange)=\"isOpenChangeHandler($event)\"\n >\n </stream-modal>\n</ng-template>\n\n<ng-template #modalContent>\n <div\n class=\"str-chat__message-bounce-prompt\"\n data-testid=\"message-bounce-prompt\"\n >\n <div class=\"str-chat__message-bounce-prompt-header\">\n {{\n \"streamChat.This message did not meet our content guidelines\"\n | translate\n }}\n </div>\n <div class=\"str-chat__message-bounce-actions\">\n <button\n class=\"str-chat__message-bounce-edit\"\n data-testid=\"message-bounce-edit\"\n type=\"button\"\n (click)=\"editMessage()\"\n (keyup.enter)=\"editMessage()\"\n >\n {{ \"streamChat.Edit Message\" | translate }}\n </button>\n <button\n class=\"str-chat__message-bounce-send\"\n data-testid=\"message-bounce-send\"\n (click)=\"resendMessage()\"\n (keyup.enter)=\"resendMessage()\"\n >\n {{ \"streamChat.Send Anyway\" | translate }}\n </button>\n <button\n class=\"str-chat__message-bounce-delete\"\n data-testid=\"message-bounce-delete\"\n (click)=\"deleteMessage()\"\n (keyup.enter)=\"deleteMessage()\"\n >\n {{ \"streamChat.Delete\" | translate }}\n </button>\n </div>\n </div>\n</ng-template>\n" }]
@@ -4105,7 +4163,7 @@ class ChannelComponent {
4105
4163
  }
4106
4164
  }
4107
4165
  ChannelComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: ChannelComponent, deps: [{ token: ChannelService }, { token: ThemeService }, { token: CustomTemplatesService }], target: i0.ɵɵFactoryTarget.Component });
4108
- ChannelComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: ChannelComponent, selector: "stream-channel", ngImport: i0, template: "<div\n class=\"str-chat str-chat-channel messaging str-chat__channel str-chat__theme-{{\n theme$ | async\n }}\"\n>\n <div\n *ngIf=\"\n (isError$ | async) === false &&\n (isInitializing$ | async) === false &&\n (isActiveChannel$ | async) === true;\n else noChannel\n \"\n class=\"str-chat__container\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.messageBouncePromptTemplate$ | async) ||\n defaultMessageBouncePrompt\n \"\n ></ng-container>\n <ng-template #defaultMessageBouncePrompt>\n <stream-message-bounce-prompt></stream-message-bounce-prompt>\n </ng-template>\n <div class=\"str-chat__main-panel\">\n <ng-content></ng-content>\n </div>\n <ng-content\n *ngIf=\"isActiveThread$ | async\"\n select='[name=\"thread\"]'\n ></ng-content>\n </div>\n <ng-template #noChannel>\n <div\n *ngIf=\"\n (isInitializing$ | async) === false &&\n ((isError$ | async) === true || (isActiveChannel$ | async) === false)\n \"\n class=\"str-chat__empty-channel\"\n >\n <stream-icon icon=\"chat-bubble\"></stream-icon>\n <p class=\"str-chat__empty-channel-text\">\n {{ \"streamChat.No chats here yet\u2026\" | translate }}\n </p>\n <div class=\"str-chat__empty-channel-notifications\">\n <stream-notification-list></stream-notification-list>\n </div>\n </div>\n <div\n *ngIf=\"\n (isInitializing$ | async) === true &&\n (isError$ | async) === false &&\n (isActiveChannel$ | async) === false\n \"\n class=\"str-chat__loading-channel\"\n >\n <div class=\"str-chat__loading-channel-header\">\n <div class=\"str-chat__loading-channel-header-avatar\"></div>\n <div class=\"str-chat__loading-channel-header-end\">\n <div class=\"str-chat__loading-channel-header-name\"></div>\n <div class=\"str-chat__loading-channel-header-info\"></div>\n </div>\n </div>\n <div class=\"str-chat__loading-channel-message-list\">\n <div class=\"str-chat__loading-channel-message\">\n <div class=\"str-chat__loading-channel-message-avatar\"></div>\n <div class=\"str-chat__loading-channel-message-end\">\n <div class=\"str-chat__loading-channel-message-sender\"></div>\n <div class=\"str-chat__loading-channel-message-last-row\">\n <div class=\"str-chat__loading-channel-message-text\"></div>\n <div class=\"str-chat__loading-channel-message-date\"></div>\n </div>\n </div>\n </div>\n <div class=\"str-chat__loading-channel-message\">\n <div class=\"str-chat__loading-channel-message-avatar\"></div>\n <div class=\"str-chat__loading-channel-message-end\">\n <div class=\"str-chat__loading-channel-message-sender\"></div>\n <div class=\"str-chat__loading-channel-message-last-row\">\n <div class=\"str-chat__loading-channel-message-text\"></div>\n <div class=\"str-chat__loading-channel-message-date\"></div>\n </div>\n </div>\n </div>\n <div class=\"str-chat__loading-channel-message\">\n <div class=\"str-chat__loading-channel-message-avatar\"></div>\n <div class=\"str-chat__loading-channel-message-end\">\n <div class=\"str-chat__loading-channel-message-sender\"></div>\n <div class=\"str-chat__loading-channel-message-last-row\">\n <div class=\"str-chat__loading-channel-message-text\"></div>\n <div class=\"str-chat__loading-channel-message-date\"></div>\n </div>\n </div>\n </div>\n </div>\n <div class=\"str-chat__loading-channel-message-input-row\">\n <div class=\"str-chat__loading-channel-message-input\"></div>\n <div class=\"str-chat__loading-channel-message-send\"></div>\n </div>\n </div>\n </ng-template>\n</div>\n", dependencies: [{ kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: IconComponent, selector: "stream-icon", inputs: ["icon"] }, { kind: "component", type: NotificationListComponent, selector: "stream-notification-list" }, { kind: "component", type: MessageBouncePromptComponent, selector: "stream-message-bounce-prompt" }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.TranslatePipe, name: "translate" }] });
4166
+ ChannelComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: ChannelComponent, selector: "stream-channel", ngImport: i0, template: "<div\n class=\"str-chat str-chat-channel messaging str-chat__channel str-chat__theme-{{\n theme$ | async\n }}\"\n>\n <div\n *ngIf=\"\n (isError$ | async) === false &&\n (isInitializing$ | async) === false &&\n (isActiveChannel$ | async) === true;\n else noChannel\n \"\n class=\"str-chat__container\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.messageBouncePromptTemplate$ | async) ||\n defaultMessageBouncePrompt\n \"\n ></ng-container>\n <ng-template #defaultMessageBouncePrompt>\n <stream-message-bounce-prompt></stream-message-bounce-prompt>\n </ng-template>\n <div class=\"str-chat__main-panel\">\n <ng-content></ng-content>\n </div>\n <ng-content\n *ngIf=\"isActiveThread$ | async\"\n select='[name=\"thread\"]'\n ></ng-content>\n </div>\n <ng-template #noChannel>\n <div\n *ngIf=\"\n (isInitializing$ | async) === false &&\n ((isError$ | async) === true || (isActiveChannel$ | async) === false)\n \"\n class=\"str-chat__empty-channel\"\n >\n <stream-icon icon=\"chat-bubble\"></stream-icon>\n <p class=\"str-chat__empty-channel-text\">\n {{ \"streamChat.No chats here yet\u2026\" | translate }}\n </p>\n <div class=\"str-chat__empty-channel-notifications\">\n <stream-notification-list></stream-notification-list>\n </div>\n </div>\n <div\n *ngIf=\"\n (isInitializing$ | async) === true &&\n (isError$ | async) === false &&\n (isActiveChannel$ | async) === false\n \"\n class=\"str-chat__loading-channel\"\n >\n <div class=\"str-chat__loading-channel-header\">\n <div class=\"str-chat__loading-channel-header-avatar\"></div>\n <div class=\"str-chat__loading-channel-header-end\">\n <div class=\"str-chat__loading-channel-header-name\"></div>\n <div class=\"str-chat__loading-channel-header-info\"></div>\n </div>\n </div>\n <div class=\"str-chat__loading-channel-message-list\">\n <div class=\"str-chat__loading-channel-message\">\n <div class=\"str-chat__loading-channel-message-avatar\"></div>\n <div class=\"str-chat__loading-channel-message-end\">\n <div class=\"str-chat__loading-channel-message-sender\"></div>\n <div class=\"str-chat__loading-channel-message-last-row\">\n <div class=\"str-chat__loading-channel-message-text\"></div>\n <div class=\"str-chat__loading-channel-message-date\"></div>\n </div>\n </div>\n </div>\n <div class=\"str-chat__loading-channel-message\">\n <div class=\"str-chat__loading-channel-message-avatar\"></div>\n <div class=\"str-chat__loading-channel-message-end\">\n <div class=\"str-chat__loading-channel-message-sender\"></div>\n <div class=\"str-chat__loading-channel-message-last-row\">\n <div class=\"str-chat__loading-channel-message-text\"></div>\n <div class=\"str-chat__loading-channel-message-date\"></div>\n </div>\n </div>\n </div>\n <div class=\"str-chat__loading-channel-message\">\n <div class=\"str-chat__loading-channel-message-avatar\"></div>\n <div class=\"str-chat__loading-channel-message-end\">\n <div class=\"str-chat__loading-channel-message-sender\"></div>\n <div class=\"str-chat__loading-channel-message-last-row\">\n <div class=\"str-chat__loading-channel-message-text\"></div>\n <div class=\"str-chat__loading-channel-message-date\"></div>\n </div>\n </div>\n </div>\n </div>\n <div class=\"str-chat__loading-channel-message-input-row\">\n <div class=\"str-chat__loading-channel-message-input\"></div>\n <div class=\"str-chat__loading-channel-message-send\"></div>\n </div>\n </div>\n </ng-template>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: IconComponent, selector: "stream-icon", inputs: ["icon"] }, { kind: "component", type: NotificationListComponent, selector: "stream-notification-list" }, { kind: "component", type: MessageBouncePromptComponent, selector: "stream-message-bounce-prompt" }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.TranslatePipe, name: "translate" }] });
4109
4167
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: ChannelComponent, decorators: [{
4110
4168
  type: Component,
4111
4169
  args: [{ selector: 'stream-channel', template: "<div\n class=\"str-chat str-chat-channel messaging str-chat__channel str-chat__theme-{{\n theme$ | async\n }}\"\n>\n <div\n *ngIf=\"\n (isError$ | async) === false &&\n (isInitializing$ | async) === false &&\n (isActiveChannel$ | async) === true;\n else noChannel\n \"\n class=\"str-chat__container\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.messageBouncePromptTemplate$ | async) ||\n defaultMessageBouncePrompt\n \"\n ></ng-container>\n <ng-template #defaultMessageBouncePrompt>\n <stream-message-bounce-prompt></stream-message-bounce-prompt>\n </ng-template>\n <div class=\"str-chat__main-panel\">\n <ng-content></ng-content>\n </div>\n <ng-content\n *ngIf=\"isActiveThread$ | async\"\n select='[name=\"thread\"]'\n ></ng-content>\n </div>\n <ng-template #noChannel>\n <div\n *ngIf=\"\n (isInitializing$ | async) === false &&\n ((isError$ | async) === true || (isActiveChannel$ | async) === false)\n \"\n class=\"str-chat__empty-channel\"\n >\n <stream-icon icon=\"chat-bubble\"></stream-icon>\n <p class=\"str-chat__empty-channel-text\">\n {{ \"streamChat.No chats here yet\u2026\" | translate }}\n </p>\n <div class=\"str-chat__empty-channel-notifications\">\n <stream-notification-list></stream-notification-list>\n </div>\n </div>\n <div\n *ngIf=\"\n (isInitializing$ | async) === true &&\n (isError$ | async) === false &&\n (isActiveChannel$ | async) === false\n \"\n class=\"str-chat__loading-channel\"\n >\n <div class=\"str-chat__loading-channel-header\">\n <div class=\"str-chat__loading-channel-header-avatar\"></div>\n <div class=\"str-chat__loading-channel-header-end\">\n <div class=\"str-chat__loading-channel-header-name\"></div>\n <div class=\"str-chat__loading-channel-header-info\"></div>\n </div>\n </div>\n <div class=\"str-chat__loading-channel-message-list\">\n <div class=\"str-chat__loading-channel-message\">\n <div class=\"str-chat__loading-channel-message-avatar\"></div>\n <div class=\"str-chat__loading-channel-message-end\">\n <div class=\"str-chat__loading-channel-message-sender\"></div>\n <div class=\"str-chat__loading-channel-message-last-row\">\n <div class=\"str-chat__loading-channel-message-text\"></div>\n <div class=\"str-chat__loading-channel-message-date\"></div>\n </div>\n </div>\n </div>\n <div class=\"str-chat__loading-channel-message\">\n <div class=\"str-chat__loading-channel-message-avatar\"></div>\n <div class=\"str-chat__loading-channel-message-end\">\n <div class=\"str-chat__loading-channel-message-sender\"></div>\n <div class=\"str-chat__loading-channel-message-last-row\">\n <div class=\"str-chat__loading-channel-message-text\"></div>\n <div class=\"str-chat__loading-channel-message-date\"></div>\n </div>\n </div>\n </div>\n <div class=\"str-chat__loading-channel-message\">\n <div class=\"str-chat__loading-channel-message-avatar\"></div>\n <div class=\"str-chat__loading-channel-message-end\">\n <div class=\"str-chat__loading-channel-message-sender\"></div>\n <div class=\"str-chat__loading-channel-message-last-row\">\n <div class=\"str-chat__loading-channel-message-text\"></div>\n <div class=\"str-chat__loading-channel-message-date\"></div>\n </div>\n </div>\n </div>\n </div>\n <div class=\"str-chat__loading-channel-message-input-row\">\n <div class=\"str-chat__loading-channel-message-input\"></div>\n <div class=\"str-chat__loading-channel-message-send\"></div>\n </div>\n </div>\n </ng-template>\n</div>\n" }]
@@ -4197,7 +4255,7 @@ class ChannelHeaderComponent {
4197
4255
  }
4198
4256
  }
4199
4257
  ChannelHeaderComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: ChannelHeaderComponent, deps: [{ token: ChannelService }, { token: CustomTemplatesService }, { token: i0.ChangeDetectorRef }, { token: ChatClientService }], target: i0.ɵɵFactoryTarget.Component });
4200
- ChannelHeaderComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: ChannelHeaderComponent, selector: "stream-channel-header", ngImport: i0, template: "<div class=\"str-chat__header-livestream str-chat__channel-header\">\n <ng-content></ng-content>\n <stream-avatar-placeholder\n type=\"channel\"\n location=\"channel-header\"\n imageUrl=\"{{ activeChannel?.data?.image }}\"\n name=\"{{ avatarName }}\"\n [channel]=\"activeChannel\"\n ></stream-avatar-placeholder>\n <div class=\"str-chat__header-livestream-left str-chat__channel-header-end\">\n <p\n data-testid=\"name\"\n class=\"str-chat__header-livestream-left--title str-chat__channel-header-title\"\n >\n {{ displayText }}\n </p>\n <ng-container\n *ngTemplateOutlet=\"\n channelHeaderInfoTemplate || defaultChannelInfo;\n context: getChannelInfoContext()\n \"\n ></ng-container>\n <ng-template #defaultChannelInfo>\n <p\n data-testid=\"info\"\n class=\"str-chat__header-livestream-left--members str-chat__channel-header-info\"\n >\n {{'streamChat.{{ memberCount }} members' | translate:memberCountParam}}\n {{canReceiveConnectEvents ? ('streamChat.{{ watcherCount }} online' |\n translate:watcherCountParam) : ''}}\n </p>\n </ng-template>\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", dependencies: [{ kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: AvatarPlaceholderComponent, selector: "stream-avatar-placeholder", inputs: ["name", "imageUrl", "location", "channel", "user", "type", "initialsType", "showOnlineIndicator"] }, { kind: "pipe", type: i6.TranslatePipe, name: "translate" }] });
4258
+ ChannelHeaderComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: ChannelHeaderComponent, selector: "stream-channel-header", ngImport: i0, template: "<div class=\"str-chat__header-livestream str-chat__channel-header\">\n <ng-content></ng-content>\n <stream-avatar-placeholder\n type=\"channel\"\n location=\"channel-header\"\n imageUrl=\"{{ activeChannel?.data?.image }}\"\n name=\"{{ avatarName }}\"\n [channel]=\"activeChannel\"\n ></stream-avatar-placeholder>\n <div class=\"str-chat__header-livestream-left str-chat__channel-header-end\">\n <p\n data-testid=\"name\"\n class=\"str-chat__header-livestream-left--title str-chat__channel-header-title\"\n >\n {{ displayText }}\n </p>\n <ng-container\n *ngTemplateOutlet=\"\n channelHeaderInfoTemplate || defaultChannelInfo;\n context: getChannelInfoContext()\n \"\n ></ng-container>\n <ng-template #defaultChannelInfo>\n <p\n data-testid=\"info\"\n class=\"str-chat__header-livestream-left--members str-chat__channel-header-info\"\n >\n {{'streamChat.{{ memberCount }} members' | translate:memberCountParam}}\n {{canReceiveConnectEvents ? ('streamChat.{{ watcherCount }} online' |\n translate:watcherCountParam) : ''}}\n </p>\n </ng-template>\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", dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: AvatarPlaceholderComponent, selector: "stream-avatar-placeholder", inputs: ["name", "imageUrl", "location", "channel", "user", "type", "initialsType", "showOnlineIndicator"] }, { kind: "pipe", type: i6.TranslatePipe, name: "translate" }] });
4201
4259
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: ChannelHeaderComponent, decorators: [{
4202
4260
  type: Component,
4203
4261
  args: [{ selector: 'stream-channel-header', template: "<div class=\"str-chat__header-livestream str-chat__channel-header\">\n <ng-content></ng-content>\n <stream-avatar-placeholder\n type=\"channel\"\n location=\"channel-header\"\n imageUrl=\"{{ activeChannel?.data?.image }}\"\n name=\"{{ avatarName }}\"\n [channel]=\"activeChannel\"\n ></stream-avatar-placeholder>\n <div class=\"str-chat__header-livestream-left str-chat__channel-header-end\">\n <p\n data-testid=\"name\"\n class=\"str-chat__header-livestream-left--title str-chat__channel-header-title\"\n >\n {{ displayText }}\n </p>\n <ng-container\n *ngTemplateOutlet=\"\n channelHeaderInfoTemplate || defaultChannelInfo;\n context: getChannelInfoContext()\n \"\n ></ng-container>\n <ng-template #defaultChannelInfo>\n <p\n data-testid=\"info\"\n class=\"str-chat__header-livestream-left--members str-chat__channel-header-info\"\n >\n {{'streamChat.{{ memberCount }} members' | translate:memberCountParam}}\n {{canReceiveConnectEvents ? ('streamChat.{{ watcherCount }} online' |\n translate:watcherCountParam) : ''}}\n </p>\n </ng-template>\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" }]
@@ -4379,6 +4437,7 @@ class ChannelPreviewComponent {
4379
4437
  });
4380
4438
  }
4381
4439
  setLatestMessage(message) {
4440
+ var _a;
4382
4441
  this.latestMessage = message;
4383
4442
  if (message === null || message === void 0 ? void 0 : message.deleted_at) {
4384
4443
  this.latestMessageText = 'streamChat.Message deleted';
@@ -4390,6 +4449,9 @@ class ChannelPreviewComponent {
4390
4449
  else if ((message === null || message === void 0 ? void 0 : message.attachments) && message.attachments.length) {
4391
4450
  this.latestMessageText = 'streamChat.🏙 Attachment...';
4392
4451
  }
4452
+ else if (message === null || message === void 0 ? void 0 : message.poll_id) {
4453
+ this.latestMessageText = `📊 ${(_a = message.poll) === null || _a === void 0 ? void 0 : _a.name}`;
4454
+ }
4393
4455
  if (this.latestMessage && this.latestMessage.type === 'regular') {
4394
4456
  this.latestMessageTime = isOnSeparateDate(new Date(), this.latestMessage.created_at)
4395
4457
  ? this.dateParser.parseDate(this.latestMessage.created_at)
@@ -4425,7 +4487,7 @@ class ChannelPreviewComponent {
4425
4487
  }
4426
4488
  }
4427
4489
  ChannelPreviewComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: ChannelPreviewComponent, deps: [{ token: ChannelService }, { token: i0.NgZone }, { token: ChatClientService }, { token: MessageService }, { token: CustomTemplatesService }, { token: DateParserService }], target: i0.ɵɵFactoryTarget.Component });
4428
- ChannelPreviewComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: ChannelPreviewComponent, selector: "stream-channel-preview", inputs: { channel: "channel" }, ngImport: i0, template: "<button\n class=\"str-chat__channel-preview-messenger str-chat__channel-preview\"\n data-testid=\"channel-preview-container\"\n [class.str-chat__channel-preview-messenger--active]=\"isActive\"\n [class.str-chat__channel-preview--active]=\"isActive\"\n [class.str-chat__channel-preview-messenger--unread]=\"isUnread\"\n (click)=\"setAsActiveChannel()\"\n>\n <div class=\"str-chat__channel-preview-messenger--left\">\n <stream-avatar-placeholder\n type=\"channel\"\n location=\"channel-preview\"\n name=\"{{ avatarName }}\"\n imageUrl=\"{{ avatarImage }}\"\n [channel]=\"channel\"\n ></stream-avatar-placeholder>\n </div>\n <div\n class=\"str-chat__channel-preview-messenger--right str-chat__channel-preview-end\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.channelPreviewInfoTemplate$ | async) ||\n defaultChannelInfo;\n context: {\n channelDisplayTitle: title,\n channel: channel,\n unreadCount: unreadCount,\n latestMessageText: latestMessageText,\n latestMessageStatus: latestMessageStatus,\n latestMessageTime: latestMessageTime,\n latestMessage: latestMessage\n }\n \"\n ></ng-container>\n <ng-template\n #defaultChannelInfo\n let-channelDisplayTitle=\"channelDisplayTitle\"\n let-unreadCount=\"unreadCount\"\n let-latestMessageText=\"latestMessageText\"\n let-latestMessageStatus=\"latestMessageStatus\"\n let-latestMessageTime=\"latestMessageTime\"\n >\n <div class=\"str-chat__channel-preview-end-first-row\">\n <div class=\"str-chat__channel-preview-messenger--name\">\n <span data-testid=\"channel-preview-title\">{{\n channelDisplayTitle\n }}</span>\n </div>\n <div\n *ngIf=\"unreadCount\"\n data-testid=\"unread-badge\"\n class=\"str-chat__channel-preview-unread-badge\"\n >\n {{ unreadCount }}\n </div>\n </div>\n <div class=\"str-chat__channel-preview-end-second-row\">\n <div\n data-testid=\"latest-message\"\n class=\"str-chat__channel-preview-messenger--last-message\"\n >\n <ng-container *ngIf=\"displayAs === 'text'; else asHTML\">\n {{ latestMessageText | translate }}\n </ng-container>\n <ng-template #asHTML>\n <span\n data-testid=\"html-content\"\n [innerHTML]=\"latestMessageText | translate\"\n ></span>\n </ng-template>\n </div>\n <div\n *ngIf=\"latestMessageStatus\"\n data-testid=\"latest-message-status\"\n class=\"str-chat__channel-preview-messenger--status str-chat__channel-preview-messenger--status-{{\n latestMessageStatus\n }}\"\n >\n <stream-icon-placeholder\n [icon]=\"latestMessageStatus === 'delivered' ? 'delivered' : 'read'\"\n ></stream-icon-placeholder>\n </div>\n <div\n *ngIf=\"latestMessageTime\"\n data-testid=\"latest-message-time\"\n class=\"str-chat__channel-preview-messenger--time\"\n >\n {{ latestMessageTime }}\n </div>\n </div>\n </ng-template>\n </div>\n</button>\n", dependencies: [{ kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: AvatarPlaceholderComponent, selector: "stream-avatar-placeholder", inputs: ["name", "imageUrl", "location", "channel", "user", "type", "initialsType", "showOnlineIndicator"] }, { kind: "component", type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.TranslatePipe, name: "translate" }] });
4490
+ ChannelPreviewComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: ChannelPreviewComponent, selector: "stream-channel-preview", inputs: { channel: "channel" }, ngImport: i0, template: "<button\n class=\"str-chat__channel-preview-messenger str-chat__channel-preview\"\n data-testid=\"channel-preview-container\"\n [class.str-chat__channel-preview-messenger--active]=\"isActive\"\n [class.str-chat__channel-preview--active]=\"isActive\"\n [class.str-chat__channel-preview-messenger--unread]=\"isUnread\"\n (click)=\"setAsActiveChannel()\"\n>\n <div class=\"str-chat__channel-preview-messenger--left\">\n <stream-avatar-placeholder\n type=\"channel\"\n location=\"channel-preview\"\n name=\"{{ avatarName }}\"\n imageUrl=\"{{ avatarImage }}\"\n [channel]=\"channel\"\n ></stream-avatar-placeholder>\n </div>\n <div\n class=\"str-chat__channel-preview-messenger--right str-chat__channel-preview-end\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.channelPreviewInfoTemplate$ | async) ||\n defaultChannelInfo;\n context: {\n channelDisplayTitle: title,\n channel: channel,\n unreadCount: unreadCount,\n latestMessageText: latestMessageText,\n latestMessageStatus: latestMessageStatus,\n latestMessageTime: latestMessageTime,\n latestMessage: latestMessage\n }\n \"\n ></ng-container>\n <ng-template\n #defaultChannelInfo\n let-channelDisplayTitle=\"channelDisplayTitle\"\n let-unreadCount=\"unreadCount\"\n let-latestMessageText=\"latestMessageText\"\n let-latestMessageStatus=\"latestMessageStatus\"\n let-latestMessageTime=\"latestMessageTime\"\n >\n <div class=\"str-chat__channel-preview-end-first-row\">\n <div class=\"str-chat__channel-preview-messenger--name\">\n <span data-testid=\"channel-preview-title\">{{\n channelDisplayTitle\n }}</span>\n </div>\n <div\n *ngIf=\"unreadCount\"\n data-testid=\"unread-badge\"\n class=\"str-chat__channel-preview-unread-badge\"\n >\n {{ unreadCount }}\n </div>\n </div>\n <div class=\"str-chat__channel-preview-end-second-row\">\n <div\n data-testid=\"latest-message\"\n class=\"str-chat__channel-preview-messenger--last-message\"\n >\n <ng-container *ngIf=\"displayAs === 'text'; else asHTML\">\n {{ latestMessageText | translate }}\n </ng-container>\n <ng-template #asHTML>\n <span\n data-testid=\"html-content\"\n [innerHTML]=\"latestMessageText | translate\"\n ></span>\n </ng-template>\n </div>\n <div\n *ngIf=\"latestMessageStatus\"\n data-testid=\"latest-message-status\"\n class=\"str-chat__channel-preview-messenger--status str-chat__channel-preview-messenger--status-{{\n latestMessageStatus\n }}\"\n >\n <stream-icon-placeholder\n [icon]=\"latestMessageStatus === 'delivered' ? 'delivered' : 'read'\"\n ></stream-icon-placeholder>\n </div>\n <div\n *ngIf=\"latestMessageTime\"\n data-testid=\"latest-message-time\"\n class=\"str-chat__channel-preview-messenger--time\"\n >\n {{ latestMessageTime }}\n </div>\n </div>\n </ng-template>\n </div>\n</button>\n", dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: AvatarPlaceholderComponent, selector: "stream-avatar-placeholder", inputs: ["name", "imageUrl", "location", "channel", "user", "type", "initialsType", "showOnlineIndicator"] }, { kind: "component", type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.TranslatePipe, name: "translate" }] });
4429
4491
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: ChannelPreviewComponent, decorators: [{
4430
4492
  type: Component,
4431
4493
  args: [{ selector: 'stream-channel-preview', template: "<button\n class=\"str-chat__channel-preview-messenger str-chat__channel-preview\"\n data-testid=\"channel-preview-container\"\n [class.str-chat__channel-preview-messenger--active]=\"isActive\"\n [class.str-chat__channel-preview--active]=\"isActive\"\n [class.str-chat__channel-preview-messenger--unread]=\"isUnread\"\n (click)=\"setAsActiveChannel()\"\n>\n <div class=\"str-chat__channel-preview-messenger--left\">\n <stream-avatar-placeholder\n type=\"channel\"\n location=\"channel-preview\"\n name=\"{{ avatarName }}\"\n imageUrl=\"{{ avatarImage }}\"\n [channel]=\"channel\"\n ></stream-avatar-placeholder>\n </div>\n <div\n class=\"str-chat__channel-preview-messenger--right str-chat__channel-preview-end\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.channelPreviewInfoTemplate$ | async) ||\n defaultChannelInfo;\n context: {\n channelDisplayTitle: title,\n channel: channel,\n unreadCount: unreadCount,\n latestMessageText: latestMessageText,\n latestMessageStatus: latestMessageStatus,\n latestMessageTime: latestMessageTime,\n latestMessage: latestMessage\n }\n \"\n ></ng-container>\n <ng-template\n #defaultChannelInfo\n let-channelDisplayTitle=\"channelDisplayTitle\"\n let-unreadCount=\"unreadCount\"\n let-latestMessageText=\"latestMessageText\"\n let-latestMessageStatus=\"latestMessageStatus\"\n let-latestMessageTime=\"latestMessageTime\"\n >\n <div class=\"str-chat__channel-preview-end-first-row\">\n <div class=\"str-chat__channel-preview-messenger--name\">\n <span data-testid=\"channel-preview-title\">{{\n channelDisplayTitle\n }}</span>\n </div>\n <div\n *ngIf=\"unreadCount\"\n data-testid=\"unread-badge\"\n class=\"str-chat__channel-preview-unread-badge\"\n >\n {{ unreadCount }}\n </div>\n </div>\n <div class=\"str-chat__channel-preview-end-second-row\">\n <div\n data-testid=\"latest-message\"\n class=\"str-chat__channel-preview-messenger--last-message\"\n >\n <ng-container *ngIf=\"displayAs === 'text'; else asHTML\">\n {{ latestMessageText | translate }}\n </ng-container>\n <ng-template #asHTML>\n <span\n data-testid=\"html-content\"\n [innerHTML]=\"latestMessageText | translate\"\n ></span>\n </ng-template>\n </div>\n <div\n *ngIf=\"latestMessageStatus\"\n data-testid=\"latest-message-status\"\n class=\"str-chat__channel-preview-messenger--status str-chat__channel-preview-messenger--status-{{\n latestMessageStatus\n }}\"\n >\n <stream-icon-placeholder\n [icon]=\"latestMessageStatus === 'delivered' ? 'delivered' : 'read'\"\n ></stream-icon-placeholder>\n </div>\n <div\n *ngIf=\"latestMessageTime\"\n data-testid=\"latest-message-time\"\n class=\"str-chat__channel-preview-messenger--time\"\n >\n {{ latestMessageTime }}\n </div>\n </div>\n </ng-template>\n </div>\n</button>\n" }]
@@ -4501,7 +4563,7 @@ class PaginatedListComponent {
4501
4563
  }
4502
4564
  }
4503
4565
  PaginatedListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: PaginatedListComponent, deps: [{ token: i0.NgZone }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
4504
- PaginatedListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: PaginatedListComponent, selector: "stream-paginated-list", inputs: { items: "items", isLoading: "isLoading", hasMore: "hasMore", trackBy: "trackBy" }, outputs: { loadMore: "loadMore" }, queries: [{ propertyName: "itemTempalteRef", first: true, predicate: TemplateRef, descendants: true }], viewQueries: [{ propertyName: "scrollContainer", first: true, predicate: ["container"], descendants: true }], ngImport: i0, template: "<div class=\"stream-chat__paginated-list\" #container>\n <div\n data-testid=\"item\"\n class=\"stream-chat__paginated-list-item\"\n *ngFor=\"let item of items; let index = index; trackBy: trackBy\"\n >\n <ng-template\n *ngIf=\"itemTempalteRef\"\n [ngTemplateOutlet]=\"itemTempalteRef\"\n [ngTemplateOutletContext]=\"{ item: item, index: index }\"\n ></ng-template>\n </div>\n <button\n *ngIf=\"hasMore && !isScrollable\"\n class=\"str-chat__load-more-button__button str-chat__cta-button\"\n data-testid=\"load-more-button\"\n [disabled]=\"isLoading\"\n (click)=\"loadMore.emit()\"\n (keyup.enter)=\"loadMore.emit()\"\n >\n <span>{{ \"Load more\" | translate }}</span>\n </button>\n <stream-loading-indicator-placeholder\n data-testid=\"loading-indicator\"\n *ngIf=\"isLoading\"\n ></stream-loading-indicator-placeholder>\n</div>\n", dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: LoadingIndicatorPlaceholderComponent, selector: "stream-loading-indicator-placeholder" }, { kind: "pipe", type: i6.TranslatePipe, name: "translate" }] });
4566
+ PaginatedListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: PaginatedListComponent, selector: "stream-paginated-list", inputs: { items: "items", isLoading: "isLoading", hasMore: "hasMore", trackBy: "trackBy" }, outputs: { loadMore: "loadMore" }, queries: [{ propertyName: "itemTempalteRef", first: true, predicate: TemplateRef, descendants: true }], viewQueries: [{ propertyName: "scrollContainer", first: true, predicate: ["container"], descendants: true }], ngImport: i0, template: "<div class=\"stream-chat__paginated-list\" #container>\n <div\n data-testid=\"item\"\n class=\"stream-chat__paginated-list-item\"\n *ngFor=\"let item of items; let index = index; trackBy: trackBy\"\n >\n <ng-template\n *ngIf=\"itemTempalteRef\"\n [ngTemplateOutlet]=\"itemTempalteRef\"\n [ngTemplateOutletContext]=\"{ item: item, index: index }\"\n ></ng-template>\n </div>\n <button\n *ngIf=\"hasMore && !isScrollable\"\n class=\"str-chat__load-more-button__button str-chat__cta-button\"\n data-testid=\"load-more-button\"\n [disabled]=\"isLoading\"\n (click)=\"loadMore.emit()\"\n (keyup.enter)=\"loadMore.emit()\"\n >\n <span>{{ \"Load more\" | translate }}</span>\n </button>\n <stream-loading-indicator-placeholder\n data-testid=\"loading-indicator\"\n *ngIf=\"isLoading\"\n ></stream-loading-indicator-placeholder>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: LoadingIndicatorPlaceholderComponent, selector: "stream-loading-indicator-placeholder" }, { kind: "pipe", type: i6.TranslatePipe, name: "translate" }] });
4505
4567
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: PaginatedListComponent, decorators: [{
4506
4568
  type: Component,
4507
4569
  args: [{ selector: 'stream-paginated-list', template: "<div class=\"stream-chat__paginated-list\" #container>\n <div\n data-testid=\"item\"\n class=\"stream-chat__paginated-list-item\"\n *ngFor=\"let item of items; let index = index; trackBy: trackBy\"\n >\n <ng-template\n *ngIf=\"itemTempalteRef\"\n [ngTemplateOutlet]=\"itemTempalteRef\"\n [ngTemplateOutletContext]=\"{ item: item, index: index }\"\n ></ng-template>\n </div>\n <button\n *ngIf=\"hasMore && !isScrollable\"\n class=\"str-chat__load-more-button__button str-chat__cta-button\"\n data-testid=\"load-more-button\"\n [disabled]=\"isLoading\"\n (click)=\"loadMore.emit()\"\n (keyup.enter)=\"loadMore.emit()\"\n >\n <span>{{ \"Load more\" | translate }}</span>\n </button>\n <stream-loading-indicator-placeholder\n data-testid=\"loading-indicator\"\n *ngIf=\"isLoading\"\n ></stream-loading-indicator-placeholder>\n</div>\n" }]
@@ -4555,7 +4617,7 @@ class ChannelListComponent {
4555
4617
  }
4556
4618
  }
4557
4619
  ChannelListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: ChannelListComponent, deps: [{ token: ChannelService }, { token: CustomTemplatesService }, { token: ThemeService }], target: i0.ɵɵFactoryTarget.Component });
4558
- ChannelListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: ChannelListComponent, selector: "stream-channel-list", ngImport: i0, template: "<div\n #container\n data-testid=\"channel-list-container\"\n class=\"str-chat str-chat-angular__channel-list str-chat__channel-list str-chat-channel-list messaging str-chat__theme-{{\n theme$ | async\n }}\"\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 <ng-content select=\"[channel-list-top]\"></ng-content>\n <div\n *ngIf=\"!(channels$ | async)?.length\"\n class=\"str-chat__channel-list-empty\"\n >\n <stream-icon icon=\"chat-bubble\"></stream-icon>\n <p data-testid=\"empty-channel-list-indicator\">\n {{ \"streamChat.You have no channels currently\" | translate }}\n </p>\n </div>\n <p\n *ngIf=\"!(channels$ | async)?.length\"\n class=\"str-chat__channel-list-empty-v1\"\n data-testid=\"empty-channel-list-indicator\"\n >\n {{ \"streamChat.You have no channels currently\" | translate }}\n </p>\n <stream-paginated-list\n [items]=\"(channels$ | async) ?? []\"\n [hasMore]=\"(hasMoreChannels$ | async) ?? false\"\n [isLoading]=\"isLoadingMoreChannels\"\n (loadMore)=\"loadMoreChannels()\"\n [trackBy]=\"trackByChannelId\"\n >\n <ng-template let-channel=\"item\">\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>\n <ng-container\n *ngTemplateOutlet=\"\n customChannelPreviewTemplate || defaultTemplate;\n context: { channel: channel }\n \"\n ></ng-container>\n </div>\n </ng-template>\n </stream-paginated-list>\n <ng-content select=\"[channel-list-bottom]\"></ng-content>\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>\n</ng-template>\n\n<ng-template #loadingChannels>\n <div\n data-testid=\"loading-indicator-full-size\"\n class=\"str-chat__loading-channels\"\n >\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\n class=\"str-chat__loading-channels-item str-chat__channel-preview-loading\"\n >\n <div class=\"str-chat__loading-channels-avatar\"></div>\n <div\n class=\"str-chat__loading-channels-meta str-chat__channel-preview-end-loading\"\n >\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", dependencies: [{ kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: IconComponent, selector: "stream-icon", inputs: ["icon"] }, { kind: "component", type: ChannelPreviewComponent, selector: "stream-channel-preview", inputs: ["channel"] }, { kind: "component", type: PaginatedListComponent, selector: "stream-paginated-list", inputs: ["items", "isLoading", "hasMore", "trackBy"], outputs: ["loadMore"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.TranslatePipe, name: "translate" }] });
4620
+ ChannelListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: ChannelListComponent, selector: "stream-channel-list", ngImport: i0, template: "<div\n #container\n data-testid=\"channel-list-container\"\n class=\"str-chat str-chat-angular__channel-list str-chat__channel-list str-chat-channel-list messaging str-chat__theme-{{\n theme$ | async\n }}\"\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 <ng-content select=\"[channel-list-top]\"></ng-content>\n <div\n *ngIf=\"!(channels$ | async)?.length\"\n class=\"str-chat__channel-list-empty\"\n >\n <stream-icon icon=\"chat-bubble\"></stream-icon>\n <p data-testid=\"empty-channel-list-indicator\">\n {{ \"streamChat.You have no channels currently\" | translate }}\n </p>\n </div>\n <p\n *ngIf=\"!(channels$ | async)?.length\"\n class=\"str-chat__channel-list-empty-v1\"\n data-testid=\"empty-channel-list-indicator\"\n >\n {{ \"streamChat.You have no channels currently\" | translate }}\n </p>\n <stream-paginated-list\n [items]=\"(channels$ | async) ?? []\"\n [hasMore]=\"(hasMoreChannels$ | async) ?? false\"\n [isLoading]=\"isLoadingMoreChannels\"\n (loadMore)=\"loadMoreChannels()\"\n [trackBy]=\"trackByChannelId\"\n >\n <ng-template let-channel=\"item\">\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>\n <ng-container\n *ngTemplateOutlet=\"\n customChannelPreviewTemplate || defaultTemplate;\n context: { channel: channel }\n \"\n ></ng-container>\n </div>\n </ng-template>\n </stream-paginated-list>\n <ng-content select=\"[channel-list-bottom]\"></ng-content>\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>\n</ng-template>\n\n<ng-template #loadingChannels>\n <div\n data-testid=\"loading-indicator-full-size\"\n class=\"str-chat__loading-channels\"\n >\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\n class=\"str-chat__loading-channels-item str-chat__channel-preview-loading\"\n >\n <div class=\"str-chat__loading-channels-avatar\"></div>\n <div\n class=\"str-chat__loading-channels-meta str-chat__channel-preview-end-loading\"\n >\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", dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: IconComponent, selector: "stream-icon", inputs: ["icon"] }, { kind: "component", type: PaginatedListComponent, selector: "stream-paginated-list", inputs: ["items", "isLoading", "hasMore", "trackBy"], outputs: ["loadMore"] }, { kind: "component", type: ChannelPreviewComponent, selector: "stream-channel-preview", inputs: ["channel"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.TranslatePipe, name: "translate" }] });
4559
4621
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: ChannelListComponent, decorators: [{
4560
4622
  type: Component,
4561
4623
  args: [{ selector: 'stream-channel-list', template: "<div\n #container\n data-testid=\"channel-list-container\"\n class=\"str-chat str-chat-angular__channel-list str-chat__channel-list str-chat-channel-list messaging str-chat__theme-{{\n theme$ | async\n }}\"\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 <ng-content select=\"[channel-list-top]\"></ng-content>\n <div\n *ngIf=\"!(channels$ | async)?.length\"\n class=\"str-chat__channel-list-empty\"\n >\n <stream-icon icon=\"chat-bubble\"></stream-icon>\n <p data-testid=\"empty-channel-list-indicator\">\n {{ \"streamChat.You have no channels currently\" | translate }}\n </p>\n </div>\n <p\n *ngIf=\"!(channels$ | async)?.length\"\n class=\"str-chat__channel-list-empty-v1\"\n data-testid=\"empty-channel-list-indicator\"\n >\n {{ \"streamChat.You have no channels currently\" | translate }}\n </p>\n <stream-paginated-list\n [items]=\"(channels$ | async) ?? []\"\n [hasMore]=\"(hasMoreChannels$ | async) ?? false\"\n [isLoading]=\"isLoadingMoreChannels\"\n (loadMore)=\"loadMoreChannels()\"\n [trackBy]=\"trackByChannelId\"\n >\n <ng-template let-channel=\"item\">\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>\n <ng-container\n *ngTemplateOutlet=\"\n customChannelPreviewTemplate || defaultTemplate;\n context: { channel: channel }\n \"\n ></ng-container>\n </div>\n </ng-template>\n </stream-paginated-list>\n <ng-content select=\"[channel-list-bottom]\"></ng-content>\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>\n</ng-template>\n\n<ng-template #loadingChannels>\n <div\n data-testid=\"loading-indicator-full-size\"\n class=\"str-chat__loading-channels\"\n >\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\n class=\"str-chat__loading-channels-item str-chat__channel-preview-loading\"\n >\n <div class=\"str-chat__loading-channels-avatar\"></div>\n <div\n class=\"str-chat__loading-channels-meta str-chat__channel-preview-end-loading\"\n >\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" }]
@@ -4749,7 +4811,7 @@ class VoiceRecordingWavebarComponent {
4749
4811
  }
4750
4812
  }
4751
4813
  VoiceRecordingWavebarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: VoiceRecordingWavebarComponent, deps: [{ token: i0.NgZone }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
4752
- VoiceRecordingWavebarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: VoiceRecordingWavebarComponent, selector: "stream-voice-recording-wavebar", inputs: { audioElement: "audioElement", waveFormData: "waveFormData", duration: "duration" }, viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<!--eslint-disable @angular-eslint/template/click-events-have-key-events-->\n<div\n #container\n class=\"str-chat__wave-progress-bar__track\"\n data-testid=\"wave-progress-bar-track\"\n role=\"progressbar\"\n (mousedown)=\"isDragging = true\"\n (mouseup)=\"isDragging = false\"\n (mouseleave)=\"isDragging = false\"\n (mousemove)=\"isDragging ? seek($event) : null\"\n (click)=\"seek($event)\"\n>\n <!--eslint-enable @angular-eslint/template/click-events-have-key-events-->\n <div\n *ngFor=\"\n let dataPoint of resampledWaveFormData;\n let i = index;\n trackBy: trackByIndex\n \"\n class=\"str-chat__wave-progress-bar__amplitude-bar\"\n [class.str-chat__wave-progress-bar__amplitude-bar--active]=\"\n progress > i / resampledWaveFormData.length\n \"\n [style.--str-chat__wave-progress-bar__amplitude-bar-height]=\"\n dataPoint ? dataPoint * 100 + '%' : '0%'\n \"\n ></div>\n <div\n class=\"str-chat__wave-progress-bar__progress-indicator\"\n data-testid=\"wave-progress-bar-progress-indicator\"\n [ngStyle]=\"{ 'inset-inline-start': progress * 100 + '%' }\"\n ></div>\n</div>\n", dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] });
4814
+ VoiceRecordingWavebarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: VoiceRecordingWavebarComponent, selector: "stream-voice-recording-wavebar", inputs: { audioElement: "audioElement", waveFormData: "waveFormData", duration: "duration" }, viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<!--eslint-disable @angular-eslint/template/click-events-have-key-events-->\n<div\n #container\n class=\"str-chat__wave-progress-bar__track\"\n data-testid=\"wave-progress-bar-track\"\n role=\"progressbar\"\n (mousedown)=\"isDragging = true\"\n (mouseup)=\"isDragging = false\"\n (mouseleave)=\"isDragging = false\"\n (mousemove)=\"isDragging ? seek($event) : null\"\n (click)=\"seek($event)\"\n>\n <!--eslint-enable @angular-eslint/template/click-events-have-key-events-->\n <div\n *ngFor=\"\n let dataPoint of resampledWaveFormData;\n let i = index;\n trackBy: trackByIndex\n \"\n class=\"str-chat__wave-progress-bar__amplitude-bar\"\n [class.str-chat__wave-progress-bar__amplitude-bar--active]=\"\n progress > i / resampledWaveFormData.length\n \"\n [style.--str-chat__wave-progress-bar__amplitude-bar-height]=\"\n dataPoint ? dataPoint * 100 + '%' : '0%'\n \"\n ></div>\n <div\n class=\"str-chat__wave-progress-bar__progress-indicator\"\n data-testid=\"wave-progress-bar-progress-indicator\"\n [ngStyle]=\"{ 'inset-inline-start': progress * 100 + '%' }\"\n ></div>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] });
4753
4815
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: VoiceRecordingWavebarComponent, decorators: [{
4754
4816
  type: Component,
4755
4817
  args: [{ selector: 'stream-voice-recording-wavebar', template: "<!--eslint-disable @angular-eslint/template/click-events-have-key-events-->\n<div\n #container\n class=\"str-chat__wave-progress-bar__track\"\n data-testid=\"wave-progress-bar-track\"\n role=\"progressbar\"\n (mousedown)=\"isDragging = true\"\n (mouseup)=\"isDragging = false\"\n (mouseleave)=\"isDragging = false\"\n (mousemove)=\"isDragging ? seek($event) : null\"\n (click)=\"seek($event)\"\n>\n <!--eslint-enable @angular-eslint/template/click-events-have-key-events-->\n <div\n *ngFor=\"\n let dataPoint of resampledWaveFormData;\n let i = index;\n trackBy: trackByIndex\n \"\n class=\"str-chat__wave-progress-bar__amplitude-bar\"\n [class.str-chat__wave-progress-bar__amplitude-bar--active]=\"\n progress > i / resampledWaveFormData.length\n \"\n [style.--str-chat__wave-progress-bar__amplitude-bar-height]=\"\n dataPoint ? dataPoint * 100 + '%' : '0%'\n \"\n ></div>\n <div\n class=\"str-chat__wave-progress-bar__progress-indicator\"\n data-testid=\"wave-progress-bar-progress-indicator\"\n [ngStyle]=\"{ 'inset-inline-start': progress * 100 + '%' }\"\n ></div>\n</div>\n" }]
@@ -4844,7 +4906,7 @@ class VoiceRecordingComponent {
4844
4906
  }
4845
4907
  }
4846
4908
  VoiceRecordingComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: VoiceRecordingComponent, deps: [{ token: i0.NgZone }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
4847
- VoiceRecordingComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: VoiceRecordingComponent, selector: "stream-voice-recording", inputs: { attachment: "attachment" }, viewQueries: [{ propertyName: "audioElement", first: true, predicate: ["audioElement"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div\n class=\"str-chat__message-attachment__voice-recording-widget\"\n data-testid=\"voice-recording-widget\"\n [class.str-chat__message-attachment__voice-recording-widget--error]=\"isError\"\n>\n <!-- Empty event handlers to trigger change detection -->\n <audio\n #audioElement\n (play)=\"(null)\"\n (pause)=\"(null)\"\n (ended)=\"(null)\"\n (error)=\"isError = true\"\n (abort)=\"isError = true\"\n >\n <source\n data-testid=\"audio-source\"\n [src]=\"attachment?.asset_url\"\n [type]=\"attachment?.mime_type\"\n />\n </audio>\n <button\n class=\"str-chat__message-attachment-audio-widget--play-button\"\n data-testid=\"play-button\"\n (click)=\"togglePlay()\"\n >\n <stream-icon-placeholder\n [icon]=\"audioElement?.paused ? 'play' : 'pause'\"\n ></stream-icon-placeholder>\n </button>\n <div class=\"str-chat__message-attachment__voice-recording-widget__metadata\">\n <div class=\"str-chat__message-attachment-voice-recording-widget--first-row\">\n <div\n class=\"str-chat__message-attachment__voice-recording-widget__title\"\n data-testid=\"voice-recording-title\"\n [title]=\"attachment?.title\"\n >\n {{ attachment?.title }}\n </div>\n </div>\n\n <ng-container *ngIf=\"isError; else state\">\n <div\n class=\"str-chat__message-attachment__voice-recording-widget__error-message\"\n >\n <stream-icon-placeholder icon=\"error\"></stream-icon-placeholder>\n <span data-testid=\"error-message\">{{\n \"streamChat.Error playing audio\" | translate\n }}</span>\n </div>\n </ng-container>\n <ng-template #state>\n <div\n class=\"str-chat__message-attachment__voice-recording-widget__audio-state\"\n >\n <div\n class=\"str-chat__message-attachment__voice-recording-widget__timer\"\n >\n <span\n *ngIf=\"!!attachment?.duration; else fileSizeTemplate\"\n data-testid=\"duration\"\n >\n {{\n secondsElapsed > 0 || !audioElement.paused\n ? secondsElapsedFormatted\n : durationFormatted\n }}</span\n >\n <ng-template #fileSizeTemplate>\n <span\n class=\"str-chat__message-attachment-file--item-size\"\n data-testid=\"file-size-indicator\"\n >\n {{ fileSize }}\n </span>\n </ng-template>\n </div>\n <stream-voice-recording-wavebar\n *ngIf=\"attachment?.waveform_data && attachment?.duration\"\n [waveFormData]=\"attachment?.waveform_data || []\"\n [duration]=\"attachment?.duration\"\n [audioElement]=\"audioElement\"\n ></stream-voice-recording-wavebar>\n </div>\n </ng-template>\n </div>\n <div\n class=\"str-chat__message-attachment__voice-recording-widget__right-section\"\n >\n <button\n *ngIf=\"!audioElement?.paused; else fileIcon\"\n class=\"str-chat__message_attachment__playback-rate-button\"\n data-testid=\"playback-rate-button\"\n (click)=\"setPlaybackRate()\"\n >\n {{ audioElement?.playbackRate | number : \"1.1-1\" }}x\n </button>\n <ng-template #fileIcon>\n <stream-icon-placeholder\n class=\"str-chat__attachment-type-icon\"\n icon=\"audio-file\"\n ></stream-icon-placeholder>\n </ng-template>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon"] }, { kind: "component", type: VoiceRecordingWavebarComponent, selector: "stream-voice-recording-wavebar", inputs: ["audioElement", "waveFormData", "duration"] }, { kind: "pipe", type: i3.DecimalPipe, name: "number" }, { kind: "pipe", type: i6.TranslatePipe, name: "translate" }] });
4909
+ VoiceRecordingComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: VoiceRecordingComponent, selector: "stream-voice-recording", inputs: { attachment: "attachment" }, viewQueries: [{ propertyName: "audioElement", first: true, predicate: ["audioElement"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div\n class=\"str-chat__message-attachment__voice-recording-widget\"\n data-testid=\"voice-recording-widget\"\n [class.str-chat__message-attachment__voice-recording-widget--error]=\"isError\"\n>\n <!-- Empty event handlers to trigger change detection -->\n <audio\n #audioElement\n (play)=\"(null)\"\n (pause)=\"(null)\"\n (ended)=\"(null)\"\n (error)=\"isError = true\"\n (abort)=\"isError = true\"\n >\n <source\n data-testid=\"audio-source\"\n [src]=\"attachment?.asset_url\"\n [type]=\"attachment?.mime_type\"\n />\n </audio>\n <button\n class=\"str-chat__message-attachment-audio-widget--play-button\"\n data-testid=\"play-button\"\n (click)=\"togglePlay()\"\n >\n <stream-icon-placeholder\n [icon]=\"audioElement?.paused ? 'play' : 'pause'\"\n ></stream-icon-placeholder>\n </button>\n <div class=\"str-chat__message-attachment__voice-recording-widget__metadata\">\n <div class=\"str-chat__message-attachment-voice-recording-widget--first-row\">\n <div\n class=\"str-chat__message-attachment__voice-recording-widget__title\"\n data-testid=\"voice-recording-title\"\n [title]=\"attachment?.title\"\n >\n {{ attachment?.title }}\n </div>\n </div>\n\n <ng-container *ngIf=\"isError; else state\">\n <div\n class=\"str-chat__message-attachment__voice-recording-widget__error-message\"\n >\n <stream-icon-placeholder icon=\"error\"></stream-icon-placeholder>\n <span data-testid=\"error-message\">{{\n \"streamChat.Error playing audio\" | translate\n }}</span>\n </div>\n </ng-container>\n <ng-template #state>\n <div\n class=\"str-chat__message-attachment__voice-recording-widget__audio-state\"\n >\n <div\n class=\"str-chat__message-attachment__voice-recording-widget__timer\"\n >\n <span\n *ngIf=\"!!attachment?.duration; else fileSizeTemplate\"\n data-testid=\"duration\"\n >\n {{\n secondsElapsed > 0 || !audioElement.paused\n ? secondsElapsedFormatted\n : durationFormatted\n }}</span\n >\n <ng-template #fileSizeTemplate>\n <span\n class=\"str-chat__message-attachment-file--item-size\"\n data-testid=\"file-size-indicator\"\n >\n {{ fileSize }}\n </span>\n </ng-template>\n </div>\n <stream-voice-recording-wavebar\n *ngIf=\"attachment?.waveform_data && attachment?.duration\"\n [waveFormData]=\"attachment?.waveform_data || []\"\n [duration]=\"attachment?.duration\"\n [audioElement]=\"audioElement\"\n ></stream-voice-recording-wavebar>\n </div>\n </ng-template>\n </div>\n <div\n class=\"str-chat__message-attachment__voice-recording-widget__right-section\"\n >\n <button\n *ngIf=\"!audioElement?.paused; else fileIcon\"\n class=\"str-chat__message_attachment__playback-rate-button\"\n data-testid=\"playback-rate-button\"\n (click)=\"setPlaybackRate()\"\n >\n {{ audioElement?.playbackRate | number : \"1.1-1\" }}x\n </button>\n <ng-template #fileIcon>\n <stream-icon-placeholder\n class=\"str-chat__attachment-type-icon\"\n icon=\"audio-file\"\n ></stream-icon-placeholder>\n </ng-template>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon"] }, { kind: "component", type: VoiceRecordingWavebarComponent, selector: "stream-voice-recording-wavebar", inputs: ["audioElement", "waveFormData", "duration"] }, { kind: "pipe", type: i1.DecimalPipe, name: "number" }, { kind: "pipe", type: i6.TranslatePipe, name: "translate" }] });
4848
4910
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: VoiceRecordingComponent, decorators: [{
4849
4911
  type: Component,
4850
4912
  args: [{ selector: 'stream-voice-recording', template: "<div\n class=\"str-chat__message-attachment__voice-recording-widget\"\n data-testid=\"voice-recording-widget\"\n [class.str-chat__message-attachment__voice-recording-widget--error]=\"isError\"\n>\n <!-- Empty event handlers to trigger change detection -->\n <audio\n #audioElement\n (play)=\"(null)\"\n (pause)=\"(null)\"\n (ended)=\"(null)\"\n (error)=\"isError = true\"\n (abort)=\"isError = true\"\n >\n <source\n data-testid=\"audio-source\"\n [src]=\"attachment?.asset_url\"\n [type]=\"attachment?.mime_type\"\n />\n </audio>\n <button\n class=\"str-chat__message-attachment-audio-widget--play-button\"\n data-testid=\"play-button\"\n (click)=\"togglePlay()\"\n >\n <stream-icon-placeholder\n [icon]=\"audioElement?.paused ? 'play' : 'pause'\"\n ></stream-icon-placeholder>\n </button>\n <div class=\"str-chat__message-attachment__voice-recording-widget__metadata\">\n <div class=\"str-chat__message-attachment-voice-recording-widget--first-row\">\n <div\n class=\"str-chat__message-attachment__voice-recording-widget__title\"\n data-testid=\"voice-recording-title\"\n [title]=\"attachment?.title\"\n >\n {{ attachment?.title }}\n </div>\n </div>\n\n <ng-container *ngIf=\"isError; else state\">\n <div\n class=\"str-chat__message-attachment__voice-recording-widget__error-message\"\n >\n <stream-icon-placeholder icon=\"error\"></stream-icon-placeholder>\n <span data-testid=\"error-message\">{{\n \"streamChat.Error playing audio\" | translate\n }}</span>\n </div>\n </ng-container>\n <ng-template #state>\n <div\n class=\"str-chat__message-attachment__voice-recording-widget__audio-state\"\n >\n <div\n class=\"str-chat__message-attachment__voice-recording-widget__timer\"\n >\n <span\n *ngIf=\"!!attachment?.duration; else fileSizeTemplate\"\n data-testid=\"duration\"\n >\n {{\n secondsElapsed > 0 || !audioElement.paused\n ? secondsElapsedFormatted\n : durationFormatted\n }}</span\n >\n <ng-template #fileSizeTemplate>\n <span\n class=\"str-chat__message-attachment-file--item-size\"\n data-testid=\"file-size-indicator\"\n >\n {{ fileSize }}\n </span>\n </ng-template>\n </div>\n <stream-voice-recording-wavebar\n *ngIf=\"attachment?.waveform_data && attachment?.duration\"\n [waveFormData]=\"attachment?.waveform_data || []\"\n [duration]=\"attachment?.duration\"\n [audioElement]=\"audioElement\"\n ></stream-voice-recording-wavebar>\n </div>\n </ng-template>\n </div>\n <div\n class=\"str-chat__message-attachment__voice-recording-widget__right-section\"\n >\n <button\n *ngIf=\"!audioElement?.paused; else fileIcon\"\n class=\"str-chat__message_attachment__playback-rate-button\"\n data-testid=\"playback-rate-button\"\n (click)=\"setPlaybackRate()\"\n >\n {{ audioElement?.playbackRate | number : \"1.1-1\" }}x\n </button>\n <ng-template #fileIcon>\n <stream-icon-placeholder\n class=\"str-chat__attachment-type-icon\"\n icon=\"audio-file\"\n ></stream-icon-placeholder>\n </ng-template>\n </div>\n</div>\n" }]
@@ -5055,7 +5117,7 @@ class AttachmentListComponent {
5055
5117
  }
5056
5118
  }
5057
5119
  AttachmentListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: AttachmentListComponent, deps: [{ token: CustomTemplatesService }, { token: ChannelService }, { token: AttachmentConfigurationService }, { token: MessageService }], target: i0.ɵɵFactoryTarget.Component });
5058
- AttachmentListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: AttachmentListComponent, selector: "stream-attachment-list", inputs: { messageId: "messageId", parentMessageId: "parentMessageId", attachments: "attachments" }, outputs: { imageModalStateChange: "imageModalStateChange" }, host: { properties: { "class": "this.class" } }, viewQueries: [{ propertyName: "modalContent", first: true, predicate: ["modalContent"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<div\n *ngIf=\"\n orderedAttachments.length > 0 ||\n (customAttachments.length > 0 && customAttachmentsTemplate)\n \"\n class=\"str-chat__attachment-list\"\n>\n <ng-container\n *ngFor=\"let attachment of orderedAttachments; trackBy: trackByUrl\"\n >\n <div\n data-testclass=\"attachment-container\"\n class=\"str-chat__message-attachment str-chat__message-attachment--{{\n attachment.type\n }} str-chat__message-attachment-dynamic-size\"\n [class.str-chat__message-attachment--card]=\"isCard(attachment)\"\n [class.str-chat-angular__message-attachment-file-single]=\"\n isFile(attachment)\n \"\n [class.str-chat__message-attachment--voice-recording]=\"\n isVoiceMessage(attachment)\n \"\n [class.str-chat__message-attachment-with-actions]=\"\n !isGalleryType(attachment) &&\n attachment.actions &&\n attachment.actions.length > 0\n \"\n [class.str-chat__message-attachment--svg-image]=\"isSvg(attachment)\"\n >\n <ng-container *ngIf=\"isImage(attachment)\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.imageAttachmentTemplate$ | async) ||\n defaultImage;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultImage let-attachmentContext=\"attachment\">\n <img\n #imgElement\n class=\"str-chat__message-attachment--img\"\n data-testclass=\"image\"\n [src]=\"\n getImageAttachmentConfiguration(\n attachmentContext,\n 'single',\n imgElement\n ).url\n \"\n [alt]=\"attachmentContext?.fallback\"\n [ngStyle]=\"{\n height: getImageAttachmentConfiguration(\n attachmentContext,\n 'single',\n imgElement\n ).height,\n width: getImageAttachmentConfiguration(\n attachmentContext,\n 'single',\n imgElement\n ).width,\n '--original-height': getImageAttachmentConfiguration(\n attachmentContext,\n 'single',\n imgElement\n ).originalHeight,\n '--original-width': getImageAttachmentConfiguration(\n attachmentContext,\n 'single',\n imgElement\n ).originalWidth\n }\"\n (click)=\"openImageModal([attachmentContext])\"\n (keyup.enter)=\"openImageModal([attachmentContext])\"\n />\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"isGallery(attachment)\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.galleryAttachmentTemplate$ | async) ||\n defaultGallery;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultGallery let-attachmentContext=\"attachment\">\n <div\n class=\"str-chat__gallery\"\n data-testid=\"image-gallery\"\n [class.str-chat__gallery--square]=\"\n (attachmentContext?.images)!.length > 3\n \"\n [class.str-chat__gallery-two-rows]=\"\n (attachmentContext?.images)!.length > 2\n \"\n >\n <ng-container\n *ngFor=\"\n let galleryImage of attachmentContext.images;\n let index = index;\n let isLast = last;\n trackBy: trackByImageUrl\n \"\n >\n <button\n *ngIf=\"index < 3 || (index === 3 && isLast)\"\n class=\"str-chat__gallery-image\"\n data-testclass=\"gallery-image\"\n [class.str-chat__message-attachment--svg-image]=\"\n isSvg(galleryImage)\n \"\n (click)=\"openImageModal(attachmentContext.images!, index)\"\n (keyup.enter)=\"openImageModal(attachmentContext.images!, index)\"\n >\n <img\n #imgElement\n fetchpriority=\"low\"\n loading=\"lazy\"\n [src]=\"\n getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n imgElement\n ).url\n \"\n [alt]=\"galleryImage.fallback\"\n [style.--original-height]=\"\n getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n imgElement\n ).originalHeight\n \"\n [style.--original-width]=\"\n getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n imgElement\n ).originalWidth\n \"\n [ngStyle]=\"{\n height: getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n imgElement\n ).height,\n width: getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n imgElement\n ).width\n }\"\n />\n </button>\n <button\n *ngIf=\"index === 3 && !isLast\"\n #element\n class=\"str-chat__gallery-placeholder\"\n data-testclass=\"gallery-image\"\n data-testid=\"more-image-button\"\n [class.str-chat__message-attachment--svg-image]=\"\n isSvg(galleryImage)\n \"\n [ngStyle]=\"{\n 'background-image':\n 'url(' +\n getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n element\n ).url +\n ')',\n height: getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n element\n ).height,\n width: getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n element\n ).width,\n '--original-height': getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n element\n ).originalHeight,\n '--original-width': getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n element\n ).originalWidth\n }\"\n (click)=\"openImageModal(attachmentContext.images!, index)\"\n (keyup.enter)=\"openImageModal(attachmentContext.images!, index)\"\n >\n <p\n [innerHTML]=\"\n 'streamChat.{{ imageCount }} more'\n | translate\n : { imageCount: attachmentContext!.images!.length - 4 }\n \"\n ></p>\n </button>\n </ng-container>\n </div>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"isVideo(attachment)\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.videoAttachmentTemplate$ | async) ||\n defaultVideo;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultVideo let-attachmentContext=\"attachment\">\n <div\n class=\"str-chat__player-wrapper\"\n data-testclass=\"video-attachment-parent\"\n [style.--original-height]=\"\n getVideoAttachmentConfiguration(attachmentContext, videoElement)\n .originalHeight\n \"\n [style.--original-width]=\"\n getVideoAttachmentConfiguration(attachmentContext, videoElement)\n .originalWidth\n \"\n [ngStyle]=\"{\n height: getVideoAttachmentConfiguration(\n attachmentContext,\n videoElement\n ).height,\n width: getVideoAttachmentConfiguration(\n attachmentContext,\n videoElement\n ).width\n }\"\n >\n <video\n #videoElement\n class=\"str-chat__video-angular\"\n controls\n data-testclass=\"video-attachment\"\n [src]=\"\n getVideoAttachmentConfiguration(attachmentContext, videoElement)\n .url\n \"\n [poster]=\"\n getVideoAttachmentConfiguration(attachmentContext, videoElement)\n .thumbUrl\n \"\n ></video>\n </div>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"isFile(attachment)\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.fileAttachmentTemplate$ | async) ||\n defaultFile;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultFile let-attachmentContext=\"attachment\">\n <div\n class=\"str-chat__message-attachment-file--item str-chat-angular__message-attachment-file-single\"\n >\n <stream-icon-placeholder\n class=\"str-chat__attachment-type-icon\"\n icon=\"unspecified-filetype\"\n ></stream-icon-placeholder>\n <div class=\"str-chat__message-attachment-file--item-text\">\n <a\n class=\"str-chat__message-attachment-file--item-first-row\"\n data-testclass=\"file-link\"\n target=\"_blank\"\n href=\"{{ attachmentContext.asset_url }}\"\n >\n <div\n data-testclass=\"file-title\"\n class=\"str-chat__message-attachment-file--item-name\"\n >\n {{ attachmentContext.title }}\n </div>\n <stream-icon-placeholder\n class=\"str-chat__message-attachment-download-icon\"\n icon=\"download\"\n ></stream-icon-placeholder>\n </a>\n <span\n *ngIf=\"hasFileSize(attachmentContext)\"\n class=\"str-chat__message-attachment-file--item-size\"\n data-testclass=\"size\"\n >{{ getFileSize(attachmentContext) }}</span\n >\n </div>\n </div>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"isVoiceMessage(attachment)\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.voiceRecordingAttachmentTemplate$\n | async) || defaultRecording;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultRecording>\n <stream-voice-recording\n data-testclass=\"voice-recording\"\n [attachment]=\"attachment\"\n ></stream-voice-recording>\n </ng-template>\n </ng-container>\n <ng-container\n *ngIf=\"\n isCard(attachment) &&\n getCardAttachmentConfiguration(attachment) as attachmentConfiguration\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.cardAttachmentTemplate$ | async) ||\n defaultCard;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultCard let-attachmentContext=\"attachment\">\n <div\n class=\"str-chat__message-attachment-card str-chat__message-attachment-card--{{\n attachmentContext.type\n }}\"\n >\n <div\n *ngIf=\"attachmentConfiguration.url\"\n class=\"str-chat__message-attachment-card--header\"\n >\n <a\n *ngIf=\"attachmentContext.type === 'video'; else cardImage\"\n [href]=\"\n attachmentContext.title_link ||\n attachmentContext.og_scrape_url\n \"\n target=\"_blank\"\n data-testclass=\"scraped-video\"\n >\n <ng-content *ngTemplateOutlet=\"cardImage\"></ng-content>\n <div\n class=\"str-chat__message-attachment-card--video-play\"\n ></div>\n <stream-icon-placeholder icon=\"play\"></stream-icon-placeholder>\n </a>\n <ng-template #cardImage>\n <img\n fetchpriority=\"low\"\n loading=\"lazy\"\n data-testclass=\"card-img\"\n alt=\"{{ attachmentConfiguration.url }}\"\n src=\"{{ attachmentConfiguration.url }}\"\n [ngStyle]=\"{\n height: attachmentConfiguration.height,\n width: attachmentConfiguration.width\n }\"\n />\n </ng-template>\n </div>\n <div class=\"str-chat__message-attachment-card--content\">\n <div class=\"str-chat__message-attachment-card--flex\">\n <div\n *ngIf=\"attachmentContext.title\"\n data-testclass=\"card-title\"\n class=\"str-chat__message-attachment-card--title\"\n >\n {{ attachmentContext.title }}\n </div>\n <div\n *ngIf=\"attachmentContext.text\"\n class=\"str-chat__message-attachment-card--text\"\n data-testclass=\"card-text\"\n >\n {{ attachmentContext.text }}\n </div>\n <a\n *ngIf=\"\n attachmentContext.title_link ||\n attachmentContext.og_scrape_url\n \"\n class=\"str-chat__message-attachment-card--url\"\n data-testclass=\"url-link\"\n noopener\n noreferrer\n target=\"_blank\"\n href=\"{{\n attachmentContext.title_link ||\n attachmentContext.og_scrape_url\n }}\"\n >\n {{\n trimUrl(\n attachmentContext.title_link ||\n attachmentContext.og_scrape_url\n )\n }}\n </a>\n </div>\n </div>\n </div>\n </ng-template>\n </ng-container>\n <ng-container\n *ngIf=\"\n !isGalleryType(attachment) &&\n attachment.actions &&\n attachment.actions.length > 0\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.attachmentActionsTemplate$ | async) ||\n defaultActions;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultActions let-attachmentContext=\"attachment\">\n <div class=\"str-chat__message-attachment-actions\">\n <div class=\"str-chat__message-attachment-actions-form\">\n <button\n *ngFor=\"\n let action of attachmentContext.actions;\n trackBy: trackByActionValue\n \"\n data-testclass=\"attachment-action\"\n class=\"str-chat__message-attachment-actions-button str-chat__message-attachment-actions-button--{{\n action.style\n }}\"\n (click)=\"sendAction(action)\"\n (keyup.enter)=\"sendAction(action)\"\n >\n {{ action.text }}\n </button>\n </div>\n </div>\n </ng-template>\n </ng-container>\n </div>\n </ng-container>\n <ng-container *ngIf=\"customAttachmentsTemplate\">\n <ng-template\n *ngTemplateOutlet=\"\n customAttachmentsTemplate;\n context: {\n messageId: messageId,\n parentMessageId: parentMessageId,\n attachments: customAttachments\n }\n \"\n ></ng-template>\n </ng-container>\n\n <ng-container *ngIf=\"imagesToView && imagesToView.length > 0\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.modalTemplate$ | async) || defaultModal;\n context: getModalContext()\n \"\n ></ng-container>\n </ng-container>\n</div>\n\n<ng-template\n #defaultModal\n let-isOpen=\"isOpen\"\n let-isOpenChangeHandler=\"isOpenChangeHandler\"\n let-content=\"content\"\n>\n <stream-modal\n class=\"stream-chat-angular__image-modal-host\"\n [isOpen]=\"isOpen\"\n [content]=\"content\"\n (isOpenChange)=\"isOpenChangeHandler($event)\"\n >\n </stream-modal>\n</ng-template>\n\n<ng-template #modalContent>\n <div class=\"stream-chat-angular__image-modal str-chat__image-carousel\">\n <img\n #imgElement\n class=\"stream-chat-angular__image-modal-image str-chat__image-carousel-image\"\n data-testid=\"modal-image\"\n [src]=\"\n getCarouselImageAttachmentConfiguration(\n imagesToView[imagesToViewCurrentIndex],\n imgElement\n ).url\n \"\n [style.--original-height]=\"\n getCarouselImageAttachmentConfiguration(\n imagesToView[imagesToViewCurrentIndex],\n imgElement\n ).originalHeight\n \"\n [style.--original-width]=\"\n getCarouselImageAttachmentConfiguration(\n imagesToView[imagesToViewCurrentIndex],\n imgElement\n ).originalWidth\n \"\n [alt]=\"imagesToView[imagesToViewCurrentIndex].fallback\"\n [ngStyle]=\"{\n width: getCarouselImageAttachmentConfiguration(\n imagesToView[imagesToViewCurrentIndex],\n imgElement\n ).width,\n height: getCarouselImageAttachmentConfiguration(\n imagesToView[imagesToViewCurrentIndex],\n imgElement\n ).height\n }\"\n />\n <div>\n <button\n class=\"stream-chat-angular__image-modal-stepper str-chat__image-carousel-stepper str-chat__image-carousel-stepper-prev\"\n data-testid=\"image-modal-prev\"\n type=\"button\"\n [ngStyle]=\"{\n visibility: isImageModalPrevButtonVisible ? 'visible' : 'hidden'\n }\"\n (click)=\"stepImages(-1)\"\n (keyup.enter)=\"stepImages(-1)\"\n >\n <stream-icon-placeholder icon=\"arrow-left\"></stream-icon-placeholder>\n </button>\n <button\n class=\"stream-chat-angular__image-modal-stepper str-chat__image-carousel-stepper str-chat__image-carousel-stepper-next\"\n type=\"button\"\n data-testid=\"image-modal-next\"\n [ngStyle]=\"{\n visibility: isImageModalNextButtonVisible ? 'visible' : 'hidden'\n }\"\n (click)=\"stepImages(1)\"\n (keyup.enter)=\"stepImages(1)\"\n >\n <stream-icon-placeholder icon=\"arrow-right\"></stream-icon-placeholder>\n </button>\n </div>\n </div>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i3.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: VoiceRecordingComponent, selector: "stream-voice-recording", inputs: ["attachment"] }, { kind: "component", type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon"] }, { kind: "component", type: ModalComponent, selector: "stream-modal", inputs: ["isOpen", "content"], outputs: ["isOpenChange"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.TranslatePipe, name: "translate" }] });
5120
+ AttachmentListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: AttachmentListComponent, selector: "stream-attachment-list", inputs: { messageId: "messageId", parentMessageId: "parentMessageId", attachments: "attachments" }, outputs: { imageModalStateChange: "imageModalStateChange" }, host: { properties: { "class": "this.class" } }, viewQueries: [{ propertyName: "modalContent", first: true, predicate: ["modalContent"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<div\n *ngIf=\"\n orderedAttachments.length > 0 ||\n (customAttachments.length > 0 && customAttachmentsTemplate)\n \"\n class=\"str-chat__attachment-list\"\n>\n <ng-container\n *ngFor=\"let attachment of orderedAttachments; trackBy: trackByUrl\"\n >\n <div\n data-testclass=\"attachment-container\"\n class=\"str-chat__message-attachment str-chat__message-attachment--{{\n attachment.type\n }} str-chat__message-attachment-dynamic-size\"\n [class.str-chat__message-attachment--card]=\"isCard(attachment)\"\n [class.str-chat-angular__message-attachment-file-single]=\"\n isFile(attachment)\n \"\n [class.str-chat__message-attachment--voice-recording]=\"\n isVoiceMessage(attachment)\n \"\n [class.str-chat__message-attachment-with-actions]=\"\n !isGalleryType(attachment) &&\n attachment.actions &&\n attachment.actions.length > 0\n \"\n [class.str-chat__message-attachment--svg-image]=\"isSvg(attachment)\"\n >\n <ng-container *ngIf=\"isImage(attachment)\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.imageAttachmentTemplate$ | async) ||\n defaultImage;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultImage let-attachmentContext=\"attachment\">\n <img\n #imgElement\n class=\"str-chat__message-attachment--img\"\n data-testclass=\"image\"\n [src]=\"\n getImageAttachmentConfiguration(\n attachmentContext,\n 'single',\n imgElement\n ).url\n \"\n [alt]=\"attachmentContext?.fallback\"\n [ngStyle]=\"{\n height: getImageAttachmentConfiguration(\n attachmentContext,\n 'single',\n imgElement\n ).height,\n width: getImageAttachmentConfiguration(\n attachmentContext,\n 'single',\n imgElement\n ).width,\n '--original-height': getImageAttachmentConfiguration(\n attachmentContext,\n 'single',\n imgElement\n ).originalHeight,\n '--original-width': getImageAttachmentConfiguration(\n attachmentContext,\n 'single',\n imgElement\n ).originalWidth\n }\"\n (click)=\"openImageModal([attachmentContext])\"\n (keyup.enter)=\"openImageModal([attachmentContext])\"\n />\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"isGallery(attachment)\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.galleryAttachmentTemplate$ | async) ||\n defaultGallery;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultGallery let-attachmentContext=\"attachment\">\n <div\n class=\"str-chat__gallery\"\n data-testid=\"image-gallery\"\n [class.str-chat__gallery--square]=\"\n (attachmentContext?.images)!.length > 3\n \"\n [class.str-chat__gallery-two-rows]=\"\n (attachmentContext?.images)!.length > 2\n \"\n >\n <ng-container\n *ngFor=\"\n let galleryImage of attachmentContext.images;\n let index = index;\n let isLast = last;\n trackBy: trackByImageUrl\n \"\n >\n <button\n *ngIf=\"index < 3 || (index === 3 && isLast)\"\n class=\"str-chat__gallery-image\"\n data-testclass=\"gallery-image\"\n [class.str-chat__message-attachment--svg-image]=\"\n isSvg(galleryImage)\n \"\n (click)=\"openImageModal(attachmentContext.images!, index)\"\n (keyup.enter)=\"openImageModal(attachmentContext.images!, index)\"\n >\n <img\n #imgElement\n fetchpriority=\"low\"\n loading=\"lazy\"\n [src]=\"\n getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n imgElement\n ).url\n \"\n [alt]=\"galleryImage.fallback\"\n [style.--original-height]=\"\n getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n imgElement\n ).originalHeight\n \"\n [style.--original-width]=\"\n getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n imgElement\n ).originalWidth\n \"\n [ngStyle]=\"{\n height: getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n imgElement\n ).height,\n width: getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n imgElement\n ).width\n }\"\n />\n </button>\n <button\n *ngIf=\"index === 3 && !isLast\"\n #element\n class=\"str-chat__gallery-placeholder\"\n data-testclass=\"gallery-image\"\n data-testid=\"more-image-button\"\n [class.str-chat__message-attachment--svg-image]=\"\n isSvg(galleryImage)\n \"\n [ngStyle]=\"{\n 'background-image':\n 'url(' +\n getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n element\n ).url +\n ')',\n height: getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n element\n ).height,\n width: getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n element\n ).width,\n '--original-height': getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n element\n ).originalHeight,\n '--original-width': getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n element\n ).originalWidth\n }\"\n (click)=\"openImageModal(attachmentContext.images!, index)\"\n (keyup.enter)=\"openImageModal(attachmentContext.images!, index)\"\n >\n <p\n [innerHTML]=\"\n 'streamChat.{{ imageCount }} more'\n | translate\n : { imageCount: attachmentContext!.images!.length - 4 }\n \"\n ></p>\n </button>\n </ng-container>\n </div>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"isVideo(attachment)\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.videoAttachmentTemplate$ | async) ||\n defaultVideo;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultVideo let-attachmentContext=\"attachment\">\n <div\n class=\"str-chat__player-wrapper\"\n data-testclass=\"video-attachment-parent\"\n [style.--original-height]=\"\n getVideoAttachmentConfiguration(attachmentContext, videoElement)\n .originalHeight\n \"\n [style.--original-width]=\"\n getVideoAttachmentConfiguration(attachmentContext, videoElement)\n .originalWidth\n \"\n [ngStyle]=\"{\n height: getVideoAttachmentConfiguration(\n attachmentContext,\n videoElement\n ).height,\n width: getVideoAttachmentConfiguration(\n attachmentContext,\n videoElement\n ).width\n }\"\n >\n <video\n #videoElement\n class=\"str-chat__video-angular\"\n controls\n data-testclass=\"video-attachment\"\n [src]=\"\n getVideoAttachmentConfiguration(attachmentContext, videoElement)\n .url\n \"\n [poster]=\"\n getVideoAttachmentConfiguration(attachmentContext, videoElement)\n .thumbUrl\n \"\n ></video>\n </div>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"isFile(attachment)\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.fileAttachmentTemplate$ | async) ||\n defaultFile;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultFile let-attachmentContext=\"attachment\">\n <div\n class=\"str-chat__message-attachment-file--item str-chat-angular__message-attachment-file-single\"\n >\n <stream-icon-placeholder\n class=\"str-chat__attachment-type-icon\"\n icon=\"unspecified-filetype\"\n ></stream-icon-placeholder>\n <div class=\"str-chat__message-attachment-file--item-text\">\n <a\n class=\"str-chat__message-attachment-file--item-first-row\"\n data-testclass=\"file-link\"\n target=\"_blank\"\n href=\"{{ attachmentContext.asset_url }}\"\n >\n <div\n data-testclass=\"file-title\"\n class=\"str-chat__message-attachment-file--item-name\"\n >\n {{ attachmentContext.title }}\n </div>\n <stream-icon-placeholder\n class=\"str-chat__message-attachment-download-icon\"\n icon=\"download\"\n ></stream-icon-placeholder>\n </a>\n <span\n *ngIf=\"hasFileSize(attachmentContext)\"\n class=\"str-chat__message-attachment-file--item-size\"\n data-testclass=\"size\"\n >{{ getFileSize(attachmentContext) }}</span\n >\n </div>\n </div>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"isVoiceMessage(attachment)\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.voiceRecordingAttachmentTemplate$\n | async) || defaultRecording;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultRecording>\n <stream-voice-recording\n data-testclass=\"voice-recording\"\n [attachment]=\"attachment\"\n ></stream-voice-recording>\n </ng-template>\n </ng-container>\n <ng-container\n *ngIf=\"\n isCard(attachment) &&\n getCardAttachmentConfiguration(attachment) as attachmentConfiguration\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.cardAttachmentTemplate$ | async) ||\n defaultCard;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultCard let-attachmentContext=\"attachment\">\n <div\n class=\"str-chat__message-attachment-card str-chat__message-attachment-card--{{\n attachmentContext.type\n }}\"\n >\n <div\n *ngIf=\"attachmentConfiguration.url\"\n class=\"str-chat__message-attachment-card--header\"\n >\n <a\n *ngIf=\"attachmentContext.type === 'video'; else cardImage\"\n [href]=\"\n attachmentContext.title_link ||\n attachmentContext.og_scrape_url\n \"\n target=\"_blank\"\n data-testclass=\"scraped-video\"\n >\n <ng-content *ngTemplateOutlet=\"cardImage\"></ng-content>\n <div\n class=\"str-chat__message-attachment-card--video-play\"\n ></div>\n <stream-icon-placeholder icon=\"play\"></stream-icon-placeholder>\n </a>\n <ng-template #cardImage>\n <img\n fetchpriority=\"low\"\n loading=\"lazy\"\n data-testclass=\"card-img\"\n alt=\"{{ attachmentConfiguration.url }}\"\n src=\"{{ attachmentConfiguration.url }}\"\n [ngStyle]=\"{\n height: attachmentConfiguration.height,\n width: attachmentConfiguration.width\n }\"\n />\n </ng-template>\n </div>\n <div class=\"str-chat__message-attachment-card--content\">\n <div class=\"str-chat__message-attachment-card--flex\">\n <div\n *ngIf=\"attachmentContext.title\"\n data-testclass=\"card-title\"\n class=\"str-chat__message-attachment-card--title\"\n >\n {{ attachmentContext.title }}\n </div>\n <div\n *ngIf=\"attachmentContext.text\"\n class=\"str-chat__message-attachment-card--text\"\n data-testclass=\"card-text\"\n >\n {{ attachmentContext.text }}\n </div>\n <a\n *ngIf=\"\n attachmentContext.title_link ||\n attachmentContext.og_scrape_url\n \"\n class=\"str-chat__message-attachment-card--url\"\n data-testclass=\"url-link\"\n noopener\n noreferrer\n target=\"_blank\"\n href=\"{{\n attachmentContext.title_link ||\n attachmentContext.og_scrape_url\n }}\"\n >\n {{\n trimUrl(\n attachmentContext.title_link ||\n attachmentContext.og_scrape_url\n )\n }}\n </a>\n </div>\n </div>\n </div>\n </ng-template>\n </ng-container>\n <ng-container\n *ngIf=\"\n !isGalleryType(attachment) &&\n attachment.actions &&\n attachment.actions.length > 0\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.attachmentActionsTemplate$ | async) ||\n defaultActions;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultActions let-attachmentContext=\"attachment\">\n <div class=\"str-chat__message-attachment-actions\">\n <div class=\"str-chat__message-attachment-actions-form\">\n <button\n *ngFor=\"\n let action of attachmentContext.actions;\n trackBy: trackByActionValue\n \"\n data-testclass=\"attachment-action\"\n class=\"str-chat__message-attachment-actions-button str-chat__message-attachment-actions-button--{{\n action.style\n }}\"\n (click)=\"sendAction(action)\"\n (keyup.enter)=\"sendAction(action)\"\n >\n {{ action.text }}\n </button>\n </div>\n </div>\n </ng-template>\n </ng-container>\n </div>\n </ng-container>\n <ng-container *ngIf=\"customAttachmentsTemplate\">\n <ng-template\n *ngTemplateOutlet=\"\n customAttachmentsTemplate;\n context: {\n messageId: messageId,\n parentMessageId: parentMessageId,\n attachments: customAttachments\n }\n \"\n ></ng-template>\n </ng-container>\n\n <ng-container *ngIf=\"imagesToView && imagesToView.length > 0\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.modalTemplate$ | async) || defaultModal;\n context: getModalContext()\n \"\n ></ng-container>\n </ng-container>\n</div>\n\n<ng-template\n #defaultModal\n let-isOpen=\"isOpen\"\n let-isOpenChangeHandler=\"isOpenChangeHandler\"\n let-content=\"content\"\n>\n <stream-modal\n class=\"stream-chat-angular__image-modal-host\"\n [isOpen]=\"isOpen\"\n [content]=\"content\"\n (isOpenChange)=\"isOpenChangeHandler($event)\"\n >\n </stream-modal>\n</ng-template>\n\n<ng-template #modalContent>\n <div class=\"stream-chat-angular__image-modal str-chat__image-carousel\">\n <img\n #imgElement\n class=\"stream-chat-angular__image-modal-image str-chat__image-carousel-image\"\n data-testid=\"modal-image\"\n [src]=\"\n getCarouselImageAttachmentConfiguration(\n imagesToView[imagesToViewCurrentIndex],\n imgElement\n ).url\n \"\n [style.--original-height]=\"\n getCarouselImageAttachmentConfiguration(\n imagesToView[imagesToViewCurrentIndex],\n imgElement\n ).originalHeight\n \"\n [style.--original-width]=\"\n getCarouselImageAttachmentConfiguration(\n imagesToView[imagesToViewCurrentIndex],\n imgElement\n ).originalWidth\n \"\n [alt]=\"imagesToView[imagesToViewCurrentIndex].fallback\"\n [ngStyle]=\"{\n width: getCarouselImageAttachmentConfiguration(\n imagesToView[imagesToViewCurrentIndex],\n imgElement\n ).width,\n height: getCarouselImageAttachmentConfiguration(\n imagesToView[imagesToViewCurrentIndex],\n imgElement\n ).height\n }\"\n />\n <div>\n <button\n class=\"stream-chat-angular__image-modal-stepper str-chat__image-carousel-stepper str-chat__image-carousel-stepper-prev\"\n data-testid=\"image-modal-prev\"\n type=\"button\"\n [ngStyle]=\"{\n visibility: isImageModalPrevButtonVisible ? 'visible' : 'hidden'\n }\"\n (click)=\"stepImages(-1)\"\n (keyup.enter)=\"stepImages(-1)\"\n >\n <stream-icon-placeholder icon=\"arrow-left\"></stream-icon-placeholder>\n </button>\n <button\n class=\"stream-chat-angular__image-modal-stepper str-chat__image-carousel-stepper str-chat__image-carousel-stepper-next\"\n type=\"button\"\n data-testid=\"image-modal-next\"\n [ngStyle]=\"{\n visibility: isImageModalNextButtonVisible ? 'visible' : 'hidden'\n }\"\n (click)=\"stepImages(1)\"\n (keyup.enter)=\"stepImages(1)\"\n >\n <stream-icon-placeholder icon=\"arrow-right\"></stream-icon-placeholder>\n </button>\n </div>\n </div>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: VoiceRecordingComponent, selector: "stream-voice-recording", inputs: ["attachment"] }, { kind: "component", type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon"] }, { kind: "component", type: ModalComponent, selector: "stream-modal", inputs: ["isOpen", "content"], outputs: ["isOpenChange"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.TranslatePipe, name: "translate" }] });
5059
5121
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: AttachmentListComponent, decorators: [{
5060
5122
  type: Component,
5061
5123
  args: [{ selector: 'stream-attachment-list', template: "<div\n *ngIf=\"\n orderedAttachments.length > 0 ||\n (customAttachments.length > 0 && customAttachmentsTemplate)\n \"\n class=\"str-chat__attachment-list\"\n>\n <ng-container\n *ngFor=\"let attachment of orderedAttachments; trackBy: trackByUrl\"\n >\n <div\n data-testclass=\"attachment-container\"\n class=\"str-chat__message-attachment str-chat__message-attachment--{{\n attachment.type\n }} str-chat__message-attachment-dynamic-size\"\n [class.str-chat__message-attachment--card]=\"isCard(attachment)\"\n [class.str-chat-angular__message-attachment-file-single]=\"\n isFile(attachment)\n \"\n [class.str-chat__message-attachment--voice-recording]=\"\n isVoiceMessage(attachment)\n \"\n [class.str-chat__message-attachment-with-actions]=\"\n !isGalleryType(attachment) &&\n attachment.actions &&\n attachment.actions.length > 0\n \"\n [class.str-chat__message-attachment--svg-image]=\"isSvg(attachment)\"\n >\n <ng-container *ngIf=\"isImage(attachment)\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.imageAttachmentTemplate$ | async) ||\n defaultImage;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultImage let-attachmentContext=\"attachment\">\n <img\n #imgElement\n class=\"str-chat__message-attachment--img\"\n data-testclass=\"image\"\n [src]=\"\n getImageAttachmentConfiguration(\n attachmentContext,\n 'single',\n imgElement\n ).url\n \"\n [alt]=\"attachmentContext?.fallback\"\n [ngStyle]=\"{\n height: getImageAttachmentConfiguration(\n attachmentContext,\n 'single',\n imgElement\n ).height,\n width: getImageAttachmentConfiguration(\n attachmentContext,\n 'single',\n imgElement\n ).width,\n '--original-height': getImageAttachmentConfiguration(\n attachmentContext,\n 'single',\n imgElement\n ).originalHeight,\n '--original-width': getImageAttachmentConfiguration(\n attachmentContext,\n 'single',\n imgElement\n ).originalWidth\n }\"\n (click)=\"openImageModal([attachmentContext])\"\n (keyup.enter)=\"openImageModal([attachmentContext])\"\n />\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"isGallery(attachment)\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.galleryAttachmentTemplate$ | async) ||\n defaultGallery;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultGallery let-attachmentContext=\"attachment\">\n <div\n class=\"str-chat__gallery\"\n data-testid=\"image-gallery\"\n [class.str-chat__gallery--square]=\"\n (attachmentContext?.images)!.length > 3\n \"\n [class.str-chat__gallery-two-rows]=\"\n (attachmentContext?.images)!.length > 2\n \"\n >\n <ng-container\n *ngFor=\"\n let galleryImage of attachmentContext.images;\n let index = index;\n let isLast = last;\n trackBy: trackByImageUrl\n \"\n >\n <button\n *ngIf=\"index < 3 || (index === 3 && isLast)\"\n class=\"str-chat__gallery-image\"\n data-testclass=\"gallery-image\"\n [class.str-chat__message-attachment--svg-image]=\"\n isSvg(galleryImage)\n \"\n (click)=\"openImageModal(attachmentContext.images!, index)\"\n (keyup.enter)=\"openImageModal(attachmentContext.images!, index)\"\n >\n <img\n #imgElement\n fetchpriority=\"low\"\n loading=\"lazy\"\n [src]=\"\n getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n imgElement\n ).url\n \"\n [alt]=\"galleryImage.fallback\"\n [style.--original-height]=\"\n getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n imgElement\n ).originalHeight\n \"\n [style.--original-width]=\"\n getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n imgElement\n ).originalWidth\n \"\n [ngStyle]=\"{\n height: getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n imgElement\n ).height,\n width: getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n imgElement\n ).width\n }\"\n />\n </button>\n <button\n *ngIf=\"index === 3 && !isLast\"\n #element\n class=\"str-chat__gallery-placeholder\"\n data-testclass=\"gallery-image\"\n data-testid=\"more-image-button\"\n [class.str-chat__message-attachment--svg-image]=\"\n isSvg(galleryImage)\n \"\n [ngStyle]=\"{\n 'background-image':\n 'url(' +\n getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n element\n ).url +\n ')',\n height: getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n element\n ).height,\n width: getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n element\n ).width,\n '--original-height': getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n element\n ).originalHeight,\n '--original-width': getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n element\n ).originalWidth\n }\"\n (click)=\"openImageModal(attachmentContext.images!, index)\"\n (keyup.enter)=\"openImageModal(attachmentContext.images!, index)\"\n >\n <p\n [innerHTML]=\"\n 'streamChat.{{ imageCount }} more'\n | translate\n : { imageCount: attachmentContext!.images!.length - 4 }\n \"\n ></p>\n </button>\n </ng-container>\n </div>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"isVideo(attachment)\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.videoAttachmentTemplate$ | async) ||\n defaultVideo;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultVideo let-attachmentContext=\"attachment\">\n <div\n class=\"str-chat__player-wrapper\"\n data-testclass=\"video-attachment-parent\"\n [style.--original-height]=\"\n getVideoAttachmentConfiguration(attachmentContext, videoElement)\n .originalHeight\n \"\n [style.--original-width]=\"\n getVideoAttachmentConfiguration(attachmentContext, videoElement)\n .originalWidth\n \"\n [ngStyle]=\"{\n height: getVideoAttachmentConfiguration(\n attachmentContext,\n videoElement\n ).height,\n width: getVideoAttachmentConfiguration(\n attachmentContext,\n videoElement\n ).width\n }\"\n >\n <video\n #videoElement\n class=\"str-chat__video-angular\"\n controls\n data-testclass=\"video-attachment\"\n [src]=\"\n getVideoAttachmentConfiguration(attachmentContext, videoElement)\n .url\n \"\n [poster]=\"\n getVideoAttachmentConfiguration(attachmentContext, videoElement)\n .thumbUrl\n \"\n ></video>\n </div>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"isFile(attachment)\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.fileAttachmentTemplate$ | async) ||\n defaultFile;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultFile let-attachmentContext=\"attachment\">\n <div\n class=\"str-chat__message-attachment-file--item str-chat-angular__message-attachment-file-single\"\n >\n <stream-icon-placeholder\n class=\"str-chat__attachment-type-icon\"\n icon=\"unspecified-filetype\"\n ></stream-icon-placeholder>\n <div class=\"str-chat__message-attachment-file--item-text\">\n <a\n class=\"str-chat__message-attachment-file--item-first-row\"\n data-testclass=\"file-link\"\n target=\"_blank\"\n href=\"{{ attachmentContext.asset_url }}\"\n >\n <div\n data-testclass=\"file-title\"\n class=\"str-chat__message-attachment-file--item-name\"\n >\n {{ attachmentContext.title }}\n </div>\n <stream-icon-placeholder\n class=\"str-chat__message-attachment-download-icon\"\n icon=\"download\"\n ></stream-icon-placeholder>\n </a>\n <span\n *ngIf=\"hasFileSize(attachmentContext)\"\n class=\"str-chat__message-attachment-file--item-size\"\n data-testclass=\"size\"\n >{{ getFileSize(attachmentContext) }}</span\n >\n </div>\n </div>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"isVoiceMessage(attachment)\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.voiceRecordingAttachmentTemplate$\n | async) || defaultRecording;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultRecording>\n <stream-voice-recording\n data-testclass=\"voice-recording\"\n [attachment]=\"attachment\"\n ></stream-voice-recording>\n </ng-template>\n </ng-container>\n <ng-container\n *ngIf=\"\n isCard(attachment) &&\n getCardAttachmentConfiguration(attachment) as attachmentConfiguration\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.cardAttachmentTemplate$ | async) ||\n defaultCard;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultCard let-attachmentContext=\"attachment\">\n <div\n class=\"str-chat__message-attachment-card str-chat__message-attachment-card--{{\n attachmentContext.type\n }}\"\n >\n <div\n *ngIf=\"attachmentConfiguration.url\"\n class=\"str-chat__message-attachment-card--header\"\n >\n <a\n *ngIf=\"attachmentContext.type === 'video'; else cardImage\"\n [href]=\"\n attachmentContext.title_link ||\n attachmentContext.og_scrape_url\n \"\n target=\"_blank\"\n data-testclass=\"scraped-video\"\n >\n <ng-content *ngTemplateOutlet=\"cardImage\"></ng-content>\n <div\n class=\"str-chat__message-attachment-card--video-play\"\n ></div>\n <stream-icon-placeholder icon=\"play\"></stream-icon-placeholder>\n </a>\n <ng-template #cardImage>\n <img\n fetchpriority=\"low\"\n loading=\"lazy\"\n data-testclass=\"card-img\"\n alt=\"{{ attachmentConfiguration.url }}\"\n src=\"{{ attachmentConfiguration.url }}\"\n [ngStyle]=\"{\n height: attachmentConfiguration.height,\n width: attachmentConfiguration.width\n }\"\n />\n </ng-template>\n </div>\n <div class=\"str-chat__message-attachment-card--content\">\n <div class=\"str-chat__message-attachment-card--flex\">\n <div\n *ngIf=\"attachmentContext.title\"\n data-testclass=\"card-title\"\n class=\"str-chat__message-attachment-card--title\"\n >\n {{ attachmentContext.title }}\n </div>\n <div\n *ngIf=\"attachmentContext.text\"\n class=\"str-chat__message-attachment-card--text\"\n data-testclass=\"card-text\"\n >\n {{ attachmentContext.text }}\n </div>\n <a\n *ngIf=\"\n attachmentContext.title_link ||\n attachmentContext.og_scrape_url\n \"\n class=\"str-chat__message-attachment-card--url\"\n data-testclass=\"url-link\"\n noopener\n noreferrer\n target=\"_blank\"\n href=\"{{\n attachmentContext.title_link ||\n attachmentContext.og_scrape_url\n }}\"\n >\n {{\n trimUrl(\n attachmentContext.title_link ||\n attachmentContext.og_scrape_url\n )\n }}\n </a>\n </div>\n </div>\n </div>\n </ng-template>\n </ng-container>\n <ng-container\n *ngIf=\"\n !isGalleryType(attachment) &&\n attachment.actions &&\n attachment.actions.length > 0\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.attachmentActionsTemplate$ | async) ||\n defaultActions;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultActions let-attachmentContext=\"attachment\">\n <div class=\"str-chat__message-attachment-actions\">\n <div class=\"str-chat__message-attachment-actions-form\">\n <button\n *ngFor=\"\n let action of attachmentContext.actions;\n trackBy: trackByActionValue\n \"\n data-testclass=\"attachment-action\"\n class=\"str-chat__message-attachment-actions-button str-chat__message-attachment-actions-button--{{\n action.style\n }}\"\n (click)=\"sendAction(action)\"\n (keyup.enter)=\"sendAction(action)\"\n >\n {{ action.text }}\n </button>\n </div>\n </div>\n </ng-template>\n </ng-container>\n </div>\n </ng-container>\n <ng-container *ngIf=\"customAttachmentsTemplate\">\n <ng-template\n *ngTemplateOutlet=\"\n customAttachmentsTemplate;\n context: {\n messageId: messageId,\n parentMessageId: parentMessageId,\n attachments: customAttachments\n }\n \"\n ></ng-template>\n </ng-container>\n\n <ng-container *ngIf=\"imagesToView && imagesToView.length > 0\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.modalTemplate$ | async) || defaultModal;\n context: getModalContext()\n \"\n ></ng-container>\n </ng-container>\n</div>\n\n<ng-template\n #defaultModal\n let-isOpen=\"isOpen\"\n let-isOpenChangeHandler=\"isOpenChangeHandler\"\n let-content=\"content\"\n>\n <stream-modal\n class=\"stream-chat-angular__image-modal-host\"\n [isOpen]=\"isOpen\"\n [content]=\"content\"\n (isOpenChange)=\"isOpenChangeHandler($event)\"\n >\n </stream-modal>\n</ng-template>\n\n<ng-template #modalContent>\n <div class=\"stream-chat-angular__image-modal str-chat__image-carousel\">\n <img\n #imgElement\n class=\"stream-chat-angular__image-modal-image str-chat__image-carousel-image\"\n data-testid=\"modal-image\"\n [src]=\"\n getCarouselImageAttachmentConfiguration(\n imagesToView[imagesToViewCurrentIndex],\n imgElement\n ).url\n \"\n [style.--original-height]=\"\n getCarouselImageAttachmentConfiguration(\n imagesToView[imagesToViewCurrentIndex],\n imgElement\n ).originalHeight\n \"\n [style.--original-width]=\"\n getCarouselImageAttachmentConfiguration(\n imagesToView[imagesToViewCurrentIndex],\n imgElement\n ).originalWidth\n \"\n [alt]=\"imagesToView[imagesToViewCurrentIndex].fallback\"\n [ngStyle]=\"{\n width: getCarouselImageAttachmentConfiguration(\n imagesToView[imagesToViewCurrentIndex],\n imgElement\n ).width,\n height: getCarouselImageAttachmentConfiguration(\n imagesToView[imagesToViewCurrentIndex],\n imgElement\n ).height\n }\"\n />\n <div>\n <button\n class=\"stream-chat-angular__image-modal-stepper str-chat__image-carousel-stepper str-chat__image-carousel-stepper-prev\"\n data-testid=\"image-modal-prev\"\n type=\"button\"\n [ngStyle]=\"{\n visibility: isImageModalPrevButtonVisible ? 'visible' : 'hidden'\n }\"\n (click)=\"stepImages(-1)\"\n (keyup.enter)=\"stepImages(-1)\"\n >\n <stream-icon-placeholder icon=\"arrow-left\"></stream-icon-placeholder>\n </button>\n <button\n class=\"stream-chat-angular__image-modal-stepper str-chat__image-carousel-stepper str-chat__image-carousel-stepper-next\"\n type=\"button\"\n data-testid=\"image-modal-next\"\n [ngStyle]=\"{\n visibility: isImageModalNextButtonVisible ? 'visible' : 'hidden'\n }\"\n (click)=\"stepImages(1)\"\n (keyup.enter)=\"stepImages(1)\"\n >\n <stream-icon-placeholder icon=\"arrow-right\"></stream-icon-placeholder>\n </button>\n </div>\n </div>\n</ng-template>\n" }]
@@ -5265,7 +5327,7 @@ class MessageReactionsComponent {
5265
5327
  }
5266
5328
  }
5267
5329
  MessageReactionsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: MessageReactionsComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: MessageReactionsService }, { token: CustomTemplatesService }], target: i0.ɵɵFactoryTarget.Component });
5268
- MessageReactionsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: MessageReactionsComponent, selector: "stream-message-reactions", inputs: { messageId: "messageId", messageReactionGroups: "messageReactionGroups", messageReactionCounts: "messageReactionCounts", latestReactions: "latestReactions", ownReactions: "ownReactions" }, viewQueries: [{ propertyName: "selectorContainer", first: true, predicate: ["selectorContainer"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div\n *ngIf=\"existingReactions.length > 0\"\n data-testid=\"reaction-list\"\n class=\"str-chat__reaction-list str-chat__message-reactions-container\"\n [class.str-chat__reaction-list--reverse]=\"true\"\n>\n <ul class=\"str-chat__message-reactions\">\n <li\n *ngFor=\"\n let reactionType of existingReactions;\n trackBy: trackByMessageReaction\n \"\n class=\"str-chat__message-reaction\"\n data-testclass=\"emoji\"\n [class.str-chat__message-reaction-own]=\"isOwnReaction(reactionType)\"\n (click)=\"reactionSelected(reactionType)\"\n (keyup.enter)=\"reactionSelected(reactionType)\"\n >\n <span class=\"emoji str-chat__message-reaction-emoji\">\n {{ getEmojiByReaction(reactionType) }}&nbsp;\n </span>\n <span\n data-testclass=\"reaction-list-reaction-count\"\n class=\"str-chat__message-reaction-count\"\n >\n {{ messageReactionGroups?.[reactionType]?.count ?? 0 }}\n </span>\n </li>\n </ul>\n</div>\n\n<ng-container *ngIf=\"selectedReactionType\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.modalTemplate$ | async) || defaultModal;\n context: {\n isOpen: !!selectedReactionType,\n messageId: messageId,\n reactionType: selectedReactionType,\n isOpenChangeHandler: isOpenChange,\n content: modalContent\n }\n \"\n ></ng-container>\n</ng-container>\n\n<ng-template\n #defaultModal\n let-isOpen=\"isOpen\"\n let-messageId=\"messageId\"\n let-reactionType=\"reactionType\"\n let-isOpenChangeHandler=\"isOpenChangeHandler\"\n let-content=\"content\"\n>\n <stream-modal\n class=\"str-chat__message-reactions-details-modal\"\n [isOpen]=\"isOpen\"\n [content]=\"content\"\n (isOpenChange)=\"isOpenChangeHandler($event)\"\n >\n </stream-modal>\n</ng-template>\n\n<ng-template #modalContent>\n <div class=\"str-chat__message-reactions-details\">\n <div class=\"str-chat__message-reactions-details-reaction-types\">\n <div\n *ngFor=\"\n let reactionType of existingReactions;\n trackBy: trackByMessageReaction\n \"\n class=\"str-chat__message-reactions-details-reaction-type\"\n attr.data-testid=\"reaction-details-selector-{{ reactionType }}\"\n [class.str-chat__message-reactions-details-reaction-type--selected]=\"\n reactionType === selectedReactionType\n \"\n (click)=\"reactionSelected(reactionType)\"\n (keyup.enter)=\"reactionSelected(reactionType)\"\n >\n <span class=\"emoji str-chat__message-reaction-emoji\">\n {{ getEmojiByReaction(reactionType) }}&nbsp;\n </span>\n <span class=\"str-chat__message-reaction-count\">\n {{ messageReactionGroups?.[reactionType]?.count ?? 0 }}\n </span>\n </div>\n </div>\n <div\n class=\"emoji str-chat__message-reaction-emoji str-chat__message-reaction-emoji-big\"\n >\n {{ getEmojiByReaction(selectedReactionType!) }}\n </div>\n <div\n data-testid=\"all-reacting-users\"\n class=\"str-chat__message-reactions-details-reacting-users\"\n >\n <ng-container\n *ngFor=\"\n let reactionType of existingReactions;\n trackBy: trackByMessageReaction\n \"\n >\n <stream-user-list\n attr.data-testid=\"{{ reactionType }}-user-list\"\n [style.display]=\"\n selectedReactionType === reactionType ? 'block' : 'none'\n \"\n [users]=\"usersByReactions[reactionType]?.users || []\"\n [isLoading]=\"isLoading\"\n [hasMore]=\"!!usersByReactions[reactionType]?.next || false\"\n (loadMore)=\"loadNextPageOfReactions()\"\n ></stream-user-list>\n </ng-container>\n </div>\n </div>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ModalComponent, selector: "stream-modal", inputs: ["isOpen", "content"], outputs: ["isOpenChange"] }, { kind: "component", type: UserListComponent, selector: "stream-user-list", inputs: ["users", "isLoading", "hasMore"], outputs: ["loadMore"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }] });
5330
+ MessageReactionsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: MessageReactionsComponent, selector: "stream-message-reactions", inputs: { messageId: "messageId", messageReactionGroups: "messageReactionGroups", messageReactionCounts: "messageReactionCounts", latestReactions: "latestReactions", ownReactions: "ownReactions" }, viewQueries: [{ propertyName: "selectorContainer", first: true, predicate: ["selectorContainer"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div\n *ngIf=\"existingReactions.length > 0\"\n data-testid=\"reaction-list\"\n class=\"str-chat__reaction-list str-chat__message-reactions-container\"\n [class.str-chat__reaction-list--reverse]=\"true\"\n>\n <ul class=\"str-chat__message-reactions\">\n <li\n *ngFor=\"\n let reactionType of existingReactions;\n trackBy: trackByMessageReaction\n \"\n class=\"str-chat__message-reaction\"\n data-testclass=\"emoji\"\n [class.str-chat__message-reaction-own]=\"isOwnReaction(reactionType)\"\n (click)=\"reactionSelected(reactionType)\"\n (keyup.enter)=\"reactionSelected(reactionType)\"\n >\n <span class=\"emoji str-chat__message-reaction-emoji\">\n {{ getEmojiByReaction(reactionType) }}&nbsp;\n </span>\n <span\n data-testclass=\"reaction-list-reaction-count\"\n class=\"str-chat__message-reaction-count\"\n >\n {{ messageReactionGroups?.[reactionType]?.count ?? 0 }}\n </span>\n </li>\n </ul>\n</div>\n\n<ng-container *ngIf=\"selectedReactionType\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.modalTemplate$ | async) || defaultModal;\n context: {\n isOpen: !!selectedReactionType,\n messageId: messageId,\n reactionType: selectedReactionType,\n isOpenChangeHandler: isOpenChange,\n content: modalContent\n }\n \"\n ></ng-container>\n</ng-container>\n\n<ng-template\n #defaultModal\n let-isOpen=\"isOpen\"\n let-messageId=\"messageId\"\n let-reactionType=\"reactionType\"\n let-isOpenChangeHandler=\"isOpenChangeHandler\"\n let-content=\"content\"\n>\n <stream-modal\n class=\"str-chat__message-reactions-details-modal\"\n [isOpen]=\"isOpen\"\n [content]=\"content\"\n (isOpenChange)=\"isOpenChangeHandler($event)\"\n >\n </stream-modal>\n</ng-template>\n\n<ng-template #modalContent>\n <div class=\"str-chat__message-reactions-details\">\n <div class=\"str-chat__message-reactions-details-reaction-types\">\n <div\n *ngFor=\"\n let reactionType of existingReactions;\n trackBy: trackByMessageReaction\n \"\n class=\"str-chat__message-reactions-details-reaction-type\"\n attr.data-testid=\"reaction-details-selector-{{ reactionType }}\"\n [class.str-chat__message-reactions-details-reaction-type--selected]=\"\n reactionType === selectedReactionType\n \"\n (click)=\"reactionSelected(reactionType)\"\n (keyup.enter)=\"reactionSelected(reactionType)\"\n >\n <span class=\"emoji str-chat__message-reaction-emoji\">\n {{ getEmojiByReaction(reactionType) }}&nbsp;\n </span>\n <span class=\"str-chat__message-reaction-count\">\n {{ messageReactionGroups?.[reactionType]?.count ?? 0 }}\n </span>\n </div>\n </div>\n <div\n class=\"emoji str-chat__message-reaction-emoji str-chat__message-reaction-emoji-big\"\n >\n {{ getEmojiByReaction(selectedReactionType!) }}\n </div>\n <div\n data-testid=\"all-reacting-users\"\n class=\"str-chat__message-reactions-details-reacting-users\"\n >\n <ng-container\n *ngFor=\"\n let reactionType of existingReactions;\n trackBy: trackByMessageReaction\n \"\n >\n <stream-user-list\n attr.data-testid=\"{{ reactionType }}-user-list\"\n [style.display]=\"\n selectedReactionType === reactionType ? 'block' : 'none'\n \"\n [users]=\"usersByReactions[reactionType]?.users || []\"\n [isLoading]=\"isLoading\"\n [hasMore]=\"!!usersByReactions[reactionType]?.next || false\"\n (loadMore)=\"loadNextPageOfReactions()\"\n ></stream-user-list>\n </ng-container>\n </div>\n </div>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ModalComponent, selector: "stream-modal", inputs: ["isOpen", "content"], outputs: ["isOpenChange"] }, { kind: "component", type: UserListComponent, selector: "stream-user-list", inputs: ["users", "isLoading", "hasMore"], outputs: ["loadMore"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }] });
5269
5331
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: MessageReactionsComponent, decorators: [{
5270
5332
  type: Component,
5271
5333
  args: [{ selector: 'stream-message-reactions', template: "<div\n *ngIf=\"existingReactions.length > 0\"\n data-testid=\"reaction-list\"\n class=\"str-chat__reaction-list str-chat__message-reactions-container\"\n [class.str-chat__reaction-list--reverse]=\"true\"\n>\n <ul class=\"str-chat__message-reactions\">\n <li\n *ngFor=\"\n let reactionType of existingReactions;\n trackBy: trackByMessageReaction\n \"\n class=\"str-chat__message-reaction\"\n data-testclass=\"emoji\"\n [class.str-chat__message-reaction-own]=\"isOwnReaction(reactionType)\"\n (click)=\"reactionSelected(reactionType)\"\n (keyup.enter)=\"reactionSelected(reactionType)\"\n >\n <span class=\"emoji str-chat__message-reaction-emoji\">\n {{ getEmojiByReaction(reactionType) }}&nbsp;\n </span>\n <span\n data-testclass=\"reaction-list-reaction-count\"\n class=\"str-chat__message-reaction-count\"\n >\n {{ messageReactionGroups?.[reactionType]?.count ?? 0 }}\n </span>\n </li>\n </ul>\n</div>\n\n<ng-container *ngIf=\"selectedReactionType\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.modalTemplate$ | async) || defaultModal;\n context: {\n isOpen: !!selectedReactionType,\n messageId: messageId,\n reactionType: selectedReactionType,\n isOpenChangeHandler: isOpenChange,\n content: modalContent\n }\n \"\n ></ng-container>\n</ng-container>\n\n<ng-template\n #defaultModal\n let-isOpen=\"isOpen\"\n let-messageId=\"messageId\"\n let-reactionType=\"reactionType\"\n let-isOpenChangeHandler=\"isOpenChangeHandler\"\n let-content=\"content\"\n>\n <stream-modal\n class=\"str-chat__message-reactions-details-modal\"\n [isOpen]=\"isOpen\"\n [content]=\"content\"\n (isOpenChange)=\"isOpenChangeHandler($event)\"\n >\n </stream-modal>\n</ng-template>\n\n<ng-template #modalContent>\n <div class=\"str-chat__message-reactions-details\">\n <div class=\"str-chat__message-reactions-details-reaction-types\">\n <div\n *ngFor=\"\n let reactionType of existingReactions;\n trackBy: trackByMessageReaction\n \"\n class=\"str-chat__message-reactions-details-reaction-type\"\n attr.data-testid=\"reaction-details-selector-{{ reactionType }}\"\n [class.str-chat__message-reactions-details-reaction-type--selected]=\"\n reactionType === selectedReactionType\n \"\n (click)=\"reactionSelected(reactionType)\"\n (keyup.enter)=\"reactionSelected(reactionType)\"\n >\n <span class=\"emoji str-chat__message-reaction-emoji\">\n {{ getEmojiByReaction(reactionType) }}&nbsp;\n </span>\n <span class=\"str-chat__message-reaction-count\">\n {{ messageReactionGroups?.[reactionType]?.count ?? 0 }}\n </span>\n </div>\n </div>\n <div\n class=\"emoji str-chat__message-reaction-emoji str-chat__message-reaction-emoji-big\"\n >\n {{ getEmojiByReaction(selectedReactionType!) }}\n </div>\n <div\n data-testid=\"all-reacting-users\"\n class=\"str-chat__message-reactions-details-reacting-users\"\n >\n <ng-container\n *ngFor=\"\n let reactionType of existingReactions;\n trackBy: trackByMessageReaction\n \"\n >\n <stream-user-list\n attr.data-testid=\"{{ reactionType }}-user-list\"\n [style.display]=\"\n selectedReactionType === reactionType ? 'block' : 'none'\n \"\n [users]=\"usersByReactions[reactionType]?.users || []\"\n [isLoading]=\"isLoading\"\n [hasMore]=\"!!usersByReactions[reactionType]?.next || false\"\n (loadMore)=\"loadNextPageOfReactions()\"\n ></stream-user-list>\n </ng-container>\n </div>\n </div>\n</ng-template>\n" }]
@@ -5410,7 +5472,7 @@ class MessageTextComponent {
5410
5472
  }
5411
5473
  }
5412
5474
  MessageTextComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: MessageTextComponent, deps: [{ token: MessageService }, { token: CustomTemplatesService }], target: i0.ɵɵFactoryTarget.Component });
5413
- MessageTextComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: MessageTextComponent, selector: "stream-message-text", inputs: { message: "message", isQuoted: "isQuoted", shouldTranslate: "shouldTranslate" }, usesOnChanges: true, ngImport: i0, template: "<p\n [class.str-chat__quoted-message-text-value]=\"isQuoted\"\n [class.str-chat__message-text-value]=\"!isQuoted\"\n *ngIf=\"message?.text\"\n data-testid=\"text\"\n>\n <ng-container *ngIf=\"messageTextParts; else defaultContent\">\n <!-- eslint-disable-next-line @angular-eslint/template/use-track-by-function -->\n <ng-container *ngFor=\"let part of messageTextParts\">\n <span\n *ngIf=\"part.type === 'text'; else mention\"\n [innerHTML]=\"part.content\"\n ></span>\n <ng-template #mention>\n <ng-template #defaultMention let-content=\"content\">\n <span class=\"str-chat__message-mention\">{{ content }}</span>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.mentionTemplate$ | async) || defaultMention;\n context: getMentionContext(part)\n \"\n ></ng-container>\n </ng-template>\n </ng-container>\n </ng-container>\n <ng-template #defaultContent>\n <ng-container *ngIf=\"displayAs === 'text'; else asHTML\">\n {{ messageText || \"\" }}\n </ng-container>\n <ng-template #asHTML\n ><span data-testid=\"html-content\" [innerHTML]=\"messageText\"></span\n ></ng-template>\n </ng-template>\n</p>\n", dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }] });
5475
+ MessageTextComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: MessageTextComponent, selector: "stream-message-text", inputs: { message: "message", isQuoted: "isQuoted", shouldTranslate: "shouldTranslate" }, usesOnChanges: true, ngImport: i0, template: "<p\n [class.str-chat__quoted-message-text-value]=\"isQuoted\"\n [class.str-chat__message-text-value]=\"!isQuoted\"\n *ngIf=\"message?.text\"\n data-testid=\"text\"\n>\n <ng-container *ngIf=\"messageTextParts; else defaultContent\">\n <!-- eslint-disable-next-line @angular-eslint/template/use-track-by-function -->\n <ng-container *ngFor=\"let part of messageTextParts\">\n <span\n *ngIf=\"part.type === 'text'; else mention\"\n [innerHTML]=\"part.content\"\n ></span>\n <ng-template #mention>\n <ng-template #defaultMention let-content=\"content\">\n <span class=\"str-chat__message-mention\">{{ content }}</span>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.mentionTemplate$ | async) || defaultMention;\n context: getMentionContext(part)\n \"\n ></ng-container>\n </ng-template>\n </ng-container>\n </ng-container>\n <ng-template #defaultContent>\n <ng-container *ngIf=\"displayAs === 'text'; else asHTML\">\n {{ messageText || \"\" }}\n </ng-container>\n <ng-template #asHTML\n ><span data-testid=\"html-content\" [innerHTML]=\"messageText\"></span\n ></ng-template>\n </ng-template>\n</p>\n", dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }] });
5414
5476
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: MessageTextComponent, decorators: [{
5415
5477
  type: Component,
5416
5478
  args: [{ selector: 'stream-message-text', template: "<p\n [class.str-chat__quoted-message-text-value]=\"isQuoted\"\n [class.str-chat__message-text-value]=\"!isQuoted\"\n *ngIf=\"message?.text\"\n data-testid=\"text\"\n>\n <ng-container *ngIf=\"messageTextParts; else defaultContent\">\n <!-- eslint-disable-next-line @angular-eslint/template/use-track-by-function -->\n <ng-container *ngFor=\"let part of messageTextParts\">\n <span\n *ngIf=\"part.type === 'text'; else mention\"\n [innerHTML]=\"part.content\"\n ></span>\n <ng-template #mention>\n <ng-template #defaultMention let-content=\"content\">\n <span class=\"str-chat__message-mention\">{{ content }}</span>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.mentionTemplate$ | async) || defaultMention;\n context: getMentionContext(part)\n \"\n ></ng-container>\n </ng-template>\n </ng-container>\n </ng-container>\n <ng-template #defaultContent>\n <ng-container *ngIf=\"displayAs === 'text'; else asHTML\">\n {{ messageText || \"\" }}\n </ng-container>\n <ng-template #asHTML\n ><span data-testid=\"html-content\" [innerHTML]=\"messageText\"></span\n ></ng-template>\n </ng-template>\n</p>\n" }]
@@ -5472,7 +5534,7 @@ class MessageComponent {
5472
5534
  this.isEditedFlagOpened = false;
5473
5535
  this.shouldDisplayTranslationNotice = false;
5474
5536
  this.displayedMessageTextContent = 'original';
5475
- this.imageAttachmentModalState = 'closed';
5537
+ this.nestedModalState = 'closed';
5476
5538
  this.shouldDisplayThreadLink = false;
5477
5539
  this.isSentByCurrentUser = false;
5478
5540
  this.readByText = '';
@@ -5545,6 +5607,12 @@ class MessageComponent {
5545
5607
  }
5546
5608
  }
5547
5609
  }));
5610
+ this.subscriptions.push(this.messageActionsService.modalOpenedForMessage.subscribe((messageId) => {
5611
+ var _a;
5612
+ if (messageId === ((_a = this.message) === null || _a === void 0 ? void 0 : _a.id)) {
5613
+ this.nestedModalState = 'opened';
5614
+ }
5615
+ }));
5548
5616
  }
5549
5617
  ngOnChanges(changes) {
5550
5618
  var _a, _b, _c, _d, _e, _f, _g;
@@ -5641,6 +5709,17 @@ class MessageComponent {
5641
5709
  (_b = this.messageMenuTrigger) === null || _b === void 0 ? void 0 : _b.hide();
5642
5710
  }
5643
5711
  }));
5712
+ this.subscriptions.push(this.messageActionsService.modalOpenedForMessage
5713
+ .pipe(pairwise())
5714
+ .subscribe(([oldId, newId]) => {
5715
+ var _a, _b;
5716
+ if (newId === ((_a = this.message) === null || _a === void 0 ? void 0 : _a.id)) {
5717
+ this.nestedModalState = 'opened';
5718
+ }
5719
+ else if (oldId === ((_b = this.message) === null || _b === void 0 ? void 0 : _b.id) && newId === undefined) {
5720
+ this.nestedModalState = 'closed';
5721
+ }
5722
+ }));
5644
5723
  }
5645
5724
  ngOnDestroy() {
5646
5725
  this.subscriptions.forEach((s) => s.unsubscribe());
@@ -5708,7 +5787,7 @@ class MessageComponent {
5708
5787
  messageId: ((_a = this.message) === null || _a === void 0 ? void 0 : _a.id) || '',
5709
5788
  attachments: ((_b = this.message) === null || _b === void 0 ? void 0 : _b.attachments) || [],
5710
5789
  parentMessageId: (_c = this.message) === null || _c === void 0 ? void 0 : _c.parent_id,
5711
- imageModalStateChangeHandler: (state) => (this.imageAttachmentModalState = state),
5790
+ imageModalStateChangeHandler: (state) => (this.nestedModalState = state),
5712
5791
  };
5713
5792
  }
5714
5793
  getMessageContext() {
@@ -5895,10 +5974,10 @@ class MessageComponent {
5895
5974
  }
5896
5975
  }
5897
5976
  MessageComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: MessageComponent, deps: [{ token: ChatClientService }, { token: ChannelService }, { token: CustomTemplatesService }, { token: i0.ChangeDetectorRef }, { token: DateParserService }, { token: MessageActionsService }, { token: i0.NgZone }, { token: i6.TranslateService }], target: i0.ɵɵFactoryTarget.Component });
5898
- MessageComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: MessageComponent, selector: "stream-message", inputs: { message: "message", enabledMessageActions: "enabledMessageActions", isLastSentMessage: "isLastSentMessage", mode: "mode", isHighlighted: "isHighlighted", scroll$: "scroll$" }, viewQueries: [{ propertyName: "messageMenuTrigger", first: true, predicate: ["messageMenuTrigger"], descendants: true }, { propertyName: "messageMenuFloat", first: true, predicate: ["messageMenuFloat"], descendants: true }, { propertyName: "messageTextElement", first: true, predicate: ["messageTextElement"], descendants: true }, { propertyName: "messageBubble", first: true, predicate: ["messageBubble"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<ng-container\n *ngIf=\"\n message?.type === 'error' &&\n (message?.moderation_details?.action ===\n 'MESSAGE_RESPONSE_ACTION_REMOVE' ||\n message?.moderation?.action === 'remove');\n else notBlockedMessage\n \"\n>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.messageBlockedTemplate$ | async) ||\n defaultBlockedMessage;\n context: getMessageBlockedContext()\n \"\n ></ng-container>\n <ng-template #defaultBlockedMessage>\n <stream-message-blocked\n [message]=\"message\"\n [isMyMessage]=\"isSentByCurrentUser\"\n ></stream-message-blocked>\n </ng-template>\n</ng-container>\n<ng-template #notBlockedMessage>\n <div\n data-testid=\"message-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 }} str-chat__message-menu-{{ areMessageOptionsOpen ? 'opened' : 'closed' }}\"\n [class.str-chat__message--me]=\"isSentByCurrentUser\"\n [class.str-chat__message--other]=\"!isSentByCurrentUser\"\n [class.str-chat__message-simple--me]=\"isSentByCurrentUser\"\n [class.str-chat__message--has-attachment]=\"hasAttachment\"\n [class.str-chat__message--with-reactions]=\"hasReactions\"\n [class.str-chat__message--highlighted]=\"isHighlighted\"\n [class.str-chat__message-with-thread-link]=\"shouldDisplayThreadLink\"\n [class.str-chat__message-send-can-be-retried]=\"\n (message?.status === 'failed' && message?.errorStatusCode !== 403) ||\n (message?.type === 'error' && message?.moderation_details)\n \"\n [class.str-chat__message-with-touch-support]=\"hasTouchSupport\"\n [class.str-chat__message-without-touch-support]=\"!hasTouchSupport\"\n >\n <ng-container *ngIf=\"!message?.deleted_at; else deletedMessage\">\n <ng-container *ngIf=\"message?.type !== 'system'; else systemMessage\">\n <stream-avatar-placeholder\n data-testid=\"avatar\"\n class=\"str-chat-angular__avatar-host str-chat__message-sender-avatar\"\n type=\"user\"\n location=\"message-sender\"\n [imageUrl]=\"message?.user?.image\"\n [name]=\"message?.user?.name || message?.user?.id\"\n [user]=\"message?.user || undefined\"\n ></stream-avatar-placeholder>\n <div class=\"str-chat__message-inner\">\n <div\n *ngIf=\"!hasTouchSupport && areOptionsVisible\"\n class=\"str-chat__message-simple__actions str-chat__message-options\"\n data-testid=\"message-options\"\n [class.str-chat__message-actions-open]=\"areMessageOptionsOpen\"\n >\n <div\n #messageActionsToggle\n data-testid=\"message-actions-container\"\n class=\"str-chat__message-actions-container str-chat__message-simple__actions__action str-chat__message-simple__actions__action--options\"\n [floatUiLoose]=\"messageMenuFloat\"\n [looseTrigger]=\"\n messageActionsService.customActionClickHandler\n ? 'none'\n : 'click'\n \"\n [hideOnScroll]=\"false\"\n [hideOnClickOutside]=\"true\"\n [hideOnMouseLeave]=\"false\"\n [disableAnimation]=\"false\"\n [preventOverflow]=\"true\"\n [positionFixed]=\"true\"\n (onSHown)=\"areMessageOptionsOpen = true\"\n (onHidden)=\"areMessageOptionsOpen = false\"\n >\n <div\n *ngIf=\"visibleMessageActionsCount > 0\"\n class=\"str-chat__message-actions-box-button\"\n data-testid=\"message-options-button\"\n (click)=\"messageOptionsButtonClicked()\"\n (keyup.enter)=\"messageOptionsButtonClicked()\"\n >\n <stream-icon-placeholder\n icon=\"action\"\n class=\"str-chat__message-action-icon\"\n ></stream-icon-placeholder>\n </div>\n </div>\n </div>\n <ng-container\n *ngIf=\"\n customTemplatesService.customMessageMetadataInsideBubbleTemplate$\n | async\n \"\n >\n <ng-template\n *ngTemplateOutlet=\"\n (customTemplatesService.customMessageMetadataInsideBubbleTemplate$\n | async)!;\n context: { message: message }\n \"\n ></ng-template>\n </ng-container>\n <div class=\"str-chat__message-reactions-host\">\n <ng-template\n #defaultMessageReactions\n let-messageReactionCounts=\"messageReactionCounts\"\n let-latestReactions=\"latestReactions\"\n let-messageId=\"messageId\"\n let-ownReactions=\"ownReactions\"\n let-messageReactionGroups=\"messageReactionGroups\"\n >\n <stream-message-reactions\n [messageReactionCounts]=\"messageReactionCounts\"\n [latestReactions]=\"latestReactions\"\n [messageId]=\"messageId\"\n [ownReactions]=\"ownReactions\"\n [messageReactionGroups]=\"messageReactionGroups\"\n ></stream-message-reactions>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.messageReactionsTemplate$ | async) ||\n defaultMessageReactions;\n context: getMessageReactionsContext()\n \"\n ></ng-container>\n </div>\n <float-ui-content #messageMenuFloat>\n <ng-template\n #defaultMessageActionsBox\n let-isMine=\"isMine\"\n let-messageInput=\"message\"\n let-enabledActions=\"enabledActions\"\n let-messageTextHtmlElement=\"messageTextHtmlElement\"\n >\n <stream-message-actions-box\n [isMine]=\"isMine\"\n [message]=\"messageInput\"\n [enabledActions]=\"enabledActions\"\n [messageTextHtmlElement]=\"messageTextHtmlElement\"\n ></stream-message-actions-box>\n </ng-template>\n <ng-container>\n <div\n (click)=\"messageActionsBoxClicked(messageMenuFloat)\"\n (keyup.enter)=\"messageActionsBoxClicked(messageMenuFloat)\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.messageActionsBoxTemplate$\n | async) || defaultMessageActionsBox;\n context: getMessageActionsBoxContext()\n \"\n >\n </ng-container>\n </div>\n </ng-container>\n </float-ui-content>\n <div\n class=\"str-chat__message-bubble str-chat-angular__message-bubble\"\n [class.str-chat-angular__message-bubble--attachment-modal-open]=\"\n imageAttachmentModalState === 'opened'\n \"\n data-testid=\"message-bubble\"\n [floatUiLoose]=\"messageMenuFloat\"\n #messageMenuTrigger=\"floatUiLoose\"\n #messageBubble\n looseTrigger=\"none\"\n [hideOnScroll]=\"false\"\n [hideOnClickOutside]=\"true\"\n [hideOnMouseLeave]=\"false\"\n [disableAnimation]=\"true\"\n [preventOverflow]=\"true\"\n (onShown)=\"areMessageOptionsOpen = true\"\n (onHidden)=\"areMessageOptionsOpen = false\"\n [positionFixed]=\"true\"\n >\n <ng-container *ngIf=\"hasAttachment && !message?.quoted_message\">\n <div class=\"str-chat__attachments-container\">\n <ng-container\n *ngTemplateOutlet=\"attachmentsTemplate\"\n ></ng-container>\n </div>\n </ng-container>\n <div\n *ngIf=\"\n message?.text || (message?.quoted_message && hasAttachment)\n \"\n class=\"str-chat__message-text\"\n tabindex=\"0\"\n [class.str-chat__message-text--pointer-cursor]=\"\n (message?.status === 'failed' &&\n message?.errorStatusCode !== 403) ||\n (this.message?.type === 'error' &&\n this.message?.moderation_details) ||\n message?.message_text_updated_at\n \"\n (click)=\"messageClicked()\"\n (keyup.enter)=\"messageClicked()\"\n >\n <div\n data-testid=\"inner-message\"\n class=\"str-chat__message-text-inner str-chat__message-simple-text-inner\"\n [class.str-chat__message-light-text-inner--has-attachment]=\"\n hasAttachment\n \"\n >\n <ng-container *ngTemplateOutlet=\"quotedMessage\"></ng-container>\n <ng-container *ngIf=\"hasAttachment && message?.quoted_message\">\n <ng-container\n *ngTemplateOutlet=\"attachmentsTemplate\"\n ></ng-container>\n </ng-container>\n <div\n *ngIf=\"message?.type === 'error'\"\n data-testid=\"client-error-message\"\n class=\"str-chat__simple-message--error-message str-chat__message--error-message\"\n >\n <ng-container *ngIf=\"!message?.moderation_details\">{{\n \"streamChat.Error \u00B7 Unsent\" | translate\n }}</ng-container>\n </div>\n <div\n *ngIf=\"message?.status === 'failed'\"\n data-testid=\"error-message\"\n class=\"str-chat__simple-message--error-message str-chat__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 <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.messageTextTemplate$ | async) ||\n defaultText;\n context: getMessageTextContext()\n \"\n ></ng-container>\n <ng-template\n #defaultText\n let-message=\"message\"\n let-isQuoted=\"isQuoted\"\n let-shouldTranslate=\"shouldTranslate\"\n >\n <stream-message-text\n [message]=\"message\"\n [isQuoted]=\"isQuoted\"\n [shouldTranslate]=\"shouldTranslate\"\n data-testid=\"quoted-message-text\"\n ></stream-message-text>\n </ng-template>\n </div>\n </div>\n <stream-icon-placeholder\n class=\"str-chat__message-error-icon\"\n icon=\"error\"\n ></stream-icon-placeholder>\n </div>\n </div>\n <ng-container\n *ngTemplateOutlet=\"replyCountButton; context: { message: message }\"\n ></ng-container>\n\n <ng-container *ngTemplateOutlet=\"messageDateAndSender\"></ng-container>\n </ng-container>\n </ng-container>\n </div>\n\n <ng-template #deletedMessage>\n <div data-testid=\"message-deleted-component\">\n <div class=\"str-chat__message--deleted-inner\" translate>\n streamChat.This message was deleted...\n </div>\n </div>\n </ng-template>\n\n <ng-template #systemMessage>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.systemMessageTemplate$ | async) ||\n defaultSystemMessage;\n context: getMessageContext()\n \"\n ></ng-container>\n <ng-template #defaultSystemMessage let-messageInput=\"message\">\n <div data-testid=\"system-message\" class=\"str-chat__message--system\">\n <div class=\"str-chat__message--system__text\">\n <div class=\"str-chat__message--system__line\"></div>\n <p>{{ messageInput?.text }}</p>\n <div class=\"str-chat__message--system__line\"></div>\n </div>\n <div class=\"str-chat__message--system__date\">\n {{ parsedDate }}\n </div>\n </div>\n </ng-template>\n </ng-template>\n\n <ng-template #quotedMessage>\n <div\n *ngIf=\"message?.quoted_message\"\n class=\"quoted-message str-chat__quoted-message-preview\"\n data-testid=\"quoted-message-container\"\n [class.mine]=\"isSentByCurrentUser\"\n (click)=\"\n jumpToMessage(\n (message?.quoted_message)!.id,\n message?.quoted_message?.parent_id\n )\n \"\n (keyup.enter)=\"\n jumpToMessage(\n (message?.quoted_message)!.id,\n message?.quoted_message?.parent_id\n )\n \"\n >\n <stream-avatar-placeholder\n data-testid=\"qouted-message-avatar\"\n class=\"str-chat-angular__avatar-host str-chat__message-sender-avatar\"\n type=\"user\"\n location=\"quoted-message-sender\"\n [imageUrl]=\"message?.quoted_message?.user?.image\"\n [name]=\"\n message?.quoted_message?.user?.name ||\n message?.quoted_message?.user?.id\n \"\n [user]=\"message?.quoted_message?.user || undefined\"\n ></stream-avatar-placeholder>\n <div class=\"quoted-message-inner str-chat__quoted-message-bubble\">\n <ng-container\n *ngIf=\"\n message?.quoted_message?.attachments &&\n message?.quoted_message?.attachments?.length\n \"\n >\n <ng-template\n #defaultAttachments\n let-messageId=\"messageId\"\n let-attachments=\"attachments\"\n let-parentMessageId=\"parentMessageId\"\n let-imageModalStateChangeHandler=\"imageModalStateChangeHandler\"\n >\n <stream-attachment-list\n [messageId]=\"messageId\"\n [attachments]=\"attachments\"\n [parentMessageId]=\"parentMessageId\"\n (imageModalStateChange)=\"imageModalStateChangeHandler($event)\"\n ></stream-attachment-list>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.attachmentListTemplate$ | async) ||\n defaultAttachments;\n context: getQuotedMessageAttachmentListContext()\n \"\n ></ng-container>\n </ng-container>\n <ng-container *ngIf=\"message?.quoted_message\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.messageTextTemplate$ | async) ||\n defaultText;\n context: getQuotedMessageTextContext()\n \"\n ></ng-container>\n <ng-template\n #defaultText\n let-message=\"message\"\n let-isQuoted=\"isQuoted\"\n let-shouldTranslate=\"shouldTranslate\"\n >\n <stream-message-text\n [message]=\"message\"\n [isQuoted]=\"isQuoted\"\n [shouldTranslate]=\"shouldTranslate\"\n data-testid=\"quoted-message-text\"\n ></stream-message-text>\n </ng-template>\n </ng-container>\n </div>\n </div>\n </ng-template>\n\n <ng-template #messageDateAndSender>\n <ng-container>\n <div\n *ngIf=\"shouldDisplayTranslationNotice\"\n class=\"str-chat__translation-notice\"\n data-testid=\"translation-notice\"\n >\n <button\n *ngIf=\"displayedMessageTextContent === 'translation'\"\n data-testid=\"see-original\"\n translate\n (click)=\"displayOriginalMessage()\"\n (keyup.enter)=\"displayOriginalMessage()\"\n >\n streamChat.See original (automatically translated)\n </button>\n <button\n *ngIf=\"displayedMessageTextContent === 'original'\"\n data-testid=\"see-translation\"\n translate\n (click)=\"displayTranslatedMessage()\"\n (keyup.enter)=\"displayTranslatedMessage()\"\n >\n streamChat.See translation\n </button>\n </div>\n <ng-container\n *ngIf=\"customTemplatesService.customMessageMetadataTemplate$ | async\"\n >\n <div class=\"str-chat__custom-message-metadata\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.customMessageMetadataTemplate$ | async)!;\n context: getMessageMetadataContext()\n \"\n ></ng-container>\n </div>\n </ng-container>\n <div\n class=\"str-chat__message-data str-chat__message-simple-data str-chat__message-metadata\"\n >\n <ng-container *ngTemplateOutlet=\"messageStatus\"></ng-container>\n\n <span\n *ngIf=\"!isSentByCurrentUser\"\n data-testid=\"sender\"\n class=\"str-chat__message-simple-name str-chat__message-sender-name\"\n >\n {{ message?.user?.name ? message?.user?.name : message?.user?.id }}\n </span>\n <span\n data-testid=\"date\"\n class=\"str-chat__message-simple-timestamp str-chat__message-simple-time\"\n >\n {{ parsedDate }}\n </span>\n <ng-container *ngIf=\"message?.message_text_updated_at\">\n <span\n data-testid=\"edited-flag\"\n class=\"str-chat__mesage-simple-edited\"\n translate\n >streamChat.Edited</span\n >\n <div\n data-testid=\"edited-timestamp\"\n class=\"str-chat__message-edited-timestamp\"\n [ngClass]=\"{\n 'str-chat__message-edited-timestamp--open': isEditedFlagOpened,\n 'str-chat__message-edited-timestamp--collapsed':\n !isEditedFlagOpened\n }\"\n >\n <span translate>streamChat.Edited</span>\n <time\n dateTime=\"{{ message?.message_text_updated_at }}\"\n title=\"{{ message?.message_text_updated_at }}\"\n >\n {{ pasedEditedDate }}\n </time>\n </div>\n </ng-container>\n </div>\n </ng-container>\n </ng-template>\n\n <ng-template #messageStatus>\n <ng-container\n *ngIf=\"\n isSentByCurrentUser &&\n ((isLastSentMessage && message?.status === 'received') ||\n message?.status === 'sending')\n \"\n >\n <ng-container *ngIf=\"message?.status === 'sending'; else sentStatus\">\n <ng-container *ngTemplateOutlet=\"sendingStatus\"></ng-container>\n </ng-container>\n <ng-template #sentStatus>\n <ng-container\n *ngIf=\"\n mode === 'main' &&\n isMessageDeliveredAndRead &&\n canDisplayReadStatus;\n else deliveredStatus\n \"\n >\n <ng-container *ngTemplateOutlet=\"readStatus\"></ng-container>\n </ng-container>\n </ng-template>\n <ng-template #deliveredStatus>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.deliveredStatusTemplate$ | async) ||\n defaultDeliveredStatus;\n context: getDeliveredStatusContext()\n \"\n ></ng-container>\n </ng-template>\n <ng-template #defaultDeliveredStatus>\n <span\n *ngIf=\"mode === 'main'\"\n class=\"str-chat__message-simple-status str-chat__message-simple-status-angular str-chat__message-status\"\n data-testid=\"delivered-indicator\"\n tabindex=\"0\"\n [floatUiLoose]=\"floatingContent\"\n loosePlacement=\"top\"\n [looseTrigger]=\"hasTouchSupport ? 'click' : 'hover'\"\n [disableAnimation]=\"true\"\n [hideOnClickOutside]=\"true\"\n [positionFixed]=\"true\"\n [preventOverflow]=\"true\"\n >\n <float-ui-content #floatingContent>\n <div class=\"str-chat__tooltip str-chat__tooltip-angular\">\n {{ \"streamChat.Delivered\" | translate }}\n </div>\n </float-ui-content>\n <stream-icon-placeholder\n data-testid=\"delivered-icon\"\n icon=\"delivered\"\n ></stream-icon-placeholder>\n </span>\n </ng-template>\n <ng-template #sendingStatus>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.sendingStatusTemplate$ | async) ||\n defaultSendingStatus;\n context: getSendingStatusContext()\n \"\n ></ng-container>\n </ng-template>\n <ng-template #defaultSendingStatus>\n <span\n class=\"str-chat__message-simple-status str-chat__message-simple-status-angular str-chat__message-status\"\n data-testid=\"sending-indicator\"\n tabindex=\"0\"\n [floatUiLoose]=\"floatingContent\"\n loosePlacement=\"top\"\n [looseTrigger]=\"hasTouchSupport ? 'click' : 'hover'\"\n [disableAnimation]=\"true\"\n [hideOnClickOutside]=\"true\"\n [positionFixed]=\"true\"\n [preventOverflow]=\"true\"\n >\n <float-ui-content #floatingContent>\n <div class=\"str-chat__tooltip str-chat__tooltip-angular\">\n {{ \"streamChat.Sending...\" | translate }}\n </div>\n </float-ui-content>\n <stream-loading-indicator-placeholder\n data-testid=\"loading-indicator\"\n ></stream-loading-indicator-placeholder>\n </span>\n </ng-template>\n <ng-template #readStatus>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.readStatusTemplate$ | async) ||\n defaultReadStatus;\n context: getReadStatusContext()\n \"\n ></ng-container>\n </ng-template>\n <ng-template #defaultReadStatus let-readByText=\"readByText\">\n <span\n class=\"str-chat__message-simple-status str-chat__message-simple-status-angular str-chat__message-status\"\n data-testid=\"read-indicator\"\n tabindex=\"0\"\n [floatUiLoose]=\"floatingContent\"\n loosePlacement=\"top\"\n [looseTrigger]=\"hasTouchSupport ? 'click' : 'hover'\"\n [disableAnimation]=\"true\"\n [hideOnClickOutside]=\"true\"\n [positionFixed]=\"true\"\n [preventOverflow]=\"true\"\n >\n <float-ui-content #floatingContent>\n <div\n class=\"str-chat__tooltip str-chat__tooltip-angular\"\n data-testid=\"read-by-tooltip\"\n >\n {{ readByText }}\n </div>\n </float-ui-content>\n <stream-icon-placeholder icon=\"read\"></stream-icon-placeholder>\n </span>\n </ng-template>\n </ng-container>\n </ng-template>\n\n <ng-template #replyCountButton>\n <div\n class=\"str-chat__message-simple-reply-button str-chat__message-replies-count-button-wrapper\"\n >\n <ng-container *ngIf=\"shouldDisplayThreadLink\">\n <ng-template\n *ngTemplateOutlet=\"\n (customTemplatesService.threadLinkButton$ | async) || defaultButton;\n context: { message: message }\n \"\n ></ng-template>\n </ng-container>\n <ng-template #defaultButton let-message=\"message\">\n <button\n class=\"str-chat__message-replies-count-button\"\n data-testid=\"reply-count-button\"\n (click)=\"setAsActiveParentMessage()\"\n >\n {{message?.reply_count === 1 ? ('streamChat.1 reply' | translate) : ('streamChat.{{ replyCount }}\n replies' | translate:replyCountParam)}}\n </button>\n </ng-template>\n </div>\n </ng-template>\n\n <ng-template #attachmentsTemplate>\n <ng-template\n #defaultAttachments\n let-messageId=\"messageId\"\n let-attachments=\"attachments\"\n let-parentMessageId=\"parentMessageId\"\n let-imageModalStateChangeHandler=\"imageModalStateChangeHandler\"\n >\n <stream-attachment-list\n [messageId]=\"messageId\"\n [attachments]=\"attachments\"\n [parentMessageId]=\"parentMessageId\"\n (imageModalStateChange)=\"imageModalStateChangeHandler($event)\"\n ></stream-attachment-list>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.attachmentListTemplate$ | async) ||\n defaultAttachments;\n context: getAttachmentListContext()\n \"\n ></ng-container>\n </ng-template>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i8.NgxFloatUiContentComponent, selector: "float-ui-content", exportAs: ["ngxFloatUiContent"] }, { kind: "directive", type: i8.NgxFloatUiLooseDirective, selector: "[floatUiLoose]", inputs: ["floatUiLoose", "loosePlacement", "looseTrigger"], exportAs: ["floatUiLoose"] }, { kind: "component", type: AvatarPlaceholderComponent, selector: "stream-avatar-placeholder", inputs: ["name", "imageUrl", "location", "channel", "user", "type", "initialsType", "showOnlineIndicator"] }, { kind: "directive", type: i6.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "component", type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon"] }, { kind: "component", type: LoadingIndicatorPlaceholderComponent, selector: "stream-loading-indicator-placeholder" }, { kind: "component", type: MessageActionsBoxComponent, selector: "stream-message-actions-box", inputs: ["isMine", "message", "messageTextHtmlElement", "enabledActions"] }, { kind: "component", type: AttachmentListComponent, selector: "stream-attachment-list", inputs: ["messageId", "parentMessageId", "attachments"], outputs: ["imageModalStateChange"] }, { kind: "component", type: MessageReactionsComponent, selector: "stream-message-reactions", inputs: ["messageId", "messageReactionGroups", "messageReactionCounts", "latestReactions", "ownReactions"] }, { kind: "component", type: MessageTextComponent, selector: "stream-message-text", inputs: ["message", "isQuoted", "shouldTranslate"] }, { kind: "component", type: MessageBlockedComponent, selector: "stream-message-blocked", inputs: ["message", "isMyMessage"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
5977
+ MessageComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: MessageComponent, selector: "stream-message", inputs: { message: "message", enabledMessageActions: "enabledMessageActions", isLastSentMessage: "isLastSentMessage", mode: "mode", isHighlighted: "isHighlighted", scroll$: "scroll$" }, viewQueries: [{ propertyName: "messageMenuTrigger", first: true, predicate: ["messageMenuTrigger"], descendants: true }, { propertyName: "messageMenuFloat", first: true, predicate: ["messageMenuFloat"], descendants: true }, { propertyName: "messageTextElement", first: true, predicate: ["messageTextElement"], descendants: true }, { propertyName: "messageBubble", first: true, predicate: ["messageBubble"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<ng-container\n *ngIf=\"\n message?.type === 'error' &&\n (message?.moderation_details?.action ===\n 'MESSAGE_RESPONSE_ACTION_REMOVE' ||\n message?.moderation?.action === 'remove');\n else notBlockedMessage\n \"\n>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.messageBlockedTemplate$ | async) ||\n defaultBlockedMessage;\n context: getMessageBlockedContext()\n \"\n ></ng-container>\n <ng-template #defaultBlockedMessage>\n <stream-message-blocked\n [message]=\"message\"\n [isMyMessage]=\"isSentByCurrentUser\"\n ></stream-message-blocked>\n </ng-template>\n</ng-container>\n<ng-template #notBlockedMessage>\n <div\n data-testid=\"message-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 }} str-chat__message-menu-{{ areMessageOptionsOpen ? 'opened' : 'closed' }}\"\n [class.str-chat__message--me]=\"isSentByCurrentUser\"\n [class.str-chat__message--other]=\"!isSentByCurrentUser\"\n [class.str-chat__message-simple--me]=\"isSentByCurrentUser\"\n [class.str-chat__message--has-attachment]=\"hasAttachment\"\n [class.str-chat__message--with-reactions]=\"hasReactions\"\n [class.str-chat__message--highlighted]=\"isHighlighted\"\n [class.str-chat__message-with-thread-link]=\"shouldDisplayThreadLink\"\n [class.str-chat__message-send-can-be-retried]=\"\n (message?.status === 'failed' && message?.errorStatusCode !== 403) ||\n (message?.type === 'error' && message?.moderation_details)\n \"\n [class.str-chat__message-with-touch-support]=\"hasTouchSupport\"\n [class.str-chat__message-without-touch-support]=\"!hasTouchSupport\"\n >\n <ng-container *ngIf=\"!message?.deleted_at; else deletedMessage\">\n <ng-container *ngIf=\"message?.type !== 'system'; else systemMessage\">\n <stream-avatar-placeholder\n data-testid=\"avatar\"\n class=\"str-chat-angular__avatar-host str-chat__message-sender-avatar\"\n type=\"user\"\n location=\"message-sender\"\n [imageUrl]=\"message?.user?.image\"\n [name]=\"message?.user?.name || message?.user?.id\"\n [user]=\"message?.user || undefined\"\n ></stream-avatar-placeholder>\n <div class=\"str-chat__message-inner\">\n <div\n *ngIf=\"!hasTouchSupport && areOptionsVisible\"\n class=\"str-chat__message-simple__actions str-chat__message-options\"\n data-testid=\"message-options\"\n [class.str-chat__message-actions-open]=\"areMessageOptionsOpen\"\n >\n <div\n #messageActionsToggle\n data-testid=\"message-actions-container\"\n class=\"str-chat__message-actions-container str-chat__message-simple__actions__action str-chat__message-simple__actions__action--options\"\n [floatUiLoose]=\"messageMenuFloat\"\n [looseTrigger]=\"\n messageActionsService.customActionClickHandler\n ? 'none'\n : 'click'\n \"\n [hideOnScroll]=\"false\"\n [hideOnClickOutside]=\"true\"\n [hideOnMouseLeave]=\"false\"\n [disableAnimation]=\"false\"\n [preventOverflow]=\"true\"\n [positionFixed]=\"true\"\n (onSHown)=\"areMessageOptionsOpen = true\"\n (onHidden)=\"areMessageOptionsOpen = false\"\n >\n <div\n *ngIf=\"visibleMessageActionsCount > 0\"\n class=\"str-chat__message-actions-box-button\"\n data-testid=\"message-options-button\"\n (click)=\"messageOptionsButtonClicked()\"\n (keyup.enter)=\"messageOptionsButtonClicked()\"\n >\n <stream-icon-placeholder\n icon=\"action\"\n class=\"str-chat__message-action-icon\"\n ></stream-icon-placeholder>\n </div>\n </div>\n </div>\n <ng-container\n *ngIf=\"\n customTemplatesService.customMessageMetadataInsideBubbleTemplate$\n | async\n \"\n >\n <ng-template\n *ngTemplateOutlet=\"\n (customTemplatesService.customMessageMetadataInsideBubbleTemplate$\n | async)!;\n context: { message: message }\n \"\n ></ng-template>\n </ng-container>\n <div class=\"str-chat__message-reactions-host\">\n <ng-template\n #defaultMessageReactions\n let-messageReactionCounts=\"messageReactionCounts\"\n let-latestReactions=\"latestReactions\"\n let-messageId=\"messageId\"\n let-ownReactions=\"ownReactions\"\n let-messageReactionGroups=\"messageReactionGroups\"\n >\n <stream-message-reactions\n [messageReactionCounts]=\"messageReactionCounts\"\n [latestReactions]=\"latestReactions\"\n [messageId]=\"messageId\"\n [ownReactions]=\"ownReactions\"\n [messageReactionGroups]=\"messageReactionGroups\"\n ></stream-message-reactions>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.messageReactionsTemplate$ | async) ||\n defaultMessageReactions;\n context: getMessageReactionsContext()\n \"\n ></ng-container>\n </div>\n <float-ui-content #messageMenuFloat>\n <ng-template\n #defaultMessageActionsBox\n let-isMine=\"isMine\"\n let-messageInput=\"message\"\n let-enabledActions=\"enabledActions\"\n let-messageTextHtmlElement=\"messageTextHtmlElement\"\n >\n <stream-message-actions-box\n [isMine]=\"isMine\"\n [message]=\"messageInput\"\n [enabledActions]=\"enabledActions\"\n [messageTextHtmlElement]=\"messageTextHtmlElement\"\n ></stream-message-actions-box>\n </ng-template>\n <ng-container>\n <div\n (click)=\"messageActionsBoxClicked(messageMenuFloat)\"\n (keyup.enter)=\"messageActionsBoxClicked(messageMenuFloat)\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.messageActionsBoxTemplate$\n | async) || defaultMessageActionsBox;\n context: getMessageActionsBoxContext()\n \"\n >\n </ng-container>\n </div>\n </ng-container>\n </float-ui-content>\n <div\n class=\"str-chat__message-bubble str-chat-angular__message-bubble\"\n [class.str-chat-angular__message-bubble--attachment-modal-open]=\"\n nestedModalState === 'opened'\n \"\n data-testid=\"message-bubble\"\n [floatUiLoose]=\"messageMenuFloat\"\n #messageMenuTrigger=\"floatUiLoose\"\n #messageBubble\n looseTrigger=\"none\"\n [hideOnScroll]=\"false\"\n [hideOnClickOutside]=\"true\"\n [hideOnMouseLeave]=\"false\"\n [disableAnimation]=\"true\"\n [preventOverflow]=\"true\"\n (onShown)=\"areMessageOptionsOpen = true\"\n (onHidden)=\"areMessageOptionsOpen = false\"\n [positionFixed]=\"true\"\n >\n <ng-container *ngIf=\"hasAttachment && !message?.quoted_message\">\n <div class=\"str-chat__attachments-container\">\n <ng-container\n *ngTemplateOutlet=\"attachmentsTemplate\"\n ></ng-container>\n </div>\n </ng-container>\n <ng-container\n *ngIf=\"\n message?.poll_id &&\n (customTemplatesService.pollTemplate$ | async)\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.pollTemplate$ | async)!;\n context: {\n pollId: message?.poll_id,\n messageId: message?.id,\n isQuote: false\n }\n \"\n ></ng-container>\n </ng-container>\n <div\n *ngIf=\"\n message?.text || (message?.quoted_message && hasAttachment)\n \"\n class=\"str-chat__message-text\"\n tabindex=\"0\"\n [class.str-chat__message-text--pointer-cursor]=\"\n (message?.status === 'failed' &&\n message?.errorStatusCode !== 403) ||\n (this.message?.type === 'error' &&\n this.message?.moderation_details) ||\n message?.message_text_updated_at\n \"\n (click)=\"messageClicked()\"\n (keyup.enter)=\"messageClicked()\"\n >\n <div\n data-testid=\"inner-message\"\n class=\"str-chat__message-text-inner str-chat__message-simple-text-inner\"\n [class.str-chat__message-light-text-inner--has-attachment]=\"\n hasAttachment\n \"\n >\n <ng-container *ngTemplateOutlet=\"quotedMessage\"></ng-container>\n <ng-container *ngIf=\"hasAttachment && message?.quoted_message\">\n <ng-container\n *ngTemplateOutlet=\"attachmentsTemplate\"\n ></ng-container>\n </ng-container>\n <div\n *ngIf=\"message?.type === 'error'\"\n data-testid=\"client-error-message\"\n class=\"str-chat__simple-message--error-message str-chat__message--error-message\"\n >\n <ng-container *ngIf=\"!message?.moderation_details\">{{\n \"streamChat.Error \u00B7 Unsent\" | translate\n }}</ng-container>\n </div>\n <div\n *ngIf=\"message?.status === 'failed'\"\n data-testid=\"error-message\"\n class=\"str-chat__simple-message--error-message str-chat__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 <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.messageTextTemplate$ | async) ||\n defaultText;\n context: getMessageTextContext()\n \"\n ></ng-container>\n <ng-template\n #defaultText\n let-message=\"message\"\n let-isQuoted=\"isQuoted\"\n let-shouldTranslate=\"shouldTranslate\"\n >\n <stream-message-text\n [message]=\"message\"\n [isQuoted]=\"isQuoted\"\n [shouldTranslate]=\"shouldTranslate\"\n data-testid=\"quoted-message-text\"\n ></stream-message-text>\n </ng-template>\n </div>\n </div>\n <stream-icon-placeholder\n class=\"str-chat__message-error-icon\"\n icon=\"error\"\n ></stream-icon-placeholder>\n </div>\n </div>\n <ng-container\n *ngTemplateOutlet=\"replyCountButton; context: { message: message }\"\n ></ng-container>\n\n <ng-container *ngTemplateOutlet=\"messageDateAndSender\"></ng-container>\n </ng-container>\n </ng-container>\n </div>\n\n <ng-template #deletedMessage>\n <div data-testid=\"message-deleted-component\">\n <div class=\"str-chat__message--deleted-inner\" translate>\n streamChat.This message was deleted...\n </div>\n </div>\n </ng-template>\n\n <ng-template #systemMessage>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.systemMessageTemplate$ | async) ||\n defaultSystemMessage;\n context: getMessageContext()\n \"\n ></ng-container>\n <ng-template #defaultSystemMessage let-messageInput=\"message\">\n <div data-testid=\"system-message\" class=\"str-chat__message--system\">\n <div class=\"str-chat__message--system__text\">\n <div class=\"str-chat__message--system__line\"></div>\n <p>{{ messageInput?.text }}</p>\n <div class=\"str-chat__message--system__line\"></div>\n </div>\n <div class=\"str-chat__message--system__date\">\n {{ parsedDate }}\n </div>\n </div>\n </ng-template>\n </ng-template>\n\n <ng-template #quotedMessage>\n <div\n *ngIf=\"message?.quoted_message\"\n class=\"quoted-message str-chat__quoted-message-preview\"\n data-testid=\"quoted-message-container\"\n [class.mine]=\"isSentByCurrentUser\"\n (click)=\"\n jumpToMessage(\n (message?.quoted_message)!.id,\n message?.quoted_message?.parent_id\n )\n \"\n (keyup.enter)=\"\n jumpToMessage(\n (message?.quoted_message)!.id,\n message?.quoted_message?.parent_id\n )\n \"\n >\n <stream-avatar-placeholder\n data-testid=\"qouted-message-avatar\"\n class=\"str-chat-angular__avatar-host str-chat__message-sender-avatar\"\n type=\"user\"\n location=\"quoted-message-sender\"\n [imageUrl]=\"message?.quoted_message?.user?.image\"\n [name]=\"\n message?.quoted_message?.user?.name ||\n message?.quoted_message?.user?.id\n \"\n [user]=\"message?.quoted_message?.user || undefined\"\n ></stream-avatar-placeholder>\n <div class=\"quoted-message-inner str-chat__quoted-message-bubble\">\n <ng-container\n *ngIf=\"\n message?.quoted_message?.attachments &&\n message?.quoted_message?.attachments?.length\n \"\n >\n <ng-template\n #defaultAttachments\n let-messageId=\"messageId\"\n let-attachments=\"attachments\"\n let-parentMessageId=\"parentMessageId\"\n let-imageModalStateChangeHandler=\"imageModalStateChangeHandler\"\n >\n <stream-attachment-list\n [messageId]=\"messageId\"\n [attachments]=\"attachments\"\n [parentMessageId]=\"parentMessageId\"\n (imageModalStateChange)=\"imageModalStateChangeHandler($event)\"\n ></stream-attachment-list>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.attachmentListTemplate$ | async) ||\n defaultAttachments;\n context: getQuotedMessageAttachmentListContext()\n \"\n ></ng-container>\n </ng-container>\n <ng-container\n *ngIf=\"\n message?.quoted_message?.poll_id &&\n (customTemplatesService.pollTemplate$ | async)\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.pollTemplate$ | async)!;\n context: {\n pollId: message?.quoted_message?.poll_id,\n messageId: message?.quoted_message?.id,\n isQuote: true\n }\n \"\n ></ng-container>\n </ng-container>\n <ng-container *ngIf=\"message?.quoted_message\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.messageTextTemplate$ | async) ||\n defaultText;\n context: getQuotedMessageTextContext()\n \"\n ></ng-container>\n <ng-template\n #defaultText\n let-message=\"message\"\n let-isQuoted=\"isQuoted\"\n let-shouldTranslate=\"shouldTranslate\"\n >\n <stream-message-text\n [message]=\"message\"\n [isQuoted]=\"isQuoted\"\n [shouldTranslate]=\"shouldTranslate\"\n data-testid=\"quoted-message-text\"\n ></stream-message-text>\n </ng-template>\n </ng-container>\n </div>\n </div>\n </ng-template>\n\n <ng-template #messageDateAndSender>\n <ng-container>\n <div\n *ngIf=\"shouldDisplayTranslationNotice\"\n class=\"str-chat__translation-notice\"\n data-testid=\"translation-notice\"\n >\n <button\n *ngIf=\"displayedMessageTextContent === 'translation'\"\n data-testid=\"see-original\"\n translate\n (click)=\"displayOriginalMessage()\"\n (keyup.enter)=\"displayOriginalMessage()\"\n >\n streamChat.See original (automatically translated)\n </button>\n <button\n *ngIf=\"displayedMessageTextContent === 'original'\"\n data-testid=\"see-translation\"\n translate\n (click)=\"displayTranslatedMessage()\"\n (keyup.enter)=\"displayTranslatedMessage()\"\n >\n streamChat.See translation\n </button>\n </div>\n <ng-container\n *ngIf=\"customTemplatesService.customMessageMetadataTemplate$ | async\"\n >\n <div class=\"str-chat__custom-message-metadata\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.customMessageMetadataTemplate$ | async)!;\n context: getMessageMetadataContext()\n \"\n ></ng-container>\n </div>\n </ng-container>\n <div\n class=\"str-chat__message-data str-chat__message-simple-data str-chat__message-metadata\"\n >\n <ng-container *ngTemplateOutlet=\"messageStatus\"></ng-container>\n\n <span\n *ngIf=\"!isSentByCurrentUser\"\n data-testid=\"sender\"\n class=\"str-chat__message-simple-name str-chat__message-sender-name\"\n >\n {{ message?.user?.name ? message?.user?.name : message?.user?.id }}\n </span>\n <span\n data-testid=\"date\"\n class=\"str-chat__message-simple-timestamp str-chat__message-simple-time\"\n >\n {{ parsedDate }}\n </span>\n <ng-container *ngIf=\"message?.message_text_updated_at\">\n <span\n data-testid=\"edited-flag\"\n class=\"str-chat__mesage-simple-edited\"\n translate\n >streamChat.Edited</span\n >\n <div\n data-testid=\"edited-timestamp\"\n class=\"str-chat__message-edited-timestamp\"\n [ngClass]=\"{\n 'str-chat__message-edited-timestamp--open': isEditedFlagOpened,\n 'str-chat__message-edited-timestamp--collapsed':\n !isEditedFlagOpened\n }\"\n >\n <span translate>streamChat.Edited</span>\n <time\n dateTime=\"{{ message?.message_text_updated_at }}\"\n title=\"{{ message?.message_text_updated_at }}\"\n >\n {{ pasedEditedDate }}\n </time>\n </div>\n </ng-container>\n </div>\n </ng-container>\n </ng-template>\n\n <ng-template #messageStatus>\n <ng-container\n *ngIf=\"\n isSentByCurrentUser &&\n ((isLastSentMessage && message?.status === 'received') ||\n message?.status === 'sending')\n \"\n >\n <ng-container *ngIf=\"message?.status === 'sending'; else sentStatus\">\n <ng-container *ngTemplateOutlet=\"sendingStatus\"></ng-container>\n </ng-container>\n <ng-template #sentStatus>\n <ng-container\n *ngIf=\"\n mode === 'main' &&\n isMessageDeliveredAndRead &&\n canDisplayReadStatus;\n else deliveredStatus\n \"\n >\n <ng-container *ngTemplateOutlet=\"readStatus\"></ng-container>\n </ng-container>\n </ng-template>\n <ng-template #deliveredStatus>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.deliveredStatusTemplate$ | async) ||\n defaultDeliveredStatus;\n context: getDeliveredStatusContext()\n \"\n ></ng-container>\n </ng-template>\n <ng-template #defaultDeliveredStatus>\n <span\n *ngIf=\"mode === 'main'\"\n class=\"str-chat__message-simple-status str-chat__message-simple-status-angular str-chat__message-status\"\n data-testid=\"delivered-indicator\"\n tabindex=\"0\"\n [floatUiLoose]=\"floatingContent\"\n loosePlacement=\"top\"\n [looseTrigger]=\"hasTouchSupport ? 'click' : 'hover'\"\n [disableAnimation]=\"true\"\n [hideOnClickOutside]=\"true\"\n [positionFixed]=\"true\"\n [preventOverflow]=\"true\"\n >\n <float-ui-content #floatingContent>\n <div class=\"str-chat__tooltip str-chat__tooltip-angular\">\n {{ \"streamChat.Delivered\" | translate }}\n </div>\n </float-ui-content>\n <stream-icon-placeholder\n data-testid=\"delivered-icon\"\n icon=\"delivered\"\n ></stream-icon-placeholder>\n </span>\n </ng-template>\n <ng-template #sendingStatus>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.sendingStatusTemplate$ | async) ||\n defaultSendingStatus;\n context: getSendingStatusContext()\n \"\n ></ng-container>\n </ng-template>\n <ng-template #defaultSendingStatus>\n <span\n class=\"str-chat__message-simple-status str-chat__message-simple-status-angular str-chat__message-status\"\n data-testid=\"sending-indicator\"\n tabindex=\"0\"\n [floatUiLoose]=\"floatingContent\"\n loosePlacement=\"top\"\n [looseTrigger]=\"hasTouchSupport ? 'click' : 'hover'\"\n [disableAnimation]=\"true\"\n [hideOnClickOutside]=\"true\"\n [positionFixed]=\"true\"\n [preventOverflow]=\"true\"\n >\n <float-ui-content #floatingContent>\n <div class=\"str-chat__tooltip str-chat__tooltip-angular\">\n {{ \"streamChat.Sending...\" | translate }}\n </div>\n </float-ui-content>\n <stream-loading-indicator-placeholder\n data-testid=\"loading-indicator\"\n ></stream-loading-indicator-placeholder>\n </span>\n </ng-template>\n <ng-template #readStatus>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.readStatusTemplate$ | async) ||\n defaultReadStatus;\n context: getReadStatusContext()\n \"\n ></ng-container>\n </ng-template>\n <ng-template #defaultReadStatus let-readByText=\"readByText\">\n <span\n class=\"str-chat__message-simple-status str-chat__message-simple-status-angular str-chat__message-status\"\n data-testid=\"read-indicator\"\n tabindex=\"0\"\n [floatUiLoose]=\"floatingContent\"\n loosePlacement=\"top\"\n [looseTrigger]=\"hasTouchSupport ? 'click' : 'hover'\"\n [disableAnimation]=\"true\"\n [hideOnClickOutside]=\"true\"\n [positionFixed]=\"true\"\n [preventOverflow]=\"true\"\n >\n <float-ui-content #floatingContent>\n <div\n class=\"str-chat__tooltip str-chat__tooltip-angular\"\n data-testid=\"read-by-tooltip\"\n >\n {{ readByText }}\n </div>\n </float-ui-content>\n <stream-icon-placeholder icon=\"read\"></stream-icon-placeholder>\n </span>\n </ng-template>\n </ng-container>\n </ng-template>\n\n <ng-template #replyCountButton>\n <div\n class=\"str-chat__message-simple-reply-button str-chat__message-replies-count-button-wrapper\"\n >\n <ng-container *ngIf=\"shouldDisplayThreadLink\">\n <ng-template\n *ngTemplateOutlet=\"\n (customTemplatesService.threadLinkButton$ | async) || defaultButton;\n context: { message: message }\n \"\n ></ng-template>\n </ng-container>\n <ng-template #defaultButton let-message=\"message\">\n <button\n class=\"str-chat__message-replies-count-button\"\n data-testid=\"reply-count-button\"\n (click)=\"setAsActiveParentMessage()\"\n >\n {{message?.reply_count === 1 ? ('streamChat.1 reply' | translate) : ('streamChat.{{ replyCount }}\n replies' | translate:replyCountParam)}}\n </button>\n </ng-template>\n </div>\n </ng-template>\n\n <ng-template #attachmentsTemplate>\n <ng-template\n #defaultAttachments\n let-messageId=\"messageId\"\n let-attachments=\"attachments\"\n let-parentMessageId=\"parentMessageId\"\n let-imageModalStateChangeHandler=\"imageModalStateChangeHandler\"\n >\n <stream-attachment-list\n [messageId]=\"messageId\"\n [attachments]=\"attachments\"\n [parentMessageId]=\"parentMessageId\"\n (imageModalStateChange)=\"imageModalStateChangeHandler($event)\"\n ></stream-attachment-list>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.attachmentListTemplate$ | async) ||\n defaultAttachments;\n context: getAttachmentListContext()\n \"\n ></ng-container>\n </ng-template>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i8.NgxFloatUiContentComponent, selector: "float-ui-content", exportAs: ["ngxFloatUiContent"] }, { kind: "directive", type: i8.NgxFloatUiLooseDirective, selector: "[floatUiLoose]", inputs: ["floatUiLoose", "loosePlacement", "looseTrigger"], exportAs: ["floatUiLoose"] }, { kind: "component", type: AvatarPlaceholderComponent, selector: "stream-avatar-placeholder", inputs: ["name", "imageUrl", "location", "channel", "user", "type", "initialsType", "showOnlineIndicator"] }, { kind: "directive", type: i6.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "component", type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon"] }, { kind: "component", type: LoadingIndicatorPlaceholderComponent, selector: "stream-loading-indicator-placeholder" }, { kind: "component", type: MessageActionsBoxComponent, selector: "stream-message-actions-box", inputs: ["isMine", "message", "messageTextHtmlElement", "enabledActions"] }, { kind: "component", type: AttachmentListComponent, selector: "stream-attachment-list", inputs: ["messageId", "parentMessageId", "attachments"], outputs: ["imageModalStateChange"] }, { kind: "component", type: MessageReactionsComponent, selector: "stream-message-reactions", inputs: ["messageId", "messageReactionGroups", "messageReactionCounts", "latestReactions", "ownReactions"] }, { kind: "component", type: MessageTextComponent, selector: "stream-message-text", inputs: ["message", "isQuoted", "shouldTranslate"] }, { kind: "component", type: MessageBlockedComponent, selector: "stream-message-blocked", inputs: ["message", "isMyMessage"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
5899
5978
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: MessageComponent, decorators: [{
5900
5979
  type: Component,
5901
- args: [{ selector: 'stream-message', changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container\n *ngIf=\"\n message?.type === 'error' &&\n (message?.moderation_details?.action ===\n 'MESSAGE_RESPONSE_ACTION_REMOVE' ||\n message?.moderation?.action === 'remove');\n else notBlockedMessage\n \"\n>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.messageBlockedTemplate$ | async) ||\n defaultBlockedMessage;\n context: getMessageBlockedContext()\n \"\n ></ng-container>\n <ng-template #defaultBlockedMessage>\n <stream-message-blocked\n [message]=\"message\"\n [isMyMessage]=\"isSentByCurrentUser\"\n ></stream-message-blocked>\n </ng-template>\n</ng-container>\n<ng-template #notBlockedMessage>\n <div\n data-testid=\"message-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 }} str-chat__message-menu-{{ areMessageOptionsOpen ? 'opened' : 'closed' }}\"\n [class.str-chat__message--me]=\"isSentByCurrentUser\"\n [class.str-chat__message--other]=\"!isSentByCurrentUser\"\n [class.str-chat__message-simple--me]=\"isSentByCurrentUser\"\n [class.str-chat__message--has-attachment]=\"hasAttachment\"\n [class.str-chat__message--with-reactions]=\"hasReactions\"\n [class.str-chat__message--highlighted]=\"isHighlighted\"\n [class.str-chat__message-with-thread-link]=\"shouldDisplayThreadLink\"\n [class.str-chat__message-send-can-be-retried]=\"\n (message?.status === 'failed' && message?.errorStatusCode !== 403) ||\n (message?.type === 'error' && message?.moderation_details)\n \"\n [class.str-chat__message-with-touch-support]=\"hasTouchSupport\"\n [class.str-chat__message-without-touch-support]=\"!hasTouchSupport\"\n >\n <ng-container *ngIf=\"!message?.deleted_at; else deletedMessage\">\n <ng-container *ngIf=\"message?.type !== 'system'; else systemMessage\">\n <stream-avatar-placeholder\n data-testid=\"avatar\"\n class=\"str-chat-angular__avatar-host str-chat__message-sender-avatar\"\n type=\"user\"\n location=\"message-sender\"\n [imageUrl]=\"message?.user?.image\"\n [name]=\"message?.user?.name || message?.user?.id\"\n [user]=\"message?.user || undefined\"\n ></stream-avatar-placeholder>\n <div class=\"str-chat__message-inner\">\n <div\n *ngIf=\"!hasTouchSupport && areOptionsVisible\"\n class=\"str-chat__message-simple__actions str-chat__message-options\"\n data-testid=\"message-options\"\n [class.str-chat__message-actions-open]=\"areMessageOptionsOpen\"\n >\n <div\n #messageActionsToggle\n data-testid=\"message-actions-container\"\n class=\"str-chat__message-actions-container str-chat__message-simple__actions__action str-chat__message-simple__actions__action--options\"\n [floatUiLoose]=\"messageMenuFloat\"\n [looseTrigger]=\"\n messageActionsService.customActionClickHandler\n ? 'none'\n : 'click'\n \"\n [hideOnScroll]=\"false\"\n [hideOnClickOutside]=\"true\"\n [hideOnMouseLeave]=\"false\"\n [disableAnimation]=\"false\"\n [preventOverflow]=\"true\"\n [positionFixed]=\"true\"\n (onSHown)=\"areMessageOptionsOpen = true\"\n (onHidden)=\"areMessageOptionsOpen = false\"\n >\n <div\n *ngIf=\"visibleMessageActionsCount > 0\"\n class=\"str-chat__message-actions-box-button\"\n data-testid=\"message-options-button\"\n (click)=\"messageOptionsButtonClicked()\"\n (keyup.enter)=\"messageOptionsButtonClicked()\"\n >\n <stream-icon-placeholder\n icon=\"action\"\n class=\"str-chat__message-action-icon\"\n ></stream-icon-placeholder>\n </div>\n </div>\n </div>\n <ng-container\n *ngIf=\"\n customTemplatesService.customMessageMetadataInsideBubbleTemplate$\n | async\n \"\n >\n <ng-template\n *ngTemplateOutlet=\"\n (customTemplatesService.customMessageMetadataInsideBubbleTemplate$\n | async)!;\n context: { message: message }\n \"\n ></ng-template>\n </ng-container>\n <div class=\"str-chat__message-reactions-host\">\n <ng-template\n #defaultMessageReactions\n let-messageReactionCounts=\"messageReactionCounts\"\n let-latestReactions=\"latestReactions\"\n let-messageId=\"messageId\"\n let-ownReactions=\"ownReactions\"\n let-messageReactionGroups=\"messageReactionGroups\"\n >\n <stream-message-reactions\n [messageReactionCounts]=\"messageReactionCounts\"\n [latestReactions]=\"latestReactions\"\n [messageId]=\"messageId\"\n [ownReactions]=\"ownReactions\"\n [messageReactionGroups]=\"messageReactionGroups\"\n ></stream-message-reactions>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.messageReactionsTemplate$ | async) ||\n defaultMessageReactions;\n context: getMessageReactionsContext()\n \"\n ></ng-container>\n </div>\n <float-ui-content #messageMenuFloat>\n <ng-template\n #defaultMessageActionsBox\n let-isMine=\"isMine\"\n let-messageInput=\"message\"\n let-enabledActions=\"enabledActions\"\n let-messageTextHtmlElement=\"messageTextHtmlElement\"\n >\n <stream-message-actions-box\n [isMine]=\"isMine\"\n [message]=\"messageInput\"\n [enabledActions]=\"enabledActions\"\n [messageTextHtmlElement]=\"messageTextHtmlElement\"\n ></stream-message-actions-box>\n </ng-template>\n <ng-container>\n <div\n (click)=\"messageActionsBoxClicked(messageMenuFloat)\"\n (keyup.enter)=\"messageActionsBoxClicked(messageMenuFloat)\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.messageActionsBoxTemplate$\n | async) || defaultMessageActionsBox;\n context: getMessageActionsBoxContext()\n \"\n >\n </ng-container>\n </div>\n </ng-container>\n </float-ui-content>\n <div\n class=\"str-chat__message-bubble str-chat-angular__message-bubble\"\n [class.str-chat-angular__message-bubble--attachment-modal-open]=\"\n imageAttachmentModalState === 'opened'\n \"\n data-testid=\"message-bubble\"\n [floatUiLoose]=\"messageMenuFloat\"\n #messageMenuTrigger=\"floatUiLoose\"\n #messageBubble\n looseTrigger=\"none\"\n [hideOnScroll]=\"false\"\n [hideOnClickOutside]=\"true\"\n [hideOnMouseLeave]=\"false\"\n [disableAnimation]=\"true\"\n [preventOverflow]=\"true\"\n (onShown)=\"areMessageOptionsOpen = true\"\n (onHidden)=\"areMessageOptionsOpen = false\"\n [positionFixed]=\"true\"\n >\n <ng-container *ngIf=\"hasAttachment && !message?.quoted_message\">\n <div class=\"str-chat__attachments-container\">\n <ng-container\n *ngTemplateOutlet=\"attachmentsTemplate\"\n ></ng-container>\n </div>\n </ng-container>\n <div\n *ngIf=\"\n message?.text || (message?.quoted_message && hasAttachment)\n \"\n class=\"str-chat__message-text\"\n tabindex=\"0\"\n [class.str-chat__message-text--pointer-cursor]=\"\n (message?.status === 'failed' &&\n message?.errorStatusCode !== 403) ||\n (this.message?.type === 'error' &&\n this.message?.moderation_details) ||\n message?.message_text_updated_at\n \"\n (click)=\"messageClicked()\"\n (keyup.enter)=\"messageClicked()\"\n >\n <div\n data-testid=\"inner-message\"\n class=\"str-chat__message-text-inner str-chat__message-simple-text-inner\"\n [class.str-chat__message-light-text-inner--has-attachment]=\"\n hasAttachment\n \"\n >\n <ng-container *ngTemplateOutlet=\"quotedMessage\"></ng-container>\n <ng-container *ngIf=\"hasAttachment && message?.quoted_message\">\n <ng-container\n *ngTemplateOutlet=\"attachmentsTemplate\"\n ></ng-container>\n </ng-container>\n <div\n *ngIf=\"message?.type === 'error'\"\n data-testid=\"client-error-message\"\n class=\"str-chat__simple-message--error-message str-chat__message--error-message\"\n >\n <ng-container *ngIf=\"!message?.moderation_details\">{{\n \"streamChat.Error \u00B7 Unsent\" | translate\n }}</ng-container>\n </div>\n <div\n *ngIf=\"message?.status === 'failed'\"\n data-testid=\"error-message\"\n class=\"str-chat__simple-message--error-message str-chat__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 <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.messageTextTemplate$ | async) ||\n defaultText;\n context: getMessageTextContext()\n \"\n ></ng-container>\n <ng-template\n #defaultText\n let-message=\"message\"\n let-isQuoted=\"isQuoted\"\n let-shouldTranslate=\"shouldTranslate\"\n >\n <stream-message-text\n [message]=\"message\"\n [isQuoted]=\"isQuoted\"\n [shouldTranslate]=\"shouldTranslate\"\n data-testid=\"quoted-message-text\"\n ></stream-message-text>\n </ng-template>\n </div>\n </div>\n <stream-icon-placeholder\n class=\"str-chat__message-error-icon\"\n icon=\"error\"\n ></stream-icon-placeholder>\n </div>\n </div>\n <ng-container\n *ngTemplateOutlet=\"replyCountButton; context: { message: message }\"\n ></ng-container>\n\n <ng-container *ngTemplateOutlet=\"messageDateAndSender\"></ng-container>\n </ng-container>\n </ng-container>\n </div>\n\n <ng-template #deletedMessage>\n <div data-testid=\"message-deleted-component\">\n <div class=\"str-chat__message--deleted-inner\" translate>\n streamChat.This message was deleted...\n </div>\n </div>\n </ng-template>\n\n <ng-template #systemMessage>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.systemMessageTemplate$ | async) ||\n defaultSystemMessage;\n context: getMessageContext()\n \"\n ></ng-container>\n <ng-template #defaultSystemMessage let-messageInput=\"message\">\n <div data-testid=\"system-message\" class=\"str-chat__message--system\">\n <div class=\"str-chat__message--system__text\">\n <div class=\"str-chat__message--system__line\"></div>\n <p>{{ messageInput?.text }}</p>\n <div class=\"str-chat__message--system__line\"></div>\n </div>\n <div class=\"str-chat__message--system__date\">\n {{ parsedDate }}\n </div>\n </div>\n </ng-template>\n </ng-template>\n\n <ng-template #quotedMessage>\n <div\n *ngIf=\"message?.quoted_message\"\n class=\"quoted-message str-chat__quoted-message-preview\"\n data-testid=\"quoted-message-container\"\n [class.mine]=\"isSentByCurrentUser\"\n (click)=\"\n jumpToMessage(\n (message?.quoted_message)!.id,\n message?.quoted_message?.parent_id\n )\n \"\n (keyup.enter)=\"\n jumpToMessage(\n (message?.quoted_message)!.id,\n message?.quoted_message?.parent_id\n )\n \"\n >\n <stream-avatar-placeholder\n data-testid=\"qouted-message-avatar\"\n class=\"str-chat-angular__avatar-host str-chat__message-sender-avatar\"\n type=\"user\"\n location=\"quoted-message-sender\"\n [imageUrl]=\"message?.quoted_message?.user?.image\"\n [name]=\"\n message?.quoted_message?.user?.name ||\n message?.quoted_message?.user?.id\n \"\n [user]=\"message?.quoted_message?.user || undefined\"\n ></stream-avatar-placeholder>\n <div class=\"quoted-message-inner str-chat__quoted-message-bubble\">\n <ng-container\n *ngIf=\"\n message?.quoted_message?.attachments &&\n message?.quoted_message?.attachments?.length\n \"\n >\n <ng-template\n #defaultAttachments\n let-messageId=\"messageId\"\n let-attachments=\"attachments\"\n let-parentMessageId=\"parentMessageId\"\n let-imageModalStateChangeHandler=\"imageModalStateChangeHandler\"\n >\n <stream-attachment-list\n [messageId]=\"messageId\"\n [attachments]=\"attachments\"\n [parentMessageId]=\"parentMessageId\"\n (imageModalStateChange)=\"imageModalStateChangeHandler($event)\"\n ></stream-attachment-list>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.attachmentListTemplate$ | async) ||\n defaultAttachments;\n context: getQuotedMessageAttachmentListContext()\n \"\n ></ng-container>\n </ng-container>\n <ng-container *ngIf=\"message?.quoted_message\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.messageTextTemplate$ | async) ||\n defaultText;\n context: getQuotedMessageTextContext()\n \"\n ></ng-container>\n <ng-template\n #defaultText\n let-message=\"message\"\n let-isQuoted=\"isQuoted\"\n let-shouldTranslate=\"shouldTranslate\"\n >\n <stream-message-text\n [message]=\"message\"\n [isQuoted]=\"isQuoted\"\n [shouldTranslate]=\"shouldTranslate\"\n data-testid=\"quoted-message-text\"\n ></stream-message-text>\n </ng-template>\n </ng-container>\n </div>\n </div>\n </ng-template>\n\n <ng-template #messageDateAndSender>\n <ng-container>\n <div\n *ngIf=\"shouldDisplayTranslationNotice\"\n class=\"str-chat__translation-notice\"\n data-testid=\"translation-notice\"\n >\n <button\n *ngIf=\"displayedMessageTextContent === 'translation'\"\n data-testid=\"see-original\"\n translate\n (click)=\"displayOriginalMessage()\"\n (keyup.enter)=\"displayOriginalMessage()\"\n >\n streamChat.See original (automatically translated)\n </button>\n <button\n *ngIf=\"displayedMessageTextContent === 'original'\"\n data-testid=\"see-translation\"\n translate\n (click)=\"displayTranslatedMessage()\"\n (keyup.enter)=\"displayTranslatedMessage()\"\n >\n streamChat.See translation\n </button>\n </div>\n <ng-container\n *ngIf=\"customTemplatesService.customMessageMetadataTemplate$ | async\"\n >\n <div class=\"str-chat__custom-message-metadata\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.customMessageMetadataTemplate$ | async)!;\n context: getMessageMetadataContext()\n \"\n ></ng-container>\n </div>\n </ng-container>\n <div\n class=\"str-chat__message-data str-chat__message-simple-data str-chat__message-metadata\"\n >\n <ng-container *ngTemplateOutlet=\"messageStatus\"></ng-container>\n\n <span\n *ngIf=\"!isSentByCurrentUser\"\n data-testid=\"sender\"\n class=\"str-chat__message-simple-name str-chat__message-sender-name\"\n >\n {{ message?.user?.name ? message?.user?.name : message?.user?.id }}\n </span>\n <span\n data-testid=\"date\"\n class=\"str-chat__message-simple-timestamp str-chat__message-simple-time\"\n >\n {{ parsedDate }}\n </span>\n <ng-container *ngIf=\"message?.message_text_updated_at\">\n <span\n data-testid=\"edited-flag\"\n class=\"str-chat__mesage-simple-edited\"\n translate\n >streamChat.Edited</span\n >\n <div\n data-testid=\"edited-timestamp\"\n class=\"str-chat__message-edited-timestamp\"\n [ngClass]=\"{\n 'str-chat__message-edited-timestamp--open': isEditedFlagOpened,\n 'str-chat__message-edited-timestamp--collapsed':\n !isEditedFlagOpened\n }\"\n >\n <span translate>streamChat.Edited</span>\n <time\n dateTime=\"{{ message?.message_text_updated_at }}\"\n title=\"{{ message?.message_text_updated_at }}\"\n >\n {{ pasedEditedDate }}\n </time>\n </div>\n </ng-container>\n </div>\n </ng-container>\n </ng-template>\n\n <ng-template #messageStatus>\n <ng-container\n *ngIf=\"\n isSentByCurrentUser &&\n ((isLastSentMessage && message?.status === 'received') ||\n message?.status === 'sending')\n \"\n >\n <ng-container *ngIf=\"message?.status === 'sending'; else sentStatus\">\n <ng-container *ngTemplateOutlet=\"sendingStatus\"></ng-container>\n </ng-container>\n <ng-template #sentStatus>\n <ng-container\n *ngIf=\"\n mode === 'main' &&\n isMessageDeliveredAndRead &&\n canDisplayReadStatus;\n else deliveredStatus\n \"\n >\n <ng-container *ngTemplateOutlet=\"readStatus\"></ng-container>\n </ng-container>\n </ng-template>\n <ng-template #deliveredStatus>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.deliveredStatusTemplate$ | async) ||\n defaultDeliveredStatus;\n context: getDeliveredStatusContext()\n \"\n ></ng-container>\n </ng-template>\n <ng-template #defaultDeliveredStatus>\n <span\n *ngIf=\"mode === 'main'\"\n class=\"str-chat__message-simple-status str-chat__message-simple-status-angular str-chat__message-status\"\n data-testid=\"delivered-indicator\"\n tabindex=\"0\"\n [floatUiLoose]=\"floatingContent\"\n loosePlacement=\"top\"\n [looseTrigger]=\"hasTouchSupport ? 'click' : 'hover'\"\n [disableAnimation]=\"true\"\n [hideOnClickOutside]=\"true\"\n [positionFixed]=\"true\"\n [preventOverflow]=\"true\"\n >\n <float-ui-content #floatingContent>\n <div class=\"str-chat__tooltip str-chat__tooltip-angular\">\n {{ \"streamChat.Delivered\" | translate }}\n </div>\n </float-ui-content>\n <stream-icon-placeholder\n data-testid=\"delivered-icon\"\n icon=\"delivered\"\n ></stream-icon-placeholder>\n </span>\n </ng-template>\n <ng-template #sendingStatus>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.sendingStatusTemplate$ | async) ||\n defaultSendingStatus;\n context: getSendingStatusContext()\n \"\n ></ng-container>\n </ng-template>\n <ng-template #defaultSendingStatus>\n <span\n class=\"str-chat__message-simple-status str-chat__message-simple-status-angular str-chat__message-status\"\n data-testid=\"sending-indicator\"\n tabindex=\"0\"\n [floatUiLoose]=\"floatingContent\"\n loosePlacement=\"top\"\n [looseTrigger]=\"hasTouchSupport ? 'click' : 'hover'\"\n [disableAnimation]=\"true\"\n [hideOnClickOutside]=\"true\"\n [positionFixed]=\"true\"\n [preventOverflow]=\"true\"\n >\n <float-ui-content #floatingContent>\n <div class=\"str-chat__tooltip str-chat__tooltip-angular\">\n {{ \"streamChat.Sending...\" | translate }}\n </div>\n </float-ui-content>\n <stream-loading-indicator-placeholder\n data-testid=\"loading-indicator\"\n ></stream-loading-indicator-placeholder>\n </span>\n </ng-template>\n <ng-template #readStatus>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.readStatusTemplate$ | async) ||\n defaultReadStatus;\n context: getReadStatusContext()\n \"\n ></ng-container>\n </ng-template>\n <ng-template #defaultReadStatus let-readByText=\"readByText\">\n <span\n class=\"str-chat__message-simple-status str-chat__message-simple-status-angular str-chat__message-status\"\n data-testid=\"read-indicator\"\n tabindex=\"0\"\n [floatUiLoose]=\"floatingContent\"\n loosePlacement=\"top\"\n [looseTrigger]=\"hasTouchSupport ? 'click' : 'hover'\"\n [disableAnimation]=\"true\"\n [hideOnClickOutside]=\"true\"\n [positionFixed]=\"true\"\n [preventOverflow]=\"true\"\n >\n <float-ui-content #floatingContent>\n <div\n class=\"str-chat__tooltip str-chat__tooltip-angular\"\n data-testid=\"read-by-tooltip\"\n >\n {{ readByText }}\n </div>\n </float-ui-content>\n <stream-icon-placeholder icon=\"read\"></stream-icon-placeholder>\n </span>\n </ng-template>\n </ng-container>\n </ng-template>\n\n <ng-template #replyCountButton>\n <div\n class=\"str-chat__message-simple-reply-button str-chat__message-replies-count-button-wrapper\"\n >\n <ng-container *ngIf=\"shouldDisplayThreadLink\">\n <ng-template\n *ngTemplateOutlet=\"\n (customTemplatesService.threadLinkButton$ | async) || defaultButton;\n context: { message: message }\n \"\n ></ng-template>\n </ng-container>\n <ng-template #defaultButton let-message=\"message\">\n <button\n class=\"str-chat__message-replies-count-button\"\n data-testid=\"reply-count-button\"\n (click)=\"setAsActiveParentMessage()\"\n >\n {{message?.reply_count === 1 ? ('streamChat.1 reply' | translate) : ('streamChat.{{ replyCount }}\n replies' | translate:replyCountParam)}}\n </button>\n </ng-template>\n </div>\n </ng-template>\n\n <ng-template #attachmentsTemplate>\n <ng-template\n #defaultAttachments\n let-messageId=\"messageId\"\n let-attachments=\"attachments\"\n let-parentMessageId=\"parentMessageId\"\n let-imageModalStateChangeHandler=\"imageModalStateChangeHandler\"\n >\n <stream-attachment-list\n [messageId]=\"messageId\"\n [attachments]=\"attachments\"\n [parentMessageId]=\"parentMessageId\"\n (imageModalStateChange)=\"imageModalStateChangeHandler($event)\"\n ></stream-attachment-list>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.attachmentListTemplate$ | async) ||\n defaultAttachments;\n context: getAttachmentListContext()\n \"\n ></ng-container>\n </ng-template>\n</ng-template>\n" }]
5980
+ args: [{ selector: 'stream-message', changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container\n *ngIf=\"\n message?.type === 'error' &&\n (message?.moderation_details?.action ===\n 'MESSAGE_RESPONSE_ACTION_REMOVE' ||\n message?.moderation?.action === 'remove');\n else notBlockedMessage\n \"\n>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.messageBlockedTemplate$ | async) ||\n defaultBlockedMessage;\n context: getMessageBlockedContext()\n \"\n ></ng-container>\n <ng-template #defaultBlockedMessage>\n <stream-message-blocked\n [message]=\"message\"\n [isMyMessage]=\"isSentByCurrentUser\"\n ></stream-message-blocked>\n </ng-template>\n</ng-container>\n<ng-template #notBlockedMessage>\n <div\n data-testid=\"message-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 }} str-chat__message-menu-{{ areMessageOptionsOpen ? 'opened' : 'closed' }}\"\n [class.str-chat__message--me]=\"isSentByCurrentUser\"\n [class.str-chat__message--other]=\"!isSentByCurrentUser\"\n [class.str-chat__message-simple--me]=\"isSentByCurrentUser\"\n [class.str-chat__message--has-attachment]=\"hasAttachment\"\n [class.str-chat__message--with-reactions]=\"hasReactions\"\n [class.str-chat__message--highlighted]=\"isHighlighted\"\n [class.str-chat__message-with-thread-link]=\"shouldDisplayThreadLink\"\n [class.str-chat__message-send-can-be-retried]=\"\n (message?.status === 'failed' && message?.errorStatusCode !== 403) ||\n (message?.type === 'error' && message?.moderation_details)\n \"\n [class.str-chat__message-with-touch-support]=\"hasTouchSupport\"\n [class.str-chat__message-without-touch-support]=\"!hasTouchSupport\"\n >\n <ng-container *ngIf=\"!message?.deleted_at; else deletedMessage\">\n <ng-container *ngIf=\"message?.type !== 'system'; else systemMessage\">\n <stream-avatar-placeholder\n data-testid=\"avatar\"\n class=\"str-chat-angular__avatar-host str-chat__message-sender-avatar\"\n type=\"user\"\n location=\"message-sender\"\n [imageUrl]=\"message?.user?.image\"\n [name]=\"message?.user?.name || message?.user?.id\"\n [user]=\"message?.user || undefined\"\n ></stream-avatar-placeholder>\n <div class=\"str-chat__message-inner\">\n <div\n *ngIf=\"!hasTouchSupport && areOptionsVisible\"\n class=\"str-chat__message-simple__actions str-chat__message-options\"\n data-testid=\"message-options\"\n [class.str-chat__message-actions-open]=\"areMessageOptionsOpen\"\n >\n <div\n #messageActionsToggle\n data-testid=\"message-actions-container\"\n class=\"str-chat__message-actions-container str-chat__message-simple__actions__action str-chat__message-simple__actions__action--options\"\n [floatUiLoose]=\"messageMenuFloat\"\n [looseTrigger]=\"\n messageActionsService.customActionClickHandler\n ? 'none'\n : 'click'\n \"\n [hideOnScroll]=\"false\"\n [hideOnClickOutside]=\"true\"\n [hideOnMouseLeave]=\"false\"\n [disableAnimation]=\"false\"\n [preventOverflow]=\"true\"\n [positionFixed]=\"true\"\n (onSHown)=\"areMessageOptionsOpen = true\"\n (onHidden)=\"areMessageOptionsOpen = false\"\n >\n <div\n *ngIf=\"visibleMessageActionsCount > 0\"\n class=\"str-chat__message-actions-box-button\"\n data-testid=\"message-options-button\"\n (click)=\"messageOptionsButtonClicked()\"\n (keyup.enter)=\"messageOptionsButtonClicked()\"\n >\n <stream-icon-placeholder\n icon=\"action\"\n class=\"str-chat__message-action-icon\"\n ></stream-icon-placeholder>\n </div>\n </div>\n </div>\n <ng-container\n *ngIf=\"\n customTemplatesService.customMessageMetadataInsideBubbleTemplate$\n | async\n \"\n >\n <ng-template\n *ngTemplateOutlet=\"\n (customTemplatesService.customMessageMetadataInsideBubbleTemplate$\n | async)!;\n context: { message: message }\n \"\n ></ng-template>\n </ng-container>\n <div class=\"str-chat__message-reactions-host\">\n <ng-template\n #defaultMessageReactions\n let-messageReactionCounts=\"messageReactionCounts\"\n let-latestReactions=\"latestReactions\"\n let-messageId=\"messageId\"\n let-ownReactions=\"ownReactions\"\n let-messageReactionGroups=\"messageReactionGroups\"\n >\n <stream-message-reactions\n [messageReactionCounts]=\"messageReactionCounts\"\n [latestReactions]=\"latestReactions\"\n [messageId]=\"messageId\"\n [ownReactions]=\"ownReactions\"\n [messageReactionGroups]=\"messageReactionGroups\"\n ></stream-message-reactions>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.messageReactionsTemplate$ | async) ||\n defaultMessageReactions;\n context: getMessageReactionsContext()\n \"\n ></ng-container>\n </div>\n <float-ui-content #messageMenuFloat>\n <ng-template\n #defaultMessageActionsBox\n let-isMine=\"isMine\"\n let-messageInput=\"message\"\n let-enabledActions=\"enabledActions\"\n let-messageTextHtmlElement=\"messageTextHtmlElement\"\n >\n <stream-message-actions-box\n [isMine]=\"isMine\"\n [message]=\"messageInput\"\n [enabledActions]=\"enabledActions\"\n [messageTextHtmlElement]=\"messageTextHtmlElement\"\n ></stream-message-actions-box>\n </ng-template>\n <ng-container>\n <div\n (click)=\"messageActionsBoxClicked(messageMenuFloat)\"\n (keyup.enter)=\"messageActionsBoxClicked(messageMenuFloat)\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.messageActionsBoxTemplate$\n | async) || defaultMessageActionsBox;\n context: getMessageActionsBoxContext()\n \"\n >\n </ng-container>\n </div>\n </ng-container>\n </float-ui-content>\n <div\n class=\"str-chat__message-bubble str-chat-angular__message-bubble\"\n [class.str-chat-angular__message-bubble--attachment-modal-open]=\"\n nestedModalState === 'opened'\n \"\n data-testid=\"message-bubble\"\n [floatUiLoose]=\"messageMenuFloat\"\n #messageMenuTrigger=\"floatUiLoose\"\n #messageBubble\n looseTrigger=\"none\"\n [hideOnScroll]=\"false\"\n [hideOnClickOutside]=\"true\"\n [hideOnMouseLeave]=\"false\"\n [disableAnimation]=\"true\"\n [preventOverflow]=\"true\"\n (onShown)=\"areMessageOptionsOpen = true\"\n (onHidden)=\"areMessageOptionsOpen = false\"\n [positionFixed]=\"true\"\n >\n <ng-container *ngIf=\"hasAttachment && !message?.quoted_message\">\n <div class=\"str-chat__attachments-container\">\n <ng-container\n *ngTemplateOutlet=\"attachmentsTemplate\"\n ></ng-container>\n </div>\n </ng-container>\n <ng-container\n *ngIf=\"\n message?.poll_id &&\n (customTemplatesService.pollTemplate$ | async)\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.pollTemplate$ | async)!;\n context: {\n pollId: message?.poll_id,\n messageId: message?.id,\n isQuote: false\n }\n \"\n ></ng-container>\n </ng-container>\n <div\n *ngIf=\"\n message?.text || (message?.quoted_message && hasAttachment)\n \"\n class=\"str-chat__message-text\"\n tabindex=\"0\"\n [class.str-chat__message-text--pointer-cursor]=\"\n (message?.status === 'failed' &&\n message?.errorStatusCode !== 403) ||\n (this.message?.type === 'error' &&\n this.message?.moderation_details) ||\n message?.message_text_updated_at\n \"\n (click)=\"messageClicked()\"\n (keyup.enter)=\"messageClicked()\"\n >\n <div\n data-testid=\"inner-message\"\n class=\"str-chat__message-text-inner str-chat__message-simple-text-inner\"\n [class.str-chat__message-light-text-inner--has-attachment]=\"\n hasAttachment\n \"\n >\n <ng-container *ngTemplateOutlet=\"quotedMessage\"></ng-container>\n <ng-container *ngIf=\"hasAttachment && message?.quoted_message\">\n <ng-container\n *ngTemplateOutlet=\"attachmentsTemplate\"\n ></ng-container>\n </ng-container>\n <div\n *ngIf=\"message?.type === 'error'\"\n data-testid=\"client-error-message\"\n class=\"str-chat__simple-message--error-message str-chat__message--error-message\"\n >\n <ng-container *ngIf=\"!message?.moderation_details\">{{\n \"streamChat.Error \u00B7 Unsent\" | translate\n }}</ng-container>\n </div>\n <div\n *ngIf=\"message?.status === 'failed'\"\n data-testid=\"error-message\"\n class=\"str-chat__simple-message--error-message str-chat__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 <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.messageTextTemplate$ | async) ||\n defaultText;\n context: getMessageTextContext()\n \"\n ></ng-container>\n <ng-template\n #defaultText\n let-message=\"message\"\n let-isQuoted=\"isQuoted\"\n let-shouldTranslate=\"shouldTranslate\"\n >\n <stream-message-text\n [message]=\"message\"\n [isQuoted]=\"isQuoted\"\n [shouldTranslate]=\"shouldTranslate\"\n data-testid=\"quoted-message-text\"\n ></stream-message-text>\n </ng-template>\n </div>\n </div>\n <stream-icon-placeholder\n class=\"str-chat__message-error-icon\"\n icon=\"error\"\n ></stream-icon-placeholder>\n </div>\n </div>\n <ng-container\n *ngTemplateOutlet=\"replyCountButton; context: { message: message }\"\n ></ng-container>\n\n <ng-container *ngTemplateOutlet=\"messageDateAndSender\"></ng-container>\n </ng-container>\n </ng-container>\n </div>\n\n <ng-template #deletedMessage>\n <div data-testid=\"message-deleted-component\">\n <div class=\"str-chat__message--deleted-inner\" translate>\n streamChat.This message was deleted...\n </div>\n </div>\n </ng-template>\n\n <ng-template #systemMessage>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.systemMessageTemplate$ | async) ||\n defaultSystemMessage;\n context: getMessageContext()\n \"\n ></ng-container>\n <ng-template #defaultSystemMessage let-messageInput=\"message\">\n <div data-testid=\"system-message\" class=\"str-chat__message--system\">\n <div class=\"str-chat__message--system__text\">\n <div class=\"str-chat__message--system__line\"></div>\n <p>{{ messageInput?.text }}</p>\n <div class=\"str-chat__message--system__line\"></div>\n </div>\n <div class=\"str-chat__message--system__date\">\n {{ parsedDate }}\n </div>\n </div>\n </ng-template>\n </ng-template>\n\n <ng-template #quotedMessage>\n <div\n *ngIf=\"message?.quoted_message\"\n class=\"quoted-message str-chat__quoted-message-preview\"\n data-testid=\"quoted-message-container\"\n [class.mine]=\"isSentByCurrentUser\"\n (click)=\"\n jumpToMessage(\n (message?.quoted_message)!.id,\n message?.quoted_message?.parent_id\n )\n \"\n (keyup.enter)=\"\n jumpToMessage(\n (message?.quoted_message)!.id,\n message?.quoted_message?.parent_id\n )\n \"\n >\n <stream-avatar-placeholder\n data-testid=\"qouted-message-avatar\"\n class=\"str-chat-angular__avatar-host str-chat__message-sender-avatar\"\n type=\"user\"\n location=\"quoted-message-sender\"\n [imageUrl]=\"message?.quoted_message?.user?.image\"\n [name]=\"\n message?.quoted_message?.user?.name ||\n message?.quoted_message?.user?.id\n \"\n [user]=\"message?.quoted_message?.user || undefined\"\n ></stream-avatar-placeholder>\n <div class=\"quoted-message-inner str-chat__quoted-message-bubble\">\n <ng-container\n *ngIf=\"\n message?.quoted_message?.attachments &&\n message?.quoted_message?.attachments?.length\n \"\n >\n <ng-template\n #defaultAttachments\n let-messageId=\"messageId\"\n let-attachments=\"attachments\"\n let-parentMessageId=\"parentMessageId\"\n let-imageModalStateChangeHandler=\"imageModalStateChangeHandler\"\n >\n <stream-attachment-list\n [messageId]=\"messageId\"\n [attachments]=\"attachments\"\n [parentMessageId]=\"parentMessageId\"\n (imageModalStateChange)=\"imageModalStateChangeHandler($event)\"\n ></stream-attachment-list>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.attachmentListTemplate$ | async) ||\n defaultAttachments;\n context: getQuotedMessageAttachmentListContext()\n \"\n ></ng-container>\n </ng-container>\n <ng-container\n *ngIf=\"\n message?.quoted_message?.poll_id &&\n (customTemplatesService.pollTemplate$ | async)\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.pollTemplate$ | async)!;\n context: {\n pollId: message?.quoted_message?.poll_id,\n messageId: message?.quoted_message?.id,\n isQuote: true\n }\n \"\n ></ng-container>\n </ng-container>\n <ng-container *ngIf=\"message?.quoted_message\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.messageTextTemplate$ | async) ||\n defaultText;\n context: getQuotedMessageTextContext()\n \"\n ></ng-container>\n <ng-template\n #defaultText\n let-message=\"message\"\n let-isQuoted=\"isQuoted\"\n let-shouldTranslate=\"shouldTranslate\"\n >\n <stream-message-text\n [message]=\"message\"\n [isQuoted]=\"isQuoted\"\n [shouldTranslate]=\"shouldTranslate\"\n data-testid=\"quoted-message-text\"\n ></stream-message-text>\n </ng-template>\n </ng-container>\n </div>\n </div>\n </ng-template>\n\n <ng-template #messageDateAndSender>\n <ng-container>\n <div\n *ngIf=\"shouldDisplayTranslationNotice\"\n class=\"str-chat__translation-notice\"\n data-testid=\"translation-notice\"\n >\n <button\n *ngIf=\"displayedMessageTextContent === 'translation'\"\n data-testid=\"see-original\"\n translate\n (click)=\"displayOriginalMessage()\"\n (keyup.enter)=\"displayOriginalMessage()\"\n >\n streamChat.See original (automatically translated)\n </button>\n <button\n *ngIf=\"displayedMessageTextContent === 'original'\"\n data-testid=\"see-translation\"\n translate\n (click)=\"displayTranslatedMessage()\"\n (keyup.enter)=\"displayTranslatedMessage()\"\n >\n streamChat.See translation\n </button>\n </div>\n <ng-container\n *ngIf=\"customTemplatesService.customMessageMetadataTemplate$ | async\"\n >\n <div class=\"str-chat__custom-message-metadata\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.customMessageMetadataTemplate$ | async)!;\n context: getMessageMetadataContext()\n \"\n ></ng-container>\n </div>\n </ng-container>\n <div\n class=\"str-chat__message-data str-chat__message-simple-data str-chat__message-metadata\"\n >\n <ng-container *ngTemplateOutlet=\"messageStatus\"></ng-container>\n\n <span\n *ngIf=\"!isSentByCurrentUser\"\n data-testid=\"sender\"\n class=\"str-chat__message-simple-name str-chat__message-sender-name\"\n >\n {{ message?.user?.name ? message?.user?.name : message?.user?.id }}\n </span>\n <span\n data-testid=\"date\"\n class=\"str-chat__message-simple-timestamp str-chat__message-simple-time\"\n >\n {{ parsedDate }}\n </span>\n <ng-container *ngIf=\"message?.message_text_updated_at\">\n <span\n data-testid=\"edited-flag\"\n class=\"str-chat__mesage-simple-edited\"\n translate\n >streamChat.Edited</span\n >\n <div\n data-testid=\"edited-timestamp\"\n class=\"str-chat__message-edited-timestamp\"\n [ngClass]=\"{\n 'str-chat__message-edited-timestamp--open': isEditedFlagOpened,\n 'str-chat__message-edited-timestamp--collapsed':\n !isEditedFlagOpened\n }\"\n >\n <span translate>streamChat.Edited</span>\n <time\n dateTime=\"{{ message?.message_text_updated_at }}\"\n title=\"{{ message?.message_text_updated_at }}\"\n >\n {{ pasedEditedDate }}\n </time>\n </div>\n </ng-container>\n </div>\n </ng-container>\n </ng-template>\n\n <ng-template #messageStatus>\n <ng-container\n *ngIf=\"\n isSentByCurrentUser &&\n ((isLastSentMessage && message?.status === 'received') ||\n message?.status === 'sending')\n \"\n >\n <ng-container *ngIf=\"message?.status === 'sending'; else sentStatus\">\n <ng-container *ngTemplateOutlet=\"sendingStatus\"></ng-container>\n </ng-container>\n <ng-template #sentStatus>\n <ng-container\n *ngIf=\"\n mode === 'main' &&\n isMessageDeliveredAndRead &&\n canDisplayReadStatus;\n else deliveredStatus\n \"\n >\n <ng-container *ngTemplateOutlet=\"readStatus\"></ng-container>\n </ng-container>\n </ng-template>\n <ng-template #deliveredStatus>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.deliveredStatusTemplate$ | async) ||\n defaultDeliveredStatus;\n context: getDeliveredStatusContext()\n \"\n ></ng-container>\n </ng-template>\n <ng-template #defaultDeliveredStatus>\n <span\n *ngIf=\"mode === 'main'\"\n class=\"str-chat__message-simple-status str-chat__message-simple-status-angular str-chat__message-status\"\n data-testid=\"delivered-indicator\"\n tabindex=\"0\"\n [floatUiLoose]=\"floatingContent\"\n loosePlacement=\"top\"\n [looseTrigger]=\"hasTouchSupport ? 'click' : 'hover'\"\n [disableAnimation]=\"true\"\n [hideOnClickOutside]=\"true\"\n [positionFixed]=\"true\"\n [preventOverflow]=\"true\"\n >\n <float-ui-content #floatingContent>\n <div class=\"str-chat__tooltip str-chat__tooltip-angular\">\n {{ \"streamChat.Delivered\" | translate }}\n </div>\n </float-ui-content>\n <stream-icon-placeholder\n data-testid=\"delivered-icon\"\n icon=\"delivered\"\n ></stream-icon-placeholder>\n </span>\n </ng-template>\n <ng-template #sendingStatus>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.sendingStatusTemplate$ | async) ||\n defaultSendingStatus;\n context: getSendingStatusContext()\n \"\n ></ng-container>\n </ng-template>\n <ng-template #defaultSendingStatus>\n <span\n class=\"str-chat__message-simple-status str-chat__message-simple-status-angular str-chat__message-status\"\n data-testid=\"sending-indicator\"\n tabindex=\"0\"\n [floatUiLoose]=\"floatingContent\"\n loosePlacement=\"top\"\n [looseTrigger]=\"hasTouchSupport ? 'click' : 'hover'\"\n [disableAnimation]=\"true\"\n [hideOnClickOutside]=\"true\"\n [positionFixed]=\"true\"\n [preventOverflow]=\"true\"\n >\n <float-ui-content #floatingContent>\n <div class=\"str-chat__tooltip str-chat__tooltip-angular\">\n {{ \"streamChat.Sending...\" | translate }}\n </div>\n </float-ui-content>\n <stream-loading-indicator-placeholder\n data-testid=\"loading-indicator\"\n ></stream-loading-indicator-placeholder>\n </span>\n </ng-template>\n <ng-template #readStatus>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.readStatusTemplate$ | async) ||\n defaultReadStatus;\n context: getReadStatusContext()\n \"\n ></ng-container>\n </ng-template>\n <ng-template #defaultReadStatus let-readByText=\"readByText\">\n <span\n class=\"str-chat__message-simple-status str-chat__message-simple-status-angular str-chat__message-status\"\n data-testid=\"read-indicator\"\n tabindex=\"0\"\n [floatUiLoose]=\"floatingContent\"\n loosePlacement=\"top\"\n [looseTrigger]=\"hasTouchSupport ? 'click' : 'hover'\"\n [disableAnimation]=\"true\"\n [hideOnClickOutside]=\"true\"\n [positionFixed]=\"true\"\n [preventOverflow]=\"true\"\n >\n <float-ui-content #floatingContent>\n <div\n class=\"str-chat__tooltip str-chat__tooltip-angular\"\n data-testid=\"read-by-tooltip\"\n >\n {{ readByText }}\n </div>\n </float-ui-content>\n <stream-icon-placeholder icon=\"read\"></stream-icon-placeholder>\n </span>\n </ng-template>\n </ng-container>\n </ng-template>\n\n <ng-template #replyCountButton>\n <div\n class=\"str-chat__message-simple-reply-button str-chat__message-replies-count-button-wrapper\"\n >\n <ng-container *ngIf=\"shouldDisplayThreadLink\">\n <ng-template\n *ngTemplateOutlet=\"\n (customTemplatesService.threadLinkButton$ | async) || defaultButton;\n context: { message: message }\n \"\n ></ng-template>\n </ng-container>\n <ng-template #defaultButton let-message=\"message\">\n <button\n class=\"str-chat__message-replies-count-button\"\n data-testid=\"reply-count-button\"\n (click)=\"setAsActiveParentMessage()\"\n >\n {{message?.reply_count === 1 ? ('streamChat.1 reply' | translate) : ('streamChat.{{ replyCount }}\n replies' | translate:replyCountParam)}}\n </button>\n </ng-template>\n </div>\n </ng-template>\n\n <ng-template #attachmentsTemplate>\n <ng-template\n #defaultAttachments\n let-messageId=\"messageId\"\n let-attachments=\"attachments\"\n let-parentMessageId=\"parentMessageId\"\n let-imageModalStateChangeHandler=\"imageModalStateChangeHandler\"\n >\n <stream-attachment-list\n [messageId]=\"messageId\"\n [attachments]=\"attachments\"\n [parentMessageId]=\"parentMessageId\"\n (imageModalStateChange)=\"imageModalStateChangeHandler($event)\"\n ></stream-attachment-list>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.attachmentListTemplate$ | async) ||\n defaultAttachments;\n context: getAttachmentListContext()\n \"\n ></ng-container>\n </ng-template>\n</ng-template>\n" }]
5902
5981
  }], ctorParameters: function () { return [{ type: ChatClientService }, { type: ChannelService }, { type: CustomTemplatesService }, { type: i0.ChangeDetectorRef }, { type: DateParserService }, { type: MessageActionsService }, { type: i0.NgZone }, { type: i6.TranslateService }]; }, propDecorators: { message: [{
5903
5982
  type: Input
5904
5983
  }], enabledMessageActions: [{
@@ -6662,7 +6741,7 @@ class AttachmentPreviewListComponent {
6662
6741
  }
6663
6742
  }
6664
6743
  AttachmentPreviewListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: AttachmentPreviewListComponent, deps: [{ token: CustomTemplatesService }, { token: AttachmentService }], target: i0.ɵɵFactoryTarget.Component });
6665
- AttachmentPreviewListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: AttachmentPreviewListComponent, selector: "stream-attachment-preview-list", inputs: { attachmentUploads$: "attachmentUploads$" }, outputs: { retryAttachmentUpload: "retryAttachmentUpload", deleteAttachment: "deleteAttachment" }, ngImport: i0, template: "<div\n *ngIf=\"\n (attachmentUploads$ | async)?.length ||\n (customAttachments.length > 0 && customAttachmentsPreview)\n \"\n class=\"str-chat__attachment-preview-list\"\n>\n <div class=\"str-chat__attachment-list-scroll-container\">\n <ng-container\n *ngFor=\"\n let attachmentUpload of attachmentUploads$ | async;\n trackBy: trackByFile\n \"\n >\n <div\n *ngIf=\"attachmentUpload.type === 'image'\"\n class=\"str-chat__attachment-preview-image\"\n data-testclass=\"attachment-image-preview\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n deleteButton;\n context: { attachmentUpload: attachmentUpload }\n \"\n ></ng-container>\n <div\n *ngIf=\"attachmentUpload.state === 'uploading'\"\n class=\"str-chat__attachment-preview-image-loading\"\n >\n <stream-loading-indicator-placeholder\n data-testclass=\"loading-indicator\"\n ></stream-loading-indicator-placeholder>\n </div>\n <ng-container\n *ngTemplateOutlet=\"\n retryButton;\n context: { attachmentUpload: attachmentUpload }\n \"\n ></ng-container>\n <img\n *ngIf=\"attachmentUpload.url || attachmentUpload.previewUri\"\n class=\"str-chat__attachment-preview-thumbnail\"\n data-testclass=\"attachment-image\"\n src=\"{{\n attachmentUpload.url\n ? attachmentUpload.url\n : attachmentUpload.previewUri\n }}\"\n alt=\"{{ attachmentUpload.file.name }}\"\n />\n </div>\n <div\n *ngIf=\"\n attachmentUpload.type === 'file' ||\n attachmentUpload.type === 'video' ||\n attachmentUpload.type === 'voiceRecording'\n \"\n class=\"str-chat__attachment-preview-file str-chat__attachment-preview-type-{{\n attachmentUpload.type\n }}\"\n data-testclass=\"attachment-file-preview\"\n >\n <stream-icon-placeholder\n class=\"str-chat__attachment-preview-file-icon\"\n icon=\"unspecified-filetype\"\n ></stream-icon-placeholder>\n\n <div class=\"str-chat__attachment-preview-file-end\">\n <div\n class=\"str-chat__attachment-preview-file-name\"\n title=\"{{ attachmentUpload.file.name }}\"\n >\n {{ attachmentUpload.file.name }}\n </div>\n <a\n *ngIf=\"attachmentUpload.state === 'success'\"\n class=\"str-chat__attachment-preview-file-download\"\n data-testclass=\"file-download-link\"\n download\n href=\"{{ attachmentUpload.url }}\"\n (click)=\"attachmentUpload.url ? null : $event.preventDefault()\"\n (keyup.enter)=\"\n attachmentUpload.url ? null : $event.preventDefault()\n \"\n >\n <stream-icon-placeholder icon=\"download\"></stream-icon-placeholder>\n </a>\n <stream-loading-indicator-placeholder\n *ngIf=\"attachmentUpload.state === 'uploading'\"\n data-testclass=\"loading-indicator\"\n ></stream-loading-indicator-placeholder>\n </div>\n <ng-container\n *ngTemplateOutlet=\"\n deleteButton;\n context: { attachmentUpload: attachmentUpload }\n \"\n ></ng-container>\n <ng-container\n *ngTemplateOutlet=\"\n retryButton;\n context: { attachmentUpload: attachmentUpload }\n \"\n ></ng-container>\n </div>\n </ng-container>\n <ng-container *ngIf=\"customAttachmentsPreview\">\n <ng-template\n *ngTemplateOutlet=\"\n customAttachmentsPreview;\n context: { service: attachmentService }\n \"\n ></ng-template>\n </ng-container>\n </div>\n</div>\n\n<ng-template #deleteButton let-attachmentUpload=\"attachmentUpload\">\n <div\n class=\"str-chat__attachment-preview-delete\"\n data-testclass=\"file-delete\"\n role=\"button\"\n (click)=\"attachmentDeleted(attachmentUpload)\"\n (keyup.enter)=\"attachmentDeleted(attachmentUpload)\"\n >\n <stream-icon-placeholder icon=\"close\"></stream-icon-placeholder>\n </div>\n</ng-template>\n\n<ng-template #retryButton let-attachmentUpload=\"attachmentUpload\">\n <div\n *ngIf=\"attachmentUpload.state === 'error'\"\n data-testclass=\"upload-retry\"\n class=\"str-chat__attachment-preview-error str-chat__attachment-preview-error-{{\n attachmentUpload.type === 'image' ? 'image' : 'file'\n }}\"\n (click)=\"attachmentUploadRetried(attachmentUpload.file)\"\n (keyup.enter)=\"attachmentUploadRetried(attachmentUpload.file)\"\n >\n <stream-icon-placeholder icon=\"retry\"></stream-icon-placeholder>\n </div>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon"] }, { kind: "component", type: LoadingIndicatorPlaceholderComponent, selector: "stream-loading-indicator-placeholder" }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }] });
6744
+ AttachmentPreviewListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: AttachmentPreviewListComponent, selector: "stream-attachment-preview-list", inputs: { attachmentUploads$: "attachmentUploads$" }, outputs: { retryAttachmentUpload: "retryAttachmentUpload", deleteAttachment: "deleteAttachment" }, ngImport: i0, template: "<div\n *ngIf=\"\n (attachmentUploads$ | async)?.length ||\n (customAttachments.length > 0 && customAttachmentsPreview)\n \"\n class=\"str-chat__attachment-preview-list\"\n>\n <div class=\"str-chat__attachment-list-scroll-container\">\n <ng-container\n *ngFor=\"\n let attachmentUpload of attachmentUploads$ | async;\n trackBy: trackByFile\n \"\n >\n <div\n *ngIf=\"attachmentUpload.type === 'image'\"\n class=\"str-chat__attachment-preview-image\"\n data-testclass=\"attachment-image-preview\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n deleteButton;\n context: { attachmentUpload: attachmentUpload }\n \"\n ></ng-container>\n <div\n *ngIf=\"attachmentUpload.state === 'uploading'\"\n class=\"str-chat__attachment-preview-image-loading\"\n >\n <stream-loading-indicator-placeholder\n data-testclass=\"loading-indicator\"\n ></stream-loading-indicator-placeholder>\n </div>\n <ng-container\n *ngTemplateOutlet=\"\n retryButton;\n context: { attachmentUpload: attachmentUpload }\n \"\n ></ng-container>\n <img\n *ngIf=\"attachmentUpload.url || attachmentUpload.previewUri\"\n class=\"str-chat__attachment-preview-thumbnail\"\n data-testclass=\"attachment-image\"\n src=\"{{\n attachmentUpload.url\n ? attachmentUpload.url\n : attachmentUpload.previewUri\n }}\"\n alt=\"{{ attachmentUpload.file.name }}\"\n />\n </div>\n <div\n *ngIf=\"\n attachmentUpload.type === 'file' ||\n attachmentUpload.type === 'video' ||\n attachmentUpload.type === 'voiceRecording'\n \"\n class=\"str-chat__attachment-preview-file str-chat__attachment-preview-type-{{\n attachmentUpload.type\n }}\"\n data-testclass=\"attachment-file-preview\"\n >\n <stream-icon-placeholder\n class=\"str-chat__attachment-preview-file-icon\"\n icon=\"unspecified-filetype\"\n ></stream-icon-placeholder>\n\n <div class=\"str-chat__attachment-preview-file-end\">\n <div\n class=\"str-chat__attachment-preview-file-name\"\n title=\"{{ attachmentUpload.file.name }}\"\n >\n {{ attachmentUpload.file.name }}\n </div>\n <a\n *ngIf=\"attachmentUpload.state === 'success'\"\n class=\"str-chat__attachment-preview-file-download\"\n data-testclass=\"file-download-link\"\n download\n href=\"{{ attachmentUpload.url }}\"\n (click)=\"attachmentUpload.url ? null : $event.preventDefault()\"\n (keyup.enter)=\"\n attachmentUpload.url ? null : $event.preventDefault()\n \"\n >\n <stream-icon-placeholder icon=\"download\"></stream-icon-placeholder>\n </a>\n <stream-loading-indicator-placeholder\n *ngIf=\"attachmentUpload.state === 'uploading'\"\n data-testclass=\"loading-indicator\"\n ></stream-loading-indicator-placeholder>\n </div>\n <ng-container\n *ngTemplateOutlet=\"\n deleteButton;\n context: { attachmentUpload: attachmentUpload }\n \"\n ></ng-container>\n <ng-container\n *ngTemplateOutlet=\"\n retryButton;\n context: { attachmentUpload: attachmentUpload }\n \"\n ></ng-container>\n </div>\n </ng-container>\n <ng-container *ngIf=\"customAttachmentsPreview\">\n <ng-template\n *ngTemplateOutlet=\"\n customAttachmentsPreview;\n context: { service: attachmentService }\n \"\n ></ng-template>\n </ng-container>\n </div>\n</div>\n\n<ng-template #deleteButton let-attachmentUpload=\"attachmentUpload\">\n <div\n class=\"str-chat__attachment-preview-delete\"\n data-testclass=\"file-delete\"\n role=\"button\"\n (click)=\"attachmentDeleted(attachmentUpload)\"\n (keyup.enter)=\"attachmentDeleted(attachmentUpload)\"\n >\n <stream-icon-placeholder icon=\"close\"></stream-icon-placeholder>\n </div>\n</ng-template>\n\n<ng-template #retryButton let-attachmentUpload=\"attachmentUpload\">\n <div\n *ngIf=\"attachmentUpload.state === 'error'\"\n data-testclass=\"upload-retry\"\n class=\"str-chat__attachment-preview-error str-chat__attachment-preview-error-{{\n attachmentUpload.type === 'image' ? 'image' : 'file'\n }}\"\n (click)=\"attachmentUploadRetried(attachmentUpload.file)\"\n (keyup.enter)=\"attachmentUploadRetried(attachmentUpload.file)\"\n >\n <stream-icon-placeholder icon=\"retry\"></stream-icon-placeholder>\n </div>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon"] }, { kind: "component", type: LoadingIndicatorPlaceholderComponent, selector: "stream-loading-indicator-placeholder" }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }] });
6666
6745
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: AttachmentPreviewListComponent, decorators: [{
6667
6746
  type: Component,
6668
6747
  args: [{ selector: 'stream-attachment-preview-list', template: "<div\n *ngIf=\"\n (attachmentUploads$ | async)?.length ||\n (customAttachments.length > 0 && customAttachmentsPreview)\n \"\n class=\"str-chat__attachment-preview-list\"\n>\n <div class=\"str-chat__attachment-list-scroll-container\">\n <ng-container\n *ngFor=\"\n let attachmentUpload of attachmentUploads$ | async;\n trackBy: trackByFile\n \"\n >\n <div\n *ngIf=\"attachmentUpload.type === 'image'\"\n class=\"str-chat__attachment-preview-image\"\n data-testclass=\"attachment-image-preview\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n deleteButton;\n context: { attachmentUpload: attachmentUpload }\n \"\n ></ng-container>\n <div\n *ngIf=\"attachmentUpload.state === 'uploading'\"\n class=\"str-chat__attachment-preview-image-loading\"\n >\n <stream-loading-indicator-placeholder\n data-testclass=\"loading-indicator\"\n ></stream-loading-indicator-placeholder>\n </div>\n <ng-container\n *ngTemplateOutlet=\"\n retryButton;\n context: { attachmentUpload: attachmentUpload }\n \"\n ></ng-container>\n <img\n *ngIf=\"attachmentUpload.url || attachmentUpload.previewUri\"\n class=\"str-chat__attachment-preview-thumbnail\"\n data-testclass=\"attachment-image\"\n src=\"{{\n attachmentUpload.url\n ? attachmentUpload.url\n : attachmentUpload.previewUri\n }}\"\n alt=\"{{ attachmentUpload.file.name }}\"\n />\n </div>\n <div\n *ngIf=\"\n attachmentUpload.type === 'file' ||\n attachmentUpload.type === 'video' ||\n attachmentUpload.type === 'voiceRecording'\n \"\n class=\"str-chat__attachment-preview-file str-chat__attachment-preview-type-{{\n attachmentUpload.type\n }}\"\n data-testclass=\"attachment-file-preview\"\n >\n <stream-icon-placeholder\n class=\"str-chat__attachment-preview-file-icon\"\n icon=\"unspecified-filetype\"\n ></stream-icon-placeholder>\n\n <div class=\"str-chat__attachment-preview-file-end\">\n <div\n class=\"str-chat__attachment-preview-file-name\"\n title=\"{{ attachmentUpload.file.name }}\"\n >\n {{ attachmentUpload.file.name }}\n </div>\n <a\n *ngIf=\"attachmentUpload.state === 'success'\"\n class=\"str-chat__attachment-preview-file-download\"\n data-testclass=\"file-download-link\"\n download\n href=\"{{ attachmentUpload.url }}\"\n (click)=\"attachmentUpload.url ? null : $event.preventDefault()\"\n (keyup.enter)=\"\n attachmentUpload.url ? null : $event.preventDefault()\n \"\n >\n <stream-icon-placeholder icon=\"download\"></stream-icon-placeholder>\n </a>\n <stream-loading-indicator-placeholder\n *ngIf=\"attachmentUpload.state === 'uploading'\"\n data-testclass=\"loading-indicator\"\n ></stream-loading-indicator-placeholder>\n </div>\n <ng-container\n *ngTemplateOutlet=\"\n deleteButton;\n context: { attachmentUpload: attachmentUpload }\n \"\n ></ng-container>\n <ng-container\n *ngTemplateOutlet=\"\n retryButton;\n context: { attachmentUpload: attachmentUpload }\n \"\n ></ng-container>\n </div>\n </ng-container>\n <ng-container *ngIf=\"customAttachmentsPreview\">\n <ng-template\n *ngTemplateOutlet=\"\n customAttachmentsPreview;\n context: { service: attachmentService }\n \"\n ></ng-template>\n </ng-container>\n </div>\n</div>\n\n<ng-template #deleteButton let-attachmentUpload=\"attachmentUpload\">\n <div\n class=\"str-chat__attachment-preview-delete\"\n data-testclass=\"file-delete\"\n role=\"button\"\n (click)=\"attachmentDeleted(attachmentUpload)\"\n (keyup.enter)=\"attachmentDeleted(attachmentUpload)\"\n >\n <stream-icon-placeholder icon=\"close\"></stream-icon-placeholder>\n </div>\n</ng-template>\n\n<ng-template #retryButton let-attachmentUpload=\"attachmentUpload\">\n <div\n *ngIf=\"attachmentUpload.state === 'error'\"\n data-testclass=\"upload-retry\"\n class=\"str-chat__attachment-preview-error str-chat__attachment-preview-error-{{\n attachmentUpload.type === 'image' ? 'image' : 'file'\n }}\"\n (click)=\"attachmentUploadRetried(attachmentUpload.file)\"\n (keyup.enter)=\"attachmentUploadRetried(attachmentUpload.file)\"\n >\n <stream-icon-placeholder icon=\"retry\"></stream-icon-placeholder>\n </div>\n</ng-template>\n" }]
@@ -6713,6 +6792,10 @@ class MessageInputComponent {
6713
6792
  * You can enable/disable voice recordings with this input
6714
6793
  */
6715
6794
  this.displayVoiceRecordingButton = false;
6795
+ /**
6796
+ * You can enable/disable polls with this input
6797
+ */
6798
+ this.displayPollCreateButton = false;
6716
6799
  /**
6717
6800
  * Emits when a message was successfuly sent or updated
6718
6801
  */
@@ -6724,10 +6807,19 @@ class MessageInputComponent {
6724
6807
  this.typingStart$ = new Subject();
6725
6808
  this.isCooldownInProgress = false;
6726
6809
  this.fileInputId = v4();
6810
+ this.isComposerOpen = false;
6727
6811
  this.subscriptions = [];
6728
6812
  this.isViewInited = false;
6729
6813
  this.defaultTextareaPlaceholder = 'streamChat.Type your message';
6730
6814
  this.slowModeTextareaPlaceholder = 'streamChat.Slow Mode ON';
6815
+ this.closePollComposer = () => {
6816
+ this.isComposerOpen = false;
6817
+ };
6818
+ this.addPoll = (pollId) => {
6819
+ this.isComposerOpen = false;
6820
+ this.pollId = pollId;
6821
+ void this.messageSent();
6822
+ };
6731
6823
  this.textareaPlaceholder = this.defaultTextareaPlaceholder;
6732
6824
  this.subscriptions.push(this.attachmentService.attachmentUploadInProgressCounter$.subscribe((counter) => {
6733
6825
  if (counter === 0 && this.hideNotification) {
@@ -6740,6 +6832,7 @@ class MessageInputComponent {
6740
6832
  if (channel && this.channel && channel.id !== this.channel.id) {
6741
6833
  this.textareaValue = '';
6742
6834
  this.attachmentService.resetAttachmentUploads();
6835
+ this.pollId = undefined;
6743
6836
  this.voiceRecorderService.isRecorderVisible$.next(false);
6744
6837
  }
6745
6838
  const capabilities = (_a = channel === null || channel === void 0 ? void 0 : channel.data) === null || _a === void 0 ? void 0 : _a.own_capabilities;
@@ -6747,6 +6840,7 @@ class MessageInputComponent {
6747
6840
  this.isFileUploadAuthorized =
6748
6841
  capabilities.indexOf('upload-file') !== -1;
6749
6842
  this.canSendLinks = capabilities.indexOf('send-links') !== -1;
6843
+ this.canSendPolls = capabilities.indexOf('send-poll') !== -1;
6750
6844
  this.channel = channel;
6751
6845
  this.setCanSendMessages();
6752
6846
  }
@@ -6886,7 +6980,8 @@ class MessageInputComponent {
6886
6980
  text = text.replace(/\n+$/g, ''); // ending empty lines
6887
6981
  const textContainsOnlySpaceChars = !text.replace(/ /g, ''); //spcae
6888
6982
  if ((!text || textContainsOnlySpaceChars) &&
6889
- (!attachments || attachments.length === 0)) {
6983
+ (!attachments || attachments.length === 0) &&
6984
+ !this.pollId) {
6890
6985
  return;
6891
6986
  }
6892
6987
  if (textContainsOnlySpaceChars) {
@@ -6896,13 +6991,15 @@ class MessageInputComponent {
6896
6991
  this.notificationService.addTemporaryNotification('streamChat.Sending links is not allowed in this conversation');
6897
6992
  return;
6898
6993
  }
6994
+ const pollId = this.pollId;
6899
6995
  if (!this.isUpdate) {
6900
6996
  this.textareaValue = '';
6997
+ this.pollId = undefined;
6901
6998
  }
6902
6999
  try {
6903
7000
  const message = yield (this.isUpdate
6904
7001
  ? this.channelService.updateMessage(Object.assign(Object.assign({}, this.message), { text: text, attachments: attachments }))
6905
- : this.channelService.sendMessage(text, attachments, this.mentionedUsers, this.parentMessageId, (_a = this.quotedMessage) === null || _a === void 0 ? void 0 : _a.id));
7002
+ : this.channelService.sendMessage(text, attachments, this.mentionedUsers, this.parentMessageId, (_a = this.quotedMessage) === null || _a === void 0 ? void 0 : _a.id, undefined, pollId));
6906
7003
  this.messageUpdate.emit({ message });
6907
7004
  if (this.isUpdate) {
6908
7005
  this.deselectMessageToEdit();
@@ -6999,6 +7096,9 @@ class MessageInputComponent {
6999
7096
  }
7000
7097
  });
7001
7098
  }
7099
+ openPollComposer() {
7100
+ this.isComposerOpen = true;
7101
+ }
7002
7102
  voiceRecordingReady(recording) {
7003
7103
  return __awaiter(this, void 0, void 0, function* () {
7004
7104
  try {
@@ -7110,17 +7210,19 @@ class MessageInputComponent {
7110
7210
  if (this.isUpdate) {
7111
7211
  this.attachmentService.createFromAttachments(this.message.attachments || []);
7112
7212
  this.textareaValue = this.message.text || '';
7213
+ this.pollId = this.message.poll_id;
7113
7214
  }
7114
7215
  else {
7115
7216
  this.textareaValue = '';
7217
+ this.pollId = undefined;
7116
7218
  }
7117
7219
  }
7118
7220
  }
7119
7221
  MessageInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: MessageInputComponent, deps: [{ token: ChannelService }, { token: NotificationService }, { token: AttachmentService }, { token: MessageInputConfigService }, { token: textareaInjectionToken }, { token: i0.ComponentFactoryResolver }, { token: i0.ChangeDetectorRef }, { token: EmojiInputService }, { token: CustomTemplatesService }, { token: MessageActionsService }, { token: VoiceRecorderService }, { token: AudioRecorderService, optional: true }], target: i0.ɵɵFactoryTarget.Component });
7120
- MessageInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: MessageInputComponent, selector: "stream-message-input", inputs: { isFileUploadEnabled: "isFileUploadEnabled", areMentionsEnabled: "areMentionsEnabled", mentionScope: "mentionScope", mode: "mode", isMultipleFileUploadEnabled: "isMultipleFileUploadEnabled", message: "message", sendMessage$: "sendMessage$", inputMode: "inputMode", autoFocus: "autoFocus", watchForMessageToEdit: "watchForMessageToEdit", displaySendButton: "displaySendButton", displayVoiceRecordingButton: "displayVoiceRecordingButton" }, outputs: { messageUpdate: "messageUpdate" }, host: { properties: { "class": "this.class" } }, providers: [AttachmentService, EmojiInputService, VoiceRecorderService], queries: [{ propertyName: "voiceRecorderRef", first: true, predicate: TemplateRef, descendants: true }], viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true }, { propertyName: "textareaAnchor", first: true, predicate: TextareaDirective, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div\n class=\"str-chat__message-input str-chat-angular__message-input\"\n [style.display]=\"isVoiceRecording ? 'none' : 'flex'\"\n>\n <div *ngIf=\"quotedMessage\" class=\"str-chat__quoted-message-preview-header\">\n <div class=\"str-chat__quoted-message-reply-to-message\">\n {{ \"streamChat.Reply to Message\" | translate }}\n </div>\n <button\n class=\"str-chat__quoted-message-remove\"\n data-testid=\"remove-quote\"\n (click)=\"deselectMessageToQuote()\"\n (keyup.enter)=\"deselectMessageToQuote()\"\n >\n <stream-icon-placeholder icon=\"close\"></stream-icon-placeholder>\n </button>\n </div>\n <div *ngIf=\"isUpdate\" class=\"str-chat__quoted-message-preview-header\">\n <div class=\"str-chat__quoted-message-reply-to-message\">\n {{ \"streamChat.Edit Message\" | translate }}\n </div>\n <button\n class=\"str-chat__quoted-message-remove\"\n data-testid=\"remove-quote\"\n (click)=\"deselectMessageToEdit()\"\n (keyup.enter)=\"deselectMessageToEdit()\"\n >\n <stream-icon-placeholder icon=\"close\"></stream-icon-placeholder>\n </button>\n </div>\n <ng-container *ngIf=\"canSendMessages; else notAllowed\">\n <div\n class=\"str-chat__message-input-inner str-chat-angular__message-input-inner\"\n >\n <ng-content select=\"[message-input-start]\"></ng-content>\n <ng-container\n *ngIf=\"isFileUploadEnabled && isFileUploadAuthorized && canSendMessages\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n customAttachmentUploadTemplate || defaultAttachmentUpload;\n context: getAttachmentUploadContext()\n \"\n ></ng-container>\n <ng-template #defaultAttachmentUpload>\n <div\n class=\"str-chat__file-input-container\"\n data-testid=\"file-upload-button\"\n >\n <input\n #fileInput\n type=\"file\"\n class=\"str-chat__file-input\"\n data-testid=\"file-input\"\n [multiple]=\"isMultipleFileUploadEnabled\"\n id=\"{{ fileInputId }}\"\n [disabled]=\"\n (attachmentService.attachmentsCounter$ | async)! >=\n attachmentService.maxNumberOfAttachments\n \"\n (change)=\"filesSelected(fileInput.files)\"\n />\n <label class=\"str-chat__file-input-label\" for=\"{{ fileInputId }}\">\n <stream-icon-placeholder icon=\"attach\"></stream-icon-placeholder>\n </label>\n </div>\n </ng-template>\n </ng-container>\n <div class=\"str-chat__message-textarea-container\">\n <div\n *ngIf=\"quotedMessage\"\n data-testid=\"quoted-message-container\"\n class=\"str-chat__quoted-message-preview\"\n >\n <stream-avatar-placeholder\n data-testid=\"qouted-message-avatar\"\n class=\"str-chat-angular__avatar-host str-chat__message-sender-avatar\"\n type=\"user\"\n location=\"quoted-message-sender\"\n [imageUrl]=\"quotedMessage.user?.image\"\n [name]=\"quotedMessage.user?.name || quotedMessage.user?.id\"\n [user]=\"quotedMessage.user || undefined\"\n ></stream-avatar-placeholder>\n <div\n class=\"quoted-message-preview-content-inner str-chat__quoted-message-bubble\"\n >\n <stream-attachment-list\n *ngIf=\"\n quotedMessage?.attachments && quotedMessage?.attachments?.length\n \"\n [attachments]=\"quotedMessageAttachments\"\n [messageId]=\"quotedMessage.id\"\n ></stream-attachment-list>\n <div class=\"str-chat__quoted-message-text\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.messageTextTemplate$ | async) ||\n defaultText;\n context: getQuotedMessageTextContext()\n \"\n ></ng-container>\n <ng-template\n #defaultText\n let-message=\"message\"\n let-isQuoted=\"isQuoted\"\n let-shouldTranslate=\"shouldTranslate\"\n >\n <stream-message-text\n [message]=\"message\"\n [isQuoted]=\"isQuoted\"\n [shouldTranslate]=\"shouldTranslate\"\n data-testid=\"quoted-message-text\"\n ></stream-message-text>\n </ng-template>\n </div>\n </div>\n </div>\n <ng-template\n #defaultAttachmentsPreview\n let-attachmentUploads$=\"attachmentUploads$\"\n let-retryUploadHandler=\"retryUploadHandler\"\n let-deleteUploadHandler=\"deleteUploadHandler\"\n >\n <stream-attachment-preview-list\n class=\"str-chat__attachment-preview-list-angular-host\"\n [attachmentUploads$]=\"attachmentUploads$\"\n (retryAttachmentUpload)=\"retryUploadHandler($event)\"\n (deleteAttachment)=\"deleteUploadHandler($event)\"\n ></stream-attachment-preview-list>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n attachmentPreviewListTemplate || defaultAttachmentsPreview;\n context: getAttachmentPreviewListContext()\n \"\n ></ng-container>\n <div class=\"str-chat__message-textarea-with-emoji-picker\">\n <ng-container\n streamTextarea\n [componentRef]=\"textareaRef\"\n [areMentionsEnabled]=\"areMentionsEnabled\"\n [mentionScope]=\"mentionScope\"\n [inputMode]=\"inputMode\"\n [autoFocus]=\"autoFocus\"\n [placeholder]=\"textareaPlaceholder\"\n [(value)]=\"textareaValue\"\n (valueChange)=\"typingStart$.next()\"\n (send)=\"messageSent()\"\n (userMentions)=\"mentionedUsers = $event\"\n (pasteFromClipboard)=\"itemsPasted($event)\"\n ></ng-container>\n <ng-container *ngIf=\"emojiPickerTemplate\" data-testid=\"emoji-picker\">\n <ng-container\n *ngTemplateOutlet=\"\n emojiPickerTemplate;\n context: getEmojiPickerContext()\n \"\n ></ng-container>\n </ng-container>\n </div>\n </div>\n <button\n *ngIf=\"canSendMessages && !isCooldownInProgress && displaySendButton\"\n data-testid=\"send-button\"\n class=\"str-chat__send-button\"\n [disabled]=\"\n (attachmentUploadInProgressCounter$ | async)! > 0 ||\n (attachmentService.attachmentsCounter$ | async)! >\n attachmentService.maxNumberOfAttachments ||\n (!textareaValue &&\n (attachmentUploads$ | async)!.length === 0 &&\n (customAttachments$ | async)!.length === 0)\n \"\n (click)=\"messageSent()\"\n (keyup.enter)=\"messageSent()\"\n >\n <stream-icon-placeholder icon=\"send\"></stream-icon-placeholder>\n </button>\n <div\n *ngIf=\"isCooldownInProgress\"\n class=\"str-chat__message-input-cooldown\"\n data-testid=\"cooldown-timer\"\n >\n {{ cooldown$ | async }}\n </div>\n <button\n *ngIf=\"displayVoiceRecordingButton\"\n class=\"str-chat__start-recording-audio-button\"\n data-testid=\"start-voice-recording\"\n [disabled]=\"\n voiceRecorderService.isRecorderVisible$.value ||\n audioRecorder?.isRecording ||\n (attachmentService.attachmentsCounter$ | async)! >=\n attachmentService.maxNumberOfAttachments\n \"\n (click)=\"startVoiceRecording()\"\n (keyup.enter)=\"startVoiceRecording()\"\n >\n <stream-icon-placeholder icon=\"mic\"></stream-icon-placeholder>\n </button>\n <ng-content select=\"[message-input-end]\"></ng-content>\n </div>\n </ng-container>\n <ng-template #notAllowed>\n <div\n class=\"str-chat__message-input-not-allowed\"\n data-testid=\"disabled-textarea\"\n >\n {{ disabledTextareaText | translate }}\n </div>\n </ng-template>\n</div>\n<ng-template\n *ngIf=\"voiceRecorderRef\"\n [ngTemplateOutlet]=\"voiceRecorderRef\"\n [ngTemplateOutletContext]=\"{ service: voiceRecorderService }\"\n></ng-template>\n", dependencies: [{ kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: AvatarPlaceholderComponent, selector: "stream-avatar-placeholder", inputs: ["name", "imageUrl", "location", "channel", "user", "type", "initialsType", "showOnlineIndicator"] }, { kind: "component", type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon"] }, { kind: "component", type: AttachmentListComponent, selector: "stream-attachment-list", inputs: ["messageId", "parentMessageId", "attachments"], outputs: ["imageModalStateChange"] }, { kind: "component", type: AttachmentPreviewListComponent, selector: "stream-attachment-preview-list", inputs: ["attachmentUploads$"], outputs: ["retryAttachmentUpload", "deleteAttachment"] }, { kind: "directive", type: TextareaDirective, selector: "[streamTextarea]", inputs: ["componentRef", "areMentionsEnabled", "mentionScope", "inputMode", "value", "placeholder", "autoFocus"], outputs: ["valueChange", "send", "userMentions", "pasteFromClipboard"] }, { kind: "component", type: MessageTextComponent, selector: "stream-message-text", inputs: ["message", "isQuoted", "shouldTranslate"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.TranslatePipe, name: "translate" }] });
7222
+ MessageInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: MessageInputComponent, selector: "stream-message-input", inputs: { isFileUploadEnabled: "isFileUploadEnabled", areMentionsEnabled: "areMentionsEnabled", mentionScope: "mentionScope", mode: "mode", isMultipleFileUploadEnabled: "isMultipleFileUploadEnabled", message: "message", sendMessage$: "sendMessage$", inputMode: "inputMode", autoFocus: "autoFocus", watchForMessageToEdit: "watchForMessageToEdit", displaySendButton: "displaySendButton", displayVoiceRecordingButton: "displayVoiceRecordingButton", displayPollCreateButton: "displayPollCreateButton" }, outputs: { messageUpdate: "messageUpdate" }, host: { properties: { "class": "this.class" } }, providers: [AttachmentService, EmojiInputService, VoiceRecorderService], queries: [{ propertyName: "voiceRecorderRef", first: true, predicate: TemplateRef, descendants: true }], viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true }, { propertyName: "textareaAnchor", first: true, predicate: TextareaDirective, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div\n class=\"str-chat__message-input str-chat-angular__message-input\"\n [style.display]=\"isVoiceRecording ? 'none' : 'flex'\"\n>\n <div *ngIf=\"quotedMessage\" class=\"str-chat__quoted-message-preview-header\">\n <div class=\"str-chat__quoted-message-reply-to-message\">\n {{ \"streamChat.Reply to Message\" | translate }}\n </div>\n <button\n class=\"str-chat__quoted-message-remove\"\n data-testid=\"remove-quote\"\n (click)=\"deselectMessageToQuote()\"\n (keyup.enter)=\"deselectMessageToQuote()\"\n >\n <stream-icon-placeholder icon=\"close\"></stream-icon-placeholder>\n </button>\n </div>\n <div *ngIf=\"isUpdate\" class=\"str-chat__quoted-message-preview-header\">\n <div class=\"str-chat__quoted-message-reply-to-message\">\n {{ \"streamChat.Edit Message\" | translate }}\n </div>\n <button\n class=\"str-chat__quoted-message-remove\"\n data-testid=\"remove-quote\"\n (click)=\"deselectMessageToEdit()\"\n (keyup.enter)=\"deselectMessageToEdit()\"\n >\n <stream-icon-placeholder icon=\"close\"></stream-icon-placeholder>\n </button>\n </div>\n <ng-container *ngIf=\"canSendMessages; else notAllowed\">\n <div\n class=\"str-chat__message-input-inner str-chat-angular__message-input-inner\"\n >\n <ng-content select=\"[message-input-start]\"></ng-content>\n <ng-container\n *ngIf=\"isFileUploadEnabled && isFileUploadAuthorized && canSendMessages\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n customAttachmentUploadTemplate || defaultAttachmentUpload;\n context: getAttachmentUploadContext()\n \"\n ></ng-container>\n <ng-template #defaultAttachmentUpload>\n <div\n class=\"str-chat__file-input-container\"\n data-testid=\"file-upload-button\"\n >\n <input\n #fileInput\n type=\"file\"\n class=\"str-chat__file-input\"\n data-testid=\"file-input\"\n [multiple]=\"isMultipleFileUploadEnabled\"\n id=\"{{ fileInputId }}\"\n [disabled]=\"\n (attachmentService.attachmentsCounter$ | async)! >=\n attachmentService.maxNumberOfAttachments\n \"\n (change)=\"filesSelected(fileInput.files)\"\n />\n <label class=\"str-chat__file-input-label\" for=\"{{ fileInputId }}\">\n <stream-icon-placeholder icon=\"attach\"></stream-icon-placeholder>\n </label>\n </div>\n </ng-template>\n </ng-container>\n <ng-container\n *ngIf=\"canSendPolls && displayPollCreateButton && mode !== 'thread'\"\n >\n <button\n class=\"str-chat-angular__create-poll\"\n (click)=\"openPollComposer()\"\n >\n <stream-icon-placeholder icon=\"poll\"></stream-icon-placeholder>\n </button>\n </ng-container>\n <div class=\"str-chat__message-textarea-container\">\n <div\n *ngIf=\"quotedMessage\"\n data-testid=\"quoted-message-container\"\n class=\"str-chat__quoted-message-preview\"\n >\n <stream-avatar-placeholder\n data-testid=\"qouted-message-avatar\"\n class=\"str-chat-angular__avatar-host str-chat__message-sender-avatar\"\n type=\"user\"\n location=\"quoted-message-sender\"\n [imageUrl]=\"quotedMessage.user?.image\"\n [name]=\"quotedMessage.user?.name || quotedMessage.user?.id\"\n [user]=\"quotedMessage.user || undefined\"\n ></stream-avatar-placeholder>\n <div\n class=\"quoted-message-preview-content-inner str-chat__quoted-message-bubble\"\n >\n <stream-attachment-list\n *ngIf=\"\n quotedMessage?.attachments && quotedMessage?.attachments?.length\n \"\n [attachments]=\"quotedMessageAttachments\"\n [messageId]=\"quotedMessage.id\"\n ></stream-attachment-list>\n <ng-container\n *ngIf=\"\n quotedMessage?.poll_id &&\n (customTemplatesService.pollTemplate$ | async)\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.pollTemplate$ | async)!;\n context: {\n pollId: quotedMessage?.poll_id,\n messageId: quotedMessage?.id,\n isQuote: true\n }\n \"\n ></ng-container>\n </ng-container>\n <div class=\"str-chat__quoted-message-text\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.messageTextTemplate$ | async) ||\n defaultText;\n context: getQuotedMessageTextContext()\n \"\n ></ng-container>\n <ng-template\n #defaultText\n let-message=\"message\"\n let-isQuoted=\"isQuoted\"\n let-shouldTranslate=\"shouldTranslate\"\n >\n <stream-message-text\n [message]=\"message\"\n [isQuoted]=\"isQuoted\"\n [shouldTranslate]=\"shouldTranslate\"\n data-testid=\"quoted-message-text\"\n ></stream-message-text>\n </ng-template>\n </div>\n </div>\n </div>\n <ng-template\n #defaultAttachmentsPreview\n let-attachmentUploads$=\"attachmentUploads$\"\n let-retryUploadHandler=\"retryUploadHandler\"\n let-deleteUploadHandler=\"deleteUploadHandler\"\n >\n <stream-attachment-preview-list\n class=\"str-chat__attachment-preview-list-angular-host\"\n [attachmentUploads$]=\"attachmentUploads$\"\n (retryAttachmentUpload)=\"retryUploadHandler($event)\"\n (deleteAttachment)=\"deleteUploadHandler($event)\"\n ></stream-attachment-preview-list>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n attachmentPreviewListTemplate || defaultAttachmentsPreview;\n context: getAttachmentPreviewListContext()\n \"\n ></ng-container>\n <div class=\"str-chat__message-textarea-with-emoji-picker\">\n <ng-container\n streamTextarea\n [componentRef]=\"textareaRef\"\n [areMentionsEnabled]=\"areMentionsEnabled\"\n [mentionScope]=\"mentionScope\"\n [inputMode]=\"inputMode\"\n [autoFocus]=\"autoFocus\"\n [placeholder]=\"textareaPlaceholder\"\n [(value)]=\"textareaValue\"\n (valueChange)=\"typingStart$.next()\"\n (send)=\"messageSent()\"\n (userMentions)=\"mentionedUsers = $event\"\n (pasteFromClipboard)=\"itemsPasted($event)\"\n ></ng-container>\n <ng-container *ngIf=\"emojiPickerTemplate\" data-testid=\"emoji-picker\">\n <ng-container\n *ngTemplateOutlet=\"\n emojiPickerTemplate;\n context: getEmojiPickerContext()\n \"\n ></ng-container>\n </ng-container>\n </div>\n </div>\n <button\n *ngIf=\"canSendMessages && !isCooldownInProgress && displaySendButton\"\n data-testid=\"send-button\"\n class=\"str-chat__send-button\"\n [disabled]=\"\n (attachmentUploadInProgressCounter$ | async)! > 0 ||\n (attachmentService.attachmentsCounter$ | async)! >\n attachmentService.maxNumberOfAttachments ||\n (!textareaValue &&\n (attachmentUploads$ | async)!.length === 0 &&\n (customAttachments$ | async)!.length === 0)\n \"\n (click)=\"messageSent()\"\n (keyup.enter)=\"messageSent()\"\n >\n <stream-icon-placeholder icon=\"send\"></stream-icon-placeholder>\n </button>\n <div\n *ngIf=\"isCooldownInProgress\"\n class=\"str-chat__message-input-cooldown\"\n data-testid=\"cooldown-timer\"\n >\n {{ cooldown$ | async }}\n </div>\n <button\n *ngIf=\"displayVoiceRecordingButton\"\n class=\"str-chat__start-recording-audio-button\"\n data-testid=\"start-voice-recording\"\n [disabled]=\"\n voiceRecorderService.isRecorderVisible$.value ||\n audioRecorder?.isRecording ||\n (attachmentService.attachmentsCounter$ | async)! >=\n attachmentService.maxNumberOfAttachments\n \"\n (click)=\"startVoiceRecording()\"\n (keyup.enter)=\"startVoiceRecording()\"\n >\n <stream-icon-placeholder icon=\"mic\"></stream-icon-placeholder>\n </button>\n <ng-content select=\"[message-input-end]\"></ng-content>\n </div>\n </ng-container>\n <ng-template #notAllowed>\n <div\n class=\"str-chat__message-input-not-allowed\"\n data-testid=\"disabled-textarea\"\n >\n {{ disabledTextareaText | translate }}\n </div>\n </ng-template>\n</div>\n<ng-template\n *ngIf=\"voiceRecorderRef\"\n [ngTemplateOutlet]=\"voiceRecorderRef\"\n [ngTemplateOutletContext]=\"{ service: voiceRecorderService }\"\n></ng-template>\n<ng-template\n *ngIf=\"\n isComposerOpen && (customTemplatesService.pollComposerTemplate$ | async)\n \"\n [ngTemplateOutlet]=\"(customTemplatesService.pollComposerTemplate$ | async)!\"\n [ngTemplateOutletContext]=\"{\n pollCompose: addPoll,\n cancel: closePollComposer\n }\"\n></ng-template>\n", dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: AvatarPlaceholderComponent, selector: "stream-avatar-placeholder", inputs: ["name", "imageUrl", "location", "channel", "user", "type", "initialsType", "showOnlineIndicator"] }, { kind: "component", type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon"] }, { kind: "component", type: AttachmentListComponent, selector: "stream-attachment-list", inputs: ["messageId", "parentMessageId", "attachments"], outputs: ["imageModalStateChange"] }, { kind: "component", type: AttachmentPreviewListComponent, selector: "stream-attachment-preview-list", inputs: ["attachmentUploads$"], outputs: ["retryAttachmentUpload", "deleteAttachment"] }, { kind: "directive", type: TextareaDirective, selector: "[streamTextarea]", inputs: ["componentRef", "areMentionsEnabled", "mentionScope", "inputMode", "value", "placeholder", "autoFocus"], outputs: ["valueChange", "send", "userMentions", "pasteFromClipboard"] }, { kind: "component", type: MessageTextComponent, selector: "stream-message-text", inputs: ["message", "isQuoted", "shouldTranslate"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.TranslatePipe, name: "translate" }] });
7121
7223
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: MessageInputComponent, decorators: [{
7122
7224
  type: Component,
7123
- args: [{ selector: 'stream-message-input', providers: [AttachmentService, EmojiInputService, VoiceRecorderService], template: "<div\n class=\"str-chat__message-input str-chat-angular__message-input\"\n [style.display]=\"isVoiceRecording ? 'none' : 'flex'\"\n>\n <div *ngIf=\"quotedMessage\" class=\"str-chat__quoted-message-preview-header\">\n <div class=\"str-chat__quoted-message-reply-to-message\">\n {{ \"streamChat.Reply to Message\" | translate }}\n </div>\n <button\n class=\"str-chat__quoted-message-remove\"\n data-testid=\"remove-quote\"\n (click)=\"deselectMessageToQuote()\"\n (keyup.enter)=\"deselectMessageToQuote()\"\n >\n <stream-icon-placeholder icon=\"close\"></stream-icon-placeholder>\n </button>\n </div>\n <div *ngIf=\"isUpdate\" class=\"str-chat__quoted-message-preview-header\">\n <div class=\"str-chat__quoted-message-reply-to-message\">\n {{ \"streamChat.Edit Message\" | translate }}\n </div>\n <button\n class=\"str-chat__quoted-message-remove\"\n data-testid=\"remove-quote\"\n (click)=\"deselectMessageToEdit()\"\n (keyup.enter)=\"deselectMessageToEdit()\"\n >\n <stream-icon-placeholder icon=\"close\"></stream-icon-placeholder>\n </button>\n </div>\n <ng-container *ngIf=\"canSendMessages; else notAllowed\">\n <div\n class=\"str-chat__message-input-inner str-chat-angular__message-input-inner\"\n >\n <ng-content select=\"[message-input-start]\"></ng-content>\n <ng-container\n *ngIf=\"isFileUploadEnabled && isFileUploadAuthorized && canSendMessages\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n customAttachmentUploadTemplate || defaultAttachmentUpload;\n context: getAttachmentUploadContext()\n \"\n ></ng-container>\n <ng-template #defaultAttachmentUpload>\n <div\n class=\"str-chat__file-input-container\"\n data-testid=\"file-upload-button\"\n >\n <input\n #fileInput\n type=\"file\"\n class=\"str-chat__file-input\"\n data-testid=\"file-input\"\n [multiple]=\"isMultipleFileUploadEnabled\"\n id=\"{{ fileInputId }}\"\n [disabled]=\"\n (attachmentService.attachmentsCounter$ | async)! >=\n attachmentService.maxNumberOfAttachments\n \"\n (change)=\"filesSelected(fileInput.files)\"\n />\n <label class=\"str-chat__file-input-label\" for=\"{{ fileInputId }}\">\n <stream-icon-placeholder icon=\"attach\"></stream-icon-placeholder>\n </label>\n </div>\n </ng-template>\n </ng-container>\n <div class=\"str-chat__message-textarea-container\">\n <div\n *ngIf=\"quotedMessage\"\n data-testid=\"quoted-message-container\"\n class=\"str-chat__quoted-message-preview\"\n >\n <stream-avatar-placeholder\n data-testid=\"qouted-message-avatar\"\n class=\"str-chat-angular__avatar-host str-chat__message-sender-avatar\"\n type=\"user\"\n location=\"quoted-message-sender\"\n [imageUrl]=\"quotedMessage.user?.image\"\n [name]=\"quotedMessage.user?.name || quotedMessage.user?.id\"\n [user]=\"quotedMessage.user || undefined\"\n ></stream-avatar-placeholder>\n <div\n class=\"quoted-message-preview-content-inner str-chat__quoted-message-bubble\"\n >\n <stream-attachment-list\n *ngIf=\"\n quotedMessage?.attachments && quotedMessage?.attachments?.length\n \"\n [attachments]=\"quotedMessageAttachments\"\n [messageId]=\"quotedMessage.id\"\n ></stream-attachment-list>\n <div class=\"str-chat__quoted-message-text\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.messageTextTemplate$ | async) ||\n defaultText;\n context: getQuotedMessageTextContext()\n \"\n ></ng-container>\n <ng-template\n #defaultText\n let-message=\"message\"\n let-isQuoted=\"isQuoted\"\n let-shouldTranslate=\"shouldTranslate\"\n >\n <stream-message-text\n [message]=\"message\"\n [isQuoted]=\"isQuoted\"\n [shouldTranslate]=\"shouldTranslate\"\n data-testid=\"quoted-message-text\"\n ></stream-message-text>\n </ng-template>\n </div>\n </div>\n </div>\n <ng-template\n #defaultAttachmentsPreview\n let-attachmentUploads$=\"attachmentUploads$\"\n let-retryUploadHandler=\"retryUploadHandler\"\n let-deleteUploadHandler=\"deleteUploadHandler\"\n >\n <stream-attachment-preview-list\n class=\"str-chat__attachment-preview-list-angular-host\"\n [attachmentUploads$]=\"attachmentUploads$\"\n (retryAttachmentUpload)=\"retryUploadHandler($event)\"\n (deleteAttachment)=\"deleteUploadHandler($event)\"\n ></stream-attachment-preview-list>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n attachmentPreviewListTemplate || defaultAttachmentsPreview;\n context: getAttachmentPreviewListContext()\n \"\n ></ng-container>\n <div class=\"str-chat__message-textarea-with-emoji-picker\">\n <ng-container\n streamTextarea\n [componentRef]=\"textareaRef\"\n [areMentionsEnabled]=\"areMentionsEnabled\"\n [mentionScope]=\"mentionScope\"\n [inputMode]=\"inputMode\"\n [autoFocus]=\"autoFocus\"\n [placeholder]=\"textareaPlaceholder\"\n [(value)]=\"textareaValue\"\n (valueChange)=\"typingStart$.next()\"\n (send)=\"messageSent()\"\n (userMentions)=\"mentionedUsers = $event\"\n (pasteFromClipboard)=\"itemsPasted($event)\"\n ></ng-container>\n <ng-container *ngIf=\"emojiPickerTemplate\" data-testid=\"emoji-picker\">\n <ng-container\n *ngTemplateOutlet=\"\n emojiPickerTemplate;\n context: getEmojiPickerContext()\n \"\n ></ng-container>\n </ng-container>\n </div>\n </div>\n <button\n *ngIf=\"canSendMessages && !isCooldownInProgress && displaySendButton\"\n data-testid=\"send-button\"\n class=\"str-chat__send-button\"\n [disabled]=\"\n (attachmentUploadInProgressCounter$ | async)! > 0 ||\n (attachmentService.attachmentsCounter$ | async)! >\n attachmentService.maxNumberOfAttachments ||\n (!textareaValue &&\n (attachmentUploads$ | async)!.length === 0 &&\n (customAttachments$ | async)!.length === 0)\n \"\n (click)=\"messageSent()\"\n (keyup.enter)=\"messageSent()\"\n >\n <stream-icon-placeholder icon=\"send\"></stream-icon-placeholder>\n </button>\n <div\n *ngIf=\"isCooldownInProgress\"\n class=\"str-chat__message-input-cooldown\"\n data-testid=\"cooldown-timer\"\n >\n {{ cooldown$ | async }}\n </div>\n <button\n *ngIf=\"displayVoiceRecordingButton\"\n class=\"str-chat__start-recording-audio-button\"\n data-testid=\"start-voice-recording\"\n [disabled]=\"\n voiceRecorderService.isRecorderVisible$.value ||\n audioRecorder?.isRecording ||\n (attachmentService.attachmentsCounter$ | async)! >=\n attachmentService.maxNumberOfAttachments\n \"\n (click)=\"startVoiceRecording()\"\n (keyup.enter)=\"startVoiceRecording()\"\n >\n <stream-icon-placeholder icon=\"mic\"></stream-icon-placeholder>\n </button>\n <ng-content select=\"[message-input-end]\"></ng-content>\n </div>\n </ng-container>\n <ng-template #notAllowed>\n <div\n class=\"str-chat__message-input-not-allowed\"\n data-testid=\"disabled-textarea\"\n >\n {{ disabledTextareaText | translate }}\n </div>\n </ng-template>\n</div>\n<ng-template\n *ngIf=\"voiceRecorderRef\"\n [ngTemplateOutlet]=\"voiceRecorderRef\"\n [ngTemplateOutletContext]=\"{ service: voiceRecorderService }\"\n></ng-template>\n" }]
7225
+ args: [{ selector: 'stream-message-input', providers: [AttachmentService, EmojiInputService, VoiceRecorderService], template: "<div\n class=\"str-chat__message-input str-chat-angular__message-input\"\n [style.display]=\"isVoiceRecording ? 'none' : 'flex'\"\n>\n <div *ngIf=\"quotedMessage\" class=\"str-chat__quoted-message-preview-header\">\n <div class=\"str-chat__quoted-message-reply-to-message\">\n {{ \"streamChat.Reply to Message\" | translate }}\n </div>\n <button\n class=\"str-chat__quoted-message-remove\"\n data-testid=\"remove-quote\"\n (click)=\"deselectMessageToQuote()\"\n (keyup.enter)=\"deselectMessageToQuote()\"\n >\n <stream-icon-placeholder icon=\"close\"></stream-icon-placeholder>\n </button>\n </div>\n <div *ngIf=\"isUpdate\" class=\"str-chat__quoted-message-preview-header\">\n <div class=\"str-chat__quoted-message-reply-to-message\">\n {{ \"streamChat.Edit Message\" | translate }}\n </div>\n <button\n class=\"str-chat__quoted-message-remove\"\n data-testid=\"remove-quote\"\n (click)=\"deselectMessageToEdit()\"\n (keyup.enter)=\"deselectMessageToEdit()\"\n >\n <stream-icon-placeholder icon=\"close\"></stream-icon-placeholder>\n </button>\n </div>\n <ng-container *ngIf=\"canSendMessages; else notAllowed\">\n <div\n class=\"str-chat__message-input-inner str-chat-angular__message-input-inner\"\n >\n <ng-content select=\"[message-input-start]\"></ng-content>\n <ng-container\n *ngIf=\"isFileUploadEnabled && isFileUploadAuthorized && canSendMessages\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n customAttachmentUploadTemplate || defaultAttachmentUpload;\n context: getAttachmentUploadContext()\n \"\n ></ng-container>\n <ng-template #defaultAttachmentUpload>\n <div\n class=\"str-chat__file-input-container\"\n data-testid=\"file-upload-button\"\n >\n <input\n #fileInput\n type=\"file\"\n class=\"str-chat__file-input\"\n data-testid=\"file-input\"\n [multiple]=\"isMultipleFileUploadEnabled\"\n id=\"{{ fileInputId }}\"\n [disabled]=\"\n (attachmentService.attachmentsCounter$ | async)! >=\n attachmentService.maxNumberOfAttachments\n \"\n (change)=\"filesSelected(fileInput.files)\"\n />\n <label class=\"str-chat__file-input-label\" for=\"{{ fileInputId }}\">\n <stream-icon-placeholder icon=\"attach\"></stream-icon-placeholder>\n </label>\n </div>\n </ng-template>\n </ng-container>\n <ng-container\n *ngIf=\"canSendPolls && displayPollCreateButton && mode !== 'thread'\"\n >\n <button\n class=\"str-chat-angular__create-poll\"\n (click)=\"openPollComposer()\"\n >\n <stream-icon-placeholder icon=\"poll\"></stream-icon-placeholder>\n </button>\n </ng-container>\n <div class=\"str-chat__message-textarea-container\">\n <div\n *ngIf=\"quotedMessage\"\n data-testid=\"quoted-message-container\"\n class=\"str-chat__quoted-message-preview\"\n >\n <stream-avatar-placeholder\n data-testid=\"qouted-message-avatar\"\n class=\"str-chat-angular__avatar-host str-chat__message-sender-avatar\"\n type=\"user\"\n location=\"quoted-message-sender\"\n [imageUrl]=\"quotedMessage.user?.image\"\n [name]=\"quotedMessage.user?.name || quotedMessage.user?.id\"\n [user]=\"quotedMessage.user || undefined\"\n ></stream-avatar-placeholder>\n <div\n class=\"quoted-message-preview-content-inner str-chat__quoted-message-bubble\"\n >\n <stream-attachment-list\n *ngIf=\"\n quotedMessage?.attachments && quotedMessage?.attachments?.length\n \"\n [attachments]=\"quotedMessageAttachments\"\n [messageId]=\"quotedMessage.id\"\n ></stream-attachment-list>\n <ng-container\n *ngIf=\"\n quotedMessage?.poll_id &&\n (customTemplatesService.pollTemplate$ | async)\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.pollTemplate$ | async)!;\n context: {\n pollId: quotedMessage?.poll_id,\n messageId: quotedMessage?.id,\n isQuote: true\n }\n \"\n ></ng-container>\n </ng-container>\n <div class=\"str-chat__quoted-message-text\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.messageTextTemplate$ | async) ||\n defaultText;\n context: getQuotedMessageTextContext()\n \"\n ></ng-container>\n <ng-template\n #defaultText\n let-message=\"message\"\n let-isQuoted=\"isQuoted\"\n let-shouldTranslate=\"shouldTranslate\"\n >\n <stream-message-text\n [message]=\"message\"\n [isQuoted]=\"isQuoted\"\n [shouldTranslate]=\"shouldTranslate\"\n data-testid=\"quoted-message-text\"\n ></stream-message-text>\n </ng-template>\n </div>\n </div>\n </div>\n <ng-template\n #defaultAttachmentsPreview\n let-attachmentUploads$=\"attachmentUploads$\"\n let-retryUploadHandler=\"retryUploadHandler\"\n let-deleteUploadHandler=\"deleteUploadHandler\"\n >\n <stream-attachment-preview-list\n class=\"str-chat__attachment-preview-list-angular-host\"\n [attachmentUploads$]=\"attachmentUploads$\"\n (retryAttachmentUpload)=\"retryUploadHandler($event)\"\n (deleteAttachment)=\"deleteUploadHandler($event)\"\n ></stream-attachment-preview-list>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n attachmentPreviewListTemplate || defaultAttachmentsPreview;\n context: getAttachmentPreviewListContext()\n \"\n ></ng-container>\n <div class=\"str-chat__message-textarea-with-emoji-picker\">\n <ng-container\n streamTextarea\n [componentRef]=\"textareaRef\"\n [areMentionsEnabled]=\"areMentionsEnabled\"\n [mentionScope]=\"mentionScope\"\n [inputMode]=\"inputMode\"\n [autoFocus]=\"autoFocus\"\n [placeholder]=\"textareaPlaceholder\"\n [(value)]=\"textareaValue\"\n (valueChange)=\"typingStart$.next()\"\n (send)=\"messageSent()\"\n (userMentions)=\"mentionedUsers = $event\"\n (pasteFromClipboard)=\"itemsPasted($event)\"\n ></ng-container>\n <ng-container *ngIf=\"emojiPickerTemplate\" data-testid=\"emoji-picker\">\n <ng-container\n *ngTemplateOutlet=\"\n emojiPickerTemplate;\n context: getEmojiPickerContext()\n \"\n ></ng-container>\n </ng-container>\n </div>\n </div>\n <button\n *ngIf=\"canSendMessages && !isCooldownInProgress && displaySendButton\"\n data-testid=\"send-button\"\n class=\"str-chat__send-button\"\n [disabled]=\"\n (attachmentUploadInProgressCounter$ | async)! > 0 ||\n (attachmentService.attachmentsCounter$ | async)! >\n attachmentService.maxNumberOfAttachments ||\n (!textareaValue &&\n (attachmentUploads$ | async)!.length === 0 &&\n (customAttachments$ | async)!.length === 0)\n \"\n (click)=\"messageSent()\"\n (keyup.enter)=\"messageSent()\"\n >\n <stream-icon-placeholder icon=\"send\"></stream-icon-placeholder>\n </button>\n <div\n *ngIf=\"isCooldownInProgress\"\n class=\"str-chat__message-input-cooldown\"\n data-testid=\"cooldown-timer\"\n >\n {{ cooldown$ | async }}\n </div>\n <button\n *ngIf=\"displayVoiceRecordingButton\"\n class=\"str-chat__start-recording-audio-button\"\n data-testid=\"start-voice-recording\"\n [disabled]=\"\n voiceRecorderService.isRecorderVisible$.value ||\n audioRecorder?.isRecording ||\n (attachmentService.attachmentsCounter$ | async)! >=\n attachmentService.maxNumberOfAttachments\n \"\n (click)=\"startVoiceRecording()\"\n (keyup.enter)=\"startVoiceRecording()\"\n >\n <stream-icon-placeholder icon=\"mic\"></stream-icon-placeholder>\n </button>\n <ng-content select=\"[message-input-end]\"></ng-content>\n </div>\n </ng-container>\n <ng-template #notAllowed>\n <div\n class=\"str-chat__message-input-not-allowed\"\n data-testid=\"disabled-textarea\"\n >\n {{ disabledTextareaText | translate }}\n </div>\n </ng-template>\n</div>\n<ng-template\n *ngIf=\"voiceRecorderRef\"\n [ngTemplateOutlet]=\"voiceRecorderRef\"\n [ngTemplateOutletContext]=\"{ service: voiceRecorderService }\"\n></ng-template>\n<ng-template\n *ngIf=\"\n isComposerOpen && (customTemplatesService.pollComposerTemplate$ | async)\n \"\n [ngTemplateOutlet]=\"(customTemplatesService.pollComposerTemplate$ | async)!\"\n [ngTemplateOutletContext]=\"{\n pollCompose: addPoll,\n cancel: closePollComposer\n }\"\n></ng-template>\n" }]
7124
7226
  }], ctorParameters: function () {
7125
7227
  return [{ type: ChannelService }, { type: NotificationService }, { type: AttachmentService }, { type: MessageInputConfigService }, { type: i0.Type, decorators: [{
7126
7228
  type: Inject,
@@ -7152,6 +7254,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImpor
7152
7254
  type: Input
7153
7255
  }], displayVoiceRecordingButton: [{
7154
7256
  type: Input
7257
+ }], displayPollCreateButton: [{
7258
+ type: Input
7155
7259
  }], messageUpdate: [{
7156
7260
  type: Output
7157
7261
  }], voiceRecorderRef: [{
@@ -7583,7 +7687,7 @@ class AutocompleteTextareaComponent {
7583
7687
  }
7584
7688
  }
7585
7689
  AutocompleteTextareaComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: AutocompleteTextareaComponent, deps: [{ token: ChannelService }, { token: ChatClientService }, { token: TransliterationService }, { token: EmojiInputService }, { token: CustomTemplatesService }, { token: i0.ChangeDetectorRef }, { token: MessageInputConfigService }], target: i0.ɵɵFactoryTarget.Component });
7586
- AutocompleteTextareaComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: AutocompleteTextareaComponent, selector: "stream-autocomplete-textarea", inputs: { value: "value", placeholder: "placeholder", areMentionsEnabled: "areMentionsEnabled", inputMode: "inputMode", mentionScope: "mentionScope", autoFocus: "autoFocus" }, outputs: { valueChange: "valueChange", send: "send", userMentions: "userMentions", pasteFromClipboard: "pasteFromClipboard" }, host: { properties: { "class": "this.class" } }, viewQueries: [{ propertyName: "messageInput", first: true, predicate: ["input"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<textarea\n #input\n data-testid=\"textarea\"\n class=\"rta__textarea str-chat__textarea__textarea str-chat__angular-textarea str-chat__message-textarea\"\n rows=\"1\"\n [value]=\"value || ''\"\n [autofocus]=\"autoFocus\"\n placeholder=\"{{ placeholder | translate }}\"\n [mentionConfig]=\"autocompleteConfig\"\n [mentionListTemplate]=\"autocompleteItem\"\n (input)=\"inputChanged()\"\n (keydown.enter)=\"enterHit($event)\"\n (searchTerm)=\"autcompleteSearchTermChanged($event)\"\n (blur)=\"inputLeft()\"\n (paste)=\"pasteFromClipboard.emit($event)\"\n></textarea>\n<ng-template #autocompleteItem let-item=\"item\">\n <ng-container *ngIf=\"item.templateRef; else builtinItem\">\n <ng-container\n *ngTemplateOutlet=\"item.templateRef; context: { item: item }\"\n ></ng-container>\n </ng-container>\n <ng-template #builtinItem>\n <div\n class=\"rta rta__item str-chat__emojisearch__item\"\n [ngSwitch]=\"item.type\"\n >\n <div *ngSwitchCase=\"'mention'\" class=\"rta__entity\">\n <ng-container\n *ngTemplateOutlet=\"\n mentionAutocompleteItemTemplate || defaultMentionTemplate;\n context: { item: item }\n \"\n ></ng-container>\n </div>\n <div *ngSwitchCase=\"'command'\" class=\"rta__entity\">\n <ng-container\n *ngTemplateOutlet=\"\n commandAutocompleteItemTemplate || defaultCommandTemplate;\n context: { item: item }\n \"\n ></ng-container>\n </div>\n </div>\n </ng-template>\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\n class=\"str-chat__slash-command-name\"\n data-testclass=\"command-name\"\n >{{ item.name }}</strong\n >\n <span class=\"str-chat__slash-command-args\"\n >/{{ item.name }} {{ item.args }}</span\n >\n </span>\n <br />\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 type=\"user\"\n location=\"autocomplete-item\"\n [imageUrl]=\"item.image || item.user?.image\"\n [name]=\"item.autocompleteLabel\"\n [user]=\"item.user || item\"\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", dependencies: [{ kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i3.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i3.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i8$1.MentionDirective, selector: "[mention], [mentionConfig]", inputs: ["mentionConfig", "mention", "mentionListTemplate"], outputs: ["searchTerm", "itemSelected", "opened", "closed"] }, { kind: "component", type: AvatarPlaceholderComponent, selector: "stream-avatar-placeholder", inputs: ["name", "imageUrl", "location", "channel", "user", "type", "initialsType", "showOnlineIndicator"] }, { kind: "pipe", type: i6.TranslatePipe, name: "translate" }] });
7690
+ AutocompleteTextareaComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: AutocompleteTextareaComponent, selector: "stream-autocomplete-textarea", inputs: { value: "value", placeholder: "placeholder", areMentionsEnabled: "areMentionsEnabled", inputMode: "inputMode", mentionScope: "mentionScope", autoFocus: "autoFocus" }, outputs: { valueChange: "valueChange", send: "send", userMentions: "userMentions", pasteFromClipboard: "pasteFromClipboard" }, host: { properties: { "class": "this.class" } }, viewQueries: [{ propertyName: "messageInput", first: true, predicate: ["input"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<textarea\n #input\n data-testid=\"textarea\"\n class=\"rta__textarea str-chat__textarea__textarea str-chat__angular-textarea str-chat__message-textarea\"\n rows=\"1\"\n [value]=\"value || ''\"\n [autofocus]=\"autoFocus\"\n placeholder=\"{{ placeholder | translate }}\"\n [mentionConfig]=\"autocompleteConfig\"\n [mentionListTemplate]=\"autocompleteItem\"\n (input)=\"inputChanged()\"\n (keydown.enter)=\"enterHit($event)\"\n (searchTerm)=\"autcompleteSearchTermChanged($event)\"\n (blur)=\"inputLeft()\"\n (paste)=\"pasteFromClipboard.emit($event)\"\n></textarea>\n<ng-template #autocompleteItem let-item=\"item\">\n <ng-container *ngIf=\"item.templateRef; else builtinItem\">\n <ng-container\n *ngTemplateOutlet=\"item.templateRef; context: { item: item }\"\n ></ng-container>\n </ng-container>\n <ng-template #builtinItem>\n <div\n class=\"rta rta__item str-chat__emojisearch__item\"\n [ngSwitch]=\"item.type\"\n >\n <div *ngSwitchCase=\"'mention'\" class=\"rta__entity\">\n <ng-container\n *ngTemplateOutlet=\"\n mentionAutocompleteItemTemplate || defaultMentionTemplate;\n context: { item: item }\n \"\n ></ng-container>\n </div>\n <div *ngSwitchCase=\"'command'\" class=\"rta__entity\">\n <ng-container\n *ngTemplateOutlet=\"\n commandAutocompleteItemTemplate || defaultCommandTemplate;\n context: { item: item }\n \"\n ></ng-container>\n </div>\n </div>\n </ng-template>\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\n class=\"str-chat__slash-command-name\"\n data-testclass=\"command-name\"\n >{{ item.name }}</strong\n >\n <span class=\"str-chat__slash-command-args\"\n >/{{ item.name }} {{ item.args }}</span\n >\n </span>\n <br />\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 type=\"user\"\n location=\"autocomplete-item\"\n [imageUrl]=\"item.image || item.user?.image\"\n [name]=\"item.autocompleteLabel\"\n [user]=\"item.user || item\"\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", dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i8$1.MentionDirective, selector: "[mention], [mentionConfig]", inputs: ["mentionConfig", "mention", "mentionListTemplate"], outputs: ["searchTerm", "itemSelected", "opened", "closed"] }, { kind: "component", type: AvatarPlaceholderComponent, selector: "stream-avatar-placeholder", inputs: ["name", "imageUrl", "location", "channel", "user", "type", "initialsType", "showOnlineIndicator"] }, { kind: "pipe", type: i6.TranslatePipe, name: "translate" }] });
7587
7691
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: AutocompleteTextareaComponent, decorators: [{
7588
7692
  type: Component,
7589
7693
  args: [{ selector: 'stream-autocomplete-textarea', template: "<textarea\n #input\n data-testid=\"textarea\"\n class=\"rta__textarea str-chat__textarea__textarea str-chat__angular-textarea str-chat__message-textarea\"\n rows=\"1\"\n [value]=\"value || ''\"\n [autofocus]=\"autoFocus\"\n placeholder=\"{{ placeholder | translate }}\"\n [mentionConfig]=\"autocompleteConfig\"\n [mentionListTemplate]=\"autocompleteItem\"\n (input)=\"inputChanged()\"\n (keydown.enter)=\"enterHit($event)\"\n (searchTerm)=\"autcompleteSearchTermChanged($event)\"\n (blur)=\"inputLeft()\"\n (paste)=\"pasteFromClipboard.emit($event)\"\n></textarea>\n<ng-template #autocompleteItem let-item=\"item\">\n <ng-container *ngIf=\"item.templateRef; else builtinItem\">\n <ng-container\n *ngTemplateOutlet=\"item.templateRef; context: { item: item }\"\n ></ng-container>\n </ng-container>\n <ng-template #builtinItem>\n <div\n class=\"rta rta__item str-chat__emojisearch__item\"\n [ngSwitch]=\"item.type\"\n >\n <div *ngSwitchCase=\"'mention'\" class=\"rta__entity\">\n <ng-container\n *ngTemplateOutlet=\"\n mentionAutocompleteItemTemplate || defaultMentionTemplate;\n context: { item: item }\n \"\n ></ng-container>\n </div>\n <div *ngSwitchCase=\"'command'\" class=\"rta__entity\">\n <ng-container\n *ngTemplateOutlet=\"\n commandAutocompleteItemTemplate || defaultCommandTemplate;\n context: { item: item }\n \"\n ></ng-container>\n </div>\n </div>\n </ng-template>\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\n class=\"str-chat__slash-command-name\"\n data-testclass=\"command-name\"\n >{{ item.name }}</strong\n >\n <span class=\"str-chat__slash-command-args\"\n >/{{ item.name }} {{ item.args }}</span\n >\n </span>\n <br />\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 type=\"user\"\n location=\"autocomplete-item\"\n [imageUrl]=\"item.image || item.user?.image\"\n [name]=\"item.autocompleteLabel\"\n [user]=\"item.user || item\"\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" }]
@@ -8698,7 +8802,7 @@ class MessageListComponent {
8698
8802
  }
8699
8803
  }
8700
8804
  MessageListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: MessageListComponent, deps: [{ token: ChannelService }, { token: ChatClientService }, { token: CustomTemplatesService }, { token: DateParserService }, { token: i0.NgZone }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
8701
- MessageListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: MessageListComponent, selector: "stream-message-list", inputs: { mode: "mode", direction: "direction", hideJumpToLatestButtonDuringScroll: "hideJumpToLatestButtonDuringScroll", displayDateSeparator: "displayDateSeparator", displayUnreadSeparator: "displayUnreadSeparator", dateSeparatorTextPos: "dateSeparatorTextPos", openMessageListAt: "openMessageListAt", hideUnreadCountForNotificationAndIndicator: "hideUnreadCountForNotificationAndIndicator", displayLoadingIndicator: "displayLoadingIndicator" }, host: { properties: { "class": "this.class" } }, viewQueries: [{ propertyName: "scrollContainer", first: true, predicate: ["scrollContainer"], descendants: true }, { propertyName: "parentMessageElement", first: true, predicate: ["parentMessageElement"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<ng-container\n *ngIf=\"\n lastReadMessageId &&\n isUnreadNotificationVisible &&\n openMessageListAt === 'last-message' &&\n displayUnreadSeparator\n \"\n>\n <ng-container\n *ngTemplateOutlet=\"\n customnewMessagesNotificationTemplate ||\n defaultUnreadMessagesNotification;\n context: {\n unreadCount: unreadCount,\n onDismiss: messageNotificationDismissClicked,\n onJump: messageNotificationJumpClicked\n }\n \"\n ></ng-container>\n</ng-container>\n<ng-template\n #defaultUnreadMessagesNotification\n let-unreadCount=\"unreadCount\"\n let-onDismiss=\"onDismiss\"\n let-onJump=\"onJump\"\n>\n <div\n class=\"str-chat__unread-messages-notification\"\n data-testid=\"unread-messages-notification\"\n >\n <button\n data-testid=\"unread-messages-notification-jump-to-message\"\n (click)=\"onJump()\"\n >\n <ng-container\n *ngIf=\"\n unreadCount > 0 && !hideUnreadCountForNotificationAndIndicator;\n else noUnreadCount\n \"\n >\n {{\n (unreadCount === 1\n ? \"streamChat.\\{\\{count\\}\\} unread message\"\n : \"streamChat.\\{\\{count\\}\\} unread messages\"\n ) | translate : { count: unreadCount }\n }}\n </ng-container>\n <ng-template #noUnreadCount>\n {{ \"streamChat.Unread messages\" | translate }}\n </ng-template>\n </button>\n <button\n data-testid=\"unread-messages-notification-dismiss\"\n (click)=\"onDismiss()\"\n >\n <stream-icon-placeholder icon=\"close\"></stream-icon-placeholder>\n </button>\n </div>\n</ng-template>\n<div #scrollContainer data-testid=\"scroll-container\" class=\"str-chat__list\">\n <ng-container *ngIf=\"mode === 'main' && isEmpty && emptyListTemplate\">\n <ng-container *ngTemplateOutlet=\"emptyListTemplate\"></ng-container>\n </ng-container>\n <div class=\"str-chat__reverse-infinite-scroll str-chat__message-list-scroll\">\n <ul class=\"str-chat__ul\">\n <li\n *ngIf=\"mode === 'thread' && parentMessage\"\n #parentMessageElement\n data-testid=\"parent-message\"\n class=\"str-chat__parent-message-li\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n messageTemplateContainer;\n context: { message: parentMessage, index: 'parent' }\n \"\n ></ng-container>\n <div data-testid=\"reply-count\" class=\"str-chat__thread-start\">\n {{parentMessage.reply_count === 1 ? ('streamChat.1 reply' | translate) : ('streamChat.{{ replyCount }}\n replies' | translate:replyCountParam)}}\n </div>\n </li>\n <ng-container *ngIf=\"mode === 'thread' && isEmpty && emptyListTemplate\">\n <ng-container *ngTemplateOutlet=\"emptyListTemplate\"></ng-container>\n </ng-container>\n <stream-loading-indicator-placeholder\n *ngIf=\"\n ((loadingState === 'loading-top' && direction === 'bottom-to-top') ||\n (loadingState === 'loading-bottom' &&\n direction === 'top-to-bottom')) &&\n displayLoadingIndicator;\n else loadingIndicatorPlaceholder\n \"\n data-testid=\"top-loading-indicator\"\n ></stream-loading-indicator-placeholder>\n <ng-container *ngIf=\"messages$ | async as messages\">\n <ng-container\n *ngFor=\"\n let message of messages;\n let i = index;\n let isFirst = first;\n let isLast = last;\n trackBy: trackByMessageId\n \"\n >\n <ng-container *ngIf=\"isFirst\">\n <ng-container\n *ngTemplateOutlet=\"\n dateSeparator;\n context: {\n date: message.created_at,\n parsedDate: parseDate(message.created_at)\n }\n \"\n ></ng-container>\n </ng-container>\n <li\n tabindex=\"0\"\n data-testclass=\"message\"\n class=\"str-chat__li str-chat__li--{{ groupStyles[i] }}\"\n id=\"{{ message.id }}\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n messageTemplateContainer;\n context: { message: message, index: i }\n \"\n ></ng-container>\n </li>\n <ng-container\n *ngIf=\"\n (lastReadMessageId === message?.id &&\n direction === 'bottom-to-top') ||\n (direction === 'top-to-bottom' &&\n lastReadMessageId === messages[i + 1]?.id)\n \"\n >\n <li\n *ngIf=\"displayUnreadSeparator\"\n id=\"stream-chat-new-message-indicator\"\n data-testid=\"new-messages-indicator\"\n class=\"str-chat__li str-chat__unread-messages-separator-wrapper\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n customnewMessagesIndicatorTemplate ||\n defaultNewMessagesIndicator;\n context: { unreadCount: unreadCount }\n \"\n ></ng-container>\n </li>\n </ng-container>\n <ng-container *ngIf=\"isNextMessageOnSeparateDate[i]\">\n <ng-container\n *ngTemplateOutlet=\"\n dateSeparator;\n context: {\n date: messages[i + 1].created_at,\n parsedDate: parseDate(messages[i + 1].created_at)\n }\n \"\n ></ng-container>\n </ng-container>\n </ng-container>\n </ng-container>\n <stream-loading-indicator-placeholder\n *ngIf=\"\n ((loadingState === 'loading-bottom' &&\n direction === 'bottom-to-top') ||\n (loadingState === 'loading-top' &&\n direction === 'top-to-bottom')) &&\n displayLoadingIndicator;\n else loadingIndicatorPlaceholder\n \"\n data-testid=\"bottom-loading-indicator\"\n ></stream-loading-indicator-placeholder>\n <ng-template #loadingIndicatorPlaceholder>\n <div class=\"str-chat__loading-indicator-placeholder\"></div>\n </ng-template>\n </ul>\n <ng-template #defaultTypingIndicator let-usersTyping$=\"usersTyping$\">\n <!-- eslint-disable-next-line @angular-eslint/template/no-any -->\n <ng-container *ngIf=\"$any(usersTyping$ | async) as users\">\n <div\n *ngIf=\"users.length > 0\"\n data-testid=\"typing-indicator\"\n class=\"str-chat__typing-indicator str-chat__typing-indicator--typing\"\n >\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 data-testid=\"typing-users\"\n class=\"str-chat__typing-indicator__users\"\n >\n {{\n users.length === 1\n ? (\"streamChat.user is typing\"\n | translate : { user: getTypingIndicatorText(users) })\n : (\"streamChat.users are typing\"\n | translate : { users: getTypingIndicatorText(users) })\n }}\n </div>\n </div>\n </ng-container>\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__jump-to-latest-message\">\n <button\n *ngIf=\"isUserScrolled && isJumpToLatestButtonVisible\"\n data-testid=\"scroll-to-latest\"\n class=\"str-chat__message-notification-scroll-to-latest str-chat__message-notification-scroll-to-latest-right str-chat__circle-fab\"\n (keyup.enter)=\"jumpToLatestMessage()\"\n (click)=\"jumpToLatestMessage()\"\n >\n <stream-icon\n class=\"str-chat__jump-to-latest-icon str-chat__circle-fab-icon\"\n [icon]=\"direction === 'bottom-to-top' ? 'arrow-down' : 'arrow-up'\"\n ></stream-icon>\n <div\n *ngIf=\"newMessageCountWhileBeingScrolled > 0\"\n class=\"str-chat__message-notification str-chat__message-notification-scroll-to-latest-unread-count str-chat__jump-to-latest-unread-count\"\n >\n {{ newMessageCountWhileBeingScrolled }}\n </div>\n </button>\n</div>\n\n<ng-template #messageTemplateContainer let-message=\"message\" let-index=\"index\">\n <ng-template\n #defaultMessageTemplate\n let-messageInput=\"message\"\n let-isLastSentMessage=\"isLastSentMessage\"\n let-enabledMessageActions=\"enabledMessageActions\"\n let-mode=\"mode\"\n let-isHighlighted=\"isHighlighted\"\n let-scroll$=\"scroll$\"\n >\n <stream-message\n [message]=\"messageInput\"\n [isLastSentMessage]=\"isLastSentMessage\"\n [enabledMessageActions]=\"enabledMessageActions\"\n [mode]=\"mode\"\n [isHighlighted]=\"isHighlighted\"\n [scroll$]=\"scroll$\"\n ></stream-message>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n messageTemplate || defaultMessageTemplate;\n context: {\n message: message,\n isLastSentMessage: !!(\n lastSentMessageId && message?.id === lastSentMessageId\n ),\n enabledMessageActions: enabledMessageActions,\n mode: mode,\n isHighlighted: message?.id === highlightedMessageId,\n scroll$: scroll$\n }\n \"\n ></ng-container>\n</ng-template>\n\n<ng-template #dateSeparator let-date=\"date\" let-parsedDate=\"parsedDate\">\n <ng-container *ngIf=\"displayDateSeparator\">\n <ng-container\n *ngTemplateOutlet=\"\n customDateSeparatorTemplate || defaultDateSeparator;\n context: {\n date: date,\n parsedDate: parsedDate\n }\n \"\n ></ng-container>\n </ng-container>\n\n <ng-template\n #defaultDateSeparator\n let-date=\"date\"\n let-parsedDate=\"parsedDate\"\n >\n <div data-testid=\"date-separator\" class=\"str-chat__date-separator\">\n <hr\n *ngIf=\"\n dateSeparatorTextPos === 'right' || dateSeparatorTextPos === 'center'\n \"\n class=\"str-chat__date-separator-line\"\n />\n <div class=\"str-chat__date-separator-date\">\n {{ parsedDate }}\n </div>\n <hr\n *ngIf=\"\n dateSeparatorTextPos === 'left' || dateSeparatorTextPos === 'center'\n \"\n class=\"str-chat__date-separator-line\"\n />\n </div>\n </ng-template>\n</ng-template>\n\n<ng-template #defaultNewMessagesIndicator let-unreadCount=\"unreadCount\">\n <div class=\"str-chat__unread-messages-separator\">\n <ng-container\n *ngIf=\"\n unreadCount > 0 && !hideUnreadCountForNotificationAndIndicator;\n else noUnreadCount\n \"\n >\n {{\n (unreadCount === 1\n ? \"streamChat.\\{\\{count\\}\\} unread message\"\n : \"streamChat.\\{\\{count\\}\\} unread messages\"\n ) | translate : { count: unreadCount }\n }}\n </ng-container>\n <ng-template #noUnreadCount>\n {{ \"streamChat.Unread messages\" | translate }}\n </ng-template>\n </div>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: IconComponent, selector: "stream-icon", inputs: ["icon"] }, { kind: "component", type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon"] }, { kind: "component", type: LoadingIndicatorPlaceholderComponent, selector: "stream-loading-indicator-placeholder" }, { kind: "component", type: MessageComponent, selector: "stream-message", inputs: ["message", "enabledMessageActions", "isLastSentMessage", "mode", "isHighlighted", "scroll$"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
8805
+ MessageListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: MessageListComponent, selector: "stream-message-list", inputs: { mode: "mode", direction: "direction", hideJumpToLatestButtonDuringScroll: "hideJumpToLatestButtonDuringScroll", displayDateSeparator: "displayDateSeparator", displayUnreadSeparator: "displayUnreadSeparator", dateSeparatorTextPos: "dateSeparatorTextPos", openMessageListAt: "openMessageListAt", hideUnreadCountForNotificationAndIndicator: "hideUnreadCountForNotificationAndIndicator", displayLoadingIndicator: "displayLoadingIndicator" }, host: { properties: { "class": "this.class" } }, viewQueries: [{ propertyName: "scrollContainer", first: true, predicate: ["scrollContainer"], descendants: true }, { propertyName: "parentMessageElement", first: true, predicate: ["parentMessageElement"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<ng-container\n *ngIf=\"\n lastReadMessageId &&\n isUnreadNotificationVisible &&\n openMessageListAt === 'last-message' &&\n displayUnreadSeparator\n \"\n>\n <ng-container\n *ngTemplateOutlet=\"\n customnewMessagesNotificationTemplate ||\n defaultUnreadMessagesNotification;\n context: {\n unreadCount: unreadCount,\n onDismiss: messageNotificationDismissClicked,\n onJump: messageNotificationJumpClicked\n }\n \"\n ></ng-container>\n</ng-container>\n<ng-template\n #defaultUnreadMessagesNotification\n let-unreadCount=\"unreadCount\"\n let-onDismiss=\"onDismiss\"\n let-onJump=\"onJump\"\n>\n <div\n class=\"str-chat__unread-messages-notification\"\n data-testid=\"unread-messages-notification\"\n >\n <button\n data-testid=\"unread-messages-notification-jump-to-message\"\n (click)=\"onJump()\"\n >\n <ng-container\n *ngIf=\"\n unreadCount > 0 && !hideUnreadCountForNotificationAndIndicator;\n else noUnreadCount\n \"\n >\n {{\n (unreadCount === 1\n ? \"streamChat.\\{\\{count\\}\\} unread message\"\n : \"streamChat.\\{\\{count\\}\\} unread messages\"\n ) | translate : { count: unreadCount }\n }}\n </ng-container>\n <ng-template #noUnreadCount>\n {{ \"streamChat.Unread messages\" | translate }}\n </ng-template>\n </button>\n <button\n data-testid=\"unread-messages-notification-dismiss\"\n (click)=\"onDismiss()\"\n >\n <stream-icon-placeholder icon=\"close\"></stream-icon-placeholder>\n </button>\n </div>\n</ng-template>\n<div #scrollContainer data-testid=\"scroll-container\" class=\"str-chat__list\">\n <ng-container *ngIf=\"mode === 'main' && isEmpty && emptyListTemplate\">\n <ng-container *ngTemplateOutlet=\"emptyListTemplate\"></ng-container>\n </ng-container>\n <div class=\"str-chat__reverse-infinite-scroll str-chat__message-list-scroll\">\n <ul class=\"str-chat__ul\">\n <li\n *ngIf=\"mode === 'thread' && parentMessage\"\n #parentMessageElement\n data-testid=\"parent-message\"\n class=\"str-chat__parent-message-li\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n messageTemplateContainer;\n context: { message: parentMessage, index: 'parent' }\n \"\n ></ng-container>\n <div data-testid=\"reply-count\" class=\"str-chat__thread-start\">\n {{parentMessage.reply_count === 1 ? ('streamChat.1 reply' | translate) : ('streamChat.{{ replyCount }}\n replies' | translate:replyCountParam)}}\n </div>\n </li>\n <ng-container *ngIf=\"mode === 'thread' && isEmpty && emptyListTemplate\">\n <ng-container *ngTemplateOutlet=\"emptyListTemplate\"></ng-container>\n </ng-container>\n <stream-loading-indicator-placeholder\n *ngIf=\"\n ((loadingState === 'loading-top' && direction === 'bottom-to-top') ||\n (loadingState === 'loading-bottom' &&\n direction === 'top-to-bottom')) &&\n displayLoadingIndicator;\n else loadingIndicatorPlaceholder\n \"\n data-testid=\"top-loading-indicator\"\n ></stream-loading-indicator-placeholder>\n <ng-container *ngIf=\"messages$ | async as messages\">\n <ng-container\n *ngFor=\"\n let message of messages;\n let i = index;\n let isFirst = first;\n let isLast = last;\n trackBy: trackByMessageId\n \"\n >\n <ng-container *ngIf=\"isFirst\">\n <ng-container\n *ngTemplateOutlet=\"\n dateSeparator;\n context: {\n date: message.created_at,\n parsedDate: parseDate(message.created_at)\n }\n \"\n ></ng-container>\n </ng-container>\n <li\n tabindex=\"0\"\n data-testclass=\"message\"\n class=\"str-chat__li str-chat__li--{{ groupStyles[i] }}\"\n id=\"{{ message.id }}\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n messageTemplateContainer;\n context: { message: message, index: i }\n \"\n ></ng-container>\n </li>\n <ng-container\n *ngIf=\"\n (lastReadMessageId === message?.id &&\n direction === 'bottom-to-top') ||\n (direction === 'top-to-bottom' &&\n lastReadMessageId === messages[i + 1]?.id)\n \"\n >\n <li\n *ngIf=\"displayUnreadSeparator\"\n id=\"stream-chat-new-message-indicator\"\n data-testid=\"new-messages-indicator\"\n class=\"str-chat__li str-chat__unread-messages-separator-wrapper\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n customnewMessagesIndicatorTemplate ||\n defaultNewMessagesIndicator;\n context: { unreadCount: unreadCount }\n \"\n ></ng-container>\n </li>\n </ng-container>\n <ng-container *ngIf=\"isNextMessageOnSeparateDate[i]\">\n <ng-container\n *ngTemplateOutlet=\"\n dateSeparator;\n context: {\n date: messages[i + 1].created_at,\n parsedDate: parseDate(messages[i + 1].created_at)\n }\n \"\n ></ng-container>\n </ng-container>\n </ng-container>\n </ng-container>\n <stream-loading-indicator-placeholder\n *ngIf=\"\n ((loadingState === 'loading-bottom' &&\n direction === 'bottom-to-top') ||\n (loadingState === 'loading-top' &&\n direction === 'top-to-bottom')) &&\n displayLoadingIndicator;\n else loadingIndicatorPlaceholder\n \"\n data-testid=\"bottom-loading-indicator\"\n ></stream-loading-indicator-placeholder>\n <ng-template #loadingIndicatorPlaceholder>\n <div class=\"str-chat__loading-indicator-placeholder\"></div>\n </ng-template>\n </ul>\n <ng-template #defaultTypingIndicator let-usersTyping$=\"usersTyping$\">\n <!-- eslint-disable-next-line @angular-eslint/template/no-any -->\n <ng-container *ngIf=\"$any(usersTyping$ | async) as users\">\n <div\n *ngIf=\"users.length > 0\"\n data-testid=\"typing-indicator\"\n class=\"str-chat__typing-indicator str-chat__typing-indicator--typing\"\n >\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 data-testid=\"typing-users\"\n class=\"str-chat__typing-indicator__users\"\n >\n {{\n users.length === 1\n ? (\"streamChat.user is typing\"\n | translate : { user: getTypingIndicatorText(users) })\n : (\"streamChat.users are typing\"\n | translate : { users: getTypingIndicatorText(users) })\n }}\n </div>\n </div>\n </ng-container>\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__jump-to-latest-message\">\n <button\n *ngIf=\"isUserScrolled && isJumpToLatestButtonVisible\"\n data-testid=\"scroll-to-latest\"\n class=\"str-chat__message-notification-scroll-to-latest str-chat__message-notification-scroll-to-latest-right str-chat__circle-fab\"\n (keyup.enter)=\"jumpToLatestMessage()\"\n (click)=\"jumpToLatestMessage()\"\n >\n <stream-icon\n class=\"str-chat__jump-to-latest-icon str-chat__circle-fab-icon\"\n [icon]=\"direction === 'bottom-to-top' ? 'arrow-down' : 'arrow-up'\"\n ></stream-icon>\n <div\n *ngIf=\"newMessageCountWhileBeingScrolled > 0\"\n class=\"str-chat__message-notification str-chat__message-notification-scroll-to-latest-unread-count str-chat__jump-to-latest-unread-count\"\n >\n {{ newMessageCountWhileBeingScrolled }}\n </div>\n </button>\n</div>\n\n<ng-template #messageTemplateContainer let-message=\"message\" let-index=\"index\">\n <ng-template\n #defaultMessageTemplate\n let-messageInput=\"message\"\n let-isLastSentMessage=\"isLastSentMessage\"\n let-enabledMessageActions=\"enabledMessageActions\"\n let-mode=\"mode\"\n let-isHighlighted=\"isHighlighted\"\n let-scroll$=\"scroll$\"\n >\n <stream-message\n [message]=\"messageInput\"\n [isLastSentMessage]=\"isLastSentMessage\"\n [enabledMessageActions]=\"enabledMessageActions\"\n [mode]=\"mode\"\n [isHighlighted]=\"isHighlighted\"\n [scroll$]=\"scroll$\"\n ></stream-message>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n messageTemplate || defaultMessageTemplate;\n context: {\n message: message,\n isLastSentMessage: !!(\n lastSentMessageId && message?.id === lastSentMessageId\n ),\n enabledMessageActions: enabledMessageActions,\n mode: mode,\n isHighlighted: message?.id === highlightedMessageId,\n scroll$: scroll$\n }\n \"\n ></ng-container>\n</ng-template>\n\n<ng-template #dateSeparator let-date=\"date\" let-parsedDate=\"parsedDate\">\n <ng-container *ngIf=\"displayDateSeparator\">\n <ng-container\n *ngTemplateOutlet=\"\n customDateSeparatorTemplate || defaultDateSeparator;\n context: {\n date: date,\n parsedDate: parsedDate\n }\n \"\n ></ng-container>\n </ng-container>\n\n <ng-template\n #defaultDateSeparator\n let-date=\"date\"\n let-parsedDate=\"parsedDate\"\n >\n <div data-testid=\"date-separator\" class=\"str-chat__date-separator\">\n <hr\n *ngIf=\"\n dateSeparatorTextPos === 'right' || dateSeparatorTextPos === 'center'\n \"\n class=\"str-chat__date-separator-line\"\n />\n <div class=\"str-chat__date-separator-date\">\n {{ parsedDate }}\n </div>\n <hr\n *ngIf=\"\n dateSeparatorTextPos === 'left' || dateSeparatorTextPos === 'center'\n \"\n class=\"str-chat__date-separator-line\"\n />\n </div>\n </ng-template>\n</ng-template>\n\n<ng-template #defaultNewMessagesIndicator let-unreadCount=\"unreadCount\">\n <div class=\"str-chat__unread-messages-separator\">\n <ng-container\n *ngIf=\"\n unreadCount > 0 && !hideUnreadCountForNotificationAndIndicator;\n else noUnreadCount\n \"\n >\n {{\n (unreadCount === 1\n ? \"streamChat.\\{\\{count\\}\\} unread message\"\n : \"streamChat.\\{\\{count\\}\\} unread messages\"\n ) | translate : { count: unreadCount }\n }}\n </ng-container>\n <ng-template #noUnreadCount>\n {{ \"streamChat.Unread messages\" | translate }}\n </ng-template>\n </div>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: IconComponent, selector: "stream-icon", inputs: ["icon"] }, { kind: "component", type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon"] }, { kind: "component", type: LoadingIndicatorPlaceholderComponent, selector: "stream-loading-indicator-placeholder" }, { kind: "component", type: MessageComponent, selector: "stream-message", inputs: ["message", "enabledMessageActions", "isLastSentMessage", "mode", "isHighlighted", "scroll$"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
8702
8806
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: MessageListComponent, decorators: [{
8703
8807
  type: Component,
8704
8808
  args: [{ selector: 'stream-message-list', changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container\n *ngIf=\"\n lastReadMessageId &&\n isUnreadNotificationVisible &&\n openMessageListAt === 'last-message' &&\n displayUnreadSeparator\n \"\n>\n <ng-container\n *ngTemplateOutlet=\"\n customnewMessagesNotificationTemplate ||\n defaultUnreadMessagesNotification;\n context: {\n unreadCount: unreadCount,\n onDismiss: messageNotificationDismissClicked,\n onJump: messageNotificationJumpClicked\n }\n \"\n ></ng-container>\n</ng-container>\n<ng-template\n #defaultUnreadMessagesNotification\n let-unreadCount=\"unreadCount\"\n let-onDismiss=\"onDismiss\"\n let-onJump=\"onJump\"\n>\n <div\n class=\"str-chat__unread-messages-notification\"\n data-testid=\"unread-messages-notification\"\n >\n <button\n data-testid=\"unread-messages-notification-jump-to-message\"\n (click)=\"onJump()\"\n >\n <ng-container\n *ngIf=\"\n unreadCount > 0 && !hideUnreadCountForNotificationAndIndicator;\n else noUnreadCount\n \"\n >\n {{\n (unreadCount === 1\n ? \"streamChat.\\{\\{count\\}\\} unread message\"\n : \"streamChat.\\{\\{count\\}\\} unread messages\"\n ) | translate : { count: unreadCount }\n }}\n </ng-container>\n <ng-template #noUnreadCount>\n {{ \"streamChat.Unread messages\" | translate }}\n </ng-template>\n </button>\n <button\n data-testid=\"unread-messages-notification-dismiss\"\n (click)=\"onDismiss()\"\n >\n <stream-icon-placeholder icon=\"close\"></stream-icon-placeholder>\n </button>\n </div>\n</ng-template>\n<div #scrollContainer data-testid=\"scroll-container\" class=\"str-chat__list\">\n <ng-container *ngIf=\"mode === 'main' && isEmpty && emptyListTemplate\">\n <ng-container *ngTemplateOutlet=\"emptyListTemplate\"></ng-container>\n </ng-container>\n <div class=\"str-chat__reverse-infinite-scroll str-chat__message-list-scroll\">\n <ul class=\"str-chat__ul\">\n <li\n *ngIf=\"mode === 'thread' && parentMessage\"\n #parentMessageElement\n data-testid=\"parent-message\"\n class=\"str-chat__parent-message-li\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n messageTemplateContainer;\n context: { message: parentMessage, index: 'parent' }\n \"\n ></ng-container>\n <div data-testid=\"reply-count\" class=\"str-chat__thread-start\">\n {{parentMessage.reply_count === 1 ? ('streamChat.1 reply' | translate) : ('streamChat.{{ replyCount }}\n replies' | translate:replyCountParam)}}\n </div>\n </li>\n <ng-container *ngIf=\"mode === 'thread' && isEmpty && emptyListTemplate\">\n <ng-container *ngTemplateOutlet=\"emptyListTemplate\"></ng-container>\n </ng-container>\n <stream-loading-indicator-placeholder\n *ngIf=\"\n ((loadingState === 'loading-top' && direction === 'bottom-to-top') ||\n (loadingState === 'loading-bottom' &&\n direction === 'top-to-bottom')) &&\n displayLoadingIndicator;\n else loadingIndicatorPlaceholder\n \"\n data-testid=\"top-loading-indicator\"\n ></stream-loading-indicator-placeholder>\n <ng-container *ngIf=\"messages$ | async as messages\">\n <ng-container\n *ngFor=\"\n let message of messages;\n let i = index;\n let isFirst = first;\n let isLast = last;\n trackBy: trackByMessageId\n \"\n >\n <ng-container *ngIf=\"isFirst\">\n <ng-container\n *ngTemplateOutlet=\"\n dateSeparator;\n context: {\n date: message.created_at,\n parsedDate: parseDate(message.created_at)\n }\n \"\n ></ng-container>\n </ng-container>\n <li\n tabindex=\"0\"\n data-testclass=\"message\"\n class=\"str-chat__li str-chat__li--{{ groupStyles[i] }}\"\n id=\"{{ message.id }}\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n messageTemplateContainer;\n context: { message: message, index: i }\n \"\n ></ng-container>\n </li>\n <ng-container\n *ngIf=\"\n (lastReadMessageId === message?.id &&\n direction === 'bottom-to-top') ||\n (direction === 'top-to-bottom' &&\n lastReadMessageId === messages[i + 1]?.id)\n \"\n >\n <li\n *ngIf=\"displayUnreadSeparator\"\n id=\"stream-chat-new-message-indicator\"\n data-testid=\"new-messages-indicator\"\n class=\"str-chat__li str-chat__unread-messages-separator-wrapper\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n customnewMessagesIndicatorTemplate ||\n defaultNewMessagesIndicator;\n context: { unreadCount: unreadCount }\n \"\n ></ng-container>\n </li>\n </ng-container>\n <ng-container *ngIf=\"isNextMessageOnSeparateDate[i]\">\n <ng-container\n *ngTemplateOutlet=\"\n dateSeparator;\n context: {\n date: messages[i + 1].created_at,\n parsedDate: parseDate(messages[i + 1].created_at)\n }\n \"\n ></ng-container>\n </ng-container>\n </ng-container>\n </ng-container>\n <stream-loading-indicator-placeholder\n *ngIf=\"\n ((loadingState === 'loading-bottom' &&\n direction === 'bottom-to-top') ||\n (loadingState === 'loading-top' &&\n direction === 'top-to-bottom')) &&\n displayLoadingIndicator;\n else loadingIndicatorPlaceholder\n \"\n data-testid=\"bottom-loading-indicator\"\n ></stream-loading-indicator-placeholder>\n <ng-template #loadingIndicatorPlaceholder>\n <div class=\"str-chat__loading-indicator-placeholder\"></div>\n </ng-template>\n </ul>\n <ng-template #defaultTypingIndicator let-usersTyping$=\"usersTyping$\">\n <!-- eslint-disable-next-line @angular-eslint/template/no-any -->\n <ng-container *ngIf=\"$any(usersTyping$ | async) as users\">\n <div\n *ngIf=\"users.length > 0\"\n data-testid=\"typing-indicator\"\n class=\"str-chat__typing-indicator str-chat__typing-indicator--typing\"\n >\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 data-testid=\"typing-users\"\n class=\"str-chat__typing-indicator__users\"\n >\n {{\n users.length === 1\n ? (\"streamChat.user is typing\"\n | translate : { user: getTypingIndicatorText(users) })\n : (\"streamChat.users are typing\"\n | translate : { users: getTypingIndicatorText(users) })\n }}\n </div>\n </div>\n </ng-container>\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__jump-to-latest-message\">\n <button\n *ngIf=\"isUserScrolled && isJumpToLatestButtonVisible\"\n data-testid=\"scroll-to-latest\"\n class=\"str-chat__message-notification-scroll-to-latest str-chat__message-notification-scroll-to-latest-right str-chat__circle-fab\"\n (keyup.enter)=\"jumpToLatestMessage()\"\n (click)=\"jumpToLatestMessage()\"\n >\n <stream-icon\n class=\"str-chat__jump-to-latest-icon str-chat__circle-fab-icon\"\n [icon]=\"direction === 'bottom-to-top' ? 'arrow-down' : 'arrow-up'\"\n ></stream-icon>\n <div\n *ngIf=\"newMessageCountWhileBeingScrolled > 0\"\n class=\"str-chat__message-notification str-chat__message-notification-scroll-to-latest-unread-count str-chat__jump-to-latest-unread-count\"\n >\n {{ newMessageCountWhileBeingScrolled }}\n </div>\n </button>\n</div>\n\n<ng-template #messageTemplateContainer let-message=\"message\" let-index=\"index\">\n <ng-template\n #defaultMessageTemplate\n let-messageInput=\"message\"\n let-isLastSentMessage=\"isLastSentMessage\"\n let-enabledMessageActions=\"enabledMessageActions\"\n let-mode=\"mode\"\n let-isHighlighted=\"isHighlighted\"\n let-scroll$=\"scroll$\"\n >\n <stream-message\n [message]=\"messageInput\"\n [isLastSentMessage]=\"isLastSentMessage\"\n [enabledMessageActions]=\"enabledMessageActions\"\n [mode]=\"mode\"\n [isHighlighted]=\"isHighlighted\"\n [scroll$]=\"scroll$\"\n ></stream-message>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n messageTemplate || defaultMessageTemplate;\n context: {\n message: message,\n isLastSentMessage: !!(\n lastSentMessageId && message?.id === lastSentMessageId\n ),\n enabledMessageActions: enabledMessageActions,\n mode: mode,\n isHighlighted: message?.id === highlightedMessageId,\n scroll$: scroll$\n }\n \"\n ></ng-container>\n</ng-template>\n\n<ng-template #dateSeparator let-date=\"date\" let-parsedDate=\"parsedDate\">\n <ng-container *ngIf=\"displayDateSeparator\">\n <ng-container\n *ngTemplateOutlet=\"\n customDateSeparatorTemplate || defaultDateSeparator;\n context: {\n date: date,\n parsedDate: parsedDate\n }\n \"\n ></ng-container>\n </ng-container>\n\n <ng-template\n #defaultDateSeparator\n let-date=\"date\"\n let-parsedDate=\"parsedDate\"\n >\n <div data-testid=\"date-separator\" class=\"str-chat__date-separator\">\n <hr\n *ngIf=\"\n dateSeparatorTextPos === 'right' || dateSeparatorTextPos === 'center'\n \"\n class=\"str-chat__date-separator-line\"\n />\n <div class=\"str-chat__date-separator-date\">\n {{ parsedDate }}\n </div>\n <hr\n *ngIf=\"\n dateSeparatorTextPos === 'left' || dateSeparatorTextPos === 'center'\n \"\n class=\"str-chat__date-separator-line\"\n />\n </div>\n </ng-template>\n</ng-template>\n\n<ng-template #defaultNewMessagesIndicator let-unreadCount=\"unreadCount\">\n <div class=\"str-chat__unread-messages-separator\">\n <ng-container\n *ngIf=\"\n unreadCount > 0 && !hideUnreadCountForNotificationAndIndicator;\n else noUnreadCount\n \"\n >\n {{\n (unreadCount === 1\n ? \"streamChat.\\{\\{count\\}\\} unread message\"\n : \"streamChat.\\{\\{count\\}\\} unread messages\"\n ) | translate : { count: unreadCount }\n }}\n </ng-container>\n <ng-template #noUnreadCount>\n {{ \"streamChat.Unread messages\" | translate }}\n </ng-template>\n </div>\n</ng-template>\n" }]
@@ -8764,7 +8868,7 @@ class ThreadComponent {
8764
8868
  }
8765
8869
  }
8766
8870
  ThreadComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: ThreadComponent, deps: [{ token: CustomTemplatesService }, { token: ChannelService }, { token: ChatClientService }], target: i0.ɵɵFactoryTarget.Component });
8767
- ThreadComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: ThreadComponent, selector: "stream-thread", host: { properties: { "class": "this.class" } }, ngImport: i0, template: "<div class=\"str-chat__thread-container\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.threadHeaderTemplate$ | async) ||\n defaultThreadHeader;\n context: getThreadHeaderContext()\n \"\n ></ng-container>\n <ng-content></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 <div class=\"str-chat__thread-header-name\" translate>\n streamChat.Thread\n </div>\n <div\n class=\"str-chat__thread-header-channel-name\"\n data-testid=\"channel-name\"\n >\n {{ channelName }}\n </div>\n </div>\n <button\n class=\"str-chat__square-button str-chat__close-thread-button\"\n data-testid=\"close-button\"\n (click)=\"closeThreadHandler()\"\n >\n <stream-icon-placeholder icon=\"close\"></stream-icon-placeholder>\n </button>\n </div>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i6.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "component", type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }] });
8871
+ ThreadComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: ThreadComponent, selector: "stream-thread", host: { properties: { "class": "this.class" } }, ngImport: i0, template: "<div class=\"str-chat__thread-container\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.threadHeaderTemplate$ | async) ||\n defaultThreadHeader;\n context: getThreadHeaderContext()\n \"\n ></ng-container>\n <ng-content></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 <div class=\"str-chat__thread-header-name\" translate>\n streamChat.Thread\n </div>\n <div\n class=\"str-chat__thread-header-channel-name\"\n data-testid=\"channel-name\"\n >\n {{ channelName }}\n </div>\n </div>\n <button\n class=\"str-chat__square-button str-chat__close-thread-button\"\n data-testid=\"close-button\"\n (click)=\"closeThreadHandler()\"\n >\n <stream-icon-placeholder icon=\"close\"></stream-icon-placeholder>\n </button>\n </div>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i6.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "component", type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }] });
8768
8872
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: ThreadComponent, decorators: [{
8769
8873
  type: Component,
8770
8874
  args: [{ selector: 'stream-thread', template: "<div class=\"str-chat__thread-container\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.threadHeaderTemplate$ | async) ||\n defaultThreadHeader;\n context: getThreadHeaderContext()\n \"\n ></ng-container>\n <ng-content></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 <div class=\"str-chat__thread-header-name\" translate>\n streamChat.Thread\n </div>\n <div\n class=\"str-chat__thread-header-channel-name\"\n data-testid=\"channel-name\"\n >\n {{ channelName }}\n </div>\n </div>\n <button\n class=\"str-chat__square-button str-chat__close-thread-button\"\n data-testid=\"close-button\"\n (click)=\"closeThreadHandler()\"\n >\n <stream-icon-placeholder icon=\"close\"></stream-icon-placeholder>\n </button>\n </div>\n</ng-template>\n" }]
@@ -8831,6 +8935,48 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImpor
8831
8935
  }]
8832
8936
  }] });
8833
8937
 
8938
+ class StreamModalModule {
8939
+ }
8940
+ StreamModalModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: StreamModalModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
8941
+ StreamModalModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.0.4", ngImport: i0, type: StreamModalModule, declarations: [ModalComponent], imports: [CommonModule, IconModule], exports: [ModalComponent] });
8942
+ StreamModalModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: StreamModalModule, imports: [CommonModule, IconModule] });
8943
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: StreamModalModule, decorators: [{
8944
+ type: NgModule,
8945
+ args: [{
8946
+ declarations: [ModalComponent],
8947
+ imports: [CommonModule, IconModule],
8948
+ exports: [ModalComponent],
8949
+ }]
8950
+ }] });
8951
+
8952
+ class StreamNotificationModule {
8953
+ }
8954
+ StreamNotificationModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: StreamNotificationModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
8955
+ StreamNotificationModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.0.4", ngImport: i0, type: StreamNotificationModule, declarations: [NotificationComponent, NotificationListComponent], imports: [CommonModule, TranslateModule], exports: [NotificationComponent, NotificationListComponent] });
8956
+ StreamNotificationModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: StreamNotificationModule, imports: [CommonModule, TranslateModule] });
8957
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: StreamNotificationModule, decorators: [{
8958
+ type: NgModule,
8959
+ args: [{
8960
+ declarations: [NotificationComponent, NotificationListComponent],
8961
+ imports: [CommonModule, TranslateModule],
8962
+ exports: [NotificationComponent, NotificationListComponent],
8963
+ }]
8964
+ }] });
8965
+
8966
+ class StreamPaginatedListModule {
8967
+ }
8968
+ StreamPaginatedListModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: StreamPaginatedListModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
8969
+ StreamPaginatedListModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.0.4", ngImport: i0, type: StreamPaginatedListModule, declarations: [PaginatedListComponent], imports: [CommonModule, TranslateModule, IconModule], exports: [PaginatedListComponent] });
8970
+ StreamPaginatedListModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: StreamPaginatedListModule, imports: [CommonModule, TranslateModule, IconModule] });
8971
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: StreamPaginatedListModule, decorators: [{
8972
+ type: NgModule,
8973
+ args: [{
8974
+ declarations: [PaginatedListComponent],
8975
+ imports: [CommonModule, TranslateModule, IconModule],
8976
+ exports: [PaginatedListComponent],
8977
+ }]
8978
+ }] });
8979
+
8834
8980
  class StreamChatModule {
8835
8981
  }
8836
8982
  StreamChatModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: StreamChatModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
@@ -8844,23 +8990,22 @@ StreamChatModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", versio
8844
8990
  MessageActionsBoxComponent,
8845
8991
  AttachmentListComponent,
8846
8992
  MessageReactionsComponent,
8847
- NotificationComponent,
8848
- NotificationListComponent,
8849
8993
  AttachmentPreviewListComponent,
8850
- ModalComponent,
8851
8994
  TextareaDirective,
8852
8995
  ThreadComponent,
8853
8996
  MessageBouncePromptComponent,
8854
8997
  MessageReactionsSelectorComponent,
8855
8998
  UserListComponent,
8856
- PaginatedListComponent,
8857
8999
  MessageTextComponent,
8858
9000
  MessageBlockedComponent], imports: [CommonModule,
8859
9001
  NgxFloatUiModule,
8860
9002
  StreamAvatarModule,
8861
9003
  TranslateModule,
8862
9004
  VoiceRecordingModule,
8863
- IconModule], exports: [ChannelComponent,
9005
+ IconModule,
9006
+ StreamModalModule,
9007
+ StreamNotificationModule,
9008
+ StreamPaginatedListModule], exports: [ChannelComponent,
8864
9009
  ChannelHeaderComponent,
8865
9010
  ChannelListComponent,
8866
9011
  ChannelPreviewComponent,
@@ -8873,25 +9018,32 @@ StreamChatModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", versio
8873
9018
  NotificationComponent,
8874
9019
  NotificationListComponent,
8875
9020
  AttachmentPreviewListComponent,
8876
- ModalComponent,
9021
+ StreamModalModule,
8877
9022
  StreamAvatarModule,
8878
9023
  ThreadComponent,
8879
9024
  MessageBouncePromptComponent,
8880
9025
  VoiceRecordingModule,
8881
9026
  MessageReactionsSelectorComponent,
8882
9027
  UserListComponent,
8883
- PaginatedListComponent,
9028
+ StreamPaginatedListModule,
8884
9029
  IconModule,
8885
9030
  MessageTextComponent,
8886
- MessageBlockedComponent] });
9031
+ MessageBlockedComponent,
9032
+ StreamNotificationModule] });
8887
9033
  StreamChatModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: StreamChatModule, providers: [VoiceRecorderService], imports: [CommonModule,
8888
9034
  NgxFloatUiModule,
8889
9035
  StreamAvatarModule,
8890
9036
  TranslateModule,
8891
9037
  VoiceRecordingModule,
8892
- IconModule, StreamAvatarModule,
9038
+ IconModule,
9039
+ StreamModalModule,
9040
+ StreamNotificationModule,
9041
+ StreamPaginatedListModule, StreamModalModule,
9042
+ StreamAvatarModule,
8893
9043
  VoiceRecordingModule,
8894
- IconModule] });
9044
+ StreamPaginatedListModule,
9045
+ IconModule,
9046
+ StreamNotificationModule] });
8895
9047
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: StreamChatModule, decorators: [{
8896
9048
  type: NgModule,
8897
9049
  args: [{
@@ -8906,16 +9058,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImpor
8906
9058
  MessageActionsBoxComponent,
8907
9059
  AttachmentListComponent,
8908
9060
  MessageReactionsComponent,
8909
- NotificationComponent,
8910
- NotificationListComponent,
8911
9061
  AttachmentPreviewListComponent,
8912
- ModalComponent,
8913
9062
  TextareaDirective,
8914
9063
  ThreadComponent,
8915
9064
  MessageBouncePromptComponent,
8916
9065
  MessageReactionsSelectorComponent,
8917
9066
  UserListComponent,
8918
- PaginatedListComponent,
8919
9067
  MessageTextComponent,
8920
9068
  MessageBlockedComponent,
8921
9069
  ],
@@ -8926,6 +9074,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImpor
8926
9074
  TranslateModule,
8927
9075
  VoiceRecordingModule,
8928
9076
  IconModule,
9077
+ StreamModalModule,
9078
+ StreamNotificationModule,
9079
+ StreamPaginatedListModule,
8929
9080
  ],
8930
9081
  exports: [
8931
9082
  ChannelComponent,
@@ -8941,17 +9092,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImpor
8941
9092
  NotificationComponent,
8942
9093
  NotificationListComponent,
8943
9094
  AttachmentPreviewListComponent,
8944
- ModalComponent,
9095
+ StreamModalModule,
8945
9096
  StreamAvatarModule,
8946
9097
  ThreadComponent,
8947
9098
  MessageBouncePromptComponent,
8948
9099
  VoiceRecordingModule,
8949
9100
  MessageReactionsSelectorComponent,
8950
9101
  UserListComponent,
8951
- PaginatedListComponent,
9102
+ StreamPaginatedListModule,
8952
9103
  IconModule,
8953
9104
  MessageTextComponent,
8954
9105
  MessageBlockedComponent,
9106
+ StreamNotificationModule,
8955
9107
  ],
8956
9108
  providers: [VoiceRecorderService],
8957
9109
  }]
@@ -9030,7 +9182,7 @@ class VoiceRecorderWavebarComponent {
9030
9182
  }
9031
9183
  }
9032
9184
  VoiceRecorderWavebarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: VoiceRecorderWavebarComponent, deps: [{ token: AmplitudeRecorderService }, { token: AudioRecorderService }], target: i0.ɵɵFactoryTarget.Component });
9033
- VoiceRecorderWavebarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: VoiceRecorderWavebarComponent, selector: "stream-voice-recorder-wavebar", ngImport: i0, template: "<div\n class=\"str-chat__recording-timer\"\n [class.str-chat__recording-timer--hours]=\"isLongerThanOneHour\"\n>\n {{ formattedDuration }}\n</div>\n<div class=\"str-chat__waveform-box-container\">\n <div class=\"str-chat__audio_recorder__waveform-box\">\n <div\n *ngFor=\"let amplitude of amplitudes$ | async; trackBy: trackByIndex\"\n class=\"str-chat__wave-progress-bar__amplitude-bar\"\n [style.--str-chat__wave-progress-bar__amplitude-bar-height]=\"\n (amplitude ?? 0) * 100 + '%'\n \"\n ></div>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }] });
9185
+ VoiceRecorderWavebarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: VoiceRecorderWavebarComponent, selector: "stream-voice-recorder-wavebar", ngImport: i0, template: "<div\n class=\"str-chat__recording-timer\"\n [class.str-chat__recording-timer--hours]=\"isLongerThanOneHour\"\n>\n {{ formattedDuration }}\n</div>\n<div class=\"str-chat__waveform-box-container\">\n <div class=\"str-chat__audio_recorder__waveform-box\">\n <div\n *ngFor=\"let amplitude of amplitudes$ | async; trackBy: trackByIndex\"\n class=\"str-chat__wave-progress-bar__amplitude-bar\"\n [style.--str-chat__wave-progress-bar__amplitude-bar-height]=\"\n (amplitude ?? 0) * 100 + '%'\n \"\n ></div>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }] });
9034
9186
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: VoiceRecorderWavebarComponent, decorators: [{
9035
9187
  type: Component,
9036
9188
  args: [{ selector: 'stream-voice-recorder-wavebar', template: "<div\n class=\"str-chat__recording-timer\"\n [class.str-chat__recording-timer--hours]=\"isLongerThanOneHour\"\n>\n {{ formattedDuration }}\n</div>\n<div class=\"str-chat__waveform-box-container\">\n <div class=\"str-chat__audio_recorder__waveform-box\">\n <div\n *ngFor=\"let amplitude of amplitudes$ | async; trackBy: trackByIndex\"\n class=\"str-chat__wave-progress-bar__amplitude-bar\"\n [style.--str-chat__wave-progress-bar__amplitude-bar-height]=\"\n (amplitude ?? 0) * 100 + '%'\n \"\n ></div>\n </div>\n</div>\n" }]
@@ -9105,7 +9257,7 @@ class VoiceRecorderComponent {
9105
9257
  }
9106
9258
  }
9107
9259
  VoiceRecorderComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: VoiceRecorderComponent, deps: [{ token: AudioRecorderService }], target: i0.ɵɵFactoryTarget.Component });
9108
- VoiceRecorderComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: VoiceRecorderComponent, selector: "stream-voice-recorder", inputs: { voiceRecorderService: "voiceRecorderService" }, providers: [], usesOnChanges: true, ngImport: i0, template: "<div\n class=\"str-chat__audio_recorder-container\"\n *ngIf=\"voiceRecorderService?.isRecorderVisible$ | async\"\n>\n <div class=\"str-chat__audio_recorder\" data-testid=\"audio-recorder\">\n <button\n class=\"str-chat__audio_recorder__cancel-button\"\n data-testid=\"cancel-recording-audio-button\"\n [disabled]=\"isLoading\"\n (click)=\"cancel()\"\n (keyup.enter)=\"cancel()\"\n >\n <stream-icon-placeholder icon=\"bin\"></stream-icon-placeholder>\n </button>\n <stream-voice-recorder-wavebar\n *ngIf=\"\n (recordState === MediaRecordingState.RECORDING ||\n recordState === MediaRecordingState.PAUSED) &&\n !recording\n \"\n ></stream-voice-recorder-wavebar>\n <!-- eslint-disable @angular-eslint/template/no-any -->\n <stream-voice-recording\n [attachment]=\"$any(recording)\"\n *ngIf=\"!!recording\"\n ></stream-voice-recording>\n <!-- eslint-enable @angular-eslint/template/no-any -->\n <button\n *ngIf=\"recordState === MediaRecordingState.PAUSED && !recording\"\n class=\"str-chat__audio_recorder__resume-recording-button\"\n (click)=\"resume()\"\n (keyup.enter)=\"resume()\"\n >\n <stream-icon-placeholder icon=\"mic\"></stream-icon-placeholder>\n </button>\n <button\n *ngIf=\"recordState === MediaRecordingState.RECORDING && !recording\"\n class=\"str-chat__audio_recorder__pause-recording-button\"\n data-testid=\"pause-recording-audio-button\"\n (click)=\"pause()\"\n (keyup.enter)=\"pause()\"\n >\n <stream-icon-placeholder icon=\"pause\"></stream-icon-placeholder>\n </button>\n <ng-container\n *ngIf=\"recordState === MediaRecordingState.STOPPED; else stopButton\"\n >\n <button\n class=\"str-chat__audio_recorder__complete-button\"\n data-testid=\"audio-recorder-complete-button\"\n [disabled]=\"!recording\"\n (click)=\"uploadRecording()\"\n (keyup.enter)=\"uploadRecording()\"\n >\n <stream-loading-indicator\n *ngIf=\"isLoading; else sendIcon\"\n ></stream-loading-indicator>\n <ng-template #sendIcon>\n <stream-icon-placeholder icon=\"send\"></stream-icon-placeholder>\n </ng-template>\n </button>\n </ng-container>\n <ng-template #stopButton>\n <button\n class=\"str-chat__audio_recorder__stop-button\"\n data-testid=\"audio-recorder-stop-button\"\n [disabled]=\"recordState === MediaRecordingState.STOPPED\"\n (click)=\"stop()\"\n (keyup.enter)=\"stop()\"\n >\n <stream-icon-placeholder icon=\"delivered\"></stream-icon-placeholder>\n </button>\n </ng-template>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: VoiceRecordingComponent, selector: "stream-voice-recording", inputs: ["attachment"] }, { kind: "component", type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon"] }, { kind: "component", type: LoadingIndicatorComponent, selector: "stream-loading-indicator" }, { kind: "component", type: VoiceRecorderWavebarComponent, selector: "stream-voice-recorder-wavebar" }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }] });
9260
+ VoiceRecorderComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: VoiceRecorderComponent, selector: "stream-voice-recorder", inputs: { voiceRecorderService: "voiceRecorderService" }, providers: [], usesOnChanges: true, ngImport: i0, template: "<div\n class=\"str-chat__audio_recorder-container\"\n *ngIf=\"voiceRecorderService?.isRecorderVisible$ | async\"\n>\n <div class=\"str-chat__audio_recorder\" data-testid=\"audio-recorder\">\n <button\n class=\"str-chat__audio_recorder__cancel-button\"\n data-testid=\"cancel-recording-audio-button\"\n [disabled]=\"isLoading\"\n (click)=\"cancel()\"\n (keyup.enter)=\"cancel()\"\n >\n <stream-icon-placeholder icon=\"bin\"></stream-icon-placeholder>\n </button>\n <stream-voice-recorder-wavebar\n *ngIf=\"\n (recordState === MediaRecordingState.RECORDING ||\n recordState === MediaRecordingState.PAUSED) &&\n !recording\n \"\n ></stream-voice-recorder-wavebar>\n <!-- eslint-disable @angular-eslint/template/no-any -->\n <stream-voice-recording\n [attachment]=\"$any(recording)\"\n *ngIf=\"!!recording\"\n ></stream-voice-recording>\n <!-- eslint-enable @angular-eslint/template/no-any -->\n <button\n *ngIf=\"recordState === MediaRecordingState.PAUSED && !recording\"\n class=\"str-chat__audio_recorder__resume-recording-button\"\n (click)=\"resume()\"\n (keyup.enter)=\"resume()\"\n >\n <stream-icon-placeholder icon=\"mic\"></stream-icon-placeholder>\n </button>\n <button\n *ngIf=\"recordState === MediaRecordingState.RECORDING && !recording\"\n class=\"str-chat__audio_recorder__pause-recording-button\"\n data-testid=\"pause-recording-audio-button\"\n (click)=\"pause()\"\n (keyup.enter)=\"pause()\"\n >\n <stream-icon-placeholder icon=\"pause\"></stream-icon-placeholder>\n </button>\n <ng-container\n *ngIf=\"recordState === MediaRecordingState.STOPPED; else stopButton\"\n >\n <button\n class=\"str-chat__audio_recorder__complete-button\"\n data-testid=\"audio-recorder-complete-button\"\n [disabled]=\"!recording\"\n (click)=\"uploadRecording()\"\n (keyup.enter)=\"uploadRecording()\"\n >\n <stream-loading-indicator\n *ngIf=\"isLoading; else sendIcon\"\n ></stream-loading-indicator>\n <ng-template #sendIcon>\n <stream-icon-placeholder icon=\"send\"></stream-icon-placeholder>\n </ng-template>\n </button>\n </ng-container>\n <ng-template #stopButton>\n <button\n class=\"str-chat__audio_recorder__stop-button\"\n data-testid=\"audio-recorder-stop-button\"\n [disabled]=\"recordState === MediaRecordingState.STOPPED\"\n (click)=\"stop()\"\n (keyup.enter)=\"stop()\"\n >\n <stream-icon-placeholder icon=\"delivered\"></stream-icon-placeholder>\n </button>\n </ng-template>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: VoiceRecordingComponent, selector: "stream-voice-recording", inputs: ["attachment"] }, { kind: "component", type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon"] }, { kind: "component", type: LoadingIndicatorComponent, selector: "stream-loading-indicator" }, { kind: "component", type: VoiceRecorderWavebarComponent, selector: "stream-voice-recorder-wavebar" }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }] });
9109
9261
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: VoiceRecorderComponent, decorators: [{
9110
9262
  type: Component,
9111
9263
  args: [{ selector: 'stream-voice-recorder', providers: [], template: "<div\n class=\"str-chat__audio_recorder-container\"\n *ngIf=\"voiceRecorderService?.isRecorderVisible$ | async\"\n>\n <div class=\"str-chat__audio_recorder\" data-testid=\"audio-recorder\">\n <button\n class=\"str-chat__audio_recorder__cancel-button\"\n data-testid=\"cancel-recording-audio-button\"\n [disabled]=\"isLoading\"\n (click)=\"cancel()\"\n (keyup.enter)=\"cancel()\"\n >\n <stream-icon-placeholder icon=\"bin\"></stream-icon-placeholder>\n </button>\n <stream-voice-recorder-wavebar\n *ngIf=\"\n (recordState === MediaRecordingState.RECORDING ||\n recordState === MediaRecordingState.PAUSED) &&\n !recording\n \"\n ></stream-voice-recorder-wavebar>\n <!-- eslint-disable @angular-eslint/template/no-any -->\n <stream-voice-recording\n [attachment]=\"$any(recording)\"\n *ngIf=\"!!recording\"\n ></stream-voice-recording>\n <!-- eslint-enable @angular-eslint/template/no-any -->\n <button\n *ngIf=\"recordState === MediaRecordingState.PAUSED && !recording\"\n class=\"str-chat__audio_recorder__resume-recording-button\"\n (click)=\"resume()\"\n (keyup.enter)=\"resume()\"\n >\n <stream-icon-placeholder icon=\"mic\"></stream-icon-placeholder>\n </button>\n <button\n *ngIf=\"recordState === MediaRecordingState.RECORDING && !recording\"\n class=\"str-chat__audio_recorder__pause-recording-button\"\n data-testid=\"pause-recording-audio-button\"\n (click)=\"pause()\"\n (keyup.enter)=\"pause()\"\n >\n <stream-icon-placeholder icon=\"pause\"></stream-icon-placeholder>\n </button>\n <ng-container\n *ngIf=\"recordState === MediaRecordingState.STOPPED; else stopButton\"\n >\n <button\n class=\"str-chat__audio_recorder__complete-button\"\n data-testid=\"audio-recorder-complete-button\"\n [disabled]=\"!recording\"\n (click)=\"uploadRecording()\"\n (keyup.enter)=\"uploadRecording()\"\n >\n <stream-loading-indicator\n *ngIf=\"isLoading; else sendIcon\"\n ></stream-loading-indicator>\n <ng-template #sendIcon>\n <stream-icon-placeholder icon=\"send\"></stream-icon-placeholder>\n </ng-template>\n </button>\n </ng-container>\n <ng-template #stopButton>\n <button\n class=\"str-chat__audio_recorder__stop-button\"\n data-testid=\"audio-recorder-stop-button\"\n [disabled]=\"recordState === MediaRecordingState.STOPPED\"\n (click)=\"stop()\"\n (keyup.enter)=\"stop()\"\n >\n <stream-icon-placeholder icon=\"delivered\"></stream-icon-placeholder>\n </button>\n </ng-template>\n </div>\n</div>\n" }]
@@ -9199,6 +9351,1126 @@ function encodeWebmToMp3(blob, lameJs) {
9199
9351
  }
9200
9352
  /* eslint-enable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-argument */
9201
9353
 
9354
+ function atLeastOneOption() {
9355
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
9356
+ return (control) => {
9357
+ const formArray = control;
9358
+ const hasAtLeastOne = formArray.value.some((item) => !!item);
9359
+ return hasAtLeastOne ? null : { atLeastOne: true };
9360
+ };
9361
+ }
9362
+ function maximumNumberOfVotes(canHaveMultipleVotes) {
9363
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
9364
+ return (control) => {
9365
+ const formControl = control;
9366
+ return canHaveMultipleVotes.value && !formControl.value
9367
+ ? { maximumNumberOfVotes: true }
9368
+ : null;
9369
+ };
9370
+ }
9371
+
9372
+ /**
9373
+ *
9374
+ */
9375
+ class PollComposerComponent {
9376
+ constructor(customTemplatesService, chatService, notificationService) {
9377
+ var _a, _b;
9378
+ this.customTemplatesService = customTemplatesService;
9379
+ this.chatService = chatService;
9380
+ this.notificationService = notificationService;
9381
+ /**
9382
+ * Emitted when a poll is created, the poll id is emitted
9383
+ */
9384
+ this.pollCompose = new EventEmitter();
9385
+ /**
9386
+ * Emitted when the poll composing is cancelled
9387
+ */
9388
+ this.cancel = new EventEmitter();
9389
+ this.formGroup = new FormGroup({
9390
+ name: new FormControl('', [Validators.required]),
9391
+ options: new FormArray([new FormControl('')], [atLeastOneOption()]),
9392
+ multiple_answers: new FormControl(false),
9393
+ maximum_number_of_votes: new FormControl(null, [
9394
+ Validators.min(2),
9395
+ Validators.max(10),
9396
+ ]),
9397
+ is_anonymous: new FormControl(false),
9398
+ allow_user_suggested_options: new FormControl(false),
9399
+ allow_answers: new FormControl(false),
9400
+ });
9401
+ this.isModalOpen = true;
9402
+ (_a = this.formGroup
9403
+ .get('maximum_number_of_votes')) === null || _a === void 0 ? void 0 : _a.addValidators([
9404
+ maximumNumberOfVotes(this.formGroup.get('multiple_answers')),
9405
+ ]);
9406
+ (_b = this.formGroup.get('maximum_number_of_votes')) === null || _b === void 0 ? void 0 : _b.disable();
9407
+ this.formGroup.valueChanges.subscribe((value) => {
9408
+ var _a, _b, _c, _d;
9409
+ if (value.multiple_answers &&
9410
+ ((_a = this.formGroup.get('maximum_number_of_votes')) === null || _a === void 0 ? void 0 : _a.disabled)) {
9411
+ (_b = this.formGroup.get('maximum_number_of_votes')) === null || _b === void 0 ? void 0 : _b.enable();
9412
+ }
9413
+ else if (!value.multiple_answers &&
9414
+ ((_c = this.formGroup.get('maximum_number_of_votes')) === null || _c === void 0 ? void 0 : _c.enabled)) {
9415
+ (_d = this.formGroup.get('maximum_number_of_votes')) === null || _d === void 0 ? void 0 : _d.disable();
9416
+ }
9417
+ });
9418
+ }
9419
+ optionChanged(index) {
9420
+ var _a, _b, _c;
9421
+ const control = this.options.at(index);
9422
+ const penultimateIndex = this.options.length - 2;
9423
+ if (index === this.options.length - 1 && ((_a = control.value) === null || _a === void 0 ? void 0 : _a.length) === 1) {
9424
+ this.addOption();
9425
+ }
9426
+ else if (index === penultimateIndex &&
9427
+ ((_b = control.value) === null || _b === void 0 ? void 0 : _b.length) === 0 &&
9428
+ ((_c = this.options.at(this.options.length - 1).value) === null || _c === void 0 ? void 0 : _c.length) === 0) {
9429
+ this.removeLastOption();
9430
+ }
9431
+ }
9432
+ get options() {
9433
+ return this.formGroup.get('options');
9434
+ }
9435
+ addOption() {
9436
+ const control = new FormControl('', []);
9437
+ this.options.push(control);
9438
+ }
9439
+ removeLastOption() {
9440
+ this.options.removeAt(this.options.length - 1);
9441
+ }
9442
+ getModalContext() {
9443
+ return {
9444
+ isOpen: this.isModalOpen,
9445
+ isOpenChangeHandler: (isOpen) => {
9446
+ if (!isOpen) {
9447
+ this.cancel.emit();
9448
+ }
9449
+ this.isModalOpen = isOpen;
9450
+ },
9451
+ content: this.formContent,
9452
+ };
9453
+ }
9454
+ createPoll() {
9455
+ var _a, _b, _c, _d;
9456
+ return __awaiter(this, void 0, void 0, function* () {
9457
+ try {
9458
+ const maxVotesControl = this.formGroup.get('maximum_number_of_votes');
9459
+ const response = yield this.chatService.chatClient.polls.createPoll({
9460
+ name: this.formGroup.get('name').value,
9461
+ options: this.formGroup
9462
+ .get('options')
9463
+ .value.filter((v) => !!v)
9464
+ .map((v) => ({ text: v })),
9465
+ enforce_unique_vote: !((_a = this.formGroup.get('multiple_answers')) === null || _a === void 0 ? void 0 : _a.value),
9466
+ max_votes_allowed: (maxVotesControl === null || maxVotesControl === void 0 ? void 0 : maxVotesControl.value)
9467
+ ? +maxVotesControl.value
9468
+ : undefined,
9469
+ voting_visibility: ((_b = this.formGroup.get('is_anonymous')) === null || _b === void 0 ? void 0 : _b.value)
9470
+ ? VotingVisibility.anonymous
9471
+ : VotingVisibility.public,
9472
+ allow_user_suggested_options: !!((_c = this.formGroup.get('allow_user_suggested_options')) === null || _c === void 0 ? void 0 : _c.value),
9473
+ allow_answers: !!((_d = this.formGroup.get('allow_answers')) === null || _d === void 0 ? void 0 : _d.value),
9474
+ });
9475
+ this.pollCompose.emit(response === null || response === void 0 ? void 0 : response.id);
9476
+ }
9477
+ catch (error) {
9478
+ this.notificationService.addTemporaryNotification('streamChat.Failed to create poll');
9479
+ throw error;
9480
+ }
9481
+ });
9482
+ }
9483
+ }
9484
+ PollComposerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: PollComposerComponent, deps: [{ token: CustomTemplatesService }, { token: ChatClientService }, { token: NotificationService }], target: i0.ɵɵFactoryTarget.Component });
9485
+ PollComposerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: PollComposerComponent, selector: "stream-poll-composer", outputs: { pollCompose: "pollCompose", cancel: "cancel" }, viewQueries: [{ propertyName: "formContent", first: true, predicate: ["formContent"], descendants: true }], ngImport: i0, template: "<ng-container>\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 class=\"str-chat-angular__create-poll-modal str-chat__create-poll-modal\"\n [isOpen]=\"isOpen\"\n [content]=\"content\"\n (isOpenChange)=\"isOpenChangeHandler($event)\"\n >\n </stream-modal>\n</ng-template>\n\n<ng-template #formContent>\n <div\n class=\"str-chat__dialog str-chat__poll-creation-dialog\"\n data-testid=\"poll-creation-dialog\"\n >\n <div class=\"str-chat__modal-header\">\n <div class=\"str-chat__modal-header__title\">\n {{ \"streamChat.Create poll\" | translate }}\n </div>\n </div>\n <div class=\"str-chat__dialog__body\">\n <form [formGroup]=\"formGroup\" autocomplete=\"off\">\n <div\n class=\"str-chat__form__field str-chat__form__input-field str-chat__form__input-field--with-label\"\n [class.str-chat__form__input-field--has-error]=\"\n formGroup.get('name')?.errors && formGroup.get('name')?.touched\n \"\n >\n <label class=\"str-chat__form__field-label\" htmlFor=\"name\">\n {{ \"streamChat.Question\" | translate }}\n </label>\n <div class=\"str-chat__form__input-field__value\">\n <div\n class=\"str-chat__form-field-error str-chat__form__input-field__error\"\n >\n {{\n (formGroup.get(\"name\")?.errors?.required &&\n formGroup.get(\"name\")?.touched\n ? \"streamChat.Question is required\"\n : \"\"\n ) | translate\n }}\n </div>\n <input\n id=\"name\"\n type=\"text\"\n formControlName=\"name\"\n placeholder=\"{{ 'streamChat.Ask a question' | translate }}\"\n />\n </div>\n </div>\n <fieldset class=\"str-chat__form__field str-chat__form__input-fieldset\">\n <legend class=\"str-chat__form__field-label\">\n {{ \"streamChat.Options\" | translate }}\n </legend>\n <div\n class=\"str-chat__form-field-error str-chat__form__input-field__error\"\n >\n {{\n (formGroup.get(\"options\")?.errors?.atLeastOne &&\n formGroup.get(\"options\")?.touched\n ? \"streamChat.Provide at least one option\"\n : \"\"\n ) | translate\n }}\n </div>\n <ng-container formArrayName=\"options\">\n <div class=\"str-chat__form__input-fieldset__values\">\n <!-- eslint-disable @angular-eslint/template/use-track-by-function -->\n <ng-container\n *ngFor=\"let option of options.controls; let i = index\"\n >\n <!-- eslint-enable @angular-eslint/template/use-track-by-function -->\n <div class=\"str-chat__drag-and-drop-container__item\">\n <div class=\"str-chat__form__input-field\">\n <input\n id=\"option{{ i }}\"\n name=\"option{{ i }}\"\n type=\"text\"\n [formControl]=\"option\"\n (input)=\"optionChanged(i)\"\n placeholder=\"{{ 'streamChat.Add an option' | translate }}\"\n />\n </div>\n </div>\n </ng-container>\n </div>\n </ng-container>\n </fieldset>\n <ng-container\n *ngTemplateOutlet=\"\n switch;\n context: {\n name: 'multiple_answers',\n control: formGroup.get('multiple_answers'),\n label: 'streamChat.Multiple answers' | translate\n }\n \"\n ></ng-container>\n <div\n *ngIf=\"formGroup.get('multiple_answers')?.value\"\n class=\"str-chat__form__field str-chat__form__input-field str-chat__form__input-field--with-label\"\n [class.str-chat__form__input-field--has-error]=\"\n formGroup.get('maximum_number_of_votes')?.errors &&\n formGroup.get('maximum_number_of_votes')?.touched\n \"\n >\n <label class=\"str-chat__form__field-label\" htmlFor=\"name\">\n {{ \"streamChat.Maximum number of votes\" | translate }}\n </label>\n <div class=\"str-chat__form__input-field__value\">\n <div\n class=\"str-chat__form-field-error str-chat__form__input-field__error\"\n >\n {{\n (formGroup.get(\"maximum_number_of_votes\")?.errors &&\n formGroup.get(\"maximum_number_of_votes\")?.touched\n ? \"streamChat.Provide a value between {{ min }}\n and {{ max }}\" : \"\" ) | translate: { min: 2, max: 10 } }}\n </div>\n <input\n id=\"maximum_number_of_votes\"\n type=\"text\"\n formControlName=\"maximum_number_of_votes\"\n placeholder=\"{{ 'streamChat.Provide a value between ' \n + '{{ min }} and {{ max }}' | translate: { min: 2, max: 10 } }}\"\n />\n </div>\n </div>\n <ng-container\n *ngTemplateOutlet=\"\n switch;\n context: {\n name: 'is_anonymous',\n control: formGroup.get('is_anonymous'),\n label: 'streamChat.Anonymous poll' | translate\n }\n \"\n ></ng-container>\n <ng-container\n *ngTemplateOutlet=\"\n switch;\n context: {\n name: 'allow_user_suggested_options',\n control: formGroup.get('allow_user_suggested_options'),\n label: 'streamChat.Allow option suggestions' | translate\n }\n \"\n ></ng-container>\n <ng-container\n *ngTemplateOutlet=\"\n switch;\n context: {\n name: 'allow_answers',\n control: formGroup.get('allow_answers'),\n label: 'streamChat.Allow comments' | translate\n }\n \"\n ></ng-container>\n </form>\n </div>\n <stream-notification-list></stream-notification-list>\n <div class=\"str-chat__dialog__controls\">\n <button\n class=\"str-chat__dialog__controls-button str-chat__dialog__controls-button--cancel\"\n (click)=\"cancel.emit()\"\n type=\"button\"\n >\n {{ \"streamChat.Cancel\" | translate }}\n </button>\n <button\n class=\"str-chat__dialog__controls-button str-chat__dialog__controls-button--submit\"\n (click)=\"createPoll()\"\n [disabled]=\"formGroup.invalid\"\n type=\"submit\"\n >\n {{ \"streamChat.Create\" | translate }}\n </button>\n </div>\n </div>\n</ng-template>\n\n<ng-template #switch let-control=\"control\" let-label=\"label\" let-name=\"name\">\n <div class=\"str-chat__form__field str-chat__form__switch-field\">\n <label>\n <div class=\"str-chat__form__field str-chat__form__switch-field-content\">\n <div class=\"str-chat__form__field str-chat__form__switch-field__text\">\n {{ label | translate }}\n </div>\n </div>\n <input\n type=\"checkbox\"\n [checked]=\"control.value\"\n id=\"{{ name }}\"\n name=\"{{ name }}\"\n />\n <div\n class=\"str-chat__form__switch-field__switch\"\n [class.str-chat__form__switch-field__switch--on]=\"control.value\"\n (click)=\"control.setValue(!control.value, { emitEvent: true })\"\n (keyup.enter)=\"control.setValue(!control.value, { emitEvent: true })\"\n >\n <div class=\"str-chat__form__switch-field__switch-handle\"></div>\n </div>\n </label>\n </div>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ModalComponent, selector: "stream-modal", inputs: ["isOpen", "content"], outputs: ["isOpenChange"] }, { kind: "component", type: NotificationListComponent, selector: "stream-notification-list" }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1$1.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.TranslatePipe, name: "translate" }] });
9486
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: PollComposerComponent, decorators: [{
9487
+ type: Component,
9488
+ args: [{ selector: 'stream-poll-composer', template: "<ng-container>\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 class=\"str-chat-angular__create-poll-modal str-chat__create-poll-modal\"\n [isOpen]=\"isOpen\"\n [content]=\"content\"\n (isOpenChange)=\"isOpenChangeHandler($event)\"\n >\n </stream-modal>\n</ng-template>\n\n<ng-template #formContent>\n <div\n class=\"str-chat__dialog str-chat__poll-creation-dialog\"\n data-testid=\"poll-creation-dialog\"\n >\n <div class=\"str-chat__modal-header\">\n <div class=\"str-chat__modal-header__title\">\n {{ \"streamChat.Create poll\" | translate }}\n </div>\n </div>\n <div class=\"str-chat__dialog__body\">\n <form [formGroup]=\"formGroup\" autocomplete=\"off\">\n <div\n class=\"str-chat__form__field str-chat__form__input-field str-chat__form__input-field--with-label\"\n [class.str-chat__form__input-field--has-error]=\"\n formGroup.get('name')?.errors && formGroup.get('name')?.touched\n \"\n >\n <label class=\"str-chat__form__field-label\" htmlFor=\"name\">\n {{ \"streamChat.Question\" | translate }}\n </label>\n <div class=\"str-chat__form__input-field__value\">\n <div\n class=\"str-chat__form-field-error str-chat__form__input-field__error\"\n >\n {{\n (formGroup.get(\"name\")?.errors?.required &&\n formGroup.get(\"name\")?.touched\n ? \"streamChat.Question is required\"\n : \"\"\n ) | translate\n }}\n </div>\n <input\n id=\"name\"\n type=\"text\"\n formControlName=\"name\"\n placeholder=\"{{ 'streamChat.Ask a question' | translate }}\"\n />\n </div>\n </div>\n <fieldset class=\"str-chat__form__field str-chat__form__input-fieldset\">\n <legend class=\"str-chat__form__field-label\">\n {{ \"streamChat.Options\" | translate }}\n </legend>\n <div\n class=\"str-chat__form-field-error str-chat__form__input-field__error\"\n >\n {{\n (formGroup.get(\"options\")?.errors?.atLeastOne &&\n formGroup.get(\"options\")?.touched\n ? \"streamChat.Provide at least one option\"\n : \"\"\n ) | translate\n }}\n </div>\n <ng-container formArrayName=\"options\">\n <div class=\"str-chat__form__input-fieldset__values\">\n <!-- eslint-disable @angular-eslint/template/use-track-by-function -->\n <ng-container\n *ngFor=\"let option of options.controls; let i = index\"\n >\n <!-- eslint-enable @angular-eslint/template/use-track-by-function -->\n <div class=\"str-chat__drag-and-drop-container__item\">\n <div class=\"str-chat__form__input-field\">\n <input\n id=\"option{{ i }}\"\n name=\"option{{ i }}\"\n type=\"text\"\n [formControl]=\"option\"\n (input)=\"optionChanged(i)\"\n placeholder=\"{{ 'streamChat.Add an option' | translate }}\"\n />\n </div>\n </div>\n </ng-container>\n </div>\n </ng-container>\n </fieldset>\n <ng-container\n *ngTemplateOutlet=\"\n switch;\n context: {\n name: 'multiple_answers',\n control: formGroup.get('multiple_answers'),\n label: 'streamChat.Multiple answers' | translate\n }\n \"\n ></ng-container>\n <div\n *ngIf=\"formGroup.get('multiple_answers')?.value\"\n class=\"str-chat__form__field str-chat__form__input-field str-chat__form__input-field--with-label\"\n [class.str-chat__form__input-field--has-error]=\"\n formGroup.get('maximum_number_of_votes')?.errors &&\n formGroup.get('maximum_number_of_votes')?.touched\n \"\n >\n <label class=\"str-chat__form__field-label\" htmlFor=\"name\">\n {{ \"streamChat.Maximum number of votes\" | translate }}\n </label>\n <div class=\"str-chat__form__input-field__value\">\n <div\n class=\"str-chat__form-field-error str-chat__form__input-field__error\"\n >\n {{\n (formGroup.get(\"maximum_number_of_votes\")?.errors &&\n formGroup.get(\"maximum_number_of_votes\")?.touched\n ? \"streamChat.Provide a value between {{ min }}\n and {{ max }}\" : \"\" ) | translate: { min: 2, max: 10 } }}\n </div>\n <input\n id=\"maximum_number_of_votes\"\n type=\"text\"\n formControlName=\"maximum_number_of_votes\"\n placeholder=\"{{ 'streamChat.Provide a value between ' \n + '{{ min }} and {{ max }}' | translate: { min: 2, max: 10 } }}\"\n />\n </div>\n </div>\n <ng-container\n *ngTemplateOutlet=\"\n switch;\n context: {\n name: 'is_anonymous',\n control: formGroup.get('is_anonymous'),\n label: 'streamChat.Anonymous poll' | translate\n }\n \"\n ></ng-container>\n <ng-container\n *ngTemplateOutlet=\"\n switch;\n context: {\n name: 'allow_user_suggested_options',\n control: formGroup.get('allow_user_suggested_options'),\n label: 'streamChat.Allow option suggestions' | translate\n }\n \"\n ></ng-container>\n <ng-container\n *ngTemplateOutlet=\"\n switch;\n context: {\n name: 'allow_answers',\n control: formGroup.get('allow_answers'),\n label: 'streamChat.Allow comments' | translate\n }\n \"\n ></ng-container>\n </form>\n </div>\n <stream-notification-list></stream-notification-list>\n <div class=\"str-chat__dialog__controls\">\n <button\n class=\"str-chat__dialog__controls-button str-chat__dialog__controls-button--cancel\"\n (click)=\"cancel.emit()\"\n type=\"button\"\n >\n {{ \"streamChat.Cancel\" | translate }}\n </button>\n <button\n class=\"str-chat__dialog__controls-button str-chat__dialog__controls-button--submit\"\n (click)=\"createPoll()\"\n [disabled]=\"formGroup.invalid\"\n type=\"submit\"\n >\n {{ \"streamChat.Create\" | translate }}\n </button>\n </div>\n </div>\n</ng-template>\n\n<ng-template #switch let-control=\"control\" let-label=\"label\" let-name=\"name\">\n <div class=\"str-chat__form__field str-chat__form__switch-field\">\n <label>\n <div class=\"str-chat__form__field str-chat__form__switch-field-content\">\n <div class=\"str-chat__form__field str-chat__form__switch-field__text\">\n {{ label | translate }}\n </div>\n </div>\n <input\n type=\"checkbox\"\n [checked]=\"control.value\"\n id=\"{{ name }}\"\n name=\"{{ name }}\"\n />\n <div\n class=\"str-chat__form__switch-field__switch\"\n [class.str-chat__form__switch-field__switch--on]=\"control.value\"\n (click)=\"control.setValue(!control.value, { emitEvent: true })\"\n (keyup.enter)=\"control.setValue(!control.value, { emitEvent: true })\"\n >\n <div class=\"str-chat__form__switch-field__switch-handle\"></div>\n </div>\n </label>\n </div>\n</ng-template>\n" }]
9489
+ }], ctorParameters: function () { return [{ type: CustomTemplatesService }, { type: ChatClientService }, { type: NotificationService }]; }, propDecorators: { pollCompose: [{
9490
+ type: Output
9491
+ }], cancel: [{
9492
+ type: Output
9493
+ }], formContent: [{
9494
+ type: ViewChild,
9495
+ args: ['formContent']
9496
+ }] } });
9497
+
9498
+ /**
9499
+ * @internal
9500
+ */
9501
+ class BasePollComponent {
9502
+ constructor(customTemplatesService, chatClientService, cdRef, channelService, notificationService) {
9503
+ this.customTemplatesService = customTemplatesService;
9504
+ this.chatClientService = chatClientService;
9505
+ this.cdRef = cdRef;
9506
+ this.channelService = channelService;
9507
+ this.notificationService = notificationService;
9508
+ this.canVote = false;
9509
+ this.canQueryVotes = false;
9510
+ this.isViewInited = false;
9511
+ this.capabilitySubscription = this.channelService.activeChannel$.subscribe((channel) => {
9512
+ var _a;
9513
+ if (channel) {
9514
+ const capabilities = (_a = channel.data) === null || _a === void 0 ? void 0 : _a.own_capabilities;
9515
+ this.canVote = capabilities.indexOf('cast-poll-vote') !== -1;
9516
+ this.canQueryVotes = capabilities.indexOf('query-poll-votes') !== -1;
9517
+ }
9518
+ });
9519
+ }
9520
+ ngOnChanges(changes) {
9521
+ var _a, _b;
9522
+ if (changes['pollId']) {
9523
+ if (this.pollId) {
9524
+ this.setupStateStoreSelector();
9525
+ }
9526
+ else {
9527
+ (_a = this.pollStateUnsubscribe) === null || _a === void 0 ? void 0 : _a.call(this);
9528
+ }
9529
+ (_b = this.dismissNotificationFn) === null || _b === void 0 ? void 0 : _b.call(this);
9530
+ }
9531
+ }
9532
+ ngAfterViewInit() {
9533
+ this.isViewInited = true;
9534
+ }
9535
+ ngOnDestroy() {
9536
+ var _a, _b, _c;
9537
+ (_a = this.pollStateUnsubscribe) === null || _a === void 0 ? void 0 : _a.call(this);
9538
+ (_b = this.dismissNotificationFn) === null || _b === void 0 ? void 0 : _b.call(this);
9539
+ (_c = this.capabilitySubscription) === null || _c === void 0 ? void 0 : _c.unsubscribe();
9540
+ }
9541
+ get poll() {
9542
+ var _a;
9543
+ return this.chatClientService.chatClient.polls.fromState((_a = this.pollId) !== null && _a !== void 0 ? _a : '');
9544
+ }
9545
+ setupStateStoreSelector() {
9546
+ var _a, _b;
9547
+ (_a = this.pollStateUnsubscribe) === null || _a === void 0 ? void 0 : _a.call(this);
9548
+ const poll = this.chatClientService.chatClient.polls.fromState((_b = this.pollId) !== null && _b !== void 0 ? _b : '');
9549
+ if (poll) {
9550
+ this.pollStateUnsubscribe = this.stateStoreSelector(poll, () => {
9551
+ this.markForCheck();
9552
+ });
9553
+ }
9554
+ }
9555
+ addNotification(...args) {
9556
+ var _a;
9557
+ (_a = this.dismissNotificationFn) === null || _a === void 0 ? void 0 : _a.call(this);
9558
+ this.dismissNotificationFn =
9559
+ this.notificationService.addTemporaryNotification(...args);
9560
+ }
9561
+ get currentUser() {
9562
+ return this.chatClientService.chatClient.user;
9563
+ }
9564
+ markForCheck() {
9565
+ if (this.isViewInited) {
9566
+ this.cdRef.detectChanges();
9567
+ }
9568
+ }
9569
+ }
9570
+ BasePollComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: BasePollComponent, deps: [{ token: CustomTemplatesService }, { token: ChatClientService }, { token: i0.ChangeDetectorRef }, { token: ChannelService }, { token: NotificationService }], target: i0.ɵɵFactoryTarget.Component });
9571
+ BasePollComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: BasePollComponent, selector: "stream-base-poll", inputs: { pollId: "pollId", messageId: "messageId" }, usesOnChanges: true, ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
9572
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: BasePollComponent, decorators: [{
9573
+ type: Component,
9574
+ args: [{
9575
+ selector: 'stream-base-poll',
9576
+ template: '',
9577
+ changeDetection: ChangeDetectionStrategy.OnPush,
9578
+ }]
9579
+ }], ctorParameters: function () { return [{ type: CustomTemplatesService }, { type: ChatClientService }, { type: i0.ChangeDetectorRef }, { type: ChannelService }, { type: NotificationService }]; }, propDecorators: { pollId: [{
9580
+ type: Input
9581
+ }], messageId: [{
9582
+ type: Input
9583
+ }] } });
9584
+
9585
+ /**
9586
+ *
9587
+ */
9588
+ class PollHeaderComponent extends BasePollComponent {
9589
+ constructor() {
9590
+ super(...arguments);
9591
+ this.name = '';
9592
+ this.selectionInstructions = {
9593
+ text: '',
9594
+ count: undefined,
9595
+ };
9596
+ }
9597
+ stateStoreSelector(poll, markForCheck) {
9598
+ const unsubscribe = poll.state.subscribeWithSelector((state) => ({
9599
+ name: state.name,
9600
+ is_closed: state.is_closed,
9601
+ enforce_unique_vote: state.enforce_unique_vote,
9602
+ max_votes_allowed: state.max_votes_allowed,
9603
+ options: state.options,
9604
+ }), (state) => {
9605
+ const name = state.name;
9606
+ const selectionInstructions = this.getSelectionInstructions(state);
9607
+ let changed = false;
9608
+ if (name !== this.name) {
9609
+ this.name = name;
9610
+ changed = true;
9611
+ }
9612
+ if (selectionInstructions.text !== this.selectionInstructions.text ||
9613
+ selectionInstructions.count !== this.selectionInstructions.count) {
9614
+ this.selectionInstructions = selectionInstructions;
9615
+ changed = true;
9616
+ }
9617
+ if (changed) {
9618
+ markForCheck();
9619
+ }
9620
+ });
9621
+ return unsubscribe;
9622
+ }
9623
+ getSelectionInstructions(state) {
9624
+ if (state.is_closed)
9625
+ return {
9626
+ text: 'streamChat.Vote ended',
9627
+ count: undefined,
9628
+ };
9629
+ if (state.enforce_unique_vote || state.options.length === 1) {
9630
+ return {
9631
+ text: 'streamChat.Select one',
9632
+ count: undefined,
9633
+ };
9634
+ }
9635
+ if (state.max_votes_allowed)
9636
+ return {
9637
+ text: 'streamChat.Select up to {{count}}',
9638
+ count: state.max_votes_allowed > state.options.length
9639
+ ? state.options.length
9640
+ : state.max_votes_allowed,
9641
+ };
9642
+ if (state.options.length > 1) {
9643
+ return {
9644
+ text: 'streamChat.Select one or more',
9645
+ count: undefined,
9646
+ };
9647
+ }
9648
+ return {
9649
+ text: '',
9650
+ count: undefined,
9651
+ };
9652
+ }
9653
+ }
9654
+ PollHeaderComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: PollHeaderComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
9655
+ PollHeaderComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: PollHeaderComponent, selector: "stream-poll-header", usesInheritance: true, ngImport: i0, template: "<div class=\"str-chat__poll-header\">\n <div class=\"str-chat__poll-title\">{{ name }}</div>\n <div class=\"str-chat__poll-subtitle\">\n {{ selectionInstructions.text | translate : selectionInstructions }}\n </div>\n</div>\n", dependencies: [{ kind: "pipe", type: i6.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
9656
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: PollHeaderComponent, decorators: [{
9657
+ type: Component,
9658
+ args: [{ selector: 'stream-poll-header', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"str-chat__poll-header\">\n <div class=\"str-chat__poll-title\">{{ name }}</div>\n <div class=\"str-chat__poll-subtitle\">\n {{ selectionInstructions.text | translate : selectionInstructions }}\n </div>\n</div>\n" }]
9659
+ }] });
9660
+
9661
+ /**
9662
+ *
9663
+ */
9664
+ class PollOptionSelectorComponent extends BasePollComponent {
9665
+ constructor() {
9666
+ super(...arguments);
9667
+ this.displayAvatarCount = 3;
9668
+ this.voteCountVerbose = false;
9669
+ this.isClosed = false;
9670
+ this.latestVotes = [];
9671
+ this.isWinner = false;
9672
+ this.voteCount = 0;
9673
+ this.winningOptionCount = 0;
9674
+ this.maxVoteAllowedCount = 0;
9675
+ this.ownVoteCount = 0;
9676
+ }
9677
+ ngOnChanges(changes) {
9678
+ super.ngOnChanges(changes);
9679
+ if (changes['option']) {
9680
+ this.setupStateStoreSelector();
9681
+ }
9682
+ }
9683
+ toggleVote() {
9684
+ var _a, _b, _c, _d;
9685
+ return __awaiter(this, void 0, void 0, function* () {
9686
+ if (!this.canVote || !((_a = this.option) === null || _a === void 0 ? void 0 : _a.id) || !this.messageId || this.isClosed)
9687
+ return;
9688
+ const haveVotedForTheOption = !!this.ownVote;
9689
+ if (!haveVotedForTheOption &&
9690
+ this.maxVoteAllowedCount > 0 &&
9691
+ this.ownVoteCount >= this.maxVoteAllowedCount) {
9692
+ this.addNotification('streamChat.You have reached the maximum number of votes allowed');
9693
+ return;
9694
+ }
9695
+ try {
9696
+ yield (haveVotedForTheOption
9697
+ ? (_b = this.poll) === null || _b === void 0 ? void 0 : _b.removeVote(this.ownVote.id, this.messageId)
9698
+ : (_c = this.poll) === null || _c === void 0 ? void 0 : _c.castVote((_d = this.option) === null || _d === void 0 ? void 0 : _d.id, this.messageId));
9699
+ }
9700
+ catch (error) {
9701
+ this.notificationService.addTemporaryNotification('streamChat.Failed to cast vote');
9702
+ throw error;
9703
+ }
9704
+ });
9705
+ }
9706
+ trackByVoteId(_, vote) {
9707
+ return vote.id;
9708
+ }
9709
+ stateStoreSelector(poll, markForCheck) {
9710
+ const unsubscribe = poll.state.subscribeWithSelector((nextValue) => {
9711
+ return {
9712
+ is_closed: nextValue.is_closed,
9713
+ latest_votes_by_option: nextValue.latest_votes_by_option,
9714
+ maxVotedOptionIds: nextValue.maxVotedOptionIds,
9715
+ ownVotesByOptionId: nextValue.ownVotesByOptionId,
9716
+ vote_counts_by_option: nextValue.vote_counts_by_option,
9717
+ voting_visibility: nextValue.voting_visibility,
9718
+ max_votes_allowed: nextValue.max_votes_allowed,
9719
+ };
9720
+ }, (state) => {
9721
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
9722
+ const isClosed = state.is_closed;
9723
+ const latestVotes = (_d = (_c = state.latest_votes_by_option[(_b = (_a = this.option) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : '']) === null || _c === void 0 ? void 0 : _c.filter((vote) => !!vote.user && !isVoteAnswer(vote))) !== null && _d !== void 0 ? _d : [];
9724
+ const isWinner = state.maxVotedOptionIds.includes((_f = (_e = this.option) === null || _e === void 0 ? void 0 : _e.id) !== null && _f !== void 0 ? _f : '') &&
9725
+ state.maxVotedOptionIds.length === 1;
9726
+ const ownVote = state.ownVotesByOptionId[(_h = (_g = this.option) === null || _g === void 0 ? void 0 : _g.id) !== null && _h !== void 0 ? _h : ''];
9727
+ const voteCount = state.vote_counts_by_option[(_k = (_j = this.option) === null || _j === void 0 ? void 0 : _j.id) !== null && _k !== void 0 ? _k : ''];
9728
+ const votingVisibility = state.voting_visibility;
9729
+ const winningOptionCount = state.vote_counts_by_option[(_m = (_l = state.maxVotedOptionIds) === null || _l === void 0 ? void 0 : _l[0]) !== null && _m !== void 0 ? _m : ''];
9730
+ const maxVoteAllowedCount = state.max_votes_allowed;
9731
+ const ownVoteCount = Object.keys(state.ownVotesByOptionId).length;
9732
+ let changed = false;
9733
+ if (isClosed !== this.isClosed) {
9734
+ this.isClosed = isClosed !== null && isClosed !== void 0 ? isClosed : false;
9735
+ changed = true;
9736
+ }
9737
+ if (latestVotes !== this.latestVotes) {
9738
+ this.latestVotes = latestVotes !== null && latestVotes !== void 0 ? latestVotes : [];
9739
+ changed = true;
9740
+ }
9741
+ if (isWinner !== this.isWinner) {
9742
+ this.isWinner = isWinner !== null && isWinner !== void 0 ? isWinner : false;
9743
+ changed = true;
9744
+ }
9745
+ if (ownVote !== this.ownVote) {
9746
+ this.ownVote = ownVote !== null && ownVote !== void 0 ? ownVote : undefined;
9747
+ changed = true;
9748
+ }
9749
+ if (voteCount !== this.voteCount) {
9750
+ this.voteCount = voteCount !== null && voteCount !== void 0 ? voteCount : 0;
9751
+ changed = true;
9752
+ }
9753
+ if (votingVisibility !== this.votingVisibility) {
9754
+ this.votingVisibility = votingVisibility !== null && votingVisibility !== void 0 ? votingVisibility : undefined;
9755
+ changed = true;
9756
+ }
9757
+ if (winningOptionCount !== this.winningOptionCount) {
9758
+ this.winningOptionCount = winningOptionCount !== null && winningOptionCount !== void 0 ? winningOptionCount : 0;
9759
+ changed = true;
9760
+ }
9761
+ if (maxVoteAllowedCount !== this.maxVoteAllowedCount) {
9762
+ this.maxVoteAllowedCount = maxVoteAllowedCount !== null && maxVoteAllowedCount !== void 0 ? maxVoteAllowedCount : 0;
9763
+ changed = true;
9764
+ }
9765
+ if (ownVoteCount !== this.ownVoteCount) {
9766
+ this.ownVoteCount = ownVoteCount !== null && ownVoteCount !== void 0 ? ownVoteCount : 0;
9767
+ changed = true;
9768
+ }
9769
+ if (this.dismissNotificationFn &&
9770
+ this.maxVoteAllowedCount > 0 &&
9771
+ this.ownVoteCount <= this.maxVoteAllowedCount) {
9772
+ this.dismissNotificationFn();
9773
+ changed = true;
9774
+ }
9775
+ if (changed) {
9776
+ markForCheck();
9777
+ }
9778
+ });
9779
+ return unsubscribe;
9780
+ }
9781
+ }
9782
+ PollOptionSelectorComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: PollOptionSelectorComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
9783
+ PollOptionSelectorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: PollOptionSelectorComponent, selector: "stream-poll-option-selector", inputs: { option: "option", displayAvatarCount: "displayAvatarCount", voteCountVerbose: "voteCountVerbose" }, usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<div\n class=\"str-chat__poll-option\"\n [class.str-chat__poll-option--votable]=\"\n !isClosed &&\n canVote &&\n maxVoteAllowedCount &&\n ownVoteCount < maxVoteAllowedCount &&\n !ownVote\n \"\n (click)=\"toggleVote()\"\n (keyup.enter)=\"toggleVote()\"\n>\n <ng-container *ngIf=\"canVote\">\n <ng-container *ngTemplateOutlet=\"checkmark\"></ng-container>\n </ng-container>\n <div class=\"str-chat__poll-option-data\">\n <p class=\"str-chat__poll-option-text\">{{ option?.text }}</p>\n <ng-container *ngIf=\"displayAvatarCount && votingVisibility === 'public'\">\n <div\n *ngFor=\"let vote of latestVotes; trackBy: trackByVoteId\"\n class=\"str-chat__poll-option-voters\"\n >\n <stream-avatar-placeholder\n location=\"poll-voter\"\n [user]=\"vote.user\"\n [imageUrl]=\"vote.user?.image\"\n [name]=\"vote.user?.name\"\n type=\"user\"\n ></stream-avatar-placeholder>\n </div>\n </ng-container>\n <div class=\"str-chat__poll-option-vote-count\">\n <ng-container *ngIf=\"voteCountVerbose; else count\">\n {{ 'streamChat.{{ count }} votes' | translate:{count: voteCount} }}\n </ng-container>\n <ng-template #count>\n {{ voteCount }}\n </ng-template>\n </div>\n </div>\n <ng-container *ngTemplateOutlet=\"amountBar\"></ng-container>\n</div>\n\n<ng-template #checkmark>\n <div\n class=\"str-chat__checkmark\"\n [class.str-chat__checkmark--checked]=\"!!ownVote\"\n ></div>\n</ng-template>\n\n<ng-template #amountBar>\n <div\n class=\"str-chat__amount-bar str-chat__poll-option__votes-bar\"\n [class.str-chat__poll-option__votes-bar--winner]=\"isClosed && isWinner\"\n role=\"progressbar\"\n [ngStyle]=\"{\n '--str-chat__amount-bar-fulfillment':\n (winningOptionCount && voteCount / winningOptionCount) * 100 + '%'\n }\"\n ></div>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: AvatarPlaceholderComponent, selector: "stream-avatar-placeholder", inputs: ["name", "imageUrl", "location", "channel", "user", "type", "initialsType", "showOnlineIndicator"] }, { kind: "pipe", type: i6.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
9784
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: PollOptionSelectorComponent, decorators: [{
9785
+ type: Component,
9786
+ args: [{ selector: 'stream-poll-option-selector', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n class=\"str-chat__poll-option\"\n [class.str-chat__poll-option--votable]=\"\n !isClosed &&\n canVote &&\n maxVoteAllowedCount &&\n ownVoteCount < maxVoteAllowedCount &&\n !ownVote\n \"\n (click)=\"toggleVote()\"\n (keyup.enter)=\"toggleVote()\"\n>\n <ng-container *ngIf=\"canVote\">\n <ng-container *ngTemplateOutlet=\"checkmark\"></ng-container>\n </ng-container>\n <div class=\"str-chat__poll-option-data\">\n <p class=\"str-chat__poll-option-text\">{{ option?.text }}</p>\n <ng-container *ngIf=\"displayAvatarCount && votingVisibility === 'public'\">\n <div\n *ngFor=\"let vote of latestVotes; trackBy: trackByVoteId\"\n class=\"str-chat__poll-option-voters\"\n >\n <stream-avatar-placeholder\n location=\"poll-voter\"\n [user]=\"vote.user\"\n [imageUrl]=\"vote.user?.image\"\n [name]=\"vote.user?.name\"\n type=\"user\"\n ></stream-avatar-placeholder>\n </div>\n </ng-container>\n <div class=\"str-chat__poll-option-vote-count\">\n <ng-container *ngIf=\"voteCountVerbose; else count\">\n {{ 'streamChat.{{ count }} votes' | translate:{count: voteCount} }}\n </ng-container>\n <ng-template #count>\n {{ voteCount }}\n </ng-template>\n </div>\n </div>\n <ng-container *ngTemplateOutlet=\"amountBar\"></ng-container>\n</div>\n\n<ng-template #checkmark>\n <div\n class=\"str-chat__checkmark\"\n [class.str-chat__checkmark--checked]=\"!!ownVote\"\n ></div>\n</ng-template>\n\n<ng-template #amountBar>\n <div\n class=\"str-chat__amount-bar str-chat__poll-option__votes-bar\"\n [class.str-chat__poll-option__votes-bar--winner]=\"isClosed && isWinner\"\n role=\"progressbar\"\n [ngStyle]=\"{\n '--str-chat__amount-bar-fulfillment':\n (winningOptionCount && voteCount / winningOptionCount) * 100 + '%'\n }\"\n ></div>\n</ng-template>\n" }]
9787
+ }], propDecorators: { option: [{
9788
+ type: Input
9789
+ }], displayAvatarCount: [{
9790
+ type: Input
9791
+ }], voteCountVerbose: [{
9792
+ type: Input
9793
+ }] } });
9794
+
9795
+ /**
9796
+ *
9797
+ */
9798
+ class PollOptionsListComponent extends BasePollComponent {
9799
+ constructor() {
9800
+ super(...arguments);
9801
+ /**
9802
+ * How many options should be displayed. If there are more options than this number, use the poll actions to display all options
9803
+ */
9804
+ this.maxOptionsDisplayed = 10;
9805
+ this.options = [];
9806
+ }
9807
+ stateStoreSelector(poll, markForCheck) {
9808
+ const unsubscribe = poll.state.subscribeWithSelector((state) => ({
9809
+ options: state.options,
9810
+ }), (state) => {
9811
+ this.options = state.options;
9812
+ markForCheck();
9813
+ });
9814
+ return unsubscribe;
9815
+ }
9816
+ trackByOptionId(_, option) {
9817
+ return option.id;
9818
+ }
9819
+ }
9820
+ PollOptionsListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: PollOptionsListComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
9821
+ PollOptionsListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: PollOptionsListComponent, selector: "stream-poll-options-list", inputs: { maxOptionsDisplayed: "maxOptionsDisplayed" }, usesInheritance: true, ngImport: i0, template: "<div\n class=\"str-chat__poll-option-list\"\n [class.str-chat__poll-option-list--full]=\"\n !maxOptionsDisplayed || maxOptionsDisplayed === options.length\n \"\n>\n <ng-container\n *ngFor=\"\n let option of options | slice : 0 : maxOptionsDisplayed;\n trackBy: trackByOptionId\n \"\n >\n <stream-poll-option-selector\n [option]=\"option\"\n [messageId]=\"messageId\"\n [pollId]=\"pollId\"\n ></stream-poll-option-selector>\n </ng-container>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: PollOptionSelectorComponent, selector: "stream-poll-option-selector", inputs: ["option", "displayAvatarCount", "voteCountVerbose"] }, { kind: "pipe", type: i1.SlicePipe, name: "slice" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
9822
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: PollOptionsListComponent, decorators: [{
9823
+ type: Component,
9824
+ args: [{ selector: 'stream-poll-options-list', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n class=\"str-chat__poll-option-list\"\n [class.str-chat__poll-option-list--full]=\"\n !maxOptionsDisplayed || maxOptionsDisplayed === options.length\n \"\n>\n <ng-container\n *ngFor=\"\n let option of options | slice : 0 : maxOptionsDisplayed;\n trackBy: trackByOptionId\n \"\n >\n <stream-poll-option-selector\n [option]=\"option\"\n [messageId]=\"messageId\"\n [pollId]=\"pollId\"\n ></stream-poll-option-selector>\n </ng-container>\n</div>\n" }]
9825
+ }], propDecorators: { maxOptionsDisplayed: [{
9826
+ type: Input
9827
+ }] } });
9828
+
9829
+ /**
9830
+ *
9831
+ */
9832
+ class PollVoteComponent {
9833
+ constructor(translateService, dateParser) {
9834
+ this.translateService = translateService;
9835
+ this.dateParser = dateParser;
9836
+ this.anonymousTranslation = 'Anonymous';
9837
+ this.translateService
9838
+ .get('streamChat.Anonymous')
9839
+ .subscribe((translation) => {
9840
+ this.anonymousTranslation = translation;
9841
+ });
9842
+ }
9843
+ parseDate(date) {
9844
+ return this.dateParser.parseDateTime(new Date(date));
9845
+ }
9846
+ }
9847
+ PollVoteComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: PollVoteComponent, deps: [{ token: i6.TranslateService }, { token: DateParserService }], target: i0.ɵɵFactoryTarget.Component });
9848
+ PollVoteComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: PollVoteComponent, selector: "stream-poll-vote", inputs: { vote: "vote" }, ngImport: i0, template: "<div class=\"str-chat__poll-vote\">\n <div class=\"str-chat__poll-vote__author\">\n <stream-avatar-placeholder\n location=\"poll-voter\"\n [user]=\"vote?.user\"\n [imageUrl]=\"vote?.user?.image\"\n [name]=\"vote?.user?.name ?? anonymousTranslation\"\n type=\"user\"\n ></stream-avatar-placeholder>\n <div class=\"str-chat__poll-vote__author__name\">\n {{ vote?.user?.name ?? anonymousTranslation }}\n </div>\n </div>\n <div *ngIf=\"vote?.created_at\" class=\"str-chat__poll-vote__timestamp\">\n {{ parseDate(vote!.created_at) }}\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: AvatarPlaceholderComponent, selector: "stream-avatar-placeholder", inputs: ["name", "imageUrl", "location", "channel", "user", "type", "initialsType", "showOnlineIndicator"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
9849
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: PollVoteComponent, decorators: [{
9850
+ type: Component,
9851
+ args: [{ selector: 'stream-poll-vote', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"str-chat__poll-vote\">\n <div class=\"str-chat__poll-vote__author\">\n <stream-avatar-placeholder\n location=\"poll-voter\"\n [user]=\"vote?.user\"\n [imageUrl]=\"vote?.user?.image\"\n [name]=\"vote?.user?.name ?? anonymousTranslation\"\n type=\"user\"\n ></stream-avatar-placeholder>\n <div class=\"str-chat__poll-vote__author__name\">\n {{ vote?.user?.name ?? anonymousTranslation }}\n </div>\n </div>\n <div *ngIf=\"vote?.created_at\" class=\"str-chat__poll-vote__timestamp\">\n {{ parseDate(vote!.created_at) }}\n </div>\n</div>\n" }]
9852
+ }], ctorParameters: function () { return [{ type: i6.TranslateService }, { type: DateParserService }]; }, propDecorators: { vote: [{
9853
+ type: Input
9854
+ }] } });
9855
+
9856
+ /**
9857
+ *
9858
+ */
9859
+ class PollVoteResultsListComponent extends BasePollComponent {
9860
+ constructor() {
9861
+ super(...arguments);
9862
+ this.isWinner = false;
9863
+ this.voteCount = 0;
9864
+ this.isLoading = false;
9865
+ this.votes = [];
9866
+ this.trackByVoteId = (_, vote) => {
9867
+ return vote.id;
9868
+ };
9869
+ }
9870
+ ngOnChanges(changes) {
9871
+ super.ngOnChanges(changes);
9872
+ if (changes['option']) {
9873
+ this.setupStateStoreSelector();
9874
+ this.next = undefined;
9875
+ this.votes = [];
9876
+ void this.loadVotes();
9877
+ }
9878
+ }
9879
+ loadVotes() {
9880
+ var _a, _b;
9881
+ return __awaiter(this, void 0, void 0, function* () {
9882
+ if (!this.poll) {
9883
+ return;
9884
+ }
9885
+ try {
9886
+ this.isLoading = true;
9887
+ const response = yield this.poll.queryOptionVotes({
9888
+ filter: {
9889
+ option_id: (_b = (_a = this.option) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : '',
9890
+ },
9891
+ sort: { created_at: -1 },
9892
+ options: {
9893
+ next: this.next,
9894
+ },
9895
+ });
9896
+ this.next = response.next;
9897
+ this.votes = [...this.votes, ...response.votes];
9898
+ this.markForCheck();
9899
+ }
9900
+ catch (error) {
9901
+ this.notificationService.addTemporaryNotification('streamChat.Error loading votes');
9902
+ throw error;
9903
+ this.markForCheck();
9904
+ }
9905
+ finally {
9906
+ this.isLoading = false;
9907
+ this.markForCheck();
9908
+ }
9909
+ });
9910
+ }
9911
+ stateStoreSelector(poll, markForCheck) {
9912
+ const subscribe = poll.state.subscribeWithSelector((state) => {
9913
+ var _a, _b;
9914
+ return ({
9915
+ voteCount: state.vote_counts_by_option[(_b = (_a = this.option) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : ''],
9916
+ maxVotedOptionIds: state.maxVotedOptionIds,
9917
+ });
9918
+ }, (state) => {
9919
+ var _a, _b, _c, _d;
9920
+ this.isWinner =
9921
+ ((_a = state.maxVotedOptionIds) === null || _a === void 0 ? void 0 : _a.includes((_c = (_b = this.option) === null || _b === void 0 ? void 0 : _b.id) !== null && _c !== void 0 ? _c : '')) &&
9922
+ state.maxVotedOptionIds.length === 1;
9923
+ this.voteCount = (_d = state.voteCount) !== null && _d !== void 0 ? _d : 0;
9924
+ markForCheck();
9925
+ });
9926
+ return subscribe;
9927
+ }
9928
+ }
9929
+ PollVoteResultsListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: PollVoteResultsListComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
9930
+ PollVoteResultsListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: PollVoteResultsListComponent, selector: "stream-poll-vote-results-list", inputs: { option: "option" }, usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<div class=\"str-chat__poll-option str-chat__poll-option--full-vote-list\">\n <div class=\"str-chat__poll-option__header\">\n <div class=\"str-chat__poll-option__option-text\">{{ option?.text }}</div>\n <div class=\"str-chat__poll-result-option-vote-counter\">\n <div\n *ngIf=\"isWinner\"\n class=\"str-chat__poll-result-winning-option-icon\"\n ></div>\n <span class=\"str-chat__poll-result-option-vote-count\">\n {{ 'streamChat.{{ count }} votes' | translate:{count: voteCount ?? 0} }}\n </span>\n </div>\n </div>\n <stream-paginated-list\n class=\"str-chat__poll-vote-listing\"\n [items]=\"votes\"\n [hasMore]=\"next !== undefined\"\n [isLoading]=\"isLoading\"\n [trackBy]=\"trackByVoteId\"\n (loadMore)=\"loadVotes()\"\n >\n <ng-template let-vote=\"item\">\n <stream-poll-vote [vote]=\"vote\"></stream-poll-vote>\n </ng-template>\n </stream-paginated-list>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: PaginatedListComponent, selector: "stream-paginated-list", inputs: ["items", "isLoading", "hasMore", "trackBy"], outputs: ["loadMore"] }, { kind: "component", type: PollVoteComponent, selector: "stream-poll-vote", inputs: ["vote"] }, { kind: "pipe", type: i6.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
9931
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: PollVoteResultsListComponent, decorators: [{
9932
+ type: Component,
9933
+ args: [{ selector: 'stream-poll-vote-results-list', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"str-chat__poll-option str-chat__poll-option--full-vote-list\">\n <div class=\"str-chat__poll-option__header\">\n <div class=\"str-chat__poll-option__option-text\">{{ option?.text }}</div>\n <div class=\"str-chat__poll-result-option-vote-counter\">\n <div\n *ngIf=\"isWinner\"\n class=\"str-chat__poll-result-winning-option-icon\"\n ></div>\n <span class=\"str-chat__poll-result-option-vote-count\">\n {{ 'streamChat.{{ count }} votes' | translate:{count: voteCount ?? 0} }}\n </span>\n </div>\n </div>\n <stream-paginated-list\n class=\"str-chat__poll-vote-listing\"\n [items]=\"votes\"\n [hasMore]=\"next !== undefined\"\n [isLoading]=\"isLoading\"\n [trackBy]=\"trackByVoteId\"\n (loadMore)=\"loadVotes()\"\n >\n <ng-template let-vote=\"item\">\n <stream-poll-vote [vote]=\"vote\"></stream-poll-vote>\n </ng-template>\n </stream-paginated-list>\n</div>\n" }]
9934
+ }], propDecorators: { option: [{
9935
+ type: Input
9936
+ }] } });
9937
+
9938
+ /**
9939
+ *
9940
+ */
9941
+ class PollResultsListComponent extends BasePollComponent {
9942
+ constructor() {
9943
+ super(...arguments);
9944
+ this.class = 'str-chat__modal__poll-results';
9945
+ this.name = '';
9946
+ this.options = [];
9947
+ this.votePreviewCount = 5;
9948
+ this.maxVotedOptionIds = [];
9949
+ this.voteCountsByOption = {};
9950
+ this.latestVotesByOption = {};
9951
+ }
9952
+ stateStoreSelector(poll, markForCheck) {
9953
+ const unsubscribe = poll.state.subscribeWithSelector((state) => ({
9954
+ name: state.name,
9955
+ options: state.options,
9956
+ maxVotedOptionIds: state.maxVotedOptionIds,
9957
+ vote_counts_by_option: state.vote_counts_by_option,
9958
+ latest_votes_by_option: state.latest_votes_by_option,
9959
+ }), (state) => {
9960
+ this.name = state.name;
9961
+ this.options = [...state.options];
9962
+ this.options.sort((a, b) => {
9963
+ var _a, _b;
9964
+ return (((_a = state.vote_counts_by_option[b.id]) !== null && _a !== void 0 ? _a : 0) -
9965
+ ((_b = state.vote_counts_by_option[a.id]) !== null && _b !== void 0 ? _b : 0));
9966
+ });
9967
+ this.maxVotedOptionIds = state.maxVotedOptionIds;
9968
+ this.voteCountsByOption = state.vote_counts_by_option;
9969
+ this.latestVotesByOption = state.latest_votes_by_option;
9970
+ markForCheck();
9971
+ });
9972
+ return unsubscribe;
9973
+ }
9974
+ isWinner(optionId) {
9975
+ return (this.maxVotedOptionIds.length === 1 &&
9976
+ this.maxVotedOptionIds[0] === optionId);
9977
+ }
9978
+ trackByOptionId(_, option) {
9979
+ return option.id;
9980
+ }
9981
+ trackByVoteId(_, vote) {
9982
+ return vote.id;
9983
+ }
9984
+ }
9985
+ PollResultsListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: PollResultsListComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
9986
+ PollResultsListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: PollResultsListComponent, selector: "stream-poll-results-list", host: { properties: { "class": "this.class" } }, usesInheritance: true, ngImport: i0, template: "<div\n class=\"str-chat__modal__poll-results\"\n [class.str-chat__modal__poll-results--option-detail]=\"optionToView\"\n>\n <div class=\"str-chat__modal-header\">\n <!-- eslint-disable-next-line @angular-eslint/template/accessibility-elements-content -->\n <button\n *ngIf=\"optionToView\"\n class=\"str-chat__modal-header__go-back-button\"\n (click)=\"optionToView = undefined\"\n ></button>\n <div class=\"str-chat__modal-header__title\" translate>\n streamChat.Poll results\n </div>\n </div>\n <ng-container *ngIf=\"optionToView; else allOptions\">\n <div class=\"str-chat__modal__poll-results__body\">\n <stream-poll-vote-results-list\n [option]=\"optionToView\"\n [messageId]=\"messageId\"\n [pollId]=\"pollId\"\n ></stream-poll-vote-results-list>\n </div>\n </ng-container>\n <ng-template #allOptions>\n <div class=\"str-chat__modal__poll-results__body\">\n <div class=\"str-chat__modal__poll-results__title\">{{ name }}</div>\n <div class=\"str-chat__modal__poll-results__option-list\">\n <div\n *ngFor=\"let option of options; trackBy: trackByOptionId\"\n class=\"str-chat__poll-option\"\n >\n <div class=\"str-chat__poll-option__header\">\n <div class=\"str-chat__poll-option__option-text\">\n {{ option.text }}\n </div>\n <div class=\"str-chat__poll-result-option-vote-counter\">\n <div\n *ngIf=\"isWinner(option.id)\"\n class=\"str-chat__poll-result-winning-option-icon\"\n ></div>\n <span class=\"str-chat__poll-result-option-vote-count\">\n {{ 'streamChat.{{ count }} votes' | translate:{count:\n voteCountsByOption[option.id] ?? 0} }}\n </span>\n </div>\n </div>\n <ng-container *ngIf=\"latestVotesByOption[option?.id ?? '']\">\n <div class=\"str-chat__poll-vote-listing\">\n <ng-container\n *ngFor=\"\n let vote of latestVotesByOption[option?.id ?? '']\n | slice : 0 : votePreviewCount;\n trackBy: trackByVoteId\n \"\n >\n <stream-poll-vote [vote]=\"vote\"></stream-poll-vote>\n </ng-container>\n </div>\n </ng-container>\n <button\n *ngIf=\"\n voteCountsByOption[option?.id ?? ''] > votePreviewCount &&\n canQueryVotes\n \"\n class=\"str-chat__poll-option__show-all-votes-button\"\n translate\n (click)=\"optionToView = option\"\n >\n streamChat.Show all\n </button>\n </div>\n </div>\n </div>\n </ng-template>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i6.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "component", type: PollVoteResultsListComponent, selector: "stream-poll-vote-results-list", inputs: ["option"] }, { kind: "component", type: PollVoteComponent, selector: "stream-poll-vote", inputs: ["vote"] }, { kind: "pipe", type: i1.SlicePipe, name: "slice" }, { kind: "pipe", type: i6.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
9987
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: PollResultsListComponent, decorators: [{
9988
+ type: Component,
9989
+ args: [{ selector: 'stream-poll-results-list', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n class=\"str-chat__modal__poll-results\"\n [class.str-chat__modal__poll-results--option-detail]=\"optionToView\"\n>\n <div class=\"str-chat__modal-header\">\n <!-- eslint-disable-next-line @angular-eslint/template/accessibility-elements-content -->\n <button\n *ngIf=\"optionToView\"\n class=\"str-chat__modal-header__go-back-button\"\n (click)=\"optionToView = undefined\"\n ></button>\n <div class=\"str-chat__modal-header__title\" translate>\n streamChat.Poll results\n </div>\n </div>\n <ng-container *ngIf=\"optionToView; else allOptions\">\n <div class=\"str-chat__modal__poll-results__body\">\n <stream-poll-vote-results-list\n [option]=\"optionToView\"\n [messageId]=\"messageId\"\n [pollId]=\"pollId\"\n ></stream-poll-vote-results-list>\n </div>\n </ng-container>\n <ng-template #allOptions>\n <div class=\"str-chat__modal__poll-results__body\">\n <div class=\"str-chat__modal__poll-results__title\">{{ name }}</div>\n <div class=\"str-chat__modal__poll-results__option-list\">\n <div\n *ngFor=\"let option of options; trackBy: trackByOptionId\"\n class=\"str-chat__poll-option\"\n >\n <div class=\"str-chat__poll-option__header\">\n <div class=\"str-chat__poll-option__option-text\">\n {{ option.text }}\n </div>\n <div class=\"str-chat__poll-result-option-vote-counter\">\n <div\n *ngIf=\"isWinner(option.id)\"\n class=\"str-chat__poll-result-winning-option-icon\"\n ></div>\n <span class=\"str-chat__poll-result-option-vote-count\">\n {{ 'streamChat.{{ count }} votes' | translate:{count:\n voteCountsByOption[option.id] ?? 0} }}\n </span>\n </div>\n </div>\n <ng-container *ngIf=\"latestVotesByOption[option?.id ?? '']\">\n <div class=\"str-chat__poll-vote-listing\">\n <ng-container\n *ngFor=\"\n let vote of latestVotesByOption[option?.id ?? '']\n | slice : 0 : votePreviewCount;\n trackBy: trackByVoteId\n \"\n >\n <stream-poll-vote [vote]=\"vote\"></stream-poll-vote>\n </ng-container>\n </div>\n </ng-container>\n <button\n *ngIf=\"\n voteCountsByOption[option?.id ?? ''] > votePreviewCount &&\n canQueryVotes\n \"\n class=\"str-chat__poll-option__show-all-votes-button\"\n translate\n (click)=\"optionToView = option\"\n >\n streamChat.Show all\n </button>\n </div>\n </div>\n </div>\n </ng-template>\n</div>\n" }]
9990
+ }], propDecorators: { class: [{
9991
+ type: HostBinding,
9992
+ args: ['class']
9993
+ }] } });
9994
+
9995
+ /**
9996
+ *
9997
+ */
9998
+ class PollAnswersListComponent extends BasePollComponent {
9999
+ constructor() {
10000
+ super(...arguments);
10001
+ this.class = 'str-chat__modal__poll-answer-list';
10002
+ /**
10003
+ * The even that's emitted when the update/add comment button is clicked
10004
+ */
10005
+ this.upsertOwnAnswer = new EventEmitter();
10006
+ this.isLoading = false;
10007
+ this.answers = [];
10008
+ this.isClosed = false;
10009
+ }
10010
+ ngOnChanges(changes) {
10011
+ super.ngOnChanges(changes);
10012
+ if (changes['pollId']) {
10013
+ void this.queryAnswers();
10014
+ }
10015
+ }
10016
+ queryAnswers() {
10017
+ return __awaiter(this, void 0, void 0, function* () {
10018
+ if (!this.poll) {
10019
+ return;
10020
+ }
10021
+ try {
10022
+ this.isLoading = true;
10023
+ const response = yield this.poll.queryAnswers({
10024
+ filter: {},
10025
+ sort: { created_at: -1 },
10026
+ options: {
10027
+ next: this.next,
10028
+ },
10029
+ });
10030
+ this.next = response.next;
10031
+ this.answers = [...this.answers, ...response.votes];
10032
+ this.markForCheck();
10033
+ }
10034
+ catch (error) {
10035
+ this.notificationService.addTemporaryNotification('streamChat.Error loading answers');
10036
+ this.markForCheck();
10037
+ throw error;
10038
+ }
10039
+ finally {
10040
+ this.isLoading = false;
10041
+ this.markForCheck();
10042
+ }
10043
+ });
10044
+ }
10045
+ trackByAnswerId(_, answer) {
10046
+ return answer.id;
10047
+ }
10048
+ stateStoreSelector(poll, markForCheck) {
10049
+ const unsubscribe = poll.state.subscribeWithSelector((state) => ({
10050
+ is_closed: state.is_closed,
10051
+ own_answer: state.ownAnswer,
10052
+ }), (state) => {
10053
+ var _a, _b;
10054
+ this.isClosed = (_a = state.is_closed) !== null && _a !== void 0 ? _a : false;
10055
+ this.ownAnswer = (_b = state.own_answer) !== null && _b !== void 0 ? _b : undefined;
10056
+ markForCheck();
10057
+ });
10058
+ return unsubscribe;
10059
+ }
10060
+ }
10061
+ PollAnswersListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: PollAnswersListComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
10062
+ PollAnswersListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: PollAnswersListComponent, selector: "stream-poll-answers-list", outputs: { upsertOwnAnswer: "upsertOwnAnswer" }, host: { properties: { "class": "this.class" } }, usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<div class=\"str-chat__modal__poll-answer-list\">\n <div class=\"str-chat__modal-header\">\n <div class=\"str-chat__modal-header__title\" translate>\n streamChat.Poll comments\n </div>\n </div>\n <div class=\"str-chat__modal__poll-answer-list__body\">\n <div class=\"str-chat__poll-answer-list\">\n <stream-paginated-list\n class=\"str-chat__poll-answer-list\"\n [items]=\"answers\"\n [hasMore]=\"next !== undefined\"\n [isLoading]=\"isLoading\"\n [trackBy]=\"trackByAnswerId\"\n (loadMore)=\"queryAnswers()\"\n >\n <ng-template let-answer=\"item\">\n <div class=\"str-chat__poll-answer\">\n <p *ngIf=\"answer.answer_text\" class=\"str-chat__poll-answer__text\">\n {{ answer.answer_text }}\n </p>\n <stream-poll-vote [vote]=\"answer\"></stream-poll-vote>\n </div>\n </ng-template>\n </stream-paginated-list>\n <button\n *ngIf=\"!isClosed\"\n class=\"str-chat__poll-action\"\n (click)=\"upsertOwnAnswer.emit()\"\n >\n {{\n (ownAnswer\n ? \"streamChat.Update your comment\"\n : \"streamChat.Add a comment\"\n ) | translate\n }}\n </button>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i6.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "component", type: PaginatedListComponent, selector: "stream-paginated-list", inputs: ["items", "isLoading", "hasMore", "trackBy"], outputs: ["loadMore"] }, { kind: "component", type: PollVoteComponent, selector: "stream-poll-vote", inputs: ["vote"] }, { kind: "pipe", type: i6.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
10063
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: PollAnswersListComponent, decorators: [{
10064
+ type: Component,
10065
+ args: [{ selector: 'stream-poll-answers-list', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"str-chat__modal__poll-answer-list\">\n <div class=\"str-chat__modal-header\">\n <div class=\"str-chat__modal-header__title\" translate>\n streamChat.Poll comments\n </div>\n </div>\n <div class=\"str-chat__modal__poll-answer-list__body\">\n <div class=\"str-chat__poll-answer-list\">\n <stream-paginated-list\n class=\"str-chat__poll-answer-list\"\n [items]=\"answers\"\n [hasMore]=\"next !== undefined\"\n [isLoading]=\"isLoading\"\n [trackBy]=\"trackByAnswerId\"\n (loadMore)=\"queryAnswers()\"\n >\n <ng-template let-answer=\"item\">\n <div class=\"str-chat__poll-answer\">\n <p *ngIf=\"answer.answer_text\" class=\"str-chat__poll-answer__text\">\n {{ answer.answer_text }}\n </p>\n <stream-poll-vote [vote]=\"answer\"></stream-poll-vote>\n </div>\n </ng-template>\n </stream-paginated-list>\n <button\n *ngIf=\"!isClosed\"\n class=\"str-chat__poll-action\"\n (click)=\"upsertOwnAnswer.emit()\"\n >\n {{\n (ownAnswer\n ? \"streamChat.Update your comment\"\n : \"streamChat.Add a comment\"\n ) | translate\n }}\n </button>\n </div>\n </div>\n</div>\n" }]
10066
+ }], propDecorators: { class: [{
10067
+ type: HostBinding,
10068
+ args: ['class']
10069
+ }], upsertOwnAnswer: [{
10070
+ type: Output
10071
+ }] } });
10072
+
10073
+ /**
10074
+ *
10075
+ */
10076
+ class UpsertAnswerComponent extends BasePollComponent {
10077
+ constructor() {
10078
+ super(...arguments);
10079
+ this.class = 'str-chat__dialog';
10080
+ /**
10081
+ * The callback to close the modal the component is displayed in
10082
+ */
10083
+ this.closeModal = () => { };
10084
+ this.formGroup = new FormGroup({
10085
+ comment: new FormControl('', [Validators.required]),
10086
+ });
10087
+ }
10088
+ ngOnChanges(changes) {
10089
+ var _a, _b, _c;
10090
+ super.ngOnChanges(changes);
10091
+ if (changes['answer']) {
10092
+ (_a = this.formGroup.get('comment')) === null || _a === void 0 ? void 0 : _a.setValue((_c = (_b = this.answer) === null || _b === void 0 ? void 0 : _b.answer_text) !== null && _c !== void 0 ? _c : '');
10093
+ }
10094
+ }
10095
+ addComment() {
10096
+ var _a;
10097
+ return __awaiter(this, void 0, void 0, function* () {
10098
+ if (this.formGroup.invalid || !this.messageId) {
10099
+ return;
10100
+ }
10101
+ try {
10102
+ yield ((_a = this.poll) === null || _a === void 0 ? void 0 : _a.addAnswer(this.formGroup.value.comment, this.messageId));
10103
+ this.closeModal();
10104
+ this.markForCheck();
10105
+ }
10106
+ catch (error) {
10107
+ this.notificationService.addTemporaryNotification('streamChat.Failed to add comment');
10108
+ this.markForCheck();
10109
+ throw error;
10110
+ }
10111
+ });
10112
+ }
10113
+ stateStoreSelector(_, __) {
10114
+ return () => { };
10115
+ }
10116
+ }
10117
+ UpsertAnswerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: UpsertAnswerComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
10118
+ UpsertAnswerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: UpsertAnswerComponent, selector: "stream-upsert-answer", inputs: { answer: "answer", closeModal: "closeModal" }, host: { properties: { "class": "this.class" } }, usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<div\n class=\"str-chat__dialog str-chat__dialog--form str-chat__prompt-dialog str-chat__modal__poll-add-comment\"\n>\n <div class=\"str-chat__dialog__body\">\n <div class=\"str-chat__dialog__title\">\n {{\n (answer ? \"streamChat.Update your comment\" : \"streamChat.Add a comment\")\n | translate\n }}\n </div>\n <form [formGroup]=\"formGroup\" (ngSubmit)=\"addComment()\">\n <div class=\"str-chat__dialog__field\">\n <input formControlName=\"comment\" id=\"comment\" type=\"text\" />\n </div>\n <div class=\"str-chat__dialog__controls\">\n <button\n class=\"str-chat__dialog__controls-button str-chat__dialog__controls-button--cancel\"\n onClick=\"{close}\"\n type=\"button\"\n (click)=\"closeModal()\"\n >\n {{ \"streamChat.Cancel\" | translate }}\n </button>\n <button\n class=\"str-chat__dialog__controls-button str-chat__dialog__controls-button--submit\"\n type=\"submit\"\n [disabled]=\"formGroup.invalid\"\n >\n {{ \"streamChat.Send\" | translate }}\n </button>\n </div>\n </form>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "pipe", type: i6.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
10119
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: UpsertAnswerComponent, decorators: [{
10120
+ type: Component,
10121
+ args: [{ selector: 'stream-upsert-answer', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n class=\"str-chat__dialog str-chat__dialog--form str-chat__prompt-dialog str-chat__modal__poll-add-comment\"\n>\n <div class=\"str-chat__dialog__body\">\n <div class=\"str-chat__dialog__title\">\n {{\n (answer ? \"streamChat.Update your comment\" : \"streamChat.Add a comment\")\n | translate\n }}\n </div>\n <form [formGroup]=\"formGroup\" (ngSubmit)=\"addComment()\">\n <div class=\"str-chat__dialog__field\">\n <input formControlName=\"comment\" id=\"comment\" type=\"text\" />\n </div>\n <div class=\"str-chat__dialog__controls\">\n <button\n class=\"str-chat__dialog__controls-button str-chat__dialog__controls-button--cancel\"\n onClick=\"{close}\"\n type=\"button\"\n (click)=\"closeModal()\"\n >\n {{ \"streamChat.Cancel\" | translate }}\n </button>\n <button\n class=\"str-chat__dialog__controls-button str-chat__dialog__controls-button--submit\"\n type=\"submit\"\n [disabled]=\"formGroup.invalid\"\n >\n {{ \"streamChat.Send\" | translate }}\n </button>\n </div>\n </form>\n </div>\n</div>\n" }]
10122
+ }], propDecorators: { class: [{
10123
+ type: HostBinding,
10124
+ args: ['class']
10125
+ }], answer: [{
10126
+ type: Input
10127
+ }], closeModal: [{
10128
+ type: Input
10129
+ }] } });
10130
+
10131
+ function createUniqueValidator(isUnique) {
10132
+ return (control) => {
10133
+ const value = control.value;
10134
+ if (!value) {
10135
+ return null;
10136
+ }
10137
+ if (!isUnique(value)) {
10138
+ return { duplicate: true };
10139
+ }
10140
+ return null;
10141
+ };
10142
+ }
10143
+
10144
+ /**
10145
+ *
10146
+ */
10147
+ class AddOptionComponent extends BasePollComponent {
10148
+ constructor() {
10149
+ super(...arguments);
10150
+ this.class = 'str-chat__dialog';
10151
+ /**
10152
+ * The callback to close the modal the component is displayed in
10153
+ */
10154
+ this.closeModal = () => { };
10155
+ this.formGroup = new FormGroup({
10156
+ text: new FormControl('', [
10157
+ Validators.required,
10158
+ createUniqueValidator((value) => {
10159
+ return !this.options.some((option) => option.text.trim().toLowerCase() === value.trim().toLowerCase());
10160
+ }),
10161
+ ]),
10162
+ });
10163
+ this.options = [];
10164
+ }
10165
+ addOption() {
10166
+ var _a;
10167
+ return __awaiter(this, void 0, void 0, function* () {
10168
+ if (this.formGroup.invalid || !this.messageId) {
10169
+ return;
10170
+ }
10171
+ try {
10172
+ yield ((_a = this.poll) === null || _a === void 0 ? void 0 : _a.createOption({
10173
+ text: this.formGroup.value.text,
10174
+ }));
10175
+ this.closeModal();
10176
+ this.markForCheck();
10177
+ }
10178
+ catch (error) {
10179
+ this.notificationService.addTemporaryNotification('streamChat.Failed to add option ({{ message }})', 'error', undefined, { message: error });
10180
+ this.markForCheck();
10181
+ throw error;
10182
+ }
10183
+ });
10184
+ }
10185
+ stateStoreSelector(poll, markForCheck) {
10186
+ const unsubscribe = poll.state.subscribeWithSelector((state) => ({
10187
+ options: state.options,
10188
+ }), (state) => {
10189
+ this.options = state.options;
10190
+ markForCheck();
10191
+ });
10192
+ return unsubscribe;
10193
+ }
10194
+ }
10195
+ AddOptionComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: AddOptionComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
10196
+ AddOptionComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: AddOptionComponent, selector: "stream-add-option", inputs: { closeModal: "closeModal" }, host: { properties: { "class": "this.class" } }, usesInheritance: true, ngImport: i0, template: "<div\n class=\"str-chat__dialog str-chat__dialog--form str-chat__prompt-dialog str-chat__modal__suggest-poll-option\"\n>\n <div class=\"str-chat__dialog__body\">\n <div class=\"str-chat__dialog__title\">\n {{ \"streamChat.Suggest an option\" | translate }}\n </div>\n <form [formGroup]=\"formGroup\">\n <div class=\"str-chat__dialog__field\">\n <input formControlName=\"text\" id=\"text\" type=\"text\" />\n <div class=\"str-chat__form-field-error\">\n {{\n formGroup.get(\"text\")?.errors?.duplicate\n ? (\"streamChat.Option already exists\" | translate)\n : \"\"\n }}\n </div>\n </div>\n <div class=\"str-chat__dialog__controls\">\n <button\n class=\"str-chat__dialog__controls-button str-chat__dialog__controls-button--cancel\"\n type=\"button\"\n (click)=\"closeModal()\"\n (keyup.enter)=\"closeModal()\"\n >\n {{ \"streamChat.Cancel\" | translate }}\n </button>\n <button\n class=\"str-chat__dialog__controls-button str-chat__dialog__controls-button--submit\"\n type=\"submit\"\n (click)=\"addOption()\"\n (keyup.enter)=\"addOption()\"\n [disabled]=\"formGroup.invalid\"\n >\n {{ \"streamChat.Send\" | translate }}\n </button>\n </div>\n </form>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "pipe", type: i6.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
10197
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: AddOptionComponent, decorators: [{
10198
+ type: Component,
10199
+ args: [{ selector: 'stream-add-option', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n class=\"str-chat__dialog str-chat__dialog--form str-chat__prompt-dialog str-chat__modal__suggest-poll-option\"\n>\n <div class=\"str-chat__dialog__body\">\n <div class=\"str-chat__dialog__title\">\n {{ \"streamChat.Suggest an option\" | translate }}\n </div>\n <form [formGroup]=\"formGroup\">\n <div class=\"str-chat__dialog__field\">\n <input formControlName=\"text\" id=\"text\" type=\"text\" />\n <div class=\"str-chat__form-field-error\">\n {{\n formGroup.get(\"text\")?.errors?.duplicate\n ? (\"streamChat.Option already exists\" | translate)\n : \"\"\n }}\n </div>\n </div>\n <div class=\"str-chat__dialog__controls\">\n <button\n class=\"str-chat__dialog__controls-button str-chat__dialog__controls-button--cancel\"\n type=\"button\"\n (click)=\"closeModal()\"\n (keyup.enter)=\"closeModal()\"\n >\n {{ \"streamChat.Cancel\" | translate }}\n </button>\n <button\n class=\"str-chat__dialog__controls-button str-chat__dialog__controls-button--submit\"\n type=\"submit\"\n (click)=\"addOption()\"\n (keyup.enter)=\"addOption()\"\n [disabled]=\"formGroup.invalid\"\n >\n {{ \"streamChat.Send\" | translate }}\n </button>\n </div>\n </form>\n </div>\n</div>\n" }]
10200
+ }], propDecorators: { class: [{
10201
+ type: HostBinding,
10202
+ args: ['class']
10203
+ }], closeModal: [{
10204
+ type: Input
10205
+ }] } });
10206
+
10207
+ /**
10208
+ *
10209
+ */
10210
+ class PollActionsComponent extends BasePollComponent {
10211
+ constructor(customTemplatesService, chatClientService, cdRef, channelService, notificationService, messageService) {
10212
+ super(customTemplatesService, chatClientService, cdRef, channelService, notificationService);
10213
+ this.messageService = messageService;
10214
+ /**
10215
+ * If there are more options than this number, the "See all options" button will be displayed
10216
+ */
10217
+ this.maxOptionsDisplayed = 10;
10218
+ /**
10219
+ * The maximum number of options allowed for the poll, this is defined by Stream API
10220
+ */
10221
+ this.maxPollOptions = 100;
10222
+ this.name = '';
10223
+ this.options = [];
10224
+ this.isClosed = false;
10225
+ this.allowUserSuggestions = false;
10226
+ this.allowAnswers = false;
10227
+ this.answerCount = 0;
10228
+ this.isOwnPoll = false;
10229
+ this.selectedAction = undefined;
10230
+ this.isModalOpen = false;
10231
+ this.modalOpened = (action) => {
10232
+ this.selectedAction = action;
10233
+ if (!this.isModalOpen) {
10234
+ this.isModalOpen = true;
10235
+ this.messageService.modalOpenedForMessage.next(this.messageId);
10236
+ }
10237
+ };
10238
+ this.modalClosed = () => {
10239
+ this.selectedAction = undefined;
10240
+ if (this.isModalOpen) {
10241
+ this.isModalOpen = false;
10242
+ this.messageService.modalOpenedForMessage.next(undefined);
10243
+ this.markForCheck();
10244
+ }
10245
+ };
10246
+ }
10247
+ stateStoreSelector(poll, markForCheck) {
10248
+ const unsubscribe = poll.state.subscribeWithSelector((state) => ({
10249
+ options: state.options,
10250
+ is_closed: state.is_closed,
10251
+ allow_user_suggested_options: state.allow_user_suggested_options,
10252
+ allow_answers: state.allow_answers,
10253
+ answer_count: state.answers_count,
10254
+ created_by: state.created_by,
10255
+ name: state.name,
10256
+ own_answer: state.ownAnswer,
10257
+ max_votes_allowed: state.max_votes_allowed,
10258
+ own_votes_by_option_id: state.ownVotesByOptionId,
10259
+ }), (state) => {
10260
+ var _a, _b, _c, _d, _e, _f, _g;
10261
+ this.options = state.options;
10262
+ this.isClosed = (_a = state.is_closed) !== null && _a !== void 0 ? _a : false;
10263
+ this.allowUserSuggestions = (_b = state.allow_user_suggested_options) !== null && _b !== void 0 ? _b : false;
10264
+ this.allowAnswers = (_c = state.allow_answers) !== null && _c !== void 0 ? _c : false;
10265
+ this.answerCount = (_d = state.answer_count) !== null && _d !== void 0 ? _d : 0;
10266
+ this.isOwnPoll = ((_e = state.created_by) === null || _e === void 0 ? void 0 : _e.id) === ((_f = this.currentUser) === null || _f === void 0 ? void 0 : _f.id);
10267
+ this.name = state.name;
10268
+ this.ownAnwer = (_g = state.own_answer) !== null && _g !== void 0 ? _g : undefined;
10269
+ markForCheck();
10270
+ });
10271
+ return unsubscribe;
10272
+ }
10273
+ closePoll() {
10274
+ var _a;
10275
+ return __awaiter(this, void 0, void 0, function* () {
10276
+ try {
10277
+ yield ((_a = this.poll) === null || _a === void 0 ? void 0 : _a.close());
10278
+ this.modalClosed();
10279
+ this.markForCheck();
10280
+ }
10281
+ catch (error) {
10282
+ this.notificationService.addTemporaryNotification('streamChat.Failed to end vote');
10283
+ throw error;
10284
+ }
10285
+ });
10286
+ }
10287
+ getModalContext() {
10288
+ return {
10289
+ isOpen: this.isModalOpen,
10290
+ isOpenChangeHandler: (isOpen) => {
10291
+ if (isOpen) {
10292
+ this.modalOpened(this.selectedAction);
10293
+ }
10294
+ else {
10295
+ this.modalClosed();
10296
+ }
10297
+ },
10298
+ content: this[this.selectedAction],
10299
+ };
10300
+ }
10301
+ }
10302
+ PollActionsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: PollActionsComponent, deps: [{ token: CustomTemplatesService }, { token: ChatClientService }, { token: i0.ChangeDetectorRef }, { token: ChannelService }, { token: NotificationService }, { token: MessageActionsService }], target: i0.ɵɵFactoryTarget.Component });
10303
+ PollActionsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: PollActionsComponent, selector: "stream-poll-actions", inputs: { maxOptionsDisplayed: "maxOptionsDisplayed", maxPollOptions: "maxPollOptions" }, viewQueries: [{ propertyName: "allOptions", first: true, predicate: ["allOptions"], descendants: true }, { propertyName: "suggestOption", first: true, predicate: ["suggestOption"], descendants: true }, { propertyName: "addAnswer", first: true, predicate: ["addAnswer"], descendants: true }, { propertyName: "viewComments", first: true, predicate: ["viewComments"], descendants: true }, { propertyName: "viewResults", first: true, predicate: ["viewResults"], descendants: true }, { propertyName: "endVote", first: true, predicate: ["endVote"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"str-chat__poll-actions\">\n <ng-container\n *ngIf=\"maxOptionsDisplayed && options.length > maxOptionsDisplayed\"\n >\n <button class=\"str-chat__poll-action\" (click)=\"modalOpened('allOptions')\">\n {{ \"streamChat.See all options ({{count}})\" | translate:{count:\n options.length} }}\n </button>\n </ng-container>\n <ng-container\n *ngIf=\"\n allowUserSuggestions &&\n canVote &&\n !isClosed &&\n options.length < maxPollOptions\n \"\n >\n <button\n class=\"str-chat__poll-action\"\n (click)=\"modalOpened('suggestOption')\"\n >\n {{ \"streamChat.Suggest an option\" | translate }}\n </button>\n </ng-container>\n <ng-container *ngIf=\"allowAnswers && canVote && !isClosed\">\n <button\n class=\"str-chat__poll-action\"\n (click)=\"modalOpened('addAnswer')\"\n (keyup.enter)=\"modalOpened('addAnswer')\"\n >\n <ng-container *ngIf=\"ownAnwer; else newAnswer\">\n {{ \"streamChat.Update your comment\" | translate }}\n </ng-container>\n <ng-template #newAnswer>\n {{ \"streamChat.Add a comment\" | translate }}\n </ng-template>\n </button>\n </ng-container>\n <ng-container *ngIf=\"answerCount > 0 && canQueryVotes\">\n <button class=\"str-chat__poll-action\" (click)=\"modalOpened('viewComments')\">\n {{ (answerCount === 1 ? \"streamChat.View {{ count }} comment\" :\n \"streamChat.View {{ count }} comments\") | translate:{count: answerCount}\n }}\n </button>\n </ng-container>\n <ng-container *ngIf=\"canQueryVotes\">\n <button class=\"str-chat__poll-action\" (click)=\"modalOpened('viewResults')\">\n {{ \"streamChat.View results\" | translate }}\n </button>\n </ng-container>\n <ng-container *ngIf=\"isOwnPoll && !isClosed\">\n <button class=\"str-chat__poll-action\" (click)=\"modalOpened('endVote')\">\n {{ \"streamChat.End vote\" | translate }}\n </button>\n </ng-container>\n</div>\n\n<ng-container *ngIf=\"selectedAction\">\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 class=\"str-chat__poll-actions str-chat-angular__poll-actions\"\n [isOpen]=\"isOpen\"\n [content]=\"content\"\n (isOpenChange)=\"isOpenChangeHandler($event)\"\n >\n </stream-modal>\n</ng-template>\n\n<ng-template #allOptions>\n <div class=\"str-chat__modal__poll-option-list str-chat-angular__poll-actions\">\n <div class=\"str-chat__modal-header\">\n <div class=\"str-chat__modal-header__title\" translate>\n streamChat.Poll options\n </div>\n </div>\n <div class=\"str-chat__modal__poll-option-list__body\">\n <div class=\"str-chat__modal__poll-option-list__title\">{{ name }}</div>\n <stream-poll-options-list\n [pollId]=\"pollId\"\n [messageId]=\"messageId\"\n [maxOptionsDisplayed]=\"undefined\"\n ></stream-poll-options-list>\n <stream-notification-list></stream-notification-list>\n </div>\n </div>\n</ng-template>\n<ng-template #suggestOption>\n <stream-add-option\n [pollId]=\"pollId\"\n [messageId]=\"messageId\"\n [closeModal]=\"modalClosed\"\n ></stream-add-option>\n <stream-notification-list></stream-notification-list>\n</ng-template>\n<ng-template #addAnswer>\n <stream-upsert-answer\n [pollId]=\"pollId\"\n [messageId]=\"messageId\"\n [answer]=\"ownAnwer\"\n [closeModal]=\"modalClosed\"\n ></stream-upsert-answer>\n <stream-notification-list></stream-notification-list>\n</ng-template>\n<ng-template #viewComments>\n <stream-poll-answers-list\n (upsertOwnAnswer)=\"modalOpened('addAnswer')\"\n [pollId]=\"pollId\"\n [messageId]=\"messageId\"\n ></stream-poll-answers-list>\n <stream-notification-list></stream-notification-list>\n</ng-template>\n<ng-template #viewResults>\n <stream-poll-results-list\n [messageId]=\"messageId\"\n [pollId]=\"pollId\"\n ></stream-poll-results-list>\n <stream-notification-list></stream-notification-list>\n</ng-template>\n<ng-template #endVote>\n <div\n class=\"str-chat__dialog str-chat__dialog--prompt str-chat__modal__end-vote\"\n >\n <div class=\"str-chat__dialog__body\">\n <div class=\"str-chat__dialog__title\" translate>streamChat.End vote</div>\n <div class=\"str-chat__dialog__prompt\" translate>\n streamChat.After a poll is closed, no more votes can be cast\n </div>\n <stream-notification-list></stream-notification-list>\n <div class=\"str-chat__dialog__controls\">\n <button\n class=\"str-chat__dialog__controls-button\"\n (click)=\"modalClosed()\"\n >\n {{ \"streamChat.Cancel\" | translate }}\n </button>\n <button class=\"str-chat__dialog__controls-button\" (click)=\"closePoll()\">\n {{ \"streamChat.End vote\" | translate }}\n </button>\n </div>\n </div>\n </div>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i6.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "component", type: ModalComponent, selector: "stream-modal", inputs: ["isOpen", "content"], outputs: ["isOpenChange"] }, { kind: "component", type: NotificationListComponent, selector: "stream-notification-list" }, { kind: "component", type: PollOptionsListComponent, selector: "stream-poll-options-list", inputs: ["maxOptionsDisplayed"] }, { kind: "component", type: PollResultsListComponent, selector: "stream-poll-results-list" }, { kind: "component", type: PollAnswersListComponent, selector: "stream-poll-answers-list", outputs: ["upsertOwnAnswer"] }, { kind: "component", type: UpsertAnswerComponent, selector: "stream-upsert-answer", inputs: ["answer", "closeModal"] }, { kind: "component", type: AddOptionComponent, selector: "stream-add-option", inputs: ["closeModal"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
10304
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: PollActionsComponent, decorators: [{
10305
+ type: Component,
10306
+ args: [{ selector: 'stream-poll-actions', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"str-chat__poll-actions\">\n <ng-container\n *ngIf=\"maxOptionsDisplayed && options.length > maxOptionsDisplayed\"\n >\n <button class=\"str-chat__poll-action\" (click)=\"modalOpened('allOptions')\">\n {{ \"streamChat.See all options ({{count}})\" | translate:{count:\n options.length} }}\n </button>\n </ng-container>\n <ng-container\n *ngIf=\"\n allowUserSuggestions &&\n canVote &&\n !isClosed &&\n options.length < maxPollOptions\n \"\n >\n <button\n class=\"str-chat__poll-action\"\n (click)=\"modalOpened('suggestOption')\"\n >\n {{ \"streamChat.Suggest an option\" | translate }}\n </button>\n </ng-container>\n <ng-container *ngIf=\"allowAnswers && canVote && !isClosed\">\n <button\n class=\"str-chat__poll-action\"\n (click)=\"modalOpened('addAnswer')\"\n (keyup.enter)=\"modalOpened('addAnswer')\"\n >\n <ng-container *ngIf=\"ownAnwer; else newAnswer\">\n {{ \"streamChat.Update your comment\" | translate }}\n </ng-container>\n <ng-template #newAnswer>\n {{ \"streamChat.Add a comment\" | translate }}\n </ng-template>\n </button>\n </ng-container>\n <ng-container *ngIf=\"answerCount > 0 && canQueryVotes\">\n <button class=\"str-chat__poll-action\" (click)=\"modalOpened('viewComments')\">\n {{ (answerCount === 1 ? \"streamChat.View {{ count }} comment\" :\n \"streamChat.View {{ count }} comments\") | translate:{count: answerCount}\n }}\n </button>\n </ng-container>\n <ng-container *ngIf=\"canQueryVotes\">\n <button class=\"str-chat__poll-action\" (click)=\"modalOpened('viewResults')\">\n {{ \"streamChat.View results\" | translate }}\n </button>\n </ng-container>\n <ng-container *ngIf=\"isOwnPoll && !isClosed\">\n <button class=\"str-chat__poll-action\" (click)=\"modalOpened('endVote')\">\n {{ \"streamChat.End vote\" | translate }}\n </button>\n </ng-container>\n</div>\n\n<ng-container *ngIf=\"selectedAction\">\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 class=\"str-chat__poll-actions str-chat-angular__poll-actions\"\n [isOpen]=\"isOpen\"\n [content]=\"content\"\n (isOpenChange)=\"isOpenChangeHandler($event)\"\n >\n </stream-modal>\n</ng-template>\n\n<ng-template #allOptions>\n <div class=\"str-chat__modal__poll-option-list str-chat-angular__poll-actions\">\n <div class=\"str-chat__modal-header\">\n <div class=\"str-chat__modal-header__title\" translate>\n streamChat.Poll options\n </div>\n </div>\n <div class=\"str-chat__modal__poll-option-list__body\">\n <div class=\"str-chat__modal__poll-option-list__title\">{{ name }}</div>\n <stream-poll-options-list\n [pollId]=\"pollId\"\n [messageId]=\"messageId\"\n [maxOptionsDisplayed]=\"undefined\"\n ></stream-poll-options-list>\n <stream-notification-list></stream-notification-list>\n </div>\n </div>\n</ng-template>\n<ng-template #suggestOption>\n <stream-add-option\n [pollId]=\"pollId\"\n [messageId]=\"messageId\"\n [closeModal]=\"modalClosed\"\n ></stream-add-option>\n <stream-notification-list></stream-notification-list>\n</ng-template>\n<ng-template #addAnswer>\n <stream-upsert-answer\n [pollId]=\"pollId\"\n [messageId]=\"messageId\"\n [answer]=\"ownAnwer\"\n [closeModal]=\"modalClosed\"\n ></stream-upsert-answer>\n <stream-notification-list></stream-notification-list>\n</ng-template>\n<ng-template #viewComments>\n <stream-poll-answers-list\n (upsertOwnAnswer)=\"modalOpened('addAnswer')\"\n [pollId]=\"pollId\"\n [messageId]=\"messageId\"\n ></stream-poll-answers-list>\n <stream-notification-list></stream-notification-list>\n</ng-template>\n<ng-template #viewResults>\n <stream-poll-results-list\n [messageId]=\"messageId\"\n [pollId]=\"pollId\"\n ></stream-poll-results-list>\n <stream-notification-list></stream-notification-list>\n</ng-template>\n<ng-template #endVote>\n <div\n class=\"str-chat__dialog str-chat__dialog--prompt str-chat__modal__end-vote\"\n >\n <div class=\"str-chat__dialog__body\">\n <div class=\"str-chat__dialog__title\" translate>streamChat.End vote</div>\n <div class=\"str-chat__dialog__prompt\" translate>\n streamChat.After a poll is closed, no more votes can be cast\n </div>\n <stream-notification-list></stream-notification-list>\n <div class=\"str-chat__dialog__controls\">\n <button\n class=\"str-chat__dialog__controls-button\"\n (click)=\"modalClosed()\"\n >\n {{ \"streamChat.Cancel\" | translate }}\n </button>\n <button class=\"str-chat__dialog__controls-button\" (click)=\"closePoll()\">\n {{ \"streamChat.End vote\" | translate }}\n </button>\n </div>\n </div>\n </div>\n</ng-template>\n" }]
10307
+ }], ctorParameters: function () { return [{ type: CustomTemplatesService }, { type: ChatClientService }, { type: i0.ChangeDetectorRef }, { type: ChannelService }, { type: NotificationService }, { type: MessageActionsService }]; }, propDecorators: { maxOptionsDisplayed: [{
10308
+ type: Input
10309
+ }], maxPollOptions: [{
10310
+ type: Input
10311
+ }], allOptions: [{
10312
+ type: ViewChild,
10313
+ args: ['allOptions']
10314
+ }], suggestOption: [{
10315
+ type: ViewChild,
10316
+ args: ['suggestOption']
10317
+ }], addAnswer: [{
10318
+ type: ViewChild,
10319
+ args: ['addAnswer']
10320
+ }], viewComments: [{
10321
+ type: ViewChild,
10322
+ args: ['viewComments']
10323
+ }], viewResults: [{
10324
+ type: ViewChild,
10325
+ args: ['viewResults']
10326
+ }], endVote: [{
10327
+ type: ViewChild,
10328
+ args: ['endVote']
10329
+ }] } });
10330
+
10331
+ /**
10332
+ *
10333
+ */
10334
+ class PollComponent extends BasePollComponent {
10335
+ constructor() {
10336
+ super(...arguments);
10337
+ this.isClosed = false;
10338
+ }
10339
+ stateStoreSelector(poll, markForCheck) {
10340
+ const unsubscribe = poll.state.subscribeWithSelector((state) => {
10341
+ return {
10342
+ is_closed: state.is_closed,
10343
+ };
10344
+ }, (state) => {
10345
+ var _a;
10346
+ this.isClosed = (_a = state.is_closed) !== null && _a !== void 0 ? _a : false;
10347
+ markForCheck();
10348
+ });
10349
+ return unsubscribe;
10350
+ }
10351
+ }
10352
+ PollComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: PollComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
10353
+ PollComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: PollComponent, selector: "stream-poll", usesInheritance: true, ngImport: i0, template: "<div class=\"str-chat__poll\" [class.str-chat__poll--closed]=\"isClosed\">\n <div #header><ng-content select=\"[poll-header]\"></ng-content></div>\n <ng-container *ngIf=\"!header.hasChildNodes()\">\n <stream-poll-header [pollId]=\"pollId\" [messageId]=\"messageId\">\n </stream-poll-header>\n </ng-container>\n <div #options><ng-content select=\"[poll-options-list]\"></ng-content></div>\n <ng-container *ngIf=\"!options.hasChildNodes()\">\n <stream-poll-options-list [pollId]=\"pollId\" [messageId]=\"messageId\">\n </stream-poll-options-list>\n </ng-container>\n <div #actions><ng-content select=\"[poll-actions]\"></ng-content></div>\n <ng-container *ngIf=\"!actions.hasChildNodes()\">\n <stream-poll-actions [pollId]=\"pollId\" [messageId]=\"messageId\">\n </stream-poll-actions>\n </ng-container>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: PollHeaderComponent, selector: "stream-poll-header" }, { kind: "component", type: PollOptionsListComponent, selector: "stream-poll-options-list", inputs: ["maxOptionsDisplayed"] }, { kind: "component", type: PollActionsComponent, selector: "stream-poll-actions", inputs: ["maxOptionsDisplayed", "maxPollOptions"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
10354
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: PollComponent, decorators: [{
10355
+ type: Component,
10356
+ args: [{ selector: 'stream-poll', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"str-chat__poll\" [class.str-chat__poll--closed]=\"isClosed\">\n <div #header><ng-content select=\"[poll-header]\"></ng-content></div>\n <ng-container *ngIf=\"!header.hasChildNodes()\">\n <stream-poll-header [pollId]=\"pollId\" [messageId]=\"messageId\">\n </stream-poll-header>\n </ng-container>\n <div #options><ng-content select=\"[poll-options-list]\"></ng-content></div>\n <ng-container *ngIf=\"!options.hasChildNodes()\">\n <stream-poll-options-list [pollId]=\"pollId\" [messageId]=\"messageId\">\n </stream-poll-options-list>\n </ng-container>\n <div #actions><ng-content select=\"[poll-actions]\"></ng-content></div>\n <ng-container *ngIf=\"!actions.hasChildNodes()\">\n <stream-poll-actions [pollId]=\"pollId\" [messageId]=\"messageId\">\n </stream-poll-actions>\n </ng-container>\n</div>\n" }]
10357
+ }] });
10358
+
10359
+ /**
10360
+ *
10361
+ */
10362
+ class PollPreviewComponent extends BasePollComponent {
10363
+ constructor() {
10364
+ super(...arguments);
10365
+ this.name = '';
10366
+ this.isClosed = false;
10367
+ }
10368
+ stateStoreSelector(poll, markForCheck) {
10369
+ const unsubscribe = poll.state.subscribeWithSelector((state) => ({
10370
+ name: state.name,
10371
+ is_closed: state.is_closed,
10372
+ }), (state) => {
10373
+ var _a;
10374
+ this.name = state.name;
10375
+ this.isClosed = (_a = state.is_closed) !== null && _a !== void 0 ? _a : false;
10376
+ markForCheck();
10377
+ });
10378
+ return unsubscribe;
10379
+ }
10380
+ }
10381
+ PollPreviewComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: PollPreviewComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
10382
+ PollPreviewComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: PollPreviewComponent, selector: "stream-poll-preview", usesInheritance: true, ngImport: i0, template: "<div\n class=\"str-chat__quoted-poll-preview\"\n [class.str-chat__quoted-poll-preview--closed]=\"isClosed\"\n>\n <div class=\"str-chat__quoted-poll-preview__icon\">\uD83D\uDCCA</div>\n <div class=\"str-chat__quoted-poll-preview__name\">{{ name }}</div>\n</div>\n", changeDetection: i0.ChangeDetectionStrategy.OnPush });
10383
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: PollPreviewComponent, decorators: [{
10384
+ type: Component,
10385
+ args: [{ selector: 'stream-poll-preview', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n class=\"str-chat__quoted-poll-preview\"\n [class.str-chat__quoted-poll-preview--closed]=\"isClosed\"\n>\n <div class=\"str-chat__quoted-poll-preview__icon\">\uD83D\uDCCA</div>\n <div class=\"str-chat__quoted-poll-preview__name\">{{ name }}</div>\n</div>\n" }]
10386
+ }] });
10387
+
10388
+ class StreamPollsModule {
10389
+ }
10390
+ StreamPollsModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: StreamPollsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
10391
+ StreamPollsModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.0.4", ngImport: i0, type: StreamPollsModule, declarations: [PollComposerComponent,
10392
+ PollComponent,
10393
+ PollHeaderComponent,
10394
+ PollOptionsListComponent,
10395
+ PollOptionSelectorComponent,
10396
+ PollActionsComponent,
10397
+ PollResultsListComponent,
10398
+ PollVoteResultsListComponent,
10399
+ PollVoteComponent,
10400
+ PollAnswersListComponent,
10401
+ UpsertAnswerComponent,
10402
+ AddOptionComponent,
10403
+ PollPreviewComponent], imports: [CommonModule,
10404
+ TranslateModule,
10405
+ StreamAvatarModule,
10406
+ StreamModalModule,
10407
+ StreamNotificationModule,
10408
+ StreamPaginatedListModule,
10409
+ ReactiveFormsModule], exports: [PollComposerComponent,
10410
+ PollComponent,
10411
+ PollHeaderComponent,
10412
+ PollOptionsListComponent,
10413
+ PollOptionSelectorComponent,
10414
+ PollActionsComponent,
10415
+ PollResultsListComponent,
10416
+ PollVoteResultsListComponent,
10417
+ PollVoteComponent,
10418
+ PollAnswersListComponent,
10419
+ UpsertAnswerComponent,
10420
+ AddOptionComponent,
10421
+ PollPreviewComponent] });
10422
+ StreamPollsModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: StreamPollsModule, imports: [CommonModule,
10423
+ TranslateModule,
10424
+ StreamAvatarModule,
10425
+ StreamModalModule,
10426
+ StreamNotificationModule,
10427
+ StreamPaginatedListModule,
10428
+ ReactiveFormsModule] });
10429
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: StreamPollsModule, decorators: [{
10430
+ type: NgModule,
10431
+ args: [{
10432
+ declarations: [
10433
+ PollComposerComponent,
10434
+ PollComponent,
10435
+ PollHeaderComponent,
10436
+ PollOptionsListComponent,
10437
+ PollOptionSelectorComponent,
10438
+ PollActionsComponent,
10439
+ PollResultsListComponent,
10440
+ PollVoteResultsListComponent,
10441
+ PollVoteComponent,
10442
+ PollAnswersListComponent,
10443
+ UpsertAnswerComponent,
10444
+ AddOptionComponent,
10445
+ PollPreviewComponent,
10446
+ ],
10447
+ imports: [
10448
+ CommonModule,
10449
+ TranslateModule,
10450
+ StreamAvatarModule,
10451
+ StreamModalModule,
10452
+ StreamNotificationModule,
10453
+ StreamPaginatedListModule,
10454
+ ReactiveFormsModule,
10455
+ ],
10456
+ exports: [
10457
+ PollComposerComponent,
10458
+ PollComponent,
10459
+ PollHeaderComponent,
10460
+ PollOptionsListComponent,
10461
+ PollOptionSelectorComponent,
10462
+ PollActionsComponent,
10463
+ PollResultsListComponent,
10464
+ PollVoteResultsListComponent,
10465
+ PollVoteComponent,
10466
+ PollAnswersListComponent,
10467
+ UpsertAnswerComponent,
10468
+ AddOptionComponent,
10469
+ PollPreviewComponent,
10470
+ ],
10471
+ }]
10472
+ }] });
10473
+
9202
10474
  /*
9203
10475
  * Public API Surface of stream-chat-angular
9204
10476
  */
@@ -9209,5 +10481,5 @@ function encodeWebmToMp3(blob, lameJs) {
9209
10481
  * Generated bundle index. Do not edit.
9210
10482
  */
9211
10483
 
9212
- export { AmplitudeRecorderService, AttachmentConfigurationService, AttachmentListComponent, AttachmentPreviewListComponent, AttachmentService, AudioRecorderService, AutocompleteTextareaComponent, AvatarComponent, AvatarPlaceholderComponent, ChannelComponent, ChannelHeaderComponent, ChannelListComponent, ChannelPreviewComponent, ChannelQuery, ChannelService, ChatClientService, CustomTemplatesService, DEFAULT_AMPLITUDE_RECORDER_CONFIG, DateParserService, EmojiInputService, IconComponent, IconModule, IconPlaceholderComponent, LoadingIndicatorComponent, LoadingIndicatorPlaceholderComponent, MediaRecordingState, MessageActionsBoxComponent, MessageActionsService, MessageBlockedComponent, MessageBouncePromptComponent, MessageComponent, MessageInputComponent, MessageInputConfigService, MessageListComponent, MessageReactionsComponent, MessageReactionsSelectorComponent, MessageReactionsService, MessageService, MessageTextComponent, ModalComponent, MultimediaRecorder, NotificationComponent, NotificationListComponent, NotificationService, PaginatedListComponent, StreamAutocompleteTextareaModule, StreamAvatarModule, StreamChatModule, StreamI18nService, StreamTextareaModule, TextareaComponent, TextareaDirective, ThemeService, ThreadComponent, TranscoderService, TransliterationService, UserListComponent, VirtualizedListService, VirtualizedMessageListService, VoiceRecorderComponent, VoiceRecorderModule, VoiceRecorderService, VoiceRecorderWavebarComponent, VoiceRecordingComponent, VoiceRecordingModule, VoiceRecordingWavebarComponent, createFileFromBlobs, createMessagePreview, createUriFromBlob, encodeWebmToMp3, formatDuration, getChannelDisplayText, getExtensionFromMimeType, getGroupStyles, getMessageTranslation, getReadBy, isImageAttachment, isImageFile, isOnSeparateDate, isSafari, listUsers, parseDate, readBlobAsArrayBuffer, textareaInjectionToken };
10484
+ export { AddOptionComponent, AmplitudeRecorderService, AttachmentConfigurationService, AttachmentListComponent, AttachmentPreviewListComponent, AttachmentService, AudioRecorderService, AutocompleteTextareaComponent, AvatarComponent, AvatarPlaceholderComponent, ChannelComponent, ChannelHeaderComponent, ChannelListComponent, ChannelPreviewComponent, ChannelQuery, ChannelService, ChatClientService, CustomTemplatesService, DEFAULT_AMPLITUDE_RECORDER_CONFIG, DateParserService, EmojiInputService, IconComponent, IconModule, IconPlaceholderComponent, LoadingIndicatorComponent, LoadingIndicatorPlaceholderComponent, MediaRecordingState, MessageActionsBoxComponent, MessageActionsService, MessageBlockedComponent, MessageBouncePromptComponent, MessageComponent, MessageInputComponent, MessageInputConfigService, MessageListComponent, MessageReactionsComponent, MessageReactionsSelectorComponent, MessageReactionsService, MessageService, MessageTextComponent, ModalComponent, MultimediaRecorder, NotificationComponent, NotificationListComponent, NotificationService, PaginatedListComponent, PollActionsComponent, PollAnswersListComponent, PollComponent, PollComposerComponent, PollHeaderComponent, PollOptionSelectorComponent, PollOptionsListComponent, PollPreviewComponent, PollResultsListComponent, PollVoteComponent, PollVoteResultsListComponent, StreamAutocompleteTextareaModule, StreamAvatarModule, StreamChatModule, StreamI18nService, StreamModalModule, StreamNotificationModule, StreamPaginatedListModule, StreamPollsModule, StreamTextareaModule, TextareaComponent, TextareaDirective, ThemeService, ThreadComponent, TranscoderService, TransliterationService, UpsertAnswerComponent, UserListComponent, VirtualizedListService, VirtualizedMessageListService, VoiceRecorderComponent, VoiceRecorderModule, VoiceRecorderService, VoiceRecorderWavebarComponent, VoiceRecordingComponent, VoiceRecordingModule, VoiceRecordingWavebarComponent, createFileFromBlobs, createMessagePreview, createUriFromBlob, encodeWebmToMp3, formatDuration, getChannelDisplayText, getExtensionFromMimeType, getGroupStyles, getMessageTranslation, getReadBy, isImageAttachment, isImageFile, isOnSeparateDate, isSafari, listUsers, parseDate, readBlobAsArrayBuffer, textareaInjectionToken };
9213
10485
  //# sourceMappingURL=stream-chat-angular.mjs.map