Skip to content

Commit 935a226

Browse files
committed
wip scroll: Go to end at first, and stay at end once there; TODO split?; TODO test
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 f75133c commit 935a226

File tree

1 file changed

+34
-0
lines changed

1 file changed

+34
-0
lines changed

lib/widgets/scrolling.dart

Lines changed: 34 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,39 @@ 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 (!super.applyContentDimensions(minScrollExtent, maxScrollExtent)) {
328+
changed = true;
329+
}
330+
331+
if (initial) {
332+
// The list is being laid out for the first time.
333+
// Start out scrolled to the end.
334+
// TODO what if the next _attemptLayout iteration finds more items below
335+
// and makes maxScrollExtent bigger?
336+
correctPixels(this.maxScrollExtent);
337+
changed = true;
338+
} else if (wasAtEnd && !_isAtEnd) {
339+
// The list was scrolled to the end before this layout round.
340+
// Make sure it stays at the end.
341+
// (For example, show the new message that just arrived.)
342+
correctPixels(this.maxScrollExtent);
343+
changed = true;
344+
}
345+
346+
return !changed;
347+
}
314348
}
315349

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

0 commit comments

Comments
 (0)