From 63705693dc863a6b08e267d91d617673080ac04e Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Thu, 1 Apr 2021 16:55:12 +0530 Subject: [PATCH] fix: fix channel list pagination spinner (#375) Signed-off-by: Sahil Kumar --- .../lib/src/channel_list_view.dart | 15 +++++------ .../lib/src/channels_bloc.dart | 11 +++++++- .../lib/src/lazy_load_scroll_view.dart | 25 ++++++++++++------- .../test/channel_list_core_test.dart | 6 ++++- 4 files changed, 39 insertions(+), 18 deletions(-) diff --git a/packages/stream_chat_flutter/lib/src/channel_list_view.dart b/packages/stream_chat_flutter/lib/src/channel_list_view.dart index 0396bffe..9751ad6d 100644 --- a/packages/stream_chat_flutter/lib/src/channel_list_view.dart +++ b/packages/stream_chat_flutter/lib/src/channel_list_view.dart @@ -628,13 +628,14 @@ class _ChannelListViewState extends State { ), ); } - return Container( - height: 100, - padding: EdgeInsets.all(32), - child: Center( - child: snapshot.data ? CircularProgressIndicator() : Container(), - ), - ); + return snapshot.data + ? Center( + child: Padding( + padding: const EdgeInsets.all(16.0), + child: const CircularProgressIndicator(), + ), + ) + : Offstage(); }); } diff --git a/packages/stream_chat_flutter_core/lib/src/channels_bloc.dart b/packages/stream_chat_flutter_core/lib/src/channels_bloc.dart index 71f0d508..2b4968eb 100644 --- a/packages/stream_chat_flutter_core/lib/src/channels_bloc.dart +++ b/packages/stream_chat_flutter_core/lib/src/channels_bloc.dart @@ -84,6 +84,8 @@ class ChannelsBlocState extends State final List _hiddenChannels = []; + bool _paginationEnded = false; + /// Calls [client.queryChannels] updating [queryChannelsLoading] stream Future queryChannels({ Map filter, @@ -93,7 +95,9 @@ class ChannelsBlocState extends State }) async { final client = StreamChatCore.of(context).client; - if (_queryChannelsLoadingController.value == true) return; + if (_paginationEnded || _queryChannelsLoadingController.value == true) { + return; + } if (_channelsController.hasValue) { _queryChannelsLoadingController.add(true); @@ -104,12 +108,14 @@ class ChannelsBlocState extends State paginationParams.offset == null || paginationParams.offset == 0; final oldChannels = List.from(channels ?? []); + var newChannels = []; await for (final channels in client.queryChannels( filter: filter, sort: sortOptions, options: options, paginationParams: paginationParams, )) { + newChannels = channels; if (clear) { _channelsController.add(channels); } else { @@ -121,6 +127,9 @@ class ChannelsBlocState extends State _queryChannelsLoadingController.sink.add(false); } } + if (newChannels.isEmpty || newChannels.length < paginationParams.limit) { + _paginationEnded = true; + } } catch (e, stk) { if (_channelsController.hasValue) { _queryChannelsLoadingController.addError(e, stk); diff --git a/packages/stream_chat_flutter_core/lib/src/lazy_load_scroll_view.dart b/packages/stream_chat_flutter_core/lib/src/lazy_load_scroll_view.dart index 80afb2ea..808c1dae 100644 --- a/packages/stream_chat_flutter_core/lib/src/lazy_load_scroll_view.dart +++ b/packages/stream_chat_flutter_core/lib/src/lazy_load_scroll_view.dart @@ -47,6 +47,7 @@ class LazyLoadScrollView extends StatefulWidget { class _LazyLoadScrollViewState extends State { _LoadingStatus _loadMoreStatus = _LoadingStatus.stable; + double _scrollPosition = 0; @override Widget build(BuildContext context) => @@ -84,15 +85,21 @@ class _LazyLoadScrollViewState extends State { final extentBefore = notification.metrics.extentBefore; final extentAfter = notification.metrics.extentAfter; + final scrollingDown = _scrollPosition < pixels; - if (extentAfter <= scrollOffset) { - _onEndOfPage(); - return true; - } - if (extentBefore <= scrollOffset) { - _onStartOfPage(); - return true; + if (scrollingDown) { + if (extentAfter <= scrollOffset) { + _onEndOfPage(); + return true; + } + } else { + if (extentBefore <= scrollOffset) { + _onStartOfPage(); + return true; + } } + + _scrollPosition = pixels; } if (notification is OverscrollNotification) { if (notification.overscroll > 0) { @@ -108,8 +115,8 @@ class _LazyLoadScrollViewState extends State { void _onEndOfPage() { if (_loadMoreStatus != null && _loadMoreStatus == _LoadingStatus.stable) { - _loadMoreStatus = _LoadingStatus.loading; if (widget.onEndOfPage != null) { + _loadMoreStatus = _LoadingStatus.loading; widget.onEndOfPage().whenComplete(() { _loadMoreStatus = _LoadingStatus.stable; }); @@ -119,8 +126,8 @@ class _LazyLoadScrollViewState extends State { void _onStartOfPage() { if (_loadMoreStatus != null && _loadMoreStatus == _LoadingStatus.stable) { - _loadMoreStatus = _LoadingStatus.loading; if (widget.onStartOfPage != null) { + _loadMoreStatus = _LoadingStatus.loading; widget.onStartOfPage().whenComplete(() { _loadMoreStatus = _LoadingStatus.stable; }); diff --git a/packages/stream_chat_flutter_core/test/channel_list_core_test.dart b/packages/stream_chat_flutter_core/test/channel_list_core_test.dart index bf24e591..b0fb9ded 100644 --- a/packages/stream_chat_flutter_core/test/channel_list_core_test.dart +++ b/packages/stream_chat_flutter_core/test/channel_list_core_test.dart @@ -9,7 +9,7 @@ import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart'; import 'mocks.dart'; void main() { - const pagination = PaginationParams(offset: 0, limit: 25); + const pagination = PaginationParams(offset: 0, limit: 3); List _generateChannels( StreamChatClient client, { @@ -180,6 +180,7 @@ void main() { emptyBuilder: (BuildContext context) => Offstage(), errorBuilder: (BuildContext context, Object error) => Container(key: errorWidgetKey), + pagination: pagination, ); final mockClient = MockClient(); @@ -227,6 +228,7 @@ void main() { loadingBuilder: (BuildContext context) => Offstage(), emptyBuilder: (BuildContext context) => Container(key: emptyWidgetKey), errorBuilder: (BuildContext context, Object error) => Offstage(), + pagination: pagination, ); final mockClient = MockClient(); @@ -274,6 +276,7 @@ void main() { loadingBuilder: (BuildContext context) => Offstage(), emptyBuilder: (BuildContext context) => Offstage(), errorBuilder: (BuildContext context, Object error) => Offstage(), + pagination: pagination, ); final mockClient = MockClient(); @@ -329,6 +332,7 @@ void main() { loadingBuilder: (BuildContext context) => Offstage(), emptyBuilder: (BuildContext context) => Offstage(), errorBuilder: (BuildContext context, Object error) => Offstage(), + pagination: pagination, ); final mockClient = MockClient();