Skip to content

Commit f75133c

Browse files
committed
wip scroll: Keep short threads pinned at bottom, not past bottom; TODO test
This is NFC as to the real message list, because so far the bottom sliver there always has height 0. This is a step toward letting us move part of the message list into the bottom sliver, because it fixes a bug that would otherwise create in the case of a thread that fits entirely on the screen.
1 parent 97db5d6 commit f75133c

File tree

1 file changed

+35
-2
lines changed

1 file changed

+35
-2
lines changed

lib/widgets/scrolling.dart

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -273,9 +273,42 @@ class MessageListScrollPosition extends ScrollPositionWithSingleContext {
273273
/// 0.0 and 60.0, or -10.0 and 10.0, or -40.0 and 0.0, or other values,
274274
/// depending on the value of [Viewport.anchor].
275275
bool applyContentDimensionsRaw(double wholeMinScrollExtent, double wholeMaxScrollExtent) {
276-
// This makes the simplifying assumption that `anchor` is 1.0.
277-
final effectiveMin = math.min(0.0, wholeMinScrollExtent + viewportDimension);
276+
// The origin point of these scroll coordinates, scroll extent 0.0,
277+
// is that the boundary between slivers is the bottom edge of the viewport.
278+
// (That's expressed by setting `anchor` to 1.0, consulted in
279+
// `_attemptLayout` below.)
280+
281+
// The farthest the list can scroll down (moving the content up)
282+
// is to the point where the bottom end of the list
283+
// touches the bottom edge of the viewport.
278284
final effectiveMax = wholeMaxScrollExtent;
285+
286+
// The farthest the list can scroll up (moving the content down)
287+
// is either:
288+
// * the same as the farthest it can scroll down,
289+
// * or the point where the top end of the list
290+
// touches the top edge of the viewport,
291+
// whichever is farther up.
292+
final effectiveMin = math.min(effectiveMax,
293+
wholeMinScrollExtent + viewportDimension);
294+
295+
// The first point comes into effect when the list is short,
296+
// so the whole thing fits into the viewport. In that case,
297+
// the only scroll position allowed is with the bottom end of the list
298+
// at the bottom edge of the viewport.
299+
300+
// The upstream answer (with no `applyContentDimensionsRaw`) would
301+
// effectively say:
302+
// final effectiveMin = math.min(0.0,
303+
// wholeMinScrollExtent + viewportDimension);
304+
//
305+
// In other words, the farthest the list can scroll up might be farther up
306+
// than the answer here: it could always scroll up to 0.0, meaning that the
307+
// boundary between slivers is at the bottom edge of the viewport.
308+
// Whenever the top sliver is shorter than the viewport (and the bottom
309+
// sliver isn't empty), this would mean one can scroll up past
310+
// the top of the list, even though that scrolls other content offscreen.
311+
279312
return applyContentDimensions(effectiveMin, effectiveMax);
280313
}
281314
}

0 commit comments

Comments
 (0)