LCOV - code coverage report
Current view: top level - src - message_search_list_core.dart (source / functions) Hit Total Coverage
Test: lcov.info Lines: 50 50 100.0 %
Date: 2021-05-27 10:59:48 Functions: 0 0 -

          Line data    Source code
       1             : import 'dart:convert';
       2             : 
       3             : import 'package:flutter/foundation.dart';
       4             : import 'package:flutter/material.dart';
       5             : import 'package:stream_chat/stream_chat.dart';
       6             : import 'package:stream_chat_flutter_core/src/message_search_bloc.dart';
       7             : import 'package:stream_chat_flutter_core/src/typedef.dart';
       8             : 
       9             : ///
      10             : /// [MessageSearchListCore] is a simplified class that allows searching for
      11             : ///  messages across channels while exposing UI builders.
      12             : ///  A [MessageSearchListController] is used to load and paginate data.
      13             : ///
      14             : /// ```dart
      15             : /// class MessageSearchPage extends StatelessWidget {
      16             : ///   @override
      17             : ///   Widget build(BuildContext context) {
      18             : ///     return Scaffold(
      19             : ///       body: MessageSearchListCore(
      20             : ///               messageQuery: _channelQuery,
      21             : ///               filters: {
      22             : ///                 'members': {
      23             : ///                   r'$in': [user.id]
      24             : ///                 }
      25             : ///               },
      26             : ///               paginationParams: PaginationParams(limit: 20),
      27             : ///       ),
      28             : ///     );
      29             : ///   }
      30             : /// }
      31             : /// ```
      32             : ///
      33             : /// Make sure to have a [MessageSearchBloc] ancestor in order to provide the
      34             : /// information about the messages.
      35             : /// The widget uses a [ListView.separated] to render the list of messages.
      36             : ///
      37             : class MessageSearchListCore extends StatefulWidget {
      38             :   /// Instantiate a new [MessageSearchListView].
      39             :   /// The following parameters must be supplied and not null:
      40             :   /// * [emptyBuilder]
      41             :   /// * [errorBuilder]
      42             :   /// * [loadingBuilder]
      43             :   /// * [childBuilder]
      44           1 :   const MessageSearchListCore({
      45             :     Key? key,
      46             :     required this.emptyBuilder,
      47             :     required this.errorBuilder,
      48             :     required this.loadingBuilder,
      49             :     required this.childBuilder,
      50             :     required this.filters,
      51             :     this.messageQuery,
      52             :     this.sortOptions,
      53             :     this.paginationParams,
      54             :     this.messageFilters,
      55             :     this.messageSearchListController,
      56           1 :   }) : super(key: key);
      57             : 
      58             :   /// A [MessageSearchListController] allows reloading and pagination.
      59             :   /// Use [MessageSearchListController.loadData] and
      60             :   /// [MessageSearchListController.paginateData] respectively for reloading and
      61             :   /// pagination.
      62             :   final MessageSearchListController? messageSearchListController;
      63             : 
      64             :   /// Message String to search on
      65             :   final String? messageQuery;
      66             : 
      67             :   /// The query filters to use.
      68             :   /// You can query on any of the custom fields you've defined on the [Channel].
      69             :   /// You can also filter other built-in channel fields.
      70             :   final Filter filters;
      71             : 
      72             :   /// The sorting used for the channels matching the filters.
      73             :   /// Sorting is based on field and direction, multiple sorting options can be
      74             :   /// provided.
      75             :   /// You can sort based on last_updated, last_message_at, updated_at, created_
      76             :   /// at or member_count. Direction can be ascending or descending.
      77             :   final List<SortOption>? sortOptions;
      78             : 
      79             :   /// Pagination parameters
      80             :   /// limit: the number of users to return (max is 30)
      81             :   /// offset: the offset (max is 1000)
      82             :   /// message_limit: how many messages should be included to each channel
      83             :   final PaginationParams? paginationParams;
      84             : 
      85             :   /// The message query filters to use.
      86             :   /// You can query on any of the custom fields you've defined on the [Channel].
      87             :   /// You can also filter other built-in channel fields.
      88             :   final Filter? messageFilters;
      89             : 
      90             :   /// The builder that is used when the search messages are fetched
      91             :   final Widget Function(List<GetMessageResponse>) childBuilder;
      92             : 
      93             :   /// The builder used when the channel list is empty.
      94             :   final WidgetBuilder emptyBuilder;
      95             : 
      96             :   /// The builder that will be used in case of error
      97             :   final ErrorBuilder errorBuilder;
      98             : 
      99             :   /// The builder that will be used in case of loading
     100             :   final WidgetBuilder loadingBuilder;
     101             : 
     102           1 :   @override
     103           1 :   MessageSearchListCoreState createState() => MessageSearchListCoreState();
     104             : }
     105             : 
     106             : /// The current state of the [MessageSearchListCore].
     107             : class MessageSearchListCoreState extends State<MessageSearchListCore> {
     108             :   MessageSearchBlocState? _messageSearchBloc;
     109             : 
     110           1 :   @override
     111             :   void didChangeDependencies() {
     112           2 :     final newMessageSearchBloc = MessageSearchBloc.of(context);
     113             : 
     114           2 :     if (newMessageSearchBloc != _messageSearchBloc) {
     115           1 :       _messageSearchBloc = newMessageSearchBloc;
     116           1 :       loadData();
     117           2 :       if (widget.messageSearchListController != null) {
     118           4 :         widget.messageSearchListController!.loadData = loadData;
     119           4 :         widget.messageSearchListController!.paginateData = paginateData;
     120             :       }
     121             :     }
     122             : 
     123           1 :     super.didChangeDependencies();
     124             :   }
     125             : 
     126           1 :   @override
     127           2 :   Widget build(BuildContext context) => _buildListView(_messageSearchBloc!);
     128             : 
     129           1 :   Widget _buildListView(MessageSearchBlocState messageSearchBloc) =>
     130           1 :       StreamBuilder<List<GetMessageResponse>>(
     131           1 :         stream: messageSearchBloc.messagesStream,
     132           1 :         builder: (context, snapshot) {
     133           1 :           if (snapshot.hasError) {
     134           4 :             return widget.errorBuilder(context, snapshot.error!);
     135             :           }
     136           1 :           if (!snapshot.hasData) {
     137           3 :             return widget.loadingBuilder(context);
     138             :           }
     139           1 :           final items = snapshot.data!;
     140           1 :           if (items.isEmpty) {
     141           3 :             return widget.emptyBuilder(context);
     142             :           }
     143           3 :           return widget.childBuilder(items);
     144             :         },
     145             :       );
     146             : 
     147             :   /// Fetches initial messages and updates the widget
     148           3 :   Future<void> loadData() => _messageSearchBloc!.search(
     149           2 :         filter: widget.filters,
     150           2 :         sort: widget.sortOptions,
     151           2 :         query: widget.messageQuery,
     152           2 :         pagination: widget.paginationParams,
     153           2 :         messageFilter: widget.messageFilters,
     154             :       );
     155             : 
     156             :   /// Fetches more messages with updated pagination and updates the widget
     157           3 :   Future<void> paginateData() => _messageSearchBloc!.search(
     158           2 :         filter: widget.filters,
     159           2 :         sort: widget.sortOptions,
     160           3 :         pagination: widget.paginationParams!.copyWith(
     161           3 :           offset: _messageSearchBloc!.messageResponses?.length ?? 0,
     162             :         ),
     163           2 :         query: widget.messageQuery,
     164           2 :         messageFilter: widget.messageFilters,
     165             :       );
     166             : 
     167           1 :   @override
     168             :   void didUpdateWidget(MessageSearchListCore oldWidget) {
     169           1 :     super.didUpdateWidget(oldWidget);
     170           6 :     if (widget.filters.toString() != oldWidget.filters.toString() ||
     171           6 :         jsonEncode(widget.sortOptions) != jsonEncode(oldWidget.sortOptions) ||
     172           4 :         widget.messageQuery?.toString() != oldWidget.messageQuery?.toString() ||
     173           3 :         widget.messageFilters?.toString() !=
     174           1 :             oldWidget.messageFilters?.toString() ||
     175           5 :         widget.paginationParams?.toJson().toString() !=
     176           3 :             oldWidget.paginationParams?.toJson().toString()) {
     177           1 :       loadData();
     178             :     }
     179             :   }
     180             : }
     181             : 
     182             : /// Controller used for paginating data in [ChannelListView]
     183             : class MessageSearchListController {
     184             :   /// Call this function to reload data
     185             :   AsyncCallback? loadData;
     186             : 
     187             :   /// Call this function to load further data
     188             :   AsyncCallback? paginateData;
     189             : }

Generated by: LCOV version 1.14