stream-chat-angular 4.12.1 → 4.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/README.md +1 -1
  2. package/assets/version.d.ts +1 -1
  3. package/bundles/stream-chat-angular.umd.js +84 -13
  4. package/bundles/stream-chat-angular.umd.js.map +1 -1
  5. package/esm2015/assets/version.js +2 -2
  6. package/esm2015/lib/attachment-list/attachment-list.component.js +2 -2
  7. package/esm2015/lib/attachment-preview-list/attachment-preview-list.component.js +2 -2
  8. package/esm2015/lib/avatar/avatar.component.js +56 -6
  9. package/esm2015/lib/avatar-placeholder/avatar-placeholder.component.js +3 -3
  10. package/esm2015/lib/channel-header/channel-header.component.js +9 -2
  11. package/esm2015/lib/channel-list/channel-list.component.js +2 -2
  12. package/esm2015/lib/custom-templates.service.js +5 -1
  13. package/esm2015/lib/icon-placeholder/icon-placeholder.component.js +2 -2
  14. package/esm2015/lib/loading-indicator-placeholder/loading-indicator-placeholder.component.js +2 -2
  15. package/esm2015/lib/types.js +1 -1
  16. package/fesm2015/stream-chat-angular.js +73 -14
  17. package/fesm2015/stream-chat-angular.js.map +1 -1
  18. package/lib/attachment-list/attachment-list.component.d.ts +1 -1
  19. package/lib/attachment-preview-list/attachment-preview-list.component.d.ts +1 -1
  20. package/lib/avatar/avatar.component.d.ts +12 -3
  21. package/lib/avatar-placeholder/avatar-placeholder.component.d.ts +1 -1
  22. package/lib/channel-header/channel-header.component.d.ts +3 -1
  23. package/lib/channel-list/channel-list.component.d.ts +1 -1
  24. package/lib/custom-templates.service.d.ts +5 -1
  25. package/lib/icon-placeholder/icon-placeholder.component.d.ts +1 -1
  26. package/lib/loading-indicator-placeholder/loading-indicator-placeholder.component.d.ts +1 -1
  27. package/lib/types.d.ts +3 -0
  28. package/package.json +1 -1
  29. package/src/assets/styles/css/index.css +1 -1
  30. package/src/assets/styles/scss/Card.scss +1 -1
  31. package/src/assets/styles/scss/ChannelHeader.scss +1 -1
  32. package/src/assets/styles/scss/MessageInput.scss +1 -1
  33. package/src/assets/styles/scss/TypingIndicator.scss +1 -1
  34. package/src/assets/styles/scss/_variables.scss +1 -1
  35. package/src/assets/styles/v2/css/index.css +1 -1
  36. package/src/assets/styles/v2/css/index.css.map +1 -1
  37. package/src/assets/styles/v2/css/index.layout.css +1 -1
  38. package/src/assets/styles/v2/css/index.layout.css.map +1 -1
  39. package/src/assets/styles/v2/scss/AttachmentList/AttachmentList-layout.scss +11 -13
  40. package/src/assets/styles/v2/scss/Avatar/Avatar-layout.scss +10 -0
  41. package/src/assets/styles/v2/scss/Avatar/Avatar-theme.scss +11 -0
  42. package/src/assets/styles/v2/scss/MessageList/MessageList-layout.scss +8 -0
  43. package/src/assets/styles/v2/scss/_global-theme-variables.scss +4 -0
  44. package/src/assets/version.ts +1 -1
@@ -3,7 +3,7 @@ import * as i0 from '@angular/core';
3
3
  import { Injectable, Component, Input, EventEmitter, Output, ViewChild, InjectionToken, Directive, HostBinding, Inject, NgModule } from '@angular/core';
4
4
  import { BehaviorSubject, ReplaySubject, combineLatest, Subject, timer, of } from 'rxjs';
5
5
  import { StreamChat } from 'stream-chat';
6
- import { map, shareReplay, first, take, tap, catchError, startWith, distinctUntilChanged, filter, debounceTime } from 'rxjs/operators';
6
+ import { map, shareReplay, first, filter, take, tap, catchError, startWith, distinctUntilChanged, debounceTime } from 'rxjs/operators';
7
7
  import { v4 } from 'uuid';
