fix(ui): refactor scroll to bottom button

This commit is contained in:
Salvatore Giordano
2021-10-25 16:18:58 +02:00
parent 1806b3a6bd
commit 1bcf9a515f
@@ -145,7 +145,7 @@ class MessageListView extends StatefulWidget {
this.threadBuilder, this.threadBuilder,
this.onThreadTap, this.onThreadTap,
this.dateDividerBuilder, this.dateDividerBuilder,
this.scrollPhysics = const ClampingScrollPhysics(), this.scrollPhysics,
this.initialScrollIndex, this.initialScrollIndex,
this.initialAlignment, this.initialAlignment,
this.scrollController, this.scrollController,
@@ -225,7 +225,7 @@ class MessageListView extends StatefulWidget {
final ItemPositionsListener? itemPositionListener; final ItemPositionsListener? itemPositionListener;
/// The ScrollPhysics used by the ListView /// The ScrollPhysics used by the ListView
final ScrollPhysics scrollPhysics; final ScrollPhysics? scrollPhysics;
/// Called when message item gets swiped /// Called when message item gets swiped
final OnMessageSwiped? onMessageSwiped; final OnMessageSwiped? onMessageSwiped;
@@ -296,7 +296,7 @@ class MessageListView extends StatefulWidget {
class _MessageListViewState extends State<MessageListView> { class _MessageListViewState extends State<MessageListView> {
ItemScrollController? _scrollController; ItemScrollController? _scrollController;
void Function(Message)? _onThreadTap; void Function(Message)? _onThreadTap;
bool _showScrollToBottom = false; final ValueNotifier<bool> _showScrollToBottom = ValueNotifier(false);
late final ItemPositionsListener _itemPositionListener; late final ItemPositionsListener _itemPositionListener;
int? _messageListLength; int? _messageListLength;
StreamChannelState? streamChannel; StreamChannelState? streamChannel;
@@ -334,7 +334,6 @@ class _MessageListViewState extends State<MessageListView> {
bool get _isThreadConversation => widget.parentMessage != null; bool get _isThreadConversation => widget.parentMessage != null;
bool _topPaginationActive = false;
bool _bottomPaginationActive = false; bool _bottomPaginationActive = false;
int initialIndex = 0; int initialIndex = 0;
@@ -404,10 +403,6 @@ class _MessageListViewState extends State<MessageListView> {
initialAlignment = first.itemLeadingEdge; initialAlignment = first.itemLeadingEdge;
} }
} }
} else if (!_topPaginationActive && _upToDate) {
// Reset the index in-case we send any new message
initialIndex = 0;
initialAlignment = 0;
} }
} }
@@ -451,7 +446,6 @@ class _MessageListViewState extends State<MessageListView> {
onStartOfPage: () async { onStartOfPage: () async {
_inBetweenList = false; _inBetweenList = false;
if (!_upToDate) { if (!_upToDate) {
_topPaginationActive = false;
_bottomPaginationActive = true; _bottomPaginationActive = true;
return _paginateData( return _paginateData(
streamChannel, streamChannel,
@@ -461,7 +455,6 @@ class _MessageListViewState extends State<MessageListView> {
}, },
onEndOfPage: () async { onEndOfPage: () async {
_inBetweenList = false; _inBetweenList = false;
_topPaginationActive = true;
_bottomPaginationActive = false; _bottomPaginationActive = false;
return _paginateData( return _paginateData(
streamChannel, streamChannel,
@@ -650,7 +643,16 @@ class _MessageListViewState extends State<MessageListView> {
); );
}, },
), ),
if (widget.showScrollToBottom) _buildScrollToBottom(), ValueListenableBuilder<bool>(
valueListenable: _showScrollToBottom,
child: _buildScrollToBottom(),
builder: (context, value, child) {
if (!streamChannel!.channel.state!.isUpToDate || value) {
return child!;
}
return const Offstage();
},
),
if (widget.showFloatingDateDivider) if (widget.showFloatingDateDivider)
_buildFloatingDateDivider(itemCount), _buildFloatingDateDivider(itemCount),
], ],
@@ -770,24 +772,15 @@ class _MessageListViewState extends State<MessageListView> {
.index; .index;
} }
Widget _buildScrollToBottom() => StreamBuilder<Tuple2<bool, int>>( Widget _buildScrollToBottom() => StreamBuilder<int>(
stream: Rx.combineLatest2( stream: streamChannel!.channel.state!.unreadCountStream,
streamChannel!.channel.state!.isUpToDateStream.distinct(),
streamChannel!.channel.state!.unreadCountStream.distinct(),
(bool isUpToDate, int unreadCount) => Tuple2(isUpToDate, unreadCount),
),
builder: (_, snapshot) { builder: (_, snapshot) {
if (snapshot.hasError) { if (snapshot.hasError) {
return const Offstage(); return const Offstage();
} else if (!snapshot.hasData) { } else if (!snapshot.hasData) {
return const Offstage(); return const Offstage();
} }
final isUpToDate = snapshot.data!.item1; final unreadCount = snapshot.data!;
final showScrollToBottom = !isUpToDate || _showScrollToBottom;
if (!showScrollToBottom) {
return const Offstage();
}
final unreadCount = snapshot.data!.item2;
final showUnreadCount = unreadCount > 0 && final showUnreadCount = unreadCount > 0 &&
streamChannel!.channel.state!.members.any((e) => streamChannel!.channel.state!.members.any((e) =>
e.userId == e.userId ==
@@ -808,10 +801,9 @@ class _MessageListViewState extends State<MessageListView> {
} }
if (!_upToDate) { if (!_upToDate) {
_bottomPaginationActive = false; _bottomPaginationActive = false;
_topPaginationActive = false;
streamChannel!.reloadChannel(); streamChannel!.reloadChannel();
} else { } else {
setState(() => _showScrollToBottom = false); _showScrollToBottom.value = false;
_scrollController!.scrollTo( _scrollController!.scrollTo(
index: 0, index: 0,
duration: const Duration(seconds: 1), duration: const Duration(seconds: 1),
@@ -886,8 +878,8 @@ class _MessageListViewState extends State<MessageListView> {
} }
} }
if (mounted) { if (mounted) {
if (_showScrollToBottom == isVisible) { if (_showScrollToBottom.value == isVisible) {
setState(() => _showScrollToBottom = !isVisible); _showScrollToBottom.value = !isVisible;
} }
} }
}, },
@@ -1252,7 +1244,6 @@ class _MessageListViewState extends State<MessageListView> {
streamChannel!.channel.on(EventType.messageNew).listen((event) { streamChannel!.channel.on(EventType.messageNew).listen((event) {
if (_upToDate) { if (_upToDate) {
_bottomPaginationActive = false; _bottomPaginationActive = false;
_topPaginationActive = false;
} }
if (event.message?.parentId == widget.parentMessage?.id && if (event.message?.parentId == widget.parentMessage?.id &&
event.message!.user!.id == event.message!.user!.id ==