diff --git a/projects/stream-chat-angular/src/lib/channel.service.spec.ts b/projects/stream-chat-angular/src/lib/channel.service.spec.ts index b5f48516..2931b3cd 100644 --- a/projects/stream-chat-angular/src/lib/channel.service.spec.ts +++ b/projects/stream-chat-angular/src/lib/channel.service.spec.ts @@ -1,10 +1,11 @@ import { fakeAsync, TestBed, tick } from '@angular/core/testing'; import { Subject } from 'rxjs'; -import { first } from 'rxjs/operators'; +import { first, take } from 'rxjs/operators'; import { Channel, ChannelMemberResponse, ChannelOptions, + ChannelResponse, ChannelSort, Event, SendMessageAPIResponse, @@ -184,10 +185,24 @@ describe('ChannelService', () => { expect(activeChannelSpy).toHaveBeenCalledWith(undefined); expect(messageToQuoteSpy).toHaveBeenCalledWith(undefined); expect(latestMessagesSpy).toHaveBeenCalledWith({}); + + channelsSpy.calls.reset(); + events$.next({ + eventType: 'message.new', + event: { + channel: { + id: 'channel', + } as ChannelResponse, + } as Event, + }); + + expect(channelsSpy).not.toHaveBeenCalled(); }); it('should deselect active channel', async () => { await init(); + let activeChannel!: Channel; + service.activeChannel$.pipe(take(1)).subscribe((c) => (activeChannel = c!)); const messagesSpy = jasmine.createSpy(); service.activeChannelMessages$.subscribe(messagesSpy); const activeChannelSpy = jasmine.createSpy(); @@ -206,6 +221,11 @@ describe('ChannelService', () => { expect(activeChannelSpy).toHaveBeenCalledWith(undefined); expect(messageToQuoteSpy).toHaveBeenCalledWith(undefined); expect(latestMessagesSpy).toHaveBeenCalledWith({}); + + messagesSpy.calls.reset(); + (activeChannel as MockChannel).handleEvent('message.new', mockMessage()); + + expect(messagesSpy).not.toHaveBeenCalled(); }); it('should tell if user #hasMoreChannels$', async () => { @@ -1508,4 +1528,20 @@ describe('ChannelService', () => { expect(customFileDeleteRequest).toHaveBeenCalledWith(url, channel); expect(channel.deleteFile).not.toHaveBeenCalled(); }); + + it('should reset state after connection recovered', async () => { + await init(); + spyOn(service, 'init'); + spyOn(service, 'reset'); + events$.next({ eventType: 'connection.recovered' } as ClientEvent); + + expect(service.init).toHaveBeenCalledWith( + service['filters']!, + service['sort'], + service['options'], + service['shouldSetActiveChannel'] + ); + + expect(service.reset).toHaveBeenCalledWith(); + }); }); diff --git a/projects/stream-chat-angular/src/lib/channel.service.ts b/projects/stream-chat-angular/src/lib/channel.service.ts index 2992b58d..7d1558c9 100644 --- a/projects/stream-chat-angular/src/lib/channel.service.ts +++ b/projects/stream-chat-angular/src/lib/channel.service.ts @@ -4,6 +4,7 @@ import { combineLatest, Observable, ReplaySubject, + Subscription, } from 'rxjs'; import { filter, first, map, shareReplay } from 'rxjs/operators'; import { @@ -258,6 +259,8 @@ export class ChannelService< [] ); private _shouldMarkActiveChannelAsRead = true; + private shouldSetActiveChannel: boolean | undefined; + private clientEventsSubscription: Subscription | undefined; private channelListSetter = ( channels: (Channel | ChannelResponse)[] @@ -392,6 +395,7 @@ export class ChannelService< if (!activeChannel) { return; } + this.stopWatchForActiveChannelEvents(activeChannel); this.activeChannelMessagesSubject.next([]); this.activeChannelSubject.next(undefined); this.activeParentMessageIdSubject.next(undefined); @@ -486,8 +490,9 @@ export class ChannelService< message_limit: this.messagePageSize, }; this.sort = sort || { last_message_at: -1, updated_at: -1 }; - const result = await this.queryChannels(shouldSetActiveChannel); - this.chatClientService.events$.subscribe( + this.shouldSetActiveChannel = shouldSetActiveChannel; + const result = await this.queryChannels(this.shouldSetActiveChannel); + this.clientEventsSubscription = this.chatClientService.events$.subscribe( (notification) => void this.handleNotification(notification) ); return result; @@ -499,6 +504,7 @@ export class ChannelService< reset() { this.deselectActiveChannel(); this.channelsSubject.next(undefined); + this.clientEventsSubscription?.unsubscribe(); } /** @@ -790,6 +796,18 @@ export class ChannelService< private handleNotification(clientEvent: ClientEvent) { switch (clientEvent.eventType) { + case 'connection.recovered': { + this.ngZone.run(() => { + this.reset(); + void this.init( + this.filters!, + this.sort, + this.options, + this.shouldSetActiveChannel + ); + }); + break; + } case 'notification.message_new': { this.ngZone.run(() => { if (this.customNewMessageNotificationHandler) {