8
8
  import * as i8 from '@ngx-translate/core';
9
9
  import { TranslateModule } from '@ngx-translate/core';
@@ -19,7 +19,7 @@ import transliterate from '@stream-io/transliterate';
19
19
  import * as i8$1 from 'angular-mentions';
20
20
  import { MentionModule } from 'angular-mentions';
21
21
 
22
- const version = '4.12.1';
22
+ const version = '4.14.0';
23
23
 
24
24
  /**
25
25
  * The `NotificationService` can be used to add or remove notifications. By default the [`NotificationList`](../components/NotificationListComponent.mdx) component displays the currently active notifications.
@@ -1989,14 +1989,60 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
1989
1989
  * The `Avatar` component displays the provided image, with fallback to the first letter of the optional name input.
1990
1990
  */
1991
1991
  class AvatarComponent {
1992
- constructor(chatClientService) {
1992
+ constructor(chatClientService, ngZone) {
1993
1993
  this.chatClientService = chatClientService;
1994
+ this.ngZone = ngZone;
1994
1995
  /**
1995
1996
  * The size in pixels of the avatar image.
1996
1997
  */
1997
1998
  this.size = 32;
1999
+ /**
2000
+ * If a channel avatar is displayed, and if the channel has exactly two members a green dot is displayed if the other member is online. Set this flag to `false` to turn off this behavior.
2001
+ */
2002
+ this.showOnlineIndicator = true;
1998
2003
  this.isLoaded = false;
1999
2004
  this.isError = false;
2005
+ this.isOnline = false;
2006
+ }
2007
+ ngOnChanges(changes) {
2008
+ var _a, _b, _c;
2009
+ return __awaiter(this, void 0, void 0, function* () {
2010
+ if (changes['channel']) {
2011
+ if (this.channel) {
2012
+ const otherMember = this.getOtherMemberIfOneToOneChannel();
2013
+ if (otherMember) {
2014
+ this.isOnlineSubscription = this.chatClientService.events$
2015
+ .pipe(filter((e) => e.eventType === 'user.presence.changed'))
2016
+ .subscribe((event) => {
2017
+ var _a;
2018
+ if (((_a = event.event.user) === null || _a === void 0 ? void 0 : _a.id) === otherMember.id) {
2019
+ this.ngZone.run(() => {
2020
+ var _a;
2021
+ this.isOnline = ((_a = event.event.user) === null || _a === void 0 ? void 0 : _a.online) || false;
2022
+ });
2023
+ }
2024
+ });
2025
+ try {
2026
+ const response = yield this.chatClientService.chatClient.queryUsers({
2027
+ id: { $eq: otherMember.id },
2028
+ });
2029
+ this.isOnline = ((_a = response.users[0]) === null || _a === void 0 ? void 0 : _a.online) || false;
2030
+ }
2031
+ catch (error) {
2032
+ // Fallback if we can't query user -> for example due to permission problems
2033
+ this.isOnline = otherMember.online || false;
2034
+ }
2035
+ }
2036
+ else {
2037
+ (_b = this.isOnlineSubscription) === null || _b === void 0 ? void 0 : _b.unsubscribe();
2038
+ }
2039
+ }
2040
+ else {
2041
+ this.isOnline = false;
2042
+ (_c = this.isOnlineSubscription) === null || _c === void 0 ? void 0 : _c.unsubscribe();
2043
+ }
2044
+ }
2045
+ });
2000
2046
  }
2001
2047
  get initials() {
2002
2048
  var _a, _b, _c, _d, _e;
@@ -2045,8 +2091,8 @@ class AvatarComponent {
2045
2091
  }
2046
2092
  }
2047
2093
  }
2048
- AvatarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: AvatarComponent, deps: [{ token: ChatClientService }], target: i0.ɵɵFactoryTarget.Component });
2049
- AvatarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: AvatarComponent, selector: "stream-avatar", inputs: { name: "name", imageUrl: "imageUrl", size: "size", location: "location", channel: "channel", user: "user", type: "type" }, ngImport: i0, template: "<div\n class=\"str-chat__avatar str-chat__avatar--circle stream-chat__avatar--{{\n location\n }}\"\n title=\"{{ name }}\"\n [style]=\"{\n flexBasis: 'calc(var(--str-chat__spacing-px, 1px) * ' + size + ')',\n fontSize: 'calc(var(--str-chat__spacing-px, 1px) * ' + size / 2 + ')',\n height: 'calc(var(--str-chat__spacing-px, 1px) * ' + size + ')',\n lineHeight: 'calc(var(--str-chat__spacing-px, 1px) * ' + size + ')',\n width: 'calc(var(--str-chat__spacing-px, 1px) * ' + size + ')'\n }\"\n>\n <img\n *ngIf=\"(imageUrl || fallbackChannelImage) && !isError; else fallback\"\n class=\"str-chat__avatar-image str-chat__avatar-image{{\n isLoaded ? ' str-chat__avatar-image--loaded' : ''\n }}\"\n src=\"{{ imageUrl || fallbackChannelImage }}\"\n alt=\"{{ initials }}\"\n data-testid=\"avatar-img\"\n (load)=\"isLoaded = true\"\n (error)=\"isError = true\"\n [style]=\"{\n flexBasis: 'calc(var(--str-chat__spacing-px, 1px) * ' + size + ')',\n height: 'calc(var(--str-chat__spacing-px, 1px) * ' + size + ')',\n objectFit: 'cover',\n width: 'calc(var(--str-chat__spacing-px, 1px) * ' + size + ')'\n }\"\n />\n <ng-template #fallback>\n <div data-testid=\"fallback-img\" class=\"str-chat__avatar-fallback\">\n {{ initials }}\n </div>\n </ng-template>\n</div>\n", styles: [""], directives: [{ type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
2094
+ AvatarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: AvatarComponent, deps: [{ token: ChatClientService }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
2095
+ AvatarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: AvatarComponent, selector: "stream-avatar", inputs: { name: "name", imageUrl: "imageUrl", size: "size", location: "location", channel: "channel", user: "user", type: "type", showOnlineIndicator: "showOnlineIndicator" }, usesOnChanges: true, ngImport: i0, template: "<div\n class=\"str-chat__avatar str-chat__avatar--circle stream-chat__avatar--{{\n location\n }}\"\n title=\"{{ name }}\"\n [style]=\"{\n flexBasis: 'calc(var(--str-chat__spacing-px, 1px) * ' + size + ')',\n fontSize: 'calc(var(--str-chat__spacing-px, 1px) * ' + size / 2 + ')',\n height: 'calc(var(--str-chat__spacing-px, 1px) * ' + size + ')',\n lineHeight: 'calc(var(--str-chat__spacing-px, 1px) * ' + size + ')',\n width: 'calc(var(--str-chat__spacing-px, 1px) * ' + size + ')'\n }\"\n>\n <img\n *ngIf=\"(imageUrl || fallbackChannelImage) && !isError; else fallback\"\n class=\"str-chat__avatar-image str-chat__avatar-image{{\n isLoaded ? ' str-chat__avatar-image--loaded' : ''\n }}\"\n src=\"{{ imageUrl || fallbackChannelImage }}\"\n alt=\"{{ initials }}\"\n data-testid=\"avatar-img\"\n (load)=\"isLoaded = true\"\n (error)=\"isError = true\"\n [style]=\"{\n flexBasis: 'calc(var(--str-chat__spacing-px, 1px) * ' + size + ')',\n height: 'calc(var(--str-chat__spacing-px, 1px) * ' + size + ')',\n objectFit: 'cover',\n width: 'calc(var(--str-chat__spacing-px, 1px) * ' + size + ')'\n }\"\n />\n <ng-template #fallback>\n <div data-testid=\"fallback-img\" class=\"str-chat__avatar-fallback\">\n {{ initials }}\n </div>\n </ng-template>\n <div\n data-testid=\"online-indicator\"\n *ngIf=\"isOnline\"\n class=\"str-chat__avatar--online-indicator\"\n ></div>\n</div>\n", styles: [""], directives: [{ type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
2050
2096
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: AvatarComponent, decorators: [{
2051
2097
  type: Component,
2052
2098
  args: [{
@@ -2054,7 +2100,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
2054
2100
  templateUrl: './avatar.component.html',
2055
2101
  styleUrls: ['./avatar.component.scss'],
2056
2102
  }]
2057
- }], ctorParameters: function () { return [{ type: ChatClientService }]; }, propDecorators: { name: [{
2103
+ }], ctorParameters: function () { return [{ type: ChatClientService }, { type: i0.NgZone }]; }, propDecorators: { name: [{
2058
2104
  type: Input
2059
2105
  }], imageUrl: [{
2060
2106
  type: Input
@@ -2068,6 +2114,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
2068
2114
  type: Input
2069
2115
  }], type: [{
2070
2116
  type: Input
2117
+ }], showOnlineIndicator: [{
2118
+ type: Input
2071
2119
  }] } });
2072
2120
 
2073
2121
  /**
@@ -2207,6 +2255,10 @@ class CustomTemplatesService {
2207
2255
  * The template used for displaying the sent state of the message inside the [message component](../components/MessageComponent.mdx)
2208
2256
  */
2209
2257
  this.readStatusTemplate$ = new BehaviorSubject(undefined);
2258
+ /**
2259
+ * The template used to display additional information about a channel under the channel name inside the [channel header component](../components/ChannelHeaderComponent.mdx)
2260
+ */
2261
+ this.channelHeaderInfoTemplate$ = new BehaviorSubject(undefined);
2210
2262
  }
2211
2263
  }
2212
2264
  CustomTemplatesService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: CustomTemplatesService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
@@ -2219,7 +2271,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
2219
2271
  }], ctorParameters: function () { return []; } });
