diff --git a/docusaurus/docs/Flutter/stream_chat_flutter_core/channel_list_core.mdx b/docusaurus/docs/Flutter/stream_chat_flutter_core/channel_list_core.mdx deleted file mode 100644 index 4196a14c..00000000 --- a/docusaurus/docs/Flutter/stream_chat_flutter_core/channel_list_core.mdx +++ /dev/null @@ -1,68 +0,0 @@ ---- -id: channel_list_core -sidebar_position: 4 -title: ChannelListCore ---- - -A Widget For Building A List Of Channels - -### Background - -The UI SDK of Stream Chat supplies a `ChannelListView` class that builds a list of channels fetching -according to the filters and sort order given. However, in some cases, implementing novel UI is necessary -that cannot be done using the customization approaches given in the widget. - -To do this, we extracted the logic required for fetching channels into a 'Core' widget - a widget that -fetches channels in the expected way via the usual params but does not supply any UI and instead -exposes builders to build the UI in situations such as loading, empty data, errors, and on data received. - -### Basic Example - -`ChannelListCore` is a simplified class that allows fetching a list of -channels while exposing UI builders. - -This allows you to construct your own UI while not having to -worry about the specific logic of fetching channels in your app. - -A `ChannelListController` is used to reload and paginate data. - -```dart -class ChannelListPage extends StatelessWidget { - @override - Widget build(BuildContext context) { - return Scaffold( - body: ChannelListCore( - filter: Filter.in_( - 'members', - [StreamChat.of(context).user!.id], - ), - sort: [SortOption('last_message_at')], - pagination: PaginationParams( - limit: 20, - ), - errorBuilder: (context, err) { - return Center( - child: Text('An error has occured'), - ); - }, - emptyBuilder: (context) { - return Center( - child: Text('Nothing here...'), - ); - }, - loadingBuilder: (context) { - return Center( - child: CircularProgressIndicator(), - ); - }, - listBuilder: (context, list) { - return ChannelPage(list); - } - ), - ); - } -} -``` - -Make sure to have a `StreamChatCore` ancestor in order to provide the -information about the channels. \ No newline at end of file diff --git a/docusaurus/docs/Flutter/stream_chat_flutter_core/introduction.mdx b/docusaurus/docs/Flutter/stream_chat_flutter_core/introduction.mdx index c7c6f4b9..fd53daee 100644 --- a/docusaurus/docs/Flutter/stream_chat_flutter_core/introduction.mdx +++ b/docusaurus/docs/Flutter/stream_chat_flutter_core/introduction.mdx @@ -27,11 +27,12 @@ the experience you want your users to have. The package primarily contains a bunch of controller classes. Controllers are used to handle the business logic of the chat. You can use them together with our UI widgets, or you can even use them to build your own UI. -* StreamChannelListController -* StreamMessageSearchListController * StreamChannelListController * StreamUserListController +* StreamMessageSearchListController * StreamMessageInputController * MessageListController +* LazyLoadScrollView +* PagedValueListenableBuilder This section goes into the individual core package widgets and their functional use. diff --git a/docusaurus/docs/Flutter/stream_chat_flutter_core/stream_channel_list_controller.mdx b/docusaurus/docs/Flutter/stream_chat_flutter_core/stream_channel_list_controller.mdx new file mode 100644 index 00000000..e1aaaec4 --- /dev/null +++ b/docusaurus/docs/Flutter/stream_chat_flutter_core/stream_channel_list_controller.mdx @@ -0,0 +1,141 @@ +--- +id: stream_channel_list_controller +sidebar_position: 4 +title: StreamChannelListController +--- + +A Widget For Controlling A List Of Channels + +### Background + +The `StreamChannelListController` is a controller class that allows you to control a list of channels. +`StreamChannelListController` is a required parameter of the `StreamChannelListView` widget. +Check the [`StreamChannelListView` documentation](../stream_chat_flutter/stream_channel_list_view.mdx) to read more about that. + +### Basic Example + +Building a custom channel list is a very common task. Here is an example of how to use the `StreamChannelListController` to build a simple list with pagination. + +First of all we should create an instance of the `StreamChannelListController` and provide it with the `StreamChatClient` instance. +You can also add a `Filter`, a list of `SortOption`s and other pagination-related parameters. + +```dart +class ChannelListPageState extends State { + /// Controller used for loading more data and controlling pagination in + /// [StreamChannelListController]. + late final channelListController = StreamChannelListController( + client: StreamChatCore.of(context).client, + filter: Filter.and([ + Filter.equal('type', 'messaging'), + Filter.in_( + 'members', + [ + StreamChatCore.of(context).currentUser!.id, + ], + ), + ]), + ); +``` + +Make sure you call `channelListController.doInitialLoad()` to load the initial data and `channelListController.dispose()` when the controller is no longer required. + +```dart +@override +void initState() { + channelListController.doInitialLoad(); + super.initState(); +} + +@override +void dispose() { + channelListController.dispose(); + super.dispose(); +} +``` + +The `StreamChannelListController` is basically a [`PagedValueNotifier`](./paged_value_notifier.mdx) that notifies you when the list of channels has changed. +You can use a [`PagedValueListenableBuilder`](./paged_value_listenable_builder.mdx) to build your UI depending on the latest channels. + +```dart +@override +Widget build(BuildContext context) => Scaffold( + body: PagedValueListenableBuilder( + valueListenable: channelListController, + builder: (context, value, child) { + return value.when( + (channels, nextPageKey, error) => LazyLoadScrollView( + onEndOfPage: () async { + if (nextPageKey != null) { + channelListController.loadMore(nextPageKey); + } + }, + child: ListView.builder( + /// We're using the channels length when there are no more + /// pages to load and there are no errors with pagination. + /// In case we need to show a loading indicator or and error + /// tile we're increasing the count by 1. + itemCount: (nextPageKey != null || error != null) + ? channels.length + 1 + : channels.length, + itemBuilder: (BuildContext context, int index) { + if (index == channels.length) { + if (error != null) { + return Text(error.message); + } + return CircularProgressIndicator(); + } + + final _item = channels[index]; + return ListTile( + title: Text(_item.name ?? ''), + subtitle: StreamBuilder( + stream: _item.state!.lastMessageStream, + initialData: _item.state!.lastMessage, + builder: (context, snapshot) { + if (snapshot.hasData) { + return Text(snapshot.data!.text!); + } + + return const SizedBox(); + }, + ), + onTap: () { + /// Display a list of messages when the user taps on + /// an item. We can use [StreamChannel] to wrap our + /// [MessageScreen] screen with the selected channel. + /// + /// This allows us to use a built-in inherited widget + /// for accessing our `channel` later on. + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => StreamChannel( + channel: _item, + child: const MessageScreen(), + ), + ), + ); + }, + ); + }, + ), + ), + loading: () => const Center( + child: SizedBox( + height: 100, + width: 100, + child: CircularProgressIndicator(), + ), + ), + error: (e) => Center( + child: Text( + 'Oh no, something went wrong. ' + 'Please check your config. $e', + ), + ), + ); + }, + ), + ); +``` + +In this case we're using the [`LazyLoadScrollView`](./lazy_load_scroll_view.mdx) widget to load more data when the user scrolls to the bottom of the list. \ No newline at end of file diff --git a/packages/stream_chat_flutter_core/example/lib/main.dart b/packages/stream_chat_flutter_core/example/lib/main.dart index 49f2be75..7f093c6d 100644 --- a/packages/stream_chat_flutter_core/example/lib/main.dart +++ b/packages/stream_chat_flutter_core/example/lib/main.dart @@ -117,8 +117,21 @@ class _HomeScreenState extends State { } }, child: ListView.builder( - itemCount: channels.length, + /// We're using the channels length when there are no more + /// pages to load and there are no errors with pagination. + /// In case we need to show a loading indicator or and error + /// tile we're increasing the count by 1. + itemCount: (nextPageKey != null || error != null) + ? channels.length + 1 + : channels.length, itemBuilder: (BuildContext context, int index) { + if (index == channels.length) { + if (error != null) { + return Text(error.message); + } + return CircularProgressIndicator(); + } + final _item = channels[index]; return ListTile( title: Text(_item.name ?? ''),