Skip to content

Commit d0bc8a5

Browse files
authored
Merge pull request #363 from GetStream/duplicate-notification-event-bug
fix: Duplicated channels after two notification events and not up to …
2 parents bbd0464 + fae0b0e commit d0bc8a5

File tree

2 files changed

+45
-14
lines changed

2 files changed

+45
-14
lines changed

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

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -766,6 +766,33 @@ describe('ChannelService', () => {
766766
expect(channel.on).toHaveBeenCalledWith(jasmine.any(Function));
767767
}));
768768

769+
it(`shouldn't add channels twice if two notification events were received for the same channel`, fakeAsync(async () => {
770+
await init();
771+
const channel = generateMockChannels()[0];
772+
channel.cid = 'channel';
773+
channel.id = 'channel';
774+
channel.type = 'messaging';
775+
mockChatClient.channel.and.returnValue(channel);
776+
spyOn(channel, 'watch').and.callThrough();
777+
spyOn(channel, 'on').and.callThrough();
778+
const spy = jasmine.createSpy();
779+
service.channels$.subscribe(spy);
780+
events$.next({
781+
eventType: 'notification.added_to_channel',
782+
event: { channel: channel } as any as Event<DefaultStreamChatGenerics>,
783+
});
784+
events$.next({
785+
eventType: 'notification.message_new',
786+
event: { channel: channel } as any as Event<DefaultStreamChatGenerics>,
787+
});
788+
tick();
789+
790+
const channels = spy.calls.mostRecent().args[0] as Channel[];
791+
792+
expect(channels.filter((c) => c.cid === channel.cid).length).toBe(1);
793+
expect(channel.on).toHaveBeenCalledOnceWith(jasmine.any(Function));
794+
}));
795+
769796
it('should remove channel form the list if user is removed from channel', async () => {
770797
await init();
771798
let channel!: Channel<DefaultStreamChatGenerics>;

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

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -273,11 +273,8 @@ export class ChannelService<
273273
const deletedChannels = currentChannels.filter(
274274
(c) => !channels?.find((channel) => channel.cid === c.cid)
275275
);
276-
this.addChannelsFromNotification(newChannels as ChannelResponse<T>[]);
276+
void this.addChannelsFromNotification(newChannels as ChannelResponse<T>[]);
277277
this.removeChannelsFromChannelList(deletedChannels.map((c) => c.cid));
278-
if (!newChannels.length && !deletedChannels.length) {
279-
this.channelsSubject.next(channels as Channel<T>[]);
280-
}
281278
};
282279

283280
private messageListSetter = (messages: StreamMessage<T>[]) => {
@@ -866,31 +863,38 @@ export class ChannelService<
866863

867864
private handleNewMessageNotification(clientEvent: ClientEvent<T>) {
868865
if (clientEvent.event.channel) {
869-
this.addChannelsFromNotification([clientEvent.event.channel]);
866+
void this.addChannelsFromNotification([clientEvent.event.channel]);
870867
}
871868
}
872869

873870
private handleAddedToChannelNotification(clientEvent: ClientEvent<T>) {
874871
if (clientEvent.event.channel) {
875-
this.addChannelsFromNotification([clientEvent.event.channel]);
872+
void this.addChannelsFromNotification([clientEvent.event.channel]);
876873
}
877874
}
878875

879-
private addChannelsFromNotification(channelResponses: ChannelResponse<T>[]) {
880-
const newChannels: Channel<T>[] = [];
876+
private async addChannelsFromNotification(
877+
channelResponses: ChannelResponse<T>[]
878+
) {
879+
let newChannels: Channel<T>[] = [];
880+
const watchRequests: Promise<any>[] = [];
881881
channelResponses.forEach((channelResponse) => {
882882
const channel = this.chatClientService.chatClient.channel(
883883
channelResponse.type,
884884
channelResponse.id
885885
);
886-
void channel.watch();
887-
this.watchForChannelEvents(channel);
886+
watchRequests.push(channel.watch());
888887
newChannels.push(channel);
889888
});
890-
this.channelsSubject.next([
891-
...newChannels,
892-
...(this.channelsSubject.getValue() || []),
893-
]);
889+
await Promise.all(watchRequests);
890+
const currentChannels = this.channelsSubject.getValue() || [];
891+
newChannels = newChannels.filter(
892+
(newChannel) => !currentChannels.find((c) => c.cid === newChannel.cid)
893+
);
894+
if (newChannels.length > 0) {
895+
newChannels.forEach((c) => this.watchForChannelEvents(c));
896+
this.channelsSubject.next([...newChannels, ...currentChannels]);
897+
}
894898
}
895899

896900
private removeChannelsFromChannelList(cids: string[]) {

0 commit comments

Comments
 (0)