Skip to content

Commit 93a9102

Browse files
committed
Merge branch 'master' into perf-message-list
2 parents 8d0c9bc + 12931ac commit 93a9102

21 files changed

+466
-169
lines changed

docusaurus/docs/Angular/components/MessageReactionsComponent.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ The `MessageReactions` component displays the reactions of a message, the curren
88

99
<img src={MessageReactionsScreenshot} width="500" />
1010

11-
**Example 2** - displaying the reacting users:
11+
**Example 2** - displaying the reacting users - only visible if a message has at maximum 1200 reactions:
1212

1313
<img src={MessageReactionsDetailsScreenshot} width="500" />
1414

projects/customizations-example/src/app/app.component.html

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,7 @@
55
</stream-channel-list>
66
<stream-channel>
77
<stream-channel-header></stream-channel-header>
8-
<stream-message-list
9-
[customMessageActions]="[
10-
{
11-
actionName: 'forward',
12-
actionLabelOrTranslationKey: 'Forward',
13-
isVisible: isVisible,
14-
actionHandler: actionHandler
15-
}
16-
]"
17-
></stream-message-list>
8+
<stream-message-list></stream-message-list>
189
<stream-notification-list></stream-notification-list>
1910
<stream-message-input></stream-message-input>
2011
<stream-thread name="thread">
@@ -175,20 +166,16 @@
175166

176167
<ng-template
177168
#messageActionsBoxTemplate
178-
let-isOpen="isOpen"
179169
let-isMine="isMine"
180170
let-enabledActions="enabledActions"
181171
let-messageInput="message"
182-
let-displayedActionsCountChangeHandler="displayedActionsCountChangeHandler"
183-
let-isEditingChangeHandler="isEditingChangeHandler"
172+
let-customActions="customActions"
184173
>
185174
<stream-message-actions-box
186-
[isOpen]="isOpen"
187175
[isMine]="isMine"
188176
[enabledActions]="enabledActions"
189177
[message]="messageInput"
190-
(displayedActionsCount)="displayedActionsCountChangeHandler($event)"
191-
(isEditing)="isEditingChangeHandler($event)"
178+
[customActions]="customActions"
192179
></stream-message-actions-box>
193180
</ng-template>
194181

projects/customizations-example/src/app/app.component.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import {
3636
ThreadHeaderContext,
3737
CustomAttachmentUploadContext,
3838
DateSeparatorContext,
39+
MessageActionsService,
3940
} from 'stream-chat-angular';
4041
import { environment } from '../environments/environment';
4142

@@ -100,8 +101,17 @@ export class AppComponent implements AfterViewInit {
100101
private chatService: ChatClientService,
101102
public channelService: ChannelService,
102103
private streamI18nService: StreamI18nService,
103-
private customTemplatesService: CustomTemplatesService
104+
private customTemplatesService: CustomTemplatesService,
105+
private messageActionsService: MessageActionsService
104106
) {
107+
this.messageActionsService.customActions$.next([
108+
{
109+
actionName: 'forward',
110+
actionLabelOrTranslationKey: 'Forward',
111+
isVisible: this.isVisible,
112+
actionHandler: this.actionHandler,
113+
},
114+
]);
105115
void this.chatService.init(
106116
environment.apiKey,
107117
environment.userId,
@@ -210,5 +220,8 @@ export class AppComponent implements AfterViewInit {
210220
return true;
211221
}
212222

213-
actionHandler() {}
223+
actionHandler() {
224+
/* eslint-disable-next-line no-console */
225+
console.log('forwarded');
226+
}
214227
}

projects/stream-chat-angular/src/lib/channel.service.spec.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2327,6 +2327,22 @@ describe('ChannelService', () => {
23272327
]);
23282328
});
23292329

