Skip to content

Commit 691d12b

Browse files
committed
In progress - message, message actions and message list cd optimization
1 parent eb2dc45 commit 691d12b

File tree

5 files changed

+69
-28
lines changed

5 files changed

+69
-28
lines changed

projects/stream-chat-angular/src/lib/message-actions-box/message-actions-box.component.html

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
data-testid="action-box"
44
class="str-chat__message-actions-box str-chat__message-actions-box-angular"
55
[class.str-chat__message-actions-box--open]="true"
6-
*ngIf="isOpen"
76
>
87
<ul class="str-chat__message-actions-list">
98
<ng-container

projects/stream-chat-angular/src/lib/message-list/message-list.component.ts

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ export class MessageListComponent
131131
private isLatestMessageInList = true;
132132
private channelId?: string;
133133
private parsedDates = new Map<Date, string>();
134+
private isViewInited = false;
134135

135136
@HostBinding('class')
136137
private get class() {
@@ -182,7 +183,9 @@ export class MessageListComponent
182183
} else {
183184
this.lastReadMessageId = undefined;
184185
}
185-
this.cdRef.detectChanges();
186+
if (this.isViewInited) {
187+
this.cdRef.detectChanges();
188+
}
186189
}
187190
const capabilites = channel?.data?.own_capabilities as string[];
188191
const capabilitesString = [...(capabilites || [])].sort().join('');
@@ -191,7 +194,9 @@ export class MessageListComponent
191194
.join('');
192195
if (capabilitesString !== enabledActionsString) {
193196
this.enabledMessageActions = capabilites || [];
194-
this.cdRef.detectChanges();
197+
if (this.isViewInited) {
198+
this.cdRef.detectChanges();
199+
}
195200
}
196201
this.newMessageSubscription?.unsubscribe();
197202
if (channel) {
@@ -217,7 +222,9 @@ export class MessageListComponent
217222
this.messageActionsService.customActions$.subscribe((actions) => {
218223
if (actions !== this.customMessageActions) {
219224
this.customMessageActions = actions;
220-
this.cdRef.detectChanges();
225+
if (this.isViewInited) {
226+
this.cdRef.detectChanges();
227+
}
221228
}
222229
})
223230
);
@@ -232,36 +239,58 @@ export class MessageListComponent
232239
this.resetScrollState();
233240
}
234241
this.parentMessage = message;
235-
this.cdRef.detectChanges();
242+
if (this.isViewInited) {
243+
this.cdRef.detectChanges();
244+
}
236245
})
237246
);
238247
this.subscriptions.push(
239248
this.customTemplatesService.messageTemplate$.subscribe((template) => {
249+
if (this.messageTemplate === template) {
250+
return;
251+
}
240252
this.messageTemplate = template;
241-
this.cdRef.detectChanges();
253+
if (this.isViewInited) {
254+
this.cdRef.detectChanges();
255+
}
242256
})
243257
);
244258
this.subscriptions.push(
245259
this.customTemplatesService.dateSeparatorTemplate$.subscribe(
246260
(template) => {
261+
if (this.customDateSeparatorTemplate === template) {
262+
return;
263+
}
247264
this.customDateSeparatorTemplate = template;
248-
this.cdRef.detectChanges();
265+
if (this.isViewInited) {
266+
this.cdRef.detectChanges();
267+
}
249268
}
250269
)
251270
);
252271
this.subscriptions.push(
253272
this.customTemplatesService.newMessagesIndicatorTemplate$.subscribe(
254273
(template) => {
274+
if (this.customnewMessagesIndicatorTemplate === template) {
275+
return;
276+
}
255277
this.customnewMessagesIndicatorTemplate = template;
256-
this.cdRef.detectChanges();
278+
if (this.isViewInited) {
279+
this.cdRef.detectChanges();
280+
}
257281
}
258282
)
259283
);
260284
this.subscriptions.push(
261285
this.customTemplatesService.typingIndicatorTemplate$.subscribe(
262286
(template) => {
287+
if (this.typingIndicatorTemplate === template) {
288+
return;
289+
}
263290
this.typingIndicatorTemplate = template;
264-
this.cdRef.detectChanges();
291+
if (this.isViewInited) {
292+
this.cdRef.detectChanges();
293+
}
265294
}
266295
)
267296
);
@@ -283,6 +312,7 @@ export class MessageListComponent
283312
}
284313

