@@ -29,6 +29,7 @@ import { NotificationService } from './notification.service';
2929import { getReadBy } from './read-by' ;
3030import {
3131 AttachmentUpload ,
32+ ChannelQueryState ,
3233 DefaultStreamChatGenerics ,
3334 MessageReactionType ,
3435 StreamMessage ,
@@ -73,6 +74,10 @@ export class ChannelService<
7374 * Our platform documentation covers the topic of [channel events](https://getstream.io/chat/docs/javascript/event_object/?language=javascript#events) in depth.
7475 */
7576 channels$ : Observable < Channel < T > [ ] | undefined > ;
77+ /**
78+ * The result of the latest channel query request.
79+ */
80+ channelQueryState$ : Observable < ChannelQueryState | undefined > ;
7681 /**
7782 * Emits the currently active channel.
7883 *
@@ -264,7 +269,9 @@ export class ChannelService<
264269 } > ( { } ) ;
265270 private filters : ChannelFilters < T > | undefined ;
266271 private sort : ChannelSort < T > | undefined ;
267- private options : ChannelOptions | undefined ;
272+ private options :
273+ | ( ChannelOptions & { keepAliveChannels$OnError ?: boolean } )
274+ | undefined ;
268275 private readonly messagePageSize = 25 ;
269276 private messageToQuoteSubject = new BehaviorSubject <
270277 StreamMessage < T > | undefined
@@ -279,6 +286,9 @@ export class ChannelService<
279286 private shouldSetActiveChannel : boolean | undefined ;
280287 private clientEventsSubscription : Subscription | undefined ;
281288 private isStateRecoveryInProgress = false ;
289+ private channelQueryStateSubject = new BehaviorSubject <
290+ ChannelQueryState | undefined
291+ > ( undefined ) ;
282292
283293 private channelListSetter = (
284294 channels : ( Channel < T > | ChannelResponse < T > ) [ ]
@@ -305,6 +315,7 @@ export class ChannelService<
305315 private parentMessageSetter = ( message : StreamMessage < T > | undefined ) => {
306316 this . activeParentMessageIdSubject . next ( message ?. id ) ;
307317 } ;
318+ private dismissErrorNotification ?: Function ;
308319
309320 constructor (
310321 private chatClientService : ChatClientService < T > ,
@@ -366,6 +377,7 @@ export class ChannelService<
366377 this . latestMessageDateByUserByChannelsSubject . asObservable ( ) ;
367378 this . activeChannelPinnedMessages$ =
368379 this . activeChannelPinnedMessagesSubject . asObservable ( ) ;
380+ this . channelQueryState$ = this . channelQueryStateSubject . asObservable ( ) ;
369381 }
370382
371383 /**
@@ -554,31 +566,33 @@ export class ChannelService<
554566 async init (
555567 filters : ChannelFilters < T > ,
556568 sort ?: ChannelSort < T > ,
557- options ?: ChannelOptions ,
569+ options ?: ChannelOptions & { keepAliveChannels$OnError ?: boolean } ,
558570 shouldSetActiveChannel : boolean = true
559571 ) {
560572 this . filters = filters ;
561- this . options = options || {
573+ this . options = {
562574 offset : 0 ,
563575 limit : 25 ,
564576 state : true ,
565577 presence : true ,
566578 watch : true ,
567579 message_limit : this . messagePageSize ,
580+ ...options ,
568581 } ;
569582 this . sort = sort || { last_message_at : - 1 , updated_at : - 1 } ;
570583 this . shouldSetActiveChannel = shouldSetActiveChannel ;
584+ this . clientEventsSubscription = this . chatClientService . events$ . subscribe (
585+ ( notification ) => void this . handleNotification ( notification )
586+ ) ;
571587 try {
572588 const result = await this . queryChannels ( this . shouldSetActiveChannel ) ;
573- this . clientEventsSubscription = this . chatClientService . events$ . subscribe (
574- ( notification ) => void this . handleNotification ( notification )
575- ) ;
576589 return result ;
577590 } catch ( error ) {
578- this . notificationService . addPermanentNotification (
579- 'streamChat.Error loading channels' ,
580- 'error'
581- ) ;
591+ this . dismissErrorNotification =
592+ this . notificationService . addPermanentNotification (
593+ 'streamChat.Error loading channels' ,
594+ 'error'
595+ ) ;
582596 throw error ;
583597 }
584598 }
@@ -589,7 +603,10 @@ export class ChannelService<
589603 reset ( ) {
590604 this . deselectActiveChannel ( ) ;
591605 this . channelsSubject . next ( undefined ) ;
606+ this . channelQueryStateSubject . next ( undefined ) ;
592607 this . clientEventsSubscription ?. unsubscribe ( ) ;
608+ this . dismissErrorNotification ?.( ) ;
609+ this . dismissErrorNotification = undefined ;
593610 }
594611
595612 /**
@@ -973,7 +990,11 @@ export class ChannelService<
973990 if ( this . options ) {
974991 this . options . offset = 0 ;
975992 }
976- await this . queryChannels ( false , true ) ;
993+ // If channel list is not inited, we set the active channel
994+ const shoulSetActiveChannel =
995+ this . shouldSetActiveChannel &&
996+ ! this . activeChannelSubject . getValue ( ) ;
997+ await this . queryChannels ( shoulSetActiveChannel || false , true ) ;
977998 // Thread messages are not refetched so active thread gets deselected to avoid displaying stale messages
978999 void this . setAsActiveParentMessage ( undefined ) ;
9791000 this . isStateRecoveryInProgress = false ;
@@ -1264,6 +1285,7 @@ export class ChannelService<
12641285 recoverState = false
12651286 ) {
12661287 try {
1288+ this . channelQueryStateSubject . next ( { state : 'in-progress' } ) ;
12671289 const channels = await this . chatClientService . chatClient . queryChannels (
12681290 this . filters ! ,
12691291 this . sort || { } ,
@@ -1274,13 +1296,14 @@ export class ChannelService<
12741296 ? [ ]
12751297 : this . channelsSubject . getValue ( ) || [ ] ;
12761298 this . channelsSubject . next ( [ ...prevChannels , ...channels ] ) ;
1277- const currentActiveChannel = this . activeChannelSubject . getValue ( ) ;
1299+ let currentActiveChannel = this . activeChannelSubject . getValue ( ) ;
12781300 if (
12791301 channels . length > 0 &&
12801302 ! currentActiveChannel &&
12811303 shouldSetActiveChannel
12821304 ) {
12831305 this . setAsActiveChannel ( channels [ 0 ] ) ;
1306+ currentActiveChannel = this . activeChannelSubject . getValue ( ) ;
12841307 }
12851308 if (
12861309 recoverState &&
@@ -1289,9 +1312,23 @@ export class ChannelService<
12891312 this . deselectActiveChannel ( ) ;
12901313 }
12911314 this . hasMoreChannelsSubject . next ( channels . length >= this . options ! . limit ! ) ;
1315+ this . channelQueryStateSubject . next ( { state : 'success' } ) ;
1316+ if (
1317+ this . options ?. keepAliveChannels$OnError &&
1318+ this . dismissErrorNotification
1319+ ) {
1320+ this . dismissErrorNotification ( ) ;
1321+ }
12921322 return channels ;
12931323 } catch ( error ) {
1294- this . channelsSubject . error ( error ) ;
1324+ if ( ! this . options ?. keepAliveChannels$OnError ) {
1325+ this . channelsSubject . error ( error ) ;
1326+ }
1327+ this . channelQueryStateSubject . next ( {
1328+ state : 'error' ,
1329+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
1330+ error,
1331+ } ) ;
12951332 throw error ;
12961333 }
12971334 }
0 commit comments