stream-chat-angular 4.56.0-perf-message-list.1 → 4.56.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.
@@ -20,7 +20,7 @@ import transliterate from '@stream-io/transliterate';
20
20
  import * as i8 from 'angular-mentions';
21
21
  import { MentionModule } from 'angular-mentions';
22
22
 
23
- const version = '4.56.0-perf-message-list.1';
23
+ const version = '4.56.0';
24
24
 
25
25
  /**
26
26
  * The `NotificationService` can be used to add or remove notifications. By default the [`NotificationList`](../components/NotificationListComponent.mdx) component displays the currently active notifications.
@@ -2416,9 +2416,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
2416
2416
  * The `Avatar` component displays the provided image, with fallback to the first letter of the optional name input.
2417
2417
  */
2418
2418
  class AvatarComponent {
2419
- constructor(chatClientService, ngZone) {
2419
+ constructor(chatClientService, ngZone, cdRef) {
2420
2420
  this.chatClientService = chatClientService;
2421
2421
  this.ngZone = ngZone;
2422
+ this.cdRef = cdRef;
2422
2423
  /**
2423
2424
  * The size in pixels of the avatar image.
2424
2425
  */
@@ -2433,37 +2434,51 @@ class AvatarComponent {
2433
2434
  this.initialsType = 'first-letter-of-first-word';
2434
2435
  this.isError = false;
2435
2436
  this.isOnline = false;
2437
+ this.initials = '';
2438
+ this.isViewInited = false;
2439
+ this.subscriptions = [];
2436
2440
  }
2437
- ngOnChanges(changes) {
2438
- var _a, _b;
2439
- if (changes['channel']) {
2440
- if (this.channel) {
2441
- const otherMember = this.getOtherMemberIfOneToOneChannel();
2442
- if (otherMember) {
2443
- this.isOnline = otherMember.online || false;
2444
- this.isOnlineSubscription = this.chatClientService.events$
2445
- .pipe(filter((e) => e.eventType === 'user.presence.changed'))
2446
- .subscribe((event) => {
2447
- var _a;
2448
- if (((_a = event.event.user) === null || _a === void 0 ? void 0 : _a.id) === otherMember.id) {
2449
- this.ngZone.run(() => {
2450
- var _a;
2451
- this.isOnline = ((_a = event.event.user) === null || _a === void 0 ? void 0 : _a.online) || false;
2452
- });
2453
- }
2454
- });
2441
+ ngOnInit() {
2442
+ this.subscriptions.push(this.chatClientService.user$.subscribe((u) => {
2443
+ if ((u === null || u === void 0 ? void 0 : u.id) !== this.userId) {
2444
+ this.userId = u === null || u === void 0 ? void 0 : u.id;
2445
+ if (this.type || this.channel || this.name) {
2446
+ this.setInitials();
2447
+ this.setFallbackChannelImage();
2448
+ this.updateIsOnlineSubscription();
2455
2449
  }
2456
- else {
2457
- (_a = this.isOnlineSubscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
2450
+ if (this.isViewInited) {
2451
+ this.cdRef.detectChanges();
2458
2452
  }
2459
2453
  }
2454
+ }));
2455
+ }
2456
+ ngOnChanges(changes) {
2457
+ if (changes['channel']) {
2458
+ this.updateIsOnlineSubscription();
2459
+ }
2460
+ if (changes.type || changes.name || changes.channel) {
2461
+ this.setInitials();
2462
+ }
2463
+ if (changes.type || changes.channel) {
2464
+ this.setFallbackChannelImage();
2465
+ }
2466
+ }
2467
+ setFallbackChannelImage() {
2468
+ if (this.type !== 'channel') {
2469
+ this.fallbackChannelImage = undefined;
2470
+ }
2471
+ else {
2472
+ const otherMember = this.getOtherMemberIfOneToOneChannel();
2473
+ if (otherMember) {
2474
+ this.fallbackChannelImage = otherMember.image;
2475
+ }
2460
2476
  else {
2461
- this.isOnline = false;
2462
- (_b = this.isOnlineSubscription) === null || _b === void 0 ? void 0 : _b.unsubscribe();
2477
+ this.fallbackChannelImage = undefined;
2463
2478
  }
2464
2479
  }
2465
2480
  }
2466
- get initials() {
2481
+ setInitials() {
2467
2482
  var _a, _b, _c, _d, _e;
2468
2483
  let result = '';
2469
2484
  if (this.type === 'user') {
@@ -2491,25 +2506,41 @@ class AvatarComponent {
2491
2506
  else {
2492
2507
  initials = words[0].charAt(0) || '';
2493
2508
  }
2494
- return initials;
2509
+ this.initials = initials;
2495
2510
  }
2496
- get fallbackChannelImage() {
2497
- if (this.type !== 'channel') {
2498
- return undefined;
2499
- }
2500
- else {
2511
+ updateIsOnlineSubscription() {
2512
+ var _a, _b;
2513
+ if (this.channel) {
2501
2514
  const otherMember = this.getOtherMemberIfOneToOneChannel();
2502
2515
  if (otherMember) {
2503
- return otherMember.image;
2516
+ this.isOnline = otherMember.online || false;
2517
+ this.isOnlineSubscription = this.chatClientService.events$
2518
+ .pipe(filter((e) => e.eventType === 'user.presence.changed'))
2519
+ .subscribe((event) => {
2520
+ var _a;
2521
+ if (((_a = event.event.user) === null || _a === void 0 ? void 0 : _a.id) === otherMember.id) {
2522
+ this.ngZone.run(() => {
2523
+ var _a;
2524
+ this.isOnline = ((_a = event.event.user) === null || _a === void 0 ? void 0 : _a.online) || false;
2525
+ });
2526
+ }
2527
+ });
2504
2528
  }
2505
2529
  else {
2506
- return undefined;
2530
+ (_a = this.isOnlineSubscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
2507
2531
  }
2508
2532
  }
2533
+ else {
2534
+ this.isOnline = false;
2535
+ (_b = this.isOnlineSubscription) === null || _b === void 0 ? void 0 : _b.unsubscribe();
2536
+ }
2537
+ }
2538
+ ngAfterViewInit() {
2539
+ this.isViewInited = true;
2509
2540
  }
2510
2541
  getOtherMemberIfOneToOneChannel() {
2511
2542
  var _a, _b;
2512
- const otherMembers = Object.values(((_b = (_a = this.channel) === null || _a === void 0 ? void 0 : _a.state) === null || _b === void 0 ? void 0 : _b.members) || {}).filter((m) => { var _a; return m.user_id !== ((_a = this.chatClientService.chatClient.user) === null || _a === void 0 ? void 0 : _a.id); });
2543
+ const otherMembers = Object.values(((_b = (_a = this.channel) === null || _a === void 0 ? void 0 : _a.state) === null || _b === void 0 ? void 0 : _b.members) || {}).filter((m) => m.user_id !== this.userId);
2513
2544
  if (otherMembers.length === 1) {
2514
2545
  return otherMembers[0].user;
2515
2546
  }
@@ -2518,7 +2549,7 @@ class AvatarComponent {
2518
2549
  }
2519
2550
  }
2520
2551
  }
2521
- 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 });
2552
+ AvatarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: AvatarComponent, deps: [{ token: ChatClientService }, { token: i0.NgZone }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
2522
2553
  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", initialsType: "initialsType" }, 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:\n initialsType === 'first-letter-of-first-word'\n ? 'calc(var(--str-chat__spacing-px, 1px) * ' + size / 2 + ')'\n : 'calc(var(--str-chat__spacing-px, 1px) * ' + size / 3 + ')',\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 src=\"{{ imageUrl || fallbackChannelImage }}\"\n alt=\"{{ initials }}\"\n data-testid=\"avatar-img\"\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 fetchpriority=\"high\"\n />\n <ng-template #fallback>\n <div\n data-testid=\"fallback-img\"\n style=\"overflow: hidden; white-space: nowrap; text-overflow: ellipsis\"\n class=\"str-chat__avatar-fallback\"\n >\n {{ initials }}\n </div>\n </ng-template>\n <div\n data-testid=\"online-indicator\"\n *ngIf=\"isOnline && showOnlineIndicator\"\n class=\"str-chat__avatar--online-indicator\"\n ></div>\n</div>\n", styles: [""], directives: [{ type: i9.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
2523
2554
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: AvatarComponent, decorators: [{
2524
2555
  type: Component,
@@ -2527,7 +2558,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
2527
2558
  templateUrl: './avatar.component.html',
2528
2559
  styleUrls: ['./avatar.component.scss'],
2529
2560
  }]
2530
- }], ctorParameters: function () { return [{ type: ChatClientService }, { type: i0.NgZone }]; }, propDecorators: { name: [{
2561
+ }], ctorParameters: function () { return [{ type: ChatClientService }, { type: i0.NgZone }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { name: [{
2531
2562
  type: Input
2532
2563
  }], imageUrl: [{
2533
2564
  type: Input
@@ -4658,6 +4689,11 @@ class MessageReactionsComponent {
4658
4689
  this.isLoading = true;
4659
4690
  this.reactions = [];
4660
4691
  this.shouldHandleReactionClick = true;
4692
+ this.existingReactions = [];
4693
+ this.reactionsCount = 0;
4694
+ this.reactionOptions = [];
4695
+ this.subscriptions = [];
4696
+ this.isViewInited = false;
4661
4697
  this.isOpenChange = (isOpen) => {
4662
4698
  this.selectedReactionType = isOpen ? this.selectedReactionType : undefined;
4663
4699
  };
@@ -4668,12 +4704,24 @@ class MessageReactionsComponent {
4668
4704
  }
4669
4705
  };
4670
4706
  }
4707
+ ngOnInit() {
4708
+ this.subscriptions.push(this.messageReactionsService.reactions$.subscribe((reactions) => {
4709
+ this.reactionOptions = Object.keys(reactions);
4710
+ this.setExistingReactions();
4711
+ if (this.isViewInited) {
4712
+ this.cdRef.detectChanges();
4713
+ }
4714
+ }));
4715
+ }
4671
4716
  ngOnChanges(changes) {
4672
4717
  if (changes.isSelectorOpen) {
4673
4718
  this.isSelectorOpen
4674
4719
  ? setTimeout(() => this.watchForOutsideClicks()) // setTimeout: wait for current click to bubble up, and only watch for clicks after that
4675
4720
  : this.stopWatchForOutsideClicks();
4676
4721
  }
4722
+ if (changes.messageReactionCounts) {
4723
+ this.setExistingReactions();
4724
+ }
4677
4725
  if (changes.messageReactionCounts && this.messageReactionCounts) {
4678
4726
  const reactionsCount = Object.keys(this.messageReactionCounts).reduce((acc, key) => acc + (this.messageReactionCounts[key] || 0), 0);
4679
4727
  this.shouldHandleReactionClick =
@@ -4681,22 +4729,17 @@ class MessageReactionsComponent {
4681
4729
  !!this.messageReactionsService.customReactionClickHandler;
4682
4730
  }
4683
4731
  }
4732
+ ngAfterViewInit() {
4733
+ this.isViewInited = true;
4734
+ }
4684
4735
  ngAfterViewChecked() {
4685
4736
  if (this.tooltipText && !this.tooltipPositions) {
4686
4737
  this.setTooltipPosition();
4687
4738
  this.cdRef.detectChanges();
4688
4739
  }
4689
4740
  }
4690
- get existingReactions() {
4691
- return Object.keys(this.messageReactionCounts)
4692
- .filter((k) => this.reactionOptions.indexOf(k) !== -1)
4693
- .filter((k) => this.messageReactionCounts[k] > 0);
4694
- }
4695
- get reactionsCount() {
4696
- return this.existingReactions.reduce((total, reaction) => total + this.messageReactionCounts[reaction], 0);
4697
- }
4698
- get reactionOptions() {
4699
- return Object.keys(this.messageReactionsService.reactions);
4741
+ ngOnDestroy() {
4742
+ this.subscriptions.forEach((s) => s.unsubscribe());
4700
4743
  }
4701
4744
  getLatestUserByReaction(reactionType) {
4702
4745
  var _a;
@@ -4826,9 +4869,15 @@ class MessageReactionsComponent {
4826
4869
  }
4827
4870
  });
4828
4871
  }
4872
+ setExistingReactions() {
4873
+ this.existingReactions = Object.keys(this.messageReactionCounts)
4874
+ .filter((k) => this.reactionOptions.indexOf(k) !== -1)
4875
+ .filter((k) => this.messageReactionCounts[k] > 0);
4876
+ this.reactionsCount = this.existingReactions.reduce((total, reaction) => total + this.messageReactionCounts[reaction], 0);
4877
+ }
4829
4878
  }
4830
4879
  MessageReactionsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: MessageReactionsComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: ChannelService }, { token: MessageReactionsService }, { token: CustomTemplatesService }, { token: ThemeService }], target: i0.ɵɵFactoryTarget.Component });
4831
- MessageReactionsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: MessageReactionsComponent, selector: "stream-message-reactions", inputs: { messageId: "messageId", messageReactionCounts: "messageReactionCounts", isSelectorOpen: "isSelectorOpen", latestReactions: "latestReactions", ownReactions: "ownReactions" }, outputs: { isSelectorOpenChange: "isSelectorOpenChange" }, viewQueries: [{ propertyName: "selectorContainer", first: true, predicate: ["selectorContainer"], descendants: true }, { propertyName: "selectorTooltip", first: true, predicate: ["selectorTooltip"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div\n *ngIf=\"existingReactions.length > 0\"\n class=\"str-chat__reaction-list str-chat__message-reactions-container\"\n [class.str-chat__reaction-list--reverse]=\"true\"\n [class.str-chat__reaction-list-hidden]=\"isSelectorOpen\"\n data-testid=\"reaction-list\"\n>\n <ul class=\"str-chat__message-reactions\">\n <li\n class=\"str-chat__message-reaction\"\n *ngFor=\"\n let reactionType of existingReactions;\n trackBy: trackByMessageReaction\n \"\n [ngStyle]=\"{ cursor: shouldHandleReactionClick ? 'pointer' : 'default' }\"\n [class.str-chat__message-reaction-own]=\"isOwnReaction(reactionType)\"\n data-testclass=\"emoji\"\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 {{ messageReactionCounts[reactionType] }}\n </span>\n </li>\n <li>\n <span\n data-testid=\"reactions-count\"\n class=\"str-chat__reaction-list--counter\"\n >{{ reactionsCount }}</span\n >\n </li>\n </ul>\n</div>\n\n<div\n #selectorContainer\n class=\"str-chat__reaction-selector str-chat__message-reaction-selector\"\n *ngIf=\"isSelectorOpen\"\n data-testid=\"reaction-selector\"\n>\n <div\n *ngIf=\"tooltipText\"\n data-testid=\"tooltip\"\n #selectorTooltip\n class=\"str-chat__reaction-selector-tooltip\"\n [ngStyle]=\"{\n left: tooltipPositions?.tooltip + 'px',\n visibility: tooltipPositions ? 'visible' : 'hidden'\n }\"\n >\n <div\n class=\"arrow\"\n [ngStyle]=\"{ left: tooltipPositions?.arrow + 'px' }\"\n ></div>\n <span class=\"latest-user-username\">\n {{ tooltipText }}\n </span>\n </div>\n <ul\n class=\"str-chat__message-reactions-list str-chat__message-reactions-options\"\n >\n <li\n class=\"\n str-chat__message-reactions-option\n str-chat__message-reactions-list-item\n str-chat__emoji\n \"\n *ngFor=\"\n let reactionType of reactionOptions;\n trackBy: trackByMessageReaction\n \"\n [class.str-chat__message-reactions-option-selected]=\"\n isOwnReaction(reactionType)\n \"\n data-testclass=\"emoji-option\"\n (click)=\"react(reactionType)\"\n (keyup.enter)=\"react(reactionType)\"\n >\n <div\n *ngIf=\"getLatestUserByReaction(reactionType) as user\"\n class=\"latest-user str-chat__message-reactions-last-user\"\n (click)=\"hideTooltip()\"\n (keyup.enter)=\"hideTooltip()\"\n (mouseenter)=\"showTooltip($event, reactionType)\"\n (mouseleave)=\"hideTooltip()\"\n attr.data-testid=\"{{ reactionType }}-last-user\"\n >\n <stream-avatar-placeholder\n attr.data-testid=\"{{ reactionType }}-avatar\"\n [imageUrl]=\"user.image\"\n [name]=\"user.name || user.id\"\n [size]=\"20\"\n location=\"reaction\"\n ></stream-avatar-placeholder>\n </div>\n <span\n class=\"\n emoji\n str-chat__emoji-selector-emoji-angular\n str-chat__message-reaction-emoji\n \"\n >\n {{ getEmojiByReaction(reactionType) }}\n </span>\n <span\n *ngIf=\"\n messageReactionCounts[reactionType] &&\n messageReactionCounts[reactionType]! > 0\n \"\n class=\"str-chat__message-reactions-list-item__count\"\n attr.data-testid=\"{{ reactionType }}-reaction-count\"\n >\n {{ messageReactionCounts[reactionType] }}\n </span>\n </li>\n </ul>\n</div>\n\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 }\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>\n <stream-modal\n class=\"str-chat__message-reactions-details-modal\"\n [isOpen]=\"isOpen\"\n (isOpenChange)=\"isOpenChangeHandler($event)\"\n >\n <div class=\"str-chat__message-reactions-details\">\n <div class=\"str-chat__message-reactions-details-reaction-types\">\n <div\n class=\"str-chat__message-reactions-details-reaction-type\"\n *ngFor=\"\n let reactionType of existingReactions;\n trackBy: trackByMessageReaction\n \"\n [ngStyle]=\"{\n cursor: shouldHandleReactionClick ? 'pointer' : 'default'\n }\"\n attr.data-testid=\"reaction-details-selector-{{ reactionType }}\"\n [class.str-chat__message-reactions-details-reaction-type--selected]=\"\n reactionType === selectedReactionType\n \"\n (click)=\"selectedReactionType = reactionType; allUsers.scrollTop = 0\"\n (keyup.enter)=\"\n selectedReactionType = reactionType; allUsers.scrollTop = 0\n \"\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 {{ messageReactionCounts[reactionType] }}\n </span>\n </div>\n </div>\n <div\n class=\"\n emoji\n str-chat__message-reaction-emoji str-chat__message-reaction-emoji-big\n \"\n >\n {{ getEmojiByReaction(selectedReactionType!) }}\n </div>\n <div\n #allUsers\n data-testid=\"all-reacting-users\"\n class=\"str-chat__message-reactions-details-reacting-users\"\n >\n <stream-loading-indicator\n *ngIf=\"isLoading; else reactions\"\n ></stream-loading-indicator>\n <ng-template #reactions>\n <div\n class=\"str-chat__message-reactions-details-reacting-user\"\n *ngFor=\"\n let user of getAllUsersByReaction(selectedReactionType);\n trackBy: trackByUserId\n \"\n >\n <stream-avatar-placeholder\n data-testclass=\"avatar\"\n class=\"str-chat__avatar str-chat__avatar--circle\"\n style=\"max-height: 100%; overflow-y: hidden\"\n [size]=\"30\"\n [imageUrl]=\"user.image\"\n [name]=\"user.name\"\n type=\"user\"\n location=\"reaction\"\n [user]=\"user\"\n ></stream-avatar-placeholder>\n <span\n data-testclass=\"reaction-user-username\"\n class=\"str-chat__user-item--name\"\n >{{ user.name }}</span\n >\n </div>\n </ng-template>\n </div>\n </div>\n </stream-modal>\n</ng-template>\n", styles: [".emoji {position: relative; display: inline-block; }"], components: [{ type: AvatarPlaceholderComponent, selector: "stream-avatar-placeholder", inputs: ["name", "imageUrl", "size", "location", "channel", "user", "type", "initialsType", "showOnlineIndicator"] }, { type: ModalComponent, selector: "stream-modal", inputs: ["isOpen", "content"], outputs: ["isOpenChange"] }, { type: LoadingIndicatorComponent, selector: "stream-loading-indicator", inputs: ["size", "color"] }], directives: [{ type: i9.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i9.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i9.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { type: i9.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], pipes: { "async": i9.AsyncPipe } });
4880
+ MessageReactionsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: MessageReactionsComponent, selector: "stream-message-reactions", inputs: { messageId: "messageId", messageReactionCounts: "messageReactionCounts", isSelectorOpen: "isSelectorOpen", latestReactions: "latestReactions", ownReactions: "ownReactions" }, outputs: { isSelectorOpenChange: "isSelectorOpenChange" }, viewQueries: [{ propertyName: "selectorContainer", first: true, predicate: ["selectorContainer"], descendants: true }, { propertyName: "selectorTooltip", first: true, predicate: ["selectorTooltip"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div\n *ngIf=\"existingReactions.length > 0\"\n class=\"str-chat__reaction-list str-chat__message-reactions-container\"\n [class.str-chat__reaction-list--reverse]=\"true\"\n [class.str-chat__reaction-list-hidden]=\"isSelectorOpen\"\n data-testid=\"reaction-list\"\n>\n <ul class=\"str-chat__message-reactions\">\n <li\n class=\"str-chat__message-reaction\"\n *ngFor=\"\n let reactionType of existingReactions;\n trackBy: trackByMessageReaction\n \"\n [ngStyle]=\"{ cursor: shouldHandleReactionClick ? 'pointer' : 'default' }\"\n [class.str-chat__message-reaction-own]=\"isOwnReaction(reactionType)\"\n data-testclass=\"emoji\"\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 {{ messageReactionCounts[reactionType] }}\n </span>\n </li>\n <li>\n <span\n data-testid=\"reactions-count\"\n class=\"str-chat__reaction-list--counter\"\n >{{ reactionsCount }}</span\n >\n </li>\n </ul>\n</div>\n\n<div\n #selectorContainer\n class=\"str-chat__reaction-selector str-chat__message-reaction-selector\"\n *ngIf=\"isSelectorOpen\"\n data-testid=\"reaction-selector\"\n>\n <div\n *ngIf=\"tooltipText\"\n data-testid=\"tooltip\"\n #selectorTooltip\n class=\"str-chat__reaction-selector-tooltip\"\n [ngStyle]=\"{\n left: tooltipPositions?.tooltip + 'px',\n visibility: tooltipPositions ? 'visible' : 'hidden'\n }\"\n >\n <div\n class=\"arrow\"\n [ngStyle]=\"{ left: tooltipPositions?.arrow + 'px' }\"\n ></div>\n <span class=\"latest-user-username\">\n {{ tooltipText }}\n </span>\n </div>\n <ul\n class=\"str-chat__message-reactions-list str-chat__message-reactions-options\"\n >\n <li\n class=\"\n str-chat__message-reactions-option\n str-chat__message-reactions-list-item\n str-chat__emoji\n \"\n *ngFor=\"\n let reactionType of reactionOptions;\n trackBy: trackByMessageReaction\n \"\n [class.str-chat__message-reactions-option-selected]=\"\n isOwnReaction(reactionType)\n \"\n data-testclass=\"emoji-option\"\n (click)=\"react(reactionType)\"\n (keyup.enter)=\"react(reactionType)\"\n >\n <div\n *ngIf=\"getLatestUserByReaction(reactionType) as user\"\n class=\"latest-user str-chat__message-reactions-last-user\"\n (click)=\"hideTooltip()\"\n (keyup.enter)=\"hideTooltip()\"\n (mouseenter)=\"showTooltip($event, reactionType)\"\n (mouseleave)=\"hideTooltip()\"\n attr.data-testid=\"{{ reactionType }}-last-user\"\n >\n <stream-avatar-placeholder\n attr.data-testid=\"{{ reactionType }}-avatar\"\n [imageUrl]=\"user.image\"\n [name]=\"user.name || user.id\"\n [size]=\"20\"\n location=\"reaction\"\n ></stream-avatar-placeholder>\n </div>\n <span\n class=\"\n emoji\n str-chat__emoji-selector-emoji-angular\n str-chat__message-reaction-emoji\n \"\n >\n {{ getEmojiByReaction(reactionType) }}\n </span>\n <span\n *ngIf=\"\n messageReactionCounts[reactionType] &&\n messageReactionCounts[reactionType]! > 0\n \"\n class=\"str-chat__message-reactions-list-item__count\"\n attr.data-testid=\"{{ reactionType }}-reaction-count\"\n >\n {{ messageReactionCounts[reactionType] }}\n </span>\n </li>\n </ul>\n</div>\n\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 (isOpenChange)=\"isOpenChangeHandler($event)\"\n [content]=\"content\"\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 class=\"str-chat__message-reactions-details-reaction-type\"\n *ngFor=\"\n let reactionType of existingReactions;\n trackBy: trackByMessageReaction\n \"\n [ngStyle]=\"{\n cursor: shouldHandleReactionClick ? 'pointer' : 'default'\n }\"\n attr.data-testid=\"reaction-details-selector-{{ reactionType }}\"\n [class.str-chat__message-reactions-details-reaction-type--selected]=\"\n reactionType === selectedReactionType\n \"\n (click)=\"selectedReactionType = reactionType; allUsers.scrollTop = 0\"\n (keyup.enter)=\"\n selectedReactionType = reactionType; allUsers.scrollTop = 0\n \"\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 {{ messageReactionCounts[reactionType] }}\n </span>\n </div>\n </div>\n <div\n class=\"\n emoji\n str-chat__message-reaction-emoji str-chat__message-reaction-emoji-big\n \"\n >\n {{ getEmojiByReaction(selectedReactionType!) }}\n </div>\n <div\n #allUsers\n data-testid=\"all-reacting-users\"\n class=\"str-chat__message-reactions-details-reacting-users\"\n >\n <stream-loading-indicator\n *ngIf=\"isLoading; else reactions\"\n ></stream-loading-indicator>\n <ng-template #reactions>\n <div\n class=\"str-chat__message-reactions-details-reacting-user\"\n *ngFor=\"\n let user of getAllUsersByReaction(selectedReactionType);\n trackBy: trackByUserId\n \"\n >\n <stream-avatar-placeholder\n data-testclass=\"avatar\"\n class=\"str-chat__avatar str-chat__avatar--circle\"\n style=\"max-height: 100%; overflow-y: hidden\"\n [size]=\"30\"\n [imageUrl]=\"user.image\"\n [name]=\"user.name\"\n type=\"user\"\n location=\"reaction\"\n [user]=\"user\"\n ></stream-avatar-placeholder>\n <span\n data-testclass=\"reaction-user-username\"\n class=\"str-chat__user-item--name\"\n >{{ user.name }}</span\n >\n </div>\n </ng-template>\n </div>\n </div>\n</ng-template>\n", styles: [".emoji {position: relative; display: inline-block; }"], components: [{ type: AvatarPlaceholderComponent, selector: "stream-avatar-placeholder", inputs: ["name", "imageUrl", "size", "location", "channel", "user", "type", "initialsType", "showOnlineIndicator"] }, { type: ModalComponent, selector: "stream-modal", inputs: ["isOpen", "content"], outputs: ["isOpenChange"] }, { type: LoadingIndicatorComponent, selector: "stream-loading-indicator", inputs: ["size", "color"] }], directives: [{ type: i9.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i9.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i9.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { type: i9.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], pipes: { "async": i9.AsyncPipe } });
4832
4881
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: MessageReactionsComponent, decorators: [{
4833
4882
  type: Component,
4834
4883
  args: [{