2220
2272
 
2221
2273
  /**
2222
- * The `AvatarPlaceholder` component displays the [default avatar](./AvatarComponent.mdx) unless a [custom template](../services/CustomTemplatesService.mdx) is provided. This componet is used by the SDK internally, you likely won't need to use it.
2274
+ * The `AvatarPlaceholder` component displays the [default avatar](./AvatarComponent.mdx) unless a [custom template](../services/CustomTemplatesService.mdx) is provided. This component is used by the SDK internally, you likely won't need to use it.
2223
2275
  */
2224
2276
  class AvatarPlaceholderComponent {
2225
2277
  constructor(customTemplatesService) {
@@ -2242,7 +2294,7 @@ class AvatarPlaceholderComponent {
2242
2294
  }
2243
2295
  }
2244
2296
  AvatarPlaceholderComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: AvatarPlaceholderComponent, deps: [{ token: CustomTemplatesService }], target: i0.ɵɵFactoryTarget.Component });
2245
- AvatarPlaceholderComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: AvatarPlaceholderComponent, selector: "stream-avatar-placeholder", inputs: { name: "name", imageUrl: "imageUrl", size: "size", location: "location", channel: "channel", user: "user", type: "type" }, ngImport: i0, template: "<ng-template\n #defaultAvatar\n let-name=\"name\"\n let-imageUrl=\"imageUrl\"\n let-size=\"size\"\n let-type=\"type\"\n let-channel=\"channel\"\n let-user=\"user\"\n let-location=\"location\"\n>\n <stream-avatar\n [name]=\"name\"\n [imageUrl]=\"imageUrl\"\n [size]=\"size\"\n [type]=\"type\"\n [channel]=\"channel\"\n [user]=\"user\"\n [location]=\"location\"\n ></stream-avatar>\n</ng-template>\n<ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.avatarTemplate$ | async) || defaultAvatar;\n context: getAvatarContext()\n \"\n></ng-container>\n", components: [{ type: AvatarComponent, selector: "stream-avatar", inputs: ["name", "imageUrl", "size", "location", "channel", "user", "type"] }], directives: [{ type: i7.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], pipes: { "async": i7.AsyncPipe } });
2297
+ AvatarPlaceholderComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: AvatarPlaceholderComponent, selector: "stream-avatar-placeholder", inputs: { name: "name", imageUrl: "imageUrl", size: "size", location: "location", channel: "channel", user: "user", type: "type" }, ngImport: i0, template: "<ng-template\n #defaultAvatar\n let-name=\"name\"\n let-imageUrl=\"imageUrl\"\n let-size=\"size\"\n let-type=\"type\"\n let-channel=\"channel\"\n let-user=\"user\"\n let-location=\"location\"\n>\n <stream-avatar\n [name]=\"name\"\n [imageUrl]=\"imageUrl\"\n [size]=\"size\"\n [type]=\"type\"\n [channel]=\"channel\"\n [user]=\"user\"\n [location]=\"location\"\n ></stream-avatar>\n</ng-template>\n<ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.avatarTemplate$ | async) || defaultAvatar;\n context: getAvatarContext()\n \"\n></ng-container>\n", components: [{ type: AvatarComponent, selector: "stream-avatar", inputs: ["name", "imageUrl", "size", "location", "channel", "user", "type", "showOnlineIndicator"] }], directives: [{ type: i7.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], pipes: { "async": i7.AsyncPipe } });
2246
2298
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: AvatarPlaceholderComponent, decorators: [{
2247
2299
  type: Component,
2248
2300
  args: [{
@@ -2288,7 +2340,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
2288
2340
  }] } });
