Skip to content

Commit f31641f

Browse files
committed
wip scroll: Go to end at first, and stay at end once there; TODO split?; TODO test
TODO should wasAtEnd case move before super too? TODO test, inter alia: adjust before super (avoids BallisticScrollActivity) This is NFC as to the real message list, because so far the bottom sliver there always has height 0, so that maxScrollExtent is always 0. This is a step toward letting us move part of the message list into the bottom sliver, because it means that doing so would preserve the list's current behavior of starting out scrolled to the end, and its current behavior of remaining scrolled to the end once there as e.g. new messages arrive.
1 parent ddafece commit f31641f

File tree

1 file changed

+36
-0
lines changed

1 file changed

+36
-0
lines changed

lib/widgets/scrolling.dart

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import 'dart:math' as math;
22

33
import 'package:flutter/foundation.dart';
44
import 'package:flutter/material.dart';
5+
import 'package:flutter/physics.dart';
56
import 'package:flutter/rendering.dart';
67

78
/// A [SingleChildScrollView] that always shows a Material [Scrollbar].
@@ -311,6 +312,41 @@ class MessageListScrollPosition extends ScrollPositionWithSingleContext {
311312

312313
return applyContentDimensions(effectiveMin, effectiveMax);
313314
}
315+
316+
bool get _isAtEnd => nearEqual(pixels, maxScrollExtent,
317+
Tolerance.defaultTolerance.distance);
318+
319+
@override
320+
bool applyContentDimensions(double minScrollExtent, double maxScrollExtent) {
321+
// Inspired by _TabBarScrollPosition.applyContentDimensions upstream.
322+
bool changed = false;
323+
324+
final initial = !hasContentDimensions;
325+
final wasAtEnd = hasContentDimensions && _isAtEnd;
326+
327+
if (initial) {
328+
// The list is being laid out for the first time.
329+
// Start out scrolled to the end.
330+
// TODO what if the next _attemptLayout iteration finds more items below
331+
// and makes maxScrollExtent bigger?
332+
correctPixels(maxScrollExtent);
333+
changed = true;
334+
}
335+
336+
if (!super.applyContentDimensions(minScrollExtent, maxScrollExtent)) {
337+
changed = true;
338+
}
339+
340+
if (wasAtEnd && !_isAtEnd) {
341+
// The list was scrolled to the end before this layout round.
342+
// Make sure it stays at the end.
343+
// (For example, show the new message that just arrived.)
344+
correctPixels(this.maxScrollExtent);
345+
changed = true;
346+
}
347+
348+
return !changed;
349+
}
314350
}
315351

316352
/// A version of [ScrollController] adapted for the Zulip message list.

0 commit comments

Comments
 (0)