This is documentation for Stream Chat Flutter SDK v7, which is nolonger actively maintained. For up-to-date documentation, see the latest version (v8).

Message Search State

A Widget For Controlling A List Of Searched Messages

Find the pub.dev documentation here

Background

The StreamMessageSearchListController is a controller class that allows you to control a list of searched messages. StreamMessageSearchListController is a required parameter of the StreamMessageSearchListView widget. Check the StreamMessageSearchListView documentation to read more about that.

Basic Example

Building a custom message search feature is a common task. Here is an example of how to use the StreamMessageSearchListController to build a simple search list with pagination.

First of all we should create an instance of the StreamMessageSearchListController and provide it with the StreamChatClient instance. You can also add a Filter, a list of SortOptions and other pagination-related parameters.

class SearchListPageState extends State<SearchListPage> {
  /// Controller used for loading more data and controlling pagination in
  /// [StreamMessageSearchListController].
  late final messageSearchListController = StreamMessageSearchListController(
    client: StreamChatCore.of(context).client,
  );

Make sure you call messageSearchListController.doInitialLoad() to load the initial data and messageSearchListController.dispose() when the controller is no longer required.

@override
void initState() {
  messageSearchListController.doInitialLoad();
  super.initState();
}

@override
void dispose() {
  messageSearchListController.dispose();
  super.dispose();
}

The StreamMessageSearchListController is basically a PagedValueNotifier that notifies you when the list of responses has changed. You can use a PagedValueListenableBuilder to build your UI depending on the latest responses.

@override
Widget build(BuildContext context) => Scaffold(
      body: Column(
        children: [
          TextField(
            /// This is just a sample implementation of a search field.
            /// In a real-world app you should throttle the search requests.
            /// You can use our library [rate_limiter](https://pub.dev/packages/rate_limiter).
            onChanged: (s) {
              messageSearchListController..searchQuery = s..doInitialLoad();
            },
          ),
          Expanded(
            child: PagedValueListenableBuilder<String, GetMessageResponse>(
              valueListenable: messageSearchListController,
              builder: (context, value, child) {
                return value.when(
                  (responses, nextPageKey, error) => LazyLoadScrollView(
                    onEndOfPage: () async {
                      if (nextPageKey != null) {
                        messageSearchListController.loadMore(nextPageKey);
                      }
                    },
                    child: ListView.builder(
                      /// We're using the responses 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)
                          ? responses.length + 1
                          : responses.length,
                      itemBuilder: (BuildContext context, int index) {
                        if (index == responses.length) {
                          if (error != null) {
                            return TextButton(
                              onPressed: () {
                                messageSearchListController.retry();
                              },
                              child: Text(error.message),
                            );
                          }
                          return const CircularProgressIndicator();
                        }

                        final _item = responses[index];
                        return ListTile(
                          title: Text(_item.channel?.name ?? ''),
                          subtitle: Text(_item.message.text ?? ''),
                        );
                      },
                    ),
                  ),
                  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 widget to load more data when the user scrolls to the bottom of the list.

© Getstream.io, Inc. All Rights Reserved.