2289
2341
 
2290
2342
  /**
2291
- * The `IconPlaceholder` component displays the [default icons](./IconComponent.mdx) unless a [custom template](../services/CustomTemplatesService.mdx) is provided. This componet is used by the SDK internally, you likely won't need to use it.
2343
+ * The `IconPlaceholder` component displays the [default icons](./IconComponent.mdx) unless a [custom template](../services/CustomTemplatesService.mdx) is provided. This component is used by the SDK internally, you likely won't need to use it.
2292
2344
  */
2293
2345
  class IconPlaceholderComponent {
2294
2346
  constructor(customTemplatesService) {
@@ -2348,7 +2400,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
2348
2400
  }] } });
2349
2401
 
2350
2402
  /**
2351
- * The `LoadingInficatorPlaceholder` component displays the [default loading indicator](./LoadingIndicatorComponent.mdx) unless a [custom template](../services/CustomTemplatesService.mdx) is provided. This componet is used by the SDK internally, you likely won't need to use it.
2403
+ * The `LoadingInficatorPlaceholder` component displays the [default loading indicator](./LoadingIndicatorComponent.mdx) unless a [custom template](../services/CustomTemplatesService.mdx) is provided. This component is used by the SDK internally, you likely won't need to use it.
2352
2404
  */
2353
2405
  class LoadingIndicatorPlaceholderComponent {
2354
2406
  constructor(customTemplatesService) {
@@ -2583,7 +2635,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
2583
2635
  }], ctorParameters: function () { return []; } });
