Skip to content

Commit 614e2c4

Browse files
committed
feat: display empty div for not visible avatars
1 parent 5fb9916 commit 614e2c4

File tree

2 files changed

+72
-9
lines changed

2 files changed

+72
-9
lines changed

projects/stream-chat-angular/src/lib/avatar-placeholder/avatar-placeholder.component.html

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,20 @@
2020
[initialsType]="initialsType"
2121
></stream-avatar>
2222
</ng-template>
23-
<ng-container
24-
*ngTemplateOutlet="
25-
(customTemplatesService.avatarTemplate$ | async) || defaultAvatar;
26-
context: context
27-
"
28-
></ng-container>
23+
<ng-container *ngIf="isVisible; else emptyPlaceholder">
24+
<ng-container
25+
*ngTemplateOutlet="
26+
(customTemplatesService.avatarTemplate$ | async) || defaultAvatar;
27+
context: context
28+
"
29+
></ng-container>
30+
</ng-container>
31+
<ng-template #emptyPlaceholder>
32+
<div
33+
class="str-chat__avatar"
34+
[ngStyle]="{
35+
width: 'calc(var(--str-chat__spacing-px, 1px) * ' + size + ')',
36+
height: 'calc(var(--str-chat__spacing-px, 1px) * ' + size + ')'
37+
}"
38+
></div>
39+
</ng-template>

projects/stream-chat-angular/src/lib/avatar-placeholder/avatar-placeholder.component.ts

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
1-
import { Component, Input, OnChanges } from '@angular/core';
1+
import {
2+
AfterViewInit,
3+
ChangeDetectorRef,
4+
Component,
5+
ElementRef,
6+
Input,
7+
OnChanges,
8+
OnDestroy,
9+
} from '@angular/core';
210
import { Channel, User } from 'stream-chat';
311
import { CustomTemplatesService } from '../custom-templates.service';
412
import {
@@ -16,7 +24,9 @@ import {
1624
templateUrl: './avatar-placeholder.component.html',
1725
styles: [],
1826
})
19-
export class AvatarPlaceholderComponent implements OnChanges {
27+
export class AvatarPlaceholderComponent
28+
implements OnChanges, AfterViewInit, OnDestroy
29+
{
2030
/**
2131
* An optional name of the image, used for fallback image or image title (if `imageUrl` is provided)
2232
*/
@@ -61,7 +71,34 @@ export class AvatarPlaceholderComponent implements OnChanges {
6171
type: undefined,
6272
initialsType: undefined,
6373
};
64-
constructor(public customTemplatesService: CustomTemplatesService) {}
74+
isVisible = true;
75+
private mutationObserver?: MutationObserver;
76+
constructor(
77+
public customTemplatesService: CustomTemplatesService,
78+
private hostElement: ElementRef<HTMLElement>,
79+
private cdRef: ChangeDetectorRef
80+
) {}
81+
82+
ngAfterViewInit(): void {
83+
if (this.location !== 'message-sender') {
84+
this.isVisible = true;
85+
this.cdRef.detectChanges();
86+
return;
87+
}
88+
this.checkIfVisible();
89+
const elementToObserve =
90+
this.hostElement.nativeElement.parentElement?.parentElement
91+
?.parentElement;
92+
if (!elementToObserve) {
93+
return;
94+
}
95+
this.mutationObserver = new MutationObserver(() => {
96+
this.checkIfVisible();
97+
});
98+
this.mutationObserver.observe(elementToObserve, {
99+
attributeFilter: ['class'],
100+
});
101+
}
65102

66103
ngOnChanges(): void {
67104
this.context = {
@@ -75,4 +112,19 @@ export class AvatarPlaceholderComponent implements OnChanges {
75112
initialsType: this.initialsType,
76113
};
77114
}
115+
116+
ngOnDestroy(): void {
117+
this.mutationObserver?.disconnect();
118+
}
119+
120+
private checkIfVisible() {
121+
const isVisible =
122+
getComputedStyle(this.hostElement.nativeElement).getPropertyValue(
123+
'visibility'
124+
) === 'visible';
125+
if (isVisible !== this.isVisible) {
126+
this.isVisible = isVisible;
127+
this.cdRef.detectChanges();
128+
}
129+
}
78130
}

0 commit comments

Comments
 (0)