From f90dc4127d43a2562a9d353328a494fa2bbd0192 Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Fri, 20 Aug 2021 16:13:27 +0530 Subject: [PATCH] refactor!(core): Refactor BetterStreamBuilder. 1. BREAKING: Renamed `BetterStreamBuilder.loadingBuilder` to `.noDataBuilder`. 2. BREAKING: Added non-null constraint on `BetterStreamBuilder`. 3. `BetterStreamBuilder.initialData` is now nullable/not-required. Signed-off-by: xsahil03x --- .../stream_chat_flutter_core/CHANGELOG.md | 6 +++ .../lib/src/better_stream_builder.dart | 39 +++++++++++-------- .../lib/src/channel_list_core.dart | 16 +++----- .../lib/src/message_list_core.dart | 6 +-- .../lib/src/message_search_list_core.dart | 14 +++---- .../lib/src/user_list_core.dart | 13 ++----- 6 files changed, 46 insertions(+), 48 deletions(-) diff --git a/packages/stream_chat_flutter_core/CHANGELOG.md b/packages/stream_chat_flutter_core/CHANGELOG.md index 65280674..ad331bc2 100644 --- a/packages/stream_chat_flutter_core/CHANGELOG.md +++ b/packages/stream_chat_flutter_core/CHANGELOG.md @@ -1,5 +1,11 @@ ## Upcoming +🛑️ Breaking Changes from `2.1.1` +- Renamed `BetterStreamBuilder.loadingBuilder` to `.noDataBuilder` + +🔄 Changed +- `BetterStreamBuilder.initialData` is now nullable/not-required. + 🐞 Fixed - [#612](https://github.com/GetStream/stream-chat-flutter/issues/612) `ChannelListView` pagination doesn't work after refresh diff --git a/packages/stream_chat_flutter_core/lib/src/better_stream_builder.dart b/packages/stream_chat_flutter_core/lib/src/better_stream_builder.dart index 871a8a1d..3c456246 100644 --- a/packages/stream_chat_flutter_core/lib/src/better_stream_builder.dart +++ b/packages/stream_chat_flutter_core/lib/src/better_stream_builder.dart @@ -6,23 +6,23 @@ import 'package:flutter/widgets.dart'; /// It requires [initialData] and will rebuild /// only when the new data is different than the current data /// The [comparator] is used to check if the new data is different -class BetterStreamBuilder extends StatefulWidget { +class BetterStreamBuilder extends StatefulWidget { /// Creates a new BetterStreamBuilder const BetterStreamBuilder({ required this.stream, - required this.initialData, required this.builder, - this.loadingBuilder, + this.initialData, + this.noDataBuilder, this.errorBuilder, this.comparator, Key? key, }) : super(key: key); /// The stream to listen to - final Stream? stream; + final Stream? stream; /// The initial data available - final T initialData; + final T? initialData; /// Comparator used to check if the new data is different than the last one final bool Function(T?, T?)? comparator; @@ -31,7 +31,7 @@ class BetterStreamBuilder extends StatefulWidget { final Widget Function(BuildContext context, T data) builder; /// Builder that builds when the data is null - final Widget Function(BuildContext context)? loadingBuilder; + final Widget Function(BuildContext context)? noDataBuilder; /// Builder used when there is an error final Widget Function(BuildContext context, Object error)? errorBuilder; @@ -40,21 +40,26 @@ class BetterStreamBuilder extends StatefulWidget { _BetterStreamBuilderState createState() => _BetterStreamBuilderState(); } -class _BetterStreamBuilderState extends State> { +class _BetterStreamBuilderState + extends State> { T? _lastEvent; - StreamSubscription? _subscription; + StreamSubscription? _subscription; Object? _lastError; @override Widget build(BuildContext context) { - if (_lastError != null) { - return widget.errorBuilder!(context, _lastError!); + final error = _lastError; + if (error != null) { + final errorBuilder = widget.errorBuilder; + if (errorBuilder != null) { + return errorBuilder(context, error); + } } - - if (_lastEvent == null) { - return widget.loadingBuilder?.call(context) ?? const Offstage(); + final event = _lastEvent; + if (event == null) { + return widget.noDataBuilder?.call(context) ?? const Offstage(); } - return widget.builder(context, _lastEvent ?? widget.initialData); + return widget.builder(context, event); } @override @@ -87,22 +92,22 @@ class _BetterStreamBuilderState extends State> { void _onError(error) { if (widget.errorBuilder != null && error != _lastError) { + _lastError = error; if (mounted) { setState(() {}); } - _lastError = error; } } - void _onEvent(T event) { + void _onEvent(T? event) { _lastError = null; final isEqual = widget.comparator?.call(_lastEvent, event) ?? event == _lastEvent; if (!isEqual) { + _lastEvent = event; if (mounted) { setState(() {}); } - _lastEvent = event; } } } diff --git a/packages/stream_chat_flutter_core/lib/src/channel_list_core.dart b/packages/stream_chat_flutter_core/lib/src/channel_list_core.dart index c59b2030..c5d3f69a 100644 --- a/packages/stream_chat_flutter_core/lib/src/channel_list_core.dart +++ b/packages/stream_chat_flutter_core/lib/src/channel_list_core.dart @@ -4,6 +4,7 @@ import 'dart:convert'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:stream_chat/stream_chat.dart'; +import 'package:stream_chat_flutter_core/src/better_stream_builder.dart'; import 'package:stream_chat_flutter_core/src/channels_bloc.dart'; import 'package:stream_chat_flutter_core/src/stream_chat_core.dart'; import 'package:stream_chat_flutter_core/src/typedef.dart'; @@ -137,19 +138,14 @@ class ChannelListCoreState extends State { @override Widget build(BuildContext context) => _buildListView(_channelsBloc); - StreamBuilder> _buildListView( + BetterStreamBuilder> _buildListView( ChannelsBlocState channelsBlocState, ) => - StreamBuilder>( + BetterStreamBuilder>( stream: channelsBlocState.channelsStream, - builder: (context, snapshot) { - if (snapshot.hasError) { - return widget.errorBuilder(context, snapshot.error!); - } - if (!snapshot.hasData) { - return widget.loadingBuilder(context); - } - final channels = snapshot.data!; + errorBuilder: widget.errorBuilder, + noDataBuilder: widget.loadingBuilder, + builder: (context, channels) { if (channels.isEmpty) { return widget.emptyBuilder(context); } diff --git a/packages/stream_chat_flutter_core/lib/src/message_list_core.dart b/packages/stream_chat_flutter_core/lib/src/message_list_core.dart index d3d69dfb..b9b423ce 100644 --- a/packages/stream_chat_flutter_core/lib/src/message_list_core.dart +++ b/packages/stream_chat_flutter_core/lib/src/message_list_core.dart @@ -138,7 +138,7 @@ class MessageListCoreState extends State { return true; } - return BetterStreamBuilder?>( + return BetterStreamBuilder>( initialData: initialData, comparator: const ListEquality().equals, stream: messagesStream!.map( @@ -148,9 +148,9 @@ class MessageListCoreState extends State { ), ), errorBuilder: widget.errorBuilder, - loadingBuilder: widget.loadingBuilder, + noDataBuilder: widget.loadingBuilder, builder: (context, data) { - final messageList = data?.reversed.toList(growable: false) ?? []; + final messageList = data.reversed.toList(growable: false); if (messageList.isEmpty && !_isThreadConversation) { if (_upToDate) { return widget.emptyBuilder(context); diff --git a/packages/stream_chat_flutter_core/lib/src/message_search_list_core.dart b/packages/stream_chat_flutter_core/lib/src/message_search_list_core.dart index 4901c332..234b5c9a 100644 --- a/packages/stream_chat_flutter_core/lib/src/message_search_list_core.dart +++ b/packages/stream_chat_flutter_core/lib/src/message_search_list_core.dart @@ -3,6 +3,7 @@ import 'dart:convert'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:stream_chat/stream_chat.dart'; +import 'package:stream_chat_flutter_core/src/better_stream_builder.dart'; import 'package:stream_chat_flutter_core/src/message_search_bloc.dart'; import 'package:stream_chat_flutter_core/src/typedef.dart'; @@ -132,16 +133,11 @@ class MessageSearchListCoreState extends State { Widget build(BuildContext context) => _buildListView(_messageSearchBloc!); Widget _buildListView(MessageSearchBlocState messageSearchBloc) => - StreamBuilder>( + BetterStreamBuilder>( stream: messageSearchBloc.messagesStream, - builder: (context, snapshot) { - if (snapshot.hasError) { - return widget.errorBuilder(context, snapshot.error!); - } - if (!snapshot.hasData) { - return widget.loadingBuilder(context); - } - final items = snapshot.data!; + errorBuilder: widget.errorBuilder, + noDataBuilder: widget.loadingBuilder, + builder: (context, items) { if (items.isEmpty) { return widget.emptyBuilder(context); } diff --git a/packages/stream_chat_flutter_core/lib/src/user_list_core.dart b/packages/stream_chat_flutter_core/lib/src/user_list_core.dart index a45aa904..57d61fe6 100644 --- a/packages/stream_chat_flutter_core/lib/src/user_list_core.dart +++ b/packages/stream_chat_flutter_core/lib/src/user_list_core.dart @@ -176,16 +176,11 @@ class UserListCoreState extends State }, ); - StreamBuilder> _buildListView() => StreamBuilder( + BetterStreamBuilder> _buildListView() => BetterStreamBuilder( stream: _buildUserStream(), - builder: (context, snapshot) { - if (snapshot.hasError) { - return widget.errorBuilder(context, snapshot.error!); - } - if (!snapshot.hasData) { - return widget.loadingBuilder(context); - } - final items = snapshot.data!; + errorBuilder: widget.errorBuilder, + noDataBuilder: widget.loadingBuilder, + builder: (context, items) { if (items.isEmpty) { return widget.emptyBuilder(context); }