@@ -4,10 +4,13 @@ import PropTypes from 'prop-types';
44import { ChannelPreview } from './ChannelPreview' ;
55import { ChannelPreviewMessenger } from './ChannelPreviewMessenger' ;
66import { withChatContext } from '../context' ;
7+ import { ChannelListHeaderNetworkDownIndicator } from './ChannelListHeaderNetworkDownIndicator' ;
8+ import { ChannelListHeaderErrorIndicator } from './ChannelListHeaderErrorIndicator' ;
79
810import { LoadingIndicator } from './LoadingIndicator' ;
911import { LoadingErrorIndicator } from './LoadingErrorIndicator' ;
1012import { EmptyStateIndicator } from './EmptyStateIndicator' ;
13+ import { ChannelListFooterLoadingIndicator } from './ChannelListFooterLoadingIndicator' ;
1114
1215/**
1316 * ChannelListMessenger - UI component for list of channels, allowing you to select the channel you want to open
@@ -44,8 +47,39 @@ const ChannelListMessenger = withChatContext(
4447 PropTypes . node ,
4548 PropTypes . elementType ,
4649 ] ) ,
50+ /**
51+ * The indicator to display network-down error at top of list, if there is connectivity issue
52+ * Default: [ChannelListHeaderNetworkDownIndicator](https://getstream.github.io/stream-chat-react-native/#ChannelListHeaderNetworkDownIndicator)
53+ */
54+ HeaderNetworkDownIndicator : PropTypes . oneOfType ( [
55+ PropTypes . node ,
56+ PropTypes . elementType ,
57+ ] ) ,
58+ /**
59+ * The indicator to display error at top of list, if there was an error loading some page/channels after the first page.
60+ * Default: [ChannelListHeaderErrorIndicator](https://getstream.github.io/stream-chat-react-native/#ChannelListHeaderErrorIndicator)
61+ */
62+ HeaderErrorIndicator : PropTypes . oneOfType ( [
63+ PropTypes . node ,
64+ PropTypes . elementType ,
65+ ] ) ,
66+ /**
67+ * Loading indicator to display at bottom of the list, while loading further pages.
68+ * Default: [ChannelListFooterLoadingIndicator](https://getstream.github.io/stream-chat-react-native/#ChannelListFooterLoadingIndicator)
69+ */
70+ FooterLoadingIndicator : PropTypes . oneOfType ( [
71+ PropTypes . node ,
72+ PropTypes . elementType ,
73+ ] ) ,
74+ /** Remove all the existing channels from UI and load fresh channels. */
75+ reloadList : PropTypes . func ,
4776 /** Loads next page of channels in channels object, which is present here as prop */
4877 loadNextPage : PropTypes . func ,
78+ /**
79+ * Refresh the channel list. Its similar to `reloadList`, but it doesn't wipe out existing channels
80+ * from UI before loading new set of channels.
81+ */
82+ refreshList : PropTypes . func ,
4983 /**
5084 * For flatlist
5185 * @see See loeadMoreThreshold [doc](https://facebook.github.io/react-native/docs/flatlist#onendreachedthreshold)
@@ -55,6 +89,10 @@ const ChannelListMessenger = withChatContext(
5589 error : PropTypes . oneOfType ( [ PropTypes . bool , PropTypes . object ] ) ,
5690 /** If channels are being queries. LoadingIndicator will be displayed if true */
5791 loadingChannels : PropTypes . bool ,
92+ /** If channel list is being refreshed. Loader at top of the list will be displayed if true. */
93+ refreshing : PropTypes . bool ,
94+ /** If further channels are being loadded. Loader will be shown at bottom of the list */
95+ loadingNextPage : PropTypes . bool ,
5896 /**
5997 * Besides existing (default) UX behaviour of underlying flatlist of ChannelListMessenger component, if you want
6098 * to attach some additional props to un derlying flatlist, you can add it to following prop.
@@ -89,6 +127,9 @@ const ChannelListMessenger = withChatContext(
89127 Preview : ChannelPreviewMessenger ,
90128 LoadingIndicator,
91129 LoadingErrorIndicator,
130+ HeaderNetworkDownIndicator : ChannelListHeaderNetworkDownIndicator ,
131+ HeaderErrorIndicator : ChannelListHeaderErrorIndicator ,
132+ FooterLoadingIndicator : ChannelListFooterLoadingIndicator ,
92133 EmptyStateIndicator,
93134 // https://github.com/facebook/react-native/blob/a7a7970e543959e9db5281914d5f132beb01db8d/Libraries/Lists/VirtualizedList.js#L466
94135 loadMoreThreshold : 2 ,
@@ -102,38 +143,74 @@ const ChannelListMessenger = withChatContext(
102143
103144 renderLoadingError = ( ) => {
104145 const Indicator = this . props . LoadingErrorIndicator ;
105- return < Indicator error = { this . props . error } listType = "channel" /> ;
146+ return (
147+ < Indicator
148+ error = { this . props . error }
149+ retry = { this . props . reloadList }
150+ listType = "channel"
151+ loadNextPage = { this . props . loadNextPage }
152+ />
153+ ) ;
106154 } ;
107155
108156 renderEmptyState = ( ) => {
109157 const Indicator = this . props . EmptyStateIndicator ;
110158 return < Indicator listType = "channel" /> ;
111159 } ;
112160
161+ renderHeaderIndicator = ( ) => {
162+ const { isOnline, error, refreshList } = this . props ;
163+
164+ if ( ! isOnline ) {
165+ const HeaderNetworkDownIndicator = this . props
166+ . HeaderNetworkDownIndicator ;
167+ return < HeaderNetworkDownIndicator /> ;
168+ }
169+
170+ if ( error ) {
171+ const HeaderErrorIndicator = this . props . HeaderErrorIndicator ;
172+ return < HeaderErrorIndicator onPress = { refreshList } /> ;
173+ }
174+ } ;
175+
113176 renderChannels = ( ) => (
114- < FlatList
115- ref = { ( flRef ) => {
116- this . props . setFlatListRef && this . props . setFlatListRef ( flRef ) ;
117- } }
118- data = { this . props . channels }
119- onEndReached = { this . props . loadNextPage }
120- onEndReachedThreshold = { this . props . loadMoreThreshold }
121- ListEmptyComponent = { this . renderEmptyState }
122- renderItem = { ( { item : channel } ) => (
123- < ChannelPreview
124- { ...this . props }
125- key = { channel . cid }
126- channel = { channel }
127- Preview = { this . props . Preview }
128- />
129- ) }
130- keyExtractor = { ( item ) => item . cid }
131- { ...this . props . additionalFlatListProps }
132- />
177+ < >
178+ { this . renderHeaderIndicator ( ) }
179+ < FlatList
180+ ref = { ( flRef ) => {
181+ this . props . setFlatListRef && this . props . setFlatListRef ( flRef ) ;
182+ } }
183+ data = { this . props . channels }
184+ onEndReached = { ( ) => this . props . loadNextPage ( false ) }
185+ onRefresh = { ( ) => this . props . refreshList ( ) }
186+ refreshing = { this . props . refreshing }
187+ onEndReachedThreshold = { this . props . loadMoreThreshold }
188+ ListEmptyComponent = { this . renderEmptyState }
189+ ListFooterComponent = { ( ) => {
190+ if ( this . props . loadingNextPage ) {
191+ const FooterLoadingIndicator = this . props . FooterLoadingIndicator ;
192+
193+ return < FooterLoadingIndicator /> ;
194+ }
195+
196+ return null ;
197+ } }
198+ renderItem = { ( { item : channel } ) => (
199+ < ChannelPreview
200+ { ...this . props }
201+ key = { channel . cid }
202+ channel = { channel }
203+ Preview = { this . props . Preview }
204+ />
205+ ) }
206+ keyExtractor = { ( item ) => item . cid }
207+ { ...this . props . additionalFlatListProps }
208+ />
209+ </ >
133210 ) ;
134211
135212 render ( ) {
136- if ( this . props . error ) {
213+ if ( this . props . error && this . props . channels . length === 0 ) {
137214 return this . renderLoadingError ( ) ;
138215 } else if ( this . props . loadingChannels ) {
139216 return this . renderLoading ( ) ;
0 commit comments