@@ -554,6 +554,7 @@ class _MessageListState extends State<MessageList> with PerAccountStoreAwareStat
554
554
// redirected us to the new location of the operand message ID.
555
555
widget.onNarrowChanged (model.narrow);
556
556
}
557
+ // TODO when model reset, reset scroll
557
558
setState (() {
558
559
// The actual state lives in the [MessageListView] model.
559
560
// This method was called because that just changed.
@@ -638,6 +639,7 @@ class _MessageListState extends State<MessageList> with PerAccountStoreAwareStat
638
639
// MessageList's dartdoc.
639
640
child: SafeArea (
640
641
child: ScrollToBottomButton (
642
+ model: model,
641
643
scrollController: scrollController,
642
644
visible: _scrollToBottomVisible))),
643
645
])))));
@@ -837,13 +839,40 @@ class _MessageListLoadingMore extends StatelessWidget {
837
839
}
838
840
839
841
class ScrollToBottomButton extends StatelessWidget {
840
- const ScrollToBottomButton ({super .key, required this .scrollController, required this .visible});
842
+ const ScrollToBottomButton ({
843
+ super .key,
844
+ required this .model,
845
+ required this .scrollController,
846
+ required this .visible,
847
+ });
841
848
842
- final ValueNotifier < bool > visible ;
849
+ final MessageListView model ;
843
850
final MessageListScrollController scrollController;
851
+ final ValueNotifier <bool > visible;
844
852
845
853
void _scrollToBottom () {
846
- scrollController.position.scrollToEnd ();
854
+ if (model.haveNewest) {
855
+ // Scrolling smoothly from here to the bottom won't require any requests
856
+ // to the server.
857
+ // It also probably isn't *that* far away: the user must have scrolled
858
+ // here from there (or from near enough that a fetch reached there),
859
+ // so scrolling back there -- at top speed -- shouldn't take too long.
860
+ // Go for it.
861
+ scrollController.position.scrollToEnd ();
862
+ } else {
863
+ // This message list doesn't have the messages for the bottom of history.
864
+ // There could be quite a lot of history between here and there --
865
+ // for example, at first unread in the combined feed or a busy channel,
866
+ // for a user who has some old unreads going back months and years.
867
+ // In that case trying to scroll smoothly to the bottom is hopeless.
868
+ //
869
+ // Given that there were at least 100 messages between this message list's
870
+ // initial anchor and the end of history (or else `fetchInitial` would
871
+ // have reached the end at the outset), that situation is very likely.
872
+ // Even if the end is close by, it's at least one fetch away.
873
+ // Instead of scrolling, jump to the end, which is always just one fetch.
874
+ model.jumpToEnd ();
875
+ }
847
876
}
848
877
849
878
@override
0 commit comments