2330+
it('should load message reactions - but no more than 1200', async () => {
2331+
await init();
2332+
const activeChannel = service.activeChannel!;
2333+
const message = service.activeChannelMessages[0]!;
2334+
const mockReactionsPage = new Array(300)
2335+
.fill(null)
2336+
.map(() => ({ type: 'wow', user: { id: 'jack' } })) as ReactionResponse[];
2337+
spyOn(activeChannel, 'getReactions').and.resolveTo({
2338+
reactions: mockReactionsPage,
2339+
duration: '',
2340+
});
2341+
const reactions = await service.getMessageReactions(message.id);
2342+
2343+
expect(reactions.length).toEqual(1200);
2344+
});
2345+
23302346
it('should load message reactions - error', async () => {
23312347
await init();
23322348
const activeChannel = service.activeChannel!;

projects/stream-chat-angular/src/lib/channel.service.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,10 @@ export class ChannelService<
304304
* You can return either an offset, or a filter using the [`$lte`/`$gte` operator](https://getstream.io/chat/docs/javascript/query_syntax_operators/). If you return a filter, it will be merged with the filter provided for the `init` method.
305305
*/
306306
customPaginator?: (channelQueryResult: Channel<T>[]) => NextPageConfiguration;
307+
/**
308+
* internal
309+
*/
310+
static readonly MAX_MESSAGE_REACTIONS_TO_FETCH = 1200;
307311
private channelsSubject = new BehaviorSubject<Channel<T>[] | undefined>(
308312
undefined
309313
);
@@ -1440,17 +1444,18 @@ export class ChannelService<
14401444
}
14411445

14421446
/**
1443-
* Get all reactions of a message in the current active channel
1447+
* Get the last 1200 reactions of a message in the current active channel. If you need to fetch more reactions please use the [following endpoint](https://getstream.io/chat/docs/javascript/send_reaction/?language=javascript#paginating-reactions).
14441448
* @param messageId
14451449
* @returns all reactions of a message
14461450
*/
14471451
async getMessageReactions(messageId: string) {
14481452
const reactions: ReactionResponse<T>[] = [];
14491453
const limit = 300;
1450-
const offset = 0;
1454+
let offset = 0;
1455+
const reactionsLimit = ChannelService.MAX_MESSAGE_REACTIONS_TO_FETCH;
14511456
let lastPageSize = limit;
14521457

1453-
while (lastPageSize === limit) {
1458+
while (lastPageSize === limit && reactions.length < reactionsLimit) {
14541459
try {
14551460
const response = await this.activeChannel?.getReactions(messageId, {
14561461
offset,
@@ -1460,6 +1465,7 @@ export class ChannelService<
14601465
if (lastPageSize > 0) {
14611466
reactions.push(...response!.reactions);
14621467
}
1468+
offset += lastPageSize;
14631469
} catch (e) {
14641470
this.notificationService.addTemporaryNotification(
14651471
'Error loading reactions'

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

Lines changed: 18 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import { NotificationService } from '../notification.service';
2626
import { DefaultStreamChatGenerics, StreamMessage } from '../types';
2727

2828
import { MessageActionsBoxComponent } from './message-actions-box.component';
29+
import { MessageActionsService } from '../message-actions.service';
2930

3031
describe('MessageActionsBoxComponent', () => {
3132
let component: MessageActionsBoxComponent;
@@ -86,6 +87,7 @@ describe('MessageActionsBoxComponent', () => {
8687
beforeEach(() => {
8788
fixture = TestBed.createComponent(MessageActionsBoxComponent);
8889
component = fixture.componentInstance;
90+
component.ngOnInit();
8991
message = mockMessage();
9092
component.message = message;
9193
component.isOpen = true;
@@ -272,42 +274,6 @@ describe('MessageActionsBoxComponent', () => {
272274
);
273275
});
274276

275-
it('should emit the number of displayed actions', () => {
276-
component.enabledActions = [
277-
'pin-message',
278-
'update-own-message',
279-
'delete-own-message',
280-
'flag-message',
281-
];
282-
component.isMine = true;
283-
const spy = jasmine.createSpy();
284-
component.displayedActionsCount.subscribe(spy);
285-
component.ngOnChanges({
286-
isMine: {} as any as SimpleChange,
287-
enabledActions: {} as any as SimpleChange,
288-
});
289-
fixture.detectChanges();
290-
291-
expect(spy).toHaveBeenCalledWith(3);
292-
293-
spy.calls.reset();
294-
component.enabledActions = [
295-
'pin-message',
296-
'update-any-message',
297-
'delete',
298-
'flag-message',
299-
'quote-message',
300-
];
301-
component.isMine = false;
302-
component.ngOnChanges({
303-
isMine: {} as any as SimpleChange,
304-
enabledActions: {} as any as SimpleChange,
305-
});
306-
fixture.detectChanges();
307-
308-
expect(spy).toHaveBeenCalledWith(4);
309-
});
310-
311277
describe('should display edit action', () => {
312278
it('if #enabledActions contains "edit" and #isMine', () => {
313279
component.enabledActions = ['update-own-message'];
@@ -376,7 +342,9 @@ describe('MessageActionsBoxComponent', () => {
376342

377343
it('should emit #isEditing if user starts to edit', () => {
378344
const spy = jasmine.createSpy();
379-
component.isEditing.subscribe(spy);
345+
const actionsService = TestBed.inject(MessageActionsService);
346+
actionsService.messageToEdit$.subscribe(spy);
347+
spy.calls.reset();
380348
component.enabledActions = [
381349
'pin-message',
382350
'update-any-message',
@@ -390,7 +358,7 @@ describe('MessageActionsBoxComponent', () => {
390358
queryEditAction()?.click();
391359
fixture.detectChanges();
392360

393-
expect(spy).toHaveBeenCalledWith(true);
361+
expect(spy).toHaveBeenCalledWith(component.message);
394362
});
395363

396364
it('should open modal if user starts to edit', () => {
@@ -440,14 +408,16 @@ describe('MessageActionsBoxComponent', () => {
440408
});
441409
fixture.detectChanges();
442410
const spy = jasmine.createSpy();
443-
component.isEditing.subscribe(spy);
411+
const actionsService = TestBed.inject(MessageActionsService);
412+
actionsService.messageToEdit$.subscribe(spy);
444413
queryEditAction()?.click();
445414
fixture.detectChanges();
415+
spy.calls.reset();
446416
queryModalCancelButton()?.click();
447417
fixture.detectChanges();
448418

449419
expect(queryEditModal()).toBeUndefined();
450-
expect(spy).toHaveBeenCalledWith(false);
420+
expect(spy).toHaveBeenCalledWith(undefined);
451421
});
452422

453423
it('should update #isEditModalOpen if modal is closed', () => {
@@ -460,14 +430,16 @@ describe('MessageActionsBoxComponent', () => {
460430
});
461431
fixture.detectChanges();
462432
const spy = jasmine.createSpy();
463-
component.isEditing.subscribe(spy);
433+
const actionsService = TestBed.inject(MessageActionsService);
434+
actionsService.messageToEdit$.subscribe(spy);
464435
queryEditAction()?.click();
465436
fixture.detectChanges();
466437
queryEditModal()?.close();
438+
spy.calls.reset();
467439
fixture.detectChanges();
468440

469441
expect(component.isEditModalOpen).toBeFalse();
470-
expect(spy).toHaveBeenCalledWith(false);
442+
expect(spy).toHaveBeenCalledWith(undefined);
471443
});
472444

473445
it('should close modal if message was updated successfully', () => {
@@ -481,14 +453,16 @@ describe('MessageActionsBoxComponent', () => {
481453
queryEditAction()?.click();
482454
fixture.detectChanges();
483455
const spy = jasmine.createSpy();
484-
component.isEditing.subscribe(spy);
456+
const actionsService = TestBed.inject(MessageActionsService);
457+
actionsService.messageToEdit$.subscribe(spy);
458+
spy.calls.reset();
485459
const messageInputComponent = queryMessageInputComponent();
486460

487461
messageInputComponent.messageUpdate.emit();
488462
fixture.detectChanges();
489463

490464
expect(queryEditModal()).toBeUndefined();
491-
expect(spy).toHaveBeenCalledWith(false);
465+
expect(spy).toHaveBeenCalledWith(undefined);
492466
});
493467

494468
it('should delete message', () => {

0 commit comments

Comments
 (0)