2584
2636
 
2585
2637
  /**
2586
- * The `AttachmentList` compontent displays the attachments of a message
2638
+ * The `AttachmentList` component displays the attachments of a message
2587
2639
  */
2588
2640
  class AttachmentListComponent {
2589
2641
  constructor(customTemplatesService, channelService, attachmentConfigurationService, themeService) {
@@ -2772,7 +2824,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
2772
2824
  }] } });
2773
2825
 
2774
2826
  /**
2775
- * The `AttachmentPreviewList` compontent displays a preview of the attachments uploaded to a message. Users can delete attachments using the preview component, or retry upload if it failed previously.
2827
+ * The `AttachmentPreviewList` component displays a preview of the attachments uploaded to a message. Users can delete attachments using the preview component, or retry upload if it failed previously.
2776
2828
  */
2777
2829
  class AttachmentPreviewListComponent {
2778
2830
  constructor(themeService) {
@@ -3578,6 +3630,10 @@ class ChannelHeaderComponent {
3578
3630
  this.channelActionsTemplate = template;
3579
3631
  this.cdRef.detectChanges();
3580
3632
  }));
3633
+ this.subscriptions.push(this.customTemplatesService.channelHeaderInfoTemplate$.subscribe((template) => {
3634
+ this.channelHeaderInfoTemplate = template;
3635
+ this.cdRef.detectChanges();
3636
+ }));
3581
3637
  }
