@@ -554,6 +554,7 @@ class _MessageListState extends State<MessageList> with PerAccountStoreAwareStat
554554 // redirected us to the new location of the operand message ID.
555555 widget.onNarrowChanged (model.narrow);
556556 }
557+ // TODO when model reset, reset scroll
557558 setState (() {
558559 // The actual state lives in the [MessageListView] model.
559560 // This method was called because that just changed.
@@ -638,6 +639,7 @@ class _MessageListState extends State<MessageList> with PerAccountStoreAwareStat
638639 // MessageList's dartdoc.
639640 child: SafeArea (
640641 child: ScrollToBottomButton (
642+ model: model,
641643 scrollController: scrollController,
642644 visible: _scrollToBottomVisible))),
643645 ])))));
@@ -837,13 +839,40 @@ class _MessageListLoadingMore extends StatelessWidget {
837839}
838840
839841class 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+ });
841848
842- final ValueNotifier < bool > visible ;
849+ final MessageListView model ;
843850 final MessageListScrollController scrollController;
851+ final ValueNotifier <bool > visible;
844852
845853 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+ }
847876 }
848877
849878 @override
0 commit comments