Merge branches 'feature/new-ui' and 'llc-independence' of https://github.com/GetStream/stream-chat-flutter into llc-independence

 Conflicts:
	packages/stream_chat_flutter_core/lib/src/lazy_load_scroll_view.dart
	packages/stream_chat_flutter_core/lib/src/stream_chat_core.dart
This commit is contained in:
Sahil Kumar
2021-02-01 14:44:58 +05:30
12 changed files with 119 additions and 69 deletions
@@ -5,27 +5,27 @@
<testcase classname="fastlane.lanes" name="0: Verifying fastlane version" time="0.000383"> <testcase classname="fastlane.lanes" name="0: Verifying fastlane version" time="0.000371">
</testcase> </testcase>
<testcase classname="fastlane.lanes" name="1: default_platform" time="0.000196"> <testcase classname="fastlane.lanes" name="1: default_platform" time="0.000177">
</testcase> </testcase>
<testcase classname="fastlane.lanes" name="2: is_ci" time="0.000194"> <testcase classname="fastlane.lanes" name="2: is_ci" time="0.000187">
</testcase> </testcase>
<testcase classname="fastlane.lanes" name="3: is_ci" time="0.000177"> <testcase classname="fastlane.lanes" name="3: is_ci" time="0.000166">
</testcase> </testcase>
<testcase classname="fastlane.lanes" name="4: match" time="36.832536"> <testcase classname="fastlane.lanes" name="4: match" time="36.640008">
</testcase> </testcase>
@@ -1,7 +1,7 @@
name: example name: example
description: A new Flutter project. description: A new Flutter project.
publish_to: 'none' publish_to: 'none'
version: 1.2.0 version: 1.2.0+1
environment: environment:
sdk: ">=2.2.2 <3.0.0" sdk: ">=2.2.2 <3.0.0"
@@ -66,7 +66,11 @@ class ChannelListCore extends StatefulWidget {
this.sort, this.sort,
this.pagination, this.pagination,
this.channelListController, this.channelListController,
}) : super(key: key); }) : assert(errorBuilder != null),
assert(emptyBuilder != null),
assert(loadingBuilder != null),
assert(listBuilder != null),
super(key: key);
/// A [ChannelListController] allows reloading and pagination. /// A [ChannelListController] allows reloading and pagination.
/// Use [ChannelListController.loadData] and [ChannelListController.paginateData] respectively for reloading and pagination. /// Use [ChannelListController.loadData] and [ChannelListController.paginateData] respectively for reloading and pagination.
@@ -257,11 +261,14 @@ class _ChannelListCoreState extends State<ChannelListCore>
} }
} }
/// Controller used for paginating data in [ChannelListCore] /// Controller used for loading more data and controlling pagination in [ChannelListCore].
class ChannelListController { class ChannelListController {
/// Call this function to reload data /// This function calls Stream's servers to load a list of channels. If there is existing data,
/// calling this function causes a reload.
VoidCallback loadData; VoidCallback loadData;
/// Call this function to load further data /// This function is used to load another page of data. Note, [loadData] should be
/// used to populate the initial page of data. Calling [paginateData] performs a query
/// to load subsequent pages.
VoidCallback paginateData; VoidCallback paginateData;
} }
@@ -3,10 +3,29 @@ import 'dart:async';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:rxdart/rxdart.dart'; import 'package:rxdart/rxdart.dart';
import 'package:stream_chat/stream_chat.dart'; import 'package:stream_chat/stream_chat.dart';
import 'package:stream_chat_flutter_core/src/channel_list_core.dart';
import 'package:stream_chat_flutter_core/src/stream_chat_core.dart'; import 'package:stream_chat_flutter_core/src/stream_chat_core.dart';
/// Widget dedicated to the management of a channel list with pagination /// Widget dedicated to the management of a channel list with pagination
/// [ChannelsBloc] is used together with [ChannelListCore] to manage a list of
/// [Channel]s with pagination, re-ordering, querying and other operations
/// associated with [Channel]s.
///
/// [ChannelsBloc] can be access at anytime by using the static [of] method
/// using Flutter's [BuildContext].
///
/// API docs: https://getstream.io/chat/docs/flutter-dart/query_channels/
class ChannelsBloc extends StatefulWidget { class ChannelsBloc extends StatefulWidget {
/// Creates a new [ChannelsBloc]. The parameter [child] must be supplied and not null.
const ChannelsBloc({
Key key,
@required this.child,
this.lockChannelsOrder = false,
this.channelsComparator,
this.shouldAddChannel,
}) : assert(child != null),
super(key: key);
/// The widget child /// The widget child
final Widget child; final Widget child;
@@ -19,15 +38,6 @@ class ChannelsBloc extends StatefulWidget {
/// Function used to evaluate if a channel should be added to the list when a message.new event is received /// Function used to evaluate if a channel should be added to the list when a message.new event is received
final bool Function(Event) shouldAddChannel; final bool Function(Event) shouldAddChannel;
/// Instantiate a new ChannelsBloc
const ChannelsBloc({
Key key,
this.child,
this.lockChannelsOrder = false,
this.channelsComparator,
this.shouldAddChannel,
}) : super(key: key);
@override @override
ChannelsBlocState createState() => ChannelsBlocState(); ChannelsBlocState createState() => ChannelsBlocState();
@@ -45,7 +55,7 @@ class ChannelsBloc extends StatefulWidget {
} }
} }
/// The current state of the [ChannelsBloc] /// The current state of the [ChannelsBloc].
class ChannelsBlocState extends State<ChannelsBloc> class ChannelsBlocState extends State<ChannelsBloc>
with AutomaticKeepAliveClientMixin { with AutomaticKeepAliveClientMixin {
@override @override
@@ -3,9 +3,23 @@ import 'package:flutter/widgets.dart';
enum _LoadingStatus { LOADING, STABLE } enum _LoadingStatus { LOADING, STABLE }
/// A widget that wraps a [Widget] and will trigger [onEndOfPage]/[onStartOfPage] when it /// Wrapper around a [Scrollable] which triggers [onEndOfPage]/[onStartOfPage] the Scrollable
/// reaches the bottom/start of the list /// reaches to the start or end of the view extent.
class LazyLoadScrollView extends StatefulWidget { class LazyLoadScrollView extends StatefulWidget {
/// Creates a new instance of [LazyLoadScrollView]. The parameter [child] must be
/// supplied and not null.
const LazyLoadScrollView({
Key key,
@required this.child,
this.onStartOfPage,
this.onEndOfPage,
this.onPageScrollStart,
this.onPageScrollEnd,
this.onInBetweenOfPage,
this.scrollOffset = 100,
}) : assert(child != null),
super(key: key);
/// The [Widget] that this widget watches for changes on /// The [Widget] that this widget watches for changes on
final Widget child; final Widget child;
@@ -27,19 +41,6 @@ class LazyLoadScrollView extends StatefulWidget {
/// The offset to take into account when triggering [onEndOfPage]/[onStartOfPage] in pixels /// The offset to take into account when triggering [onEndOfPage]/[onStartOfPage] in pixels
final double scrollOffset; final double scrollOffset;
/// Initiates a LazyLoadScrollView widget
const LazyLoadScrollView({
Key key,
@required this.child,
this.onStartOfPage,
this.onEndOfPage,
this.onPageScrollStart,
this.onPageScrollEnd,
this.onInBetweenOfPage,
this.scrollOffset = 100,
}) : assert(child != null),
super(key: key);
@override @override
State<StatefulWidget> createState() => _LazyLoadScrollViewState(); State<StatefulWidget> createState() => _LazyLoadScrollViewState();
} }
@@ -53,20 +53,22 @@ import 'stream_channel.dart';
/// Make sure to have a [StreamChannel] ancestor in order to provide the information about the channels. /// Make sure to have a [StreamChannel] ancestor in order to provide the information about the channels.
/// The widget uses a [ListView.custom] to render the list of channels. /// The widget uses a [ListView.custom] to render the list of channels.
/// ///
/// The widget components render the ui based on the first ancestor of type [StreamChatTheme].
/// Modify it to change the widget appearance.
class MessageListCore extends StatefulWidget { class MessageListCore extends StatefulWidget {
/// Instantiate a new MessageListView /// Instantiate a new [MessageListView].
MessageListCore({ MessageListCore({
Key key, Key key,
this.showScrollToBottom = true,
this.parentMessage,
@required this.loadingBuilder, @required this.loadingBuilder,
@required this.emptyBuilder, @required this.emptyBuilder,
@required this.messageListBuilder, @required this.messageListBuilder,
@required this.errorWidgetBuilder, @required this.errorWidgetBuilder,
this.showScrollToBottom = true,
this.parentMessage,
this.messageListController, this.messageListController,
}) : super(key: key); }) : assert(loadingBuilder != null),
assert(emptyBuilder != null),
assert(messageListBuilder != null),
assert(errorWidgetBuilder != null),
super(key: key);
/// A [MessageListController] allows pagination. /// A [MessageListController] allows pagination.
/// Use [ChannelListController.paginateData] pagination. /// Use [ChannelListController.paginateData] pagination.
@@ -89,7 +91,8 @@ class MessageListCore extends StatefulWidget {
/// If true will show a scroll to bottom message when there are new messages and the scroll offset is not zero /// If true will show a scroll to bottom message when there are new messages and the scroll offset is not zero
final bool showScrollToBottom; final bool showScrollToBottom;
/// Parent message in case of a thread /// If the current message belongs to a `thread`, this property represents the
/// first message or the parent of the conversation.
final Message parentMessage; final Message parentMessage;
@override @override
@@ -4,16 +4,23 @@ import 'package:stream_chat/stream_chat.dart';
import 'stream_chat_core.dart'; import 'stream_chat_core.dart';
/// Widget dedicated to the management of a message list with pagination /// [MessageSearchBloc] is used to manage a list of messages with pagination.
/// This class can be used to load messages, perform queries, etc.
///
/// [MessageSearchBloc] can be access at anytime by using the static [of] method
/// using Flutter's [BuildContext].
///
// API docs: https://getstream.io/chat/docs/flutter-dart/send_message/
class MessageSearchBloc extends StatefulWidget { class MessageSearchBloc extends StatefulWidget {
/// The widget child
final Widget child;
/// Instantiate a new MessageSearchBloc /// Instantiate a new MessageSearchBloc
const MessageSearchBloc({ const MessageSearchBloc({
Key key, Key key,
@required this.child, @required this.child,
}) : super(key: key); }) : assert(child != null),
super(key: key);
/// The widget child
final Widget child;
@override @override
MessageSearchBlocState createState() => MessageSearchBlocState(); MessageSearchBlocState createState() => MessageSearchBlocState();
@@ -32,7 +32,12 @@ import 'message_search_bloc.dart';
/// The widget uses a [ListView.separated] to render the list of messages. /// The widget uses a [ListView.separated] to render the list of messages.
/// ///
class MessageSearchListCore extends StatefulWidget { class MessageSearchListCore extends StatefulWidget {
/// Instantiate a new MessageSearchListView /// Instantiate a new [MessageSearchListView].
/// The following parameters must be supplied and not null:
/// * [emptyBuilder]
/// * [errorBuilder]
/// * [loadingBuilder]
/// * [childBuilder]
const MessageSearchListCore({ const MessageSearchListCore({
Key key, Key key,
@required this.emptyBuilder, @required this.emptyBuilder,
@@ -45,7 +50,11 @@ class MessageSearchListCore extends StatefulWidget {
this.paginationParams, this.paginationParams,
this.messageFilters, this.messageFilters,
this.messageSearchListController, this.messageSearchListController,
}) : super(key: key); }) : assert(emptyBuilder != null),
assert(errorBuilder != null),
assert(loadingBuilder != null),
assert(childBuilder != null),
super(key: key);
/// A [MessageSearchListController] allows reloading and pagination. /// A [MessageSearchListController] allows reloading and pagination.
/// Use [MessageSearchListController.loadData] and [MessageSearchListController.paginateData] respectively for reloading and pagination. /// Use [MessageSearchListController.loadData] and [MessageSearchListController.paginateData] respectively for reloading and pagination.
@@ -17,7 +17,8 @@ enum QueryDirection {
/// ///
/// Use [StreamChannel.of] to get the current [StreamChannelState] instance. /// Use [StreamChannel.of] to get the current [StreamChannelState] instance.
class StreamChannel extends StatefulWidget { class StreamChannel extends StatefulWidget {
// ignore: public_member_api_docs /// Creates a new instance of [StreamChannel]. Both [child] and [client] must
/// be supplied and not null.
const StreamChannel({ const StreamChannel({
Key key, Key key,
@required this.child, @required this.child,
@@ -34,6 +34,20 @@ typedef EventHandler = void Function(Event event);
/// ``` /// ```
/// ///
class StreamChatCore extends StatefulWidget { class StreamChatCore extends StatefulWidget {
/// Constructor used for creating a new instance of [StreamChatCore].
///
/// [StreamChatCore] is a stateful widget which reacts to system events and updates
/// Stream's connection status accordingly.
StreamChatCore({
Key key,
@required this.client,
@required this.child,
this.onBackgroundEventReceived,
this.backgroundKeepAlive = const Duration(minutes: 1),
}) : assert(client != null),
assert(child != null),
super(key: key);
/// Instance of Stream Chat Client containing information about the current /// Instance of Stream Chat Client containing information about the current
/// application. /// application.
final Client client; final Client client;
@@ -49,18 +63,6 @@ class StreamChatCore extends StatefulWidget {
/// upon the [Event.type] /// upon the [Event.type]
final EventHandler onBackgroundEventReceived; final EventHandler onBackgroundEventReceived;
/// Constructor used for creating a new instance of [StreamChatCore].
///
/// [StreamChatCore] is a stateful widget which reacts to system events and updates
/// Stream's connection status accordingly.
StreamChatCore({
Key key,
@required this.client,
@required this.child,
this.onBackgroundEventReceived,
this.backgroundKeepAlive = const Duration(minutes: 1),
}) : super(key: key);
@override @override
StreamChatCoreState createState() => StreamChatCoreState(); StreamChatCoreState createState() => StreamChatCoreState();
@@ -50,7 +50,6 @@ import 'package:stream_chat_flutter_core/src/users_bloc.dart';
/// [UsersBloc] must be the ancestor of this widget. This is necessary since /// [UsersBloc] must be the ancestor of this widget. This is necessary since
/// [UserListCore] depends on functionality contained within [UsersBloc]. /// [UserListCore] depends on functionality contained within [UsersBloc].
/// ///
/// The widget uses a [ListView.separated], [GridView.builder] to render the list, grid of channels.
/// The parameters [listBuilder], [loadingBuilder], [emptyBuilder] and [errorBuilder] must all be supplied /// The parameters [listBuilder], [loadingBuilder], [emptyBuilder] and [errorBuilder] must all be supplied
/// and not null. /// and not null.
class UserListCore extends StatefulWidget { class UserListCore extends StatefulWidget {
@@ -67,7 +66,11 @@ class UserListCore extends StatefulWidget {
this.pagination, this.pagination,
this.groupAlphabetically = false, this.groupAlphabetically = false,
this.userListController, this.userListController,
}) : super(key: key); }) : assert(errorBuilder != null),
assert(emptyBuilder != null),
assert(loadingBuilder != null),
assert(listBuilder != null),
super(key: key);
/// A [UserListController] allows reloading and pagination. /// A [UserListController] allows reloading and pagination.
/// Use [UserListController.loadData] and [UserListController.paginateData] respectively for reloading and pagination. /// Use [UserListController.loadData] and [UserListController.paginateData] respectively for reloading and pagination.
@@ -5,15 +5,22 @@ import 'package:stream_chat/stream_chat.dart';
import 'stream_chat_core.dart'; import 'stream_chat_core.dart';
/// Widget dedicated to the management of a users list with pagination. /// Widget dedicated to the management of a users list with pagination.
///
/// [UsersBloc] can be access at anytime by using the static [of] method
/// using Flutter's [BuildContext].
///
/// API docs: https://getstream.io/chat/docs/flutter-dart/init_and_users/
class UsersBloc extends StatefulWidget { class UsersBloc extends StatefulWidget {
/// The widget child /// Instantiate a new [UsersBloc]. The parameter [child] must be supplied and
final Widget child; /// not null.
/// Instantiate a new UsersBloc
const UsersBloc({ const UsersBloc({
Key key, Key key,
@required this.child, @required this.child,
}) : super(key: key); }) : assert(child != null),
super(key: key);
/// The widget child
final Widget child;
@override @override
UsersBlocState createState() => UsersBlocState(); UsersBlocState createState() => UsersBlocState();