3582
3638
  ngOnDestroy() {
3583
3639
  this.subscriptions.forEach((s) => s.unsubscribe());
@@ -3589,6 +3645,9 @@ class ChannelHeaderComponent {
3589
3645
  getChannelActionsContext() {
3590
3646
  return { channel: this.activeChannel };
3591
3647
  }
3648
+ getChannelInfoContext() {
3649
+ return { channel: this.activeChannel };
3650
+ }
3592
3651
  get memberCountParam() {
3593
3652
  var _a, _b;
3594
3653
  return { memberCount: ((_b = (_a = this.activeChannel) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.member_count) || 0 };
@@ -3609,7 +3668,7 @@ class ChannelHeaderComponent {
3609
3668
  }
3610
3669
  }
3611
3670
  ChannelHeaderComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ChannelHeaderComponent, deps: [{ token: ChannelService }, { token: ChannelListToggleService }, { token: CustomTemplatesService }, { token: i0.ChangeDetectorRef }, { token: ChatClientService }], target: i0.ɵɵFactoryTarget.Component });
3612
- ChannelHeaderComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: ChannelHeaderComponent, selector: "stream-channel-header", ngImport: i0, template: "<div class=\"str-chat__header-livestream str-chat__channel-header\">\n <div\n class=\"str-chat__header-hamburger\"\n (click)=\"toggleMenu($event)\"\n (keyup.enter)=\"toggleMenu($event)\"\n >\n <stream-icon-placeholder icon=\"menu\"></stream-icon-placeholder>\n </div>\n <ng-content></ng-content>\n <stream-avatar-placeholder\n imageUrl=\"{{ activeChannel?.data?.image }}\"\n name=\"{{ avatarName }}\"\n type=\"channel\"\n location=\"channel-header\"\n [channel]=\"activeChannel\"\n [size]=\"40\"\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=\"\n str-chat__header-livestream-left--title str-chat__channel-header-title\n \"\n >\n {{ displayText }}\n </p>\n <p\n data-testid=\"info\"\n class=\"\n str-chat__header-livestream-left--members str-chat__channel-header-info\n \"\n >\n {{'streamChat.{{ memberCount }} members' | translate:memberCountParam}}\n {{canReceiveConnectEvents ? ('streamChat.{{ watcherCount }} online' |\n translate:watcherCountParam) : ''}}\n </p>\n </div>\n <ng-container *ngIf=\"channelActionsTemplate\">\n <ng-container\n *ngTemplateOutlet=\"\n channelActionsTemplate;\n context: getChannelActionsContext()\n \"\n ></ng-container>\n </ng-container>\n</div>\n", components: [{ type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon", "size"] }, { type: AvatarPlaceholderComponent, selector: "stream-avatar-placeholder", inputs: ["name", "imageUrl", "size", "location", "channel", "user", "type"] }], directives: [{ type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i7.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], pipes: { "translate": i8.TranslatePipe } });
3671
+ ChannelHeaderComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: ChannelHeaderComponent, selector: "stream-channel-header", ngImport: i0, template: "<div class=\"str-chat__header-livestream str-chat__channel-header\">\n <div\n class=\"str-chat__header-hamburger\"\n (click)=\"toggleMenu($event)\"\n (keyup.enter)=\"toggleMenu($event)\"\n >\n <stream-icon-placeholder icon=\"menu\"></stream-icon-placeholder>\n </div>\n <ng-content></ng-content>\n <stream-avatar-placeholder\n imageUrl=\"{{ activeChannel?.data?.image }}\"\n name=\"{{ avatarName }}\"\n type=\"channel\"\n location=\"channel-header\"\n [channel]=\"activeChannel\"\n [size]=\"40\"\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=\"\n str-chat__header-livestream-left--title str-chat__channel-header-title\n \"\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=\"\n str-chat__header-livestream-left--members\n str-chat__channel-header-info\n \"\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", components: [{ type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon", "size"] }, { type: AvatarPlaceholderComponent, selector: "stream-avatar-placeholder", inputs: ["name", "imageUrl", "size", "location", "channel", "user", "type"] }], directives: [{ type: i7.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], pipes: { "translate": i8.TranslatePipe } });
3613
3672
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ChannelHeaderComponent, decorators: [{
3614
3673
  type: Component,
3615
3674
  args: [{
@@ -3766,7 +3825,7 @@ class ChannelListComponent {
3766
3825
  }
3767
3826
  }
3768
3827
  ChannelListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ChannelListComponent, deps: [{ token: ChannelService }, { token: ChannelListToggleService }, { token: CustomTemplatesService }, { token: ThemeService }], target: i0.ɵɵFactoryTarget.Component });
3769
- ChannelListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: ChannelListComponent, selector: "stream-channel-list", viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true }], ngImport: i0, template: "<div\n #container\n data-testid=\"channel-list-container\"\n style=\"max-width: unset\"\n class=\"str-chat str-chat__channel-list str-chat-channel-list messaging str-chat__theme-{{\n theme$ | async\n }}\"\n [class.str-chat-channel-list--open]=\"(isOpen$ | async) === true\"\n>\n <div\n *ngIf=\"\n (isError$ | async) === false && (isInitializing$ | async) === false;\n else statusIndicator\n \"\n class=\"str-chat__channel-list-messenger\"\n >\n <div class=\"str-chat__channel-list-messenger__main\">\n <div\n class=\"str-chat__channel-list-empty\"\n *ngIf=\"!(channels$ | async)?.length\"\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 <ng-container\n *ngFor=\"let channel of channels$ | async; trackBy: trackByChannelId\"\n >\n <ng-template #defaultTemplate let-channelInput=\"channel\">\n <stream-channel-preview\n data-testclass=\"channel-preview\"\n [channel]=\"channelInput\"\n ></stream-channel-preview>\n </ng-template>\n <div (click)=\"channelSelected()\" (keyup.enter)=\"channelSelected()\">\n <ng-container\n *ngTemplateOutlet=\"\n customChannelPreviewTemplate || defaultTemplate;\n context: getChannelPreviewContext(channel)\n \"\n ></ng-container>\n </div>\n </ng-container>\n <div\n *ngIf=\"hasMoreChannels$ | async\"\n class=\"str-chat__load-more-button\"\n (click)=\"loadMoreChannels()\"\n (keyup.enter)=\"loadMoreChannels()\"\n data-testid=\"load-more\"\n >\n <button\n class=\"str-chat__load-more-button__button str-chat__cta-button\"\n data-testid=\"load-more-button\"\n [disabled]=\"isLoadingMoreChannels\"\n >\n <span *ngIf=\"!isLoadingMoreChannels; else loadingIndicator\">{{\n \"Load more\" | translate\n }}</span>\n <ng-template #loadingIndicator\n ><stream-loading-indicator-placeholder></stream-loading-indicator-placeholder\n ></ng-template>\n </button>\n </div>\n </div>\n </div>\n</div>\n\n<ng-template #statusIndicator>\n <ng-container *ngIf=\"isError$ | async\">\n <ng-container *ngTemplateOutlet=\"chatDown\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"isInitializing$ | async\">\n <ng-container *ngTemplateOutlet=\"loadingChannels\"></ng-container>\n </ng-container>\n</ng-template>\n\n<ng-template #chatDown>\n <div data-testid=\"chatdown-container\" class=\"str-chat__down\">\n <ng-container *ngTemplateOutlet=\"loadingChannels\"></ng-container>\n <div class=\"str-chat__down-main\">\n <stream-icon-placeholder\n icon=\"connection-error\"\n ></stream-icon-placeholder>\n <h1>{{ \"streamChat.Connection error\" | translate }}</h1>\n <h3>\n {{\n \"streamChat.Error connecting to chat, refresh the page to try again.\"\n | translate\n }}\n </h3>\n </div>\n </div>\n</ng-template>\n\n<ng-template #loadingChannels>\n <div data-testid=\"loading-indicator\" class=\"str-chat__loading-channels\">\n <ng-container *ngTemplateOutlet=\"loadingChannel\"></ng-container>\n <ng-container *ngTemplateOutlet=\"loadingChannel\"></ng-container>\n <ng-container *ngTemplateOutlet=\"loadingChannel\"></ng-container>\n </div>\n</ng-template>\n\n<ng-template #loadingChannel>\n <div\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=\"\n str-chat__loading-channels-meta str-chat__channel-preview-end-loading\n \"\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", components: [{ type: IconComponent, selector: "stream-icon", inputs: ["icon", "size"] }, { type: ChannelPreviewComponent, selector: "stream-channel-preview", inputs: ["channel"] }, { type: LoadingIndicatorPlaceholderComponent, selector: "stream-loading-indicator-placeholder", inputs: ["size", "color"] }, { type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon", "size"] }], directives: [{ type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i7.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i7.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], pipes: { "async": i7.AsyncPipe, "translate": i8.TranslatePipe } });
3828
+ ChannelListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: ChannelListComponent, selector: "stream-channel-list", viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true }], ngImport: i0, template: "<div\n #container\n data-testid=\"channel-list-container\"\n style=\"max-width: unset\"\n class=\"str-chat str-chat__channel-list str-chat-channel-list messaging str-chat__theme-{{\n theme$ | async\n }}\"\n [class.str-chat-channel-list--open]=\"(isOpen$ | async) === true\"\n>\n <div\n *ngIf=\"\n (isError$ | async) === false && (isInitializing$ | async) === false;\n else statusIndicator\n \"\n class=\"str-chat__channel-list-messenger\"\n >\n <div class=\"str-chat__channel-list-messenger__main\">\n <div\n class=\"str-chat__channel-list-empty\"\n *ngIf=\"!(channels$ | async)?.length\"\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 <ng-content select=\"[channel-list-top]\"></ng-content>\n <ng-container\n *ngFor=\"let channel of channels$ | async; trackBy: trackByChannelId\"\n >\n <ng-template #defaultTemplate let-channelInput=\"channel\">\n <stream-channel-preview\n data-testclass=\"channel-preview\"\n [channel]=\"channelInput\"\n ></stream-channel-preview>\n </ng-template>\n <div (click)=\"channelSelected()\" (keyup.enter)=\"channelSelected()\">\n <ng-container\n *ngTemplateOutlet=\"\n customChannelPreviewTemplate || defaultTemplate;\n context: getChannelPreviewContext(channel)\n \"\n ></ng-container>\n </div>\n </ng-container>\n <div\n *ngIf=\"hasMoreChannels$ | async\"\n class=\"str-chat__load-more-button\"\n (click)=\"loadMoreChannels()\"\n (keyup.enter)=\"loadMoreChannels()\"\n data-testid=\"load-more\"\n >\n <button\n class=\"str-chat__load-more-button__button str-chat__cta-button\"\n data-testid=\"load-more-button\"\n [disabled]=\"isLoadingMoreChannels\"\n >\n <span *ngIf=\"!isLoadingMoreChannels; else loadingIndicator\">{{\n \"Load more\" | translate\n }}</span>\n <ng-template #loadingIndicator\n ><stream-loading-indicator-placeholder></stream-loading-indicator-placeholder\n ></ng-template>\n </button>\n </div>\n <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 class=\"str-chat__down-main\">\n <stream-icon-placeholder\n icon=\"connection-error\"\n ></stream-icon-placeholder>\n <h1>{{ \"streamChat.Connection error\" | translate }}</h1>\n <h3>\n {{\n \"streamChat.Error connecting to chat, refresh the page to try again.\"\n | translate\n }}\n </h3>\n </div>\n </div>\n</ng-template>\n\n<ng-template #loadingChannels>\n <div data-testid=\"loading-indicator\" class=\"str-chat__loading-channels\">\n <ng-container *ngTemplateOutlet=\"loadingChannel\"></ng-container>\n <ng-container *ngTemplateOutlet=\"loadingChannel\"></ng-container>\n <ng-container *ngTemplateOutlet=\"loadingChannel\"></ng-container>\n </div>\n</ng-template>\n\n<ng-template #loadingChannel>\n <div\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=\"\n str-chat__loading-channels-meta str-chat__channel-preview-end-loading\n \"\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", components: [{ type: IconComponent, selector: "stream-icon", inputs: ["icon", "size"] }, { type: ChannelPreviewComponent, selector: "stream-channel-preview", inputs: ["channel"] }, { type: LoadingIndicatorPlaceholderComponent, selector: "stream-loading-indicator-placeholder", inputs: ["size", "color"] }, { type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon", "size"] }], directives: [{ type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i7.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i7.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], pipes: { "async": i7.AsyncPipe, "translate": i8.TranslatePipe } });
3770
3829
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ChannelListComponent, decorators: [{
3771
3830
  type: Component,
3772
3831
  args: [{