285314
ngAfterViewInit(): void {
315+
this.isViewInited = true;
286316
this.ngZone.runOutsideAngular(() => {
287317
this.scrollContainer.nativeElement.addEventListener('scroll', () =>
288318
this.scrolled()

projects/stream-chat-angular/src/lib/message/message.component.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
class="str-chat__message-simple__actions str-chat__message-options"
3737
data-testid="message-options"
3838
[class.str-chat__message-edit-in-progress]="isEditing"
39-
*ngIf="areOptionsVisible && optionsRenderTimeoutEnded"
39+
*ngIf="areOptionsVisible"
4040
>
4141
<div
4242
data-testid="message-actions-container"
@@ -67,6 +67,7 @@
6767
let-customActions="customActions"
6868
>
6969
<stream-message-actions-box
70+
*ngIf="isOpen"
7071
[isOpen]="isOpen"
7172
[isMine]="isMine"
7273
[enabledActions]="enabledActions"

projects/stream-chat-angular/src/lib/message/message.component.spec.ts

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@ describe('MessageComponent', () => {
4242
let queryMessageOptions: () => HTMLElement | null;
4343
let queryActionIcon: () => HTMLElement | null;
4444
let queryText: () => HTMLElement | null;
45-
let messageActionsBoxComponent: MessageActionsBoxComponent;
45+
let queryMessageActionsBoxComponent: () =>
46+
| MessageActionsBoxComponent
47+
| undefined;
4648
let queryAttachmentComponent: () => AttachmentListComponent;
4749
let queryReactionIcon: () => HTMLElement | null;
4850
let queryMessageReactions: () => MessageReactionsComponent;
@@ -146,13 +148,13 @@ describe('MessageComponent', () => {
146148
queryReplyInThreadIcon = () =>
147149
nativeElement.querySelector('[data-testid="reply-in-thread"]');
148150
message = mockMessage();
149-
component.optionsRenderTimeoutEnded = true;
150151
component.message = message;
151152
component.ngOnChanges({ message: {} as SimpleChange });
153+
component.ngAfterViewInit();
152154
fixture.detectChanges();
153-
messageActionsBoxComponent = fixture.debugElement.query(
154-
By.directive(MessageActionsBoxComponent)
155-
)?.componentInstance as MessageActionsBoxComponent;
155+
queryMessageActionsBoxComponent = () =>
156+
fixture.debugElement.query(By.directive(MessageActionsBoxComponent))
157+
?.componentInstance as MessageActionsBoxComponent;
156158
queryAttachmentComponent = () =>
157159
fixture.debugElement.query(By.directive(AttachmentListComponent))
158160
?.componentInstance as AttachmentListComponent;
@@ -539,12 +541,12 @@ describe('MessageComponent', () => {
539541
component.ngOnChanges({ enabledMessageActions: {} as SimpleChange });
540542
fixture.detectChanges();
541543

542-
expect(messageActionsBoxComponent.isOpen).toBeFalse();
544+
expect(queryMessageActionsBoxComponent()).toBeUndefined();
543545

544546
queryActionIcon()?.click();
545547
fixture.detectChanges();
546548

547-
expect(messageActionsBoxComponent.isOpen).toBeTrue();
549+
expect(queryMessageActionsBoxComponent()?.isOpen).toBeTrue();
548550
});
549551

550552
it('should close message actions box on mouseleave event', () => {
@@ -560,12 +562,20 @@ describe('MessageComponent', () => {
560562
});
561563

562564
it('should provide #enabledActions to message actions box', () => {
565+
component.isActionBoxOpen = true;
566+
fixture.detectChanges();
567+
const messageActionsBoxComponent = queryMessageActionsBoxComponent()!;
568+
563569
expect(messageActionsBoxComponent.enabledActions).toBe(
564570
component.enabledMessageActions
565571
);
566572
});
567573

568574
it('should provide #isMine to message actions box', () => {
575+
component.isActionBoxOpen = true;
576+
fixture.detectChanges();
577+
const messageActionsBoxComponent = queryMessageActionsBoxComponent()!;
578+
569579
expect(messageActionsBoxComponent.isMine).toBeTrue();
570580

571581
component.message = { ...message, ...{ user: { id: 'notcurrentuser' } } };
@@ -576,7 +586,9 @@ describe('MessageComponent', () => {
576586
});
577587

578588
it('should provide #message to message actions box', () => {
589+
component.isActionBoxOpen = true;
579590
fixture.detectChanges();
591+
const messageActionsBoxComponent = queryMessageActionsBoxComponent()!;
580592

581593
expect(messageActionsBoxComponent.message).toBe(message);
582594
});
@@ -591,7 +603,9 @@ describe('MessageComponent', () => {
591603
},
592604
];
593605
component.customActions = customActions;
606+
component.isActionBoxOpen = true;
594607
fixture.detectChanges();
608+
const messageActionsBoxComponent = queryMessageActionsBoxComponent()!;
595609

596610
expect(messageActionsBoxComponent.customActions).toBe(customActions);
597611
});

projects/stream-chat-angular/src/lib/message/message.component.ts

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -114,10 +114,9 @@ export class MessageComponent
114114
};
115115
canDisplayReadStatus = false;
116116
private quotedMessageAttachments: Attachment[] | undefined;
117-
user: UserResponse<DefaultStreamChatGenerics> | undefined;
118-
optionsRenderTimeoutEnded = false;
119117
private subscriptions: Subscription[] = [];
120118
private isViewInited = false;
119+
private userId?: string;
121120
@ViewChild('container') private container:
122121
| ElementRef<HTMLElement>
123122
| undefined;
@@ -143,11 +142,13 @@ export class MessageComponent
143142
ngOnInit(): void {
144143
this.subscriptions.push(
145144
this.chatClientService.user$.subscribe((u) => {
146-
if (u !== this.user) {
147-
this.user = u;
145+
if (u?.id !== this.userId) {
146+
this.userId = u?.id;
148147
this.setIsSentByCurrentUser();
149148
this.setLastReadUser();
150-
this.cdRef.detectChanges();
149+
if (this.isViewInited) {
150+
this.cdRef.detectChanges();
151+
}
151152
}
152153
})
153154
);
@@ -260,10 +261,6 @@ export class MessageComponent
260261
this.mouseLeft()
261262
);
262263
});
263-
setTimeout(() => {
264-
this.optionsRenderTimeoutEnded = true;
265-
this.cdRef.detectChanges();
266-
}, 0);
267264
}
268265

269266
ngOnDestroy(): void {
@@ -489,12 +486,12 @@ export class MessageComponent
489486
}
490487

491488
private setIsSentByCurrentUser() {
492-
this.isSentByCurrentUser = this.message?.user?.id === this.user?.id;
489+
this.isSentByCurrentUser = this.message?.user?.id === this.userId;
493490
}
494491

495492
private setLastReadUser() {
496493
this.lastReadUser = this.message?.readBy?.filter(
497-
(u) => u.id !== this.user?.id
494+
(u) => u.id !== this.userId
498495
)[0];
499496
}
500497
}

0 commit comments

Comments
 (0)