fix: guard scroll operations against infinite extents

This commit is contained in:
edde746
2026-03-28 13:51:39 +01:00
parent 46ebda944a
commit 53d50dbc3b
3 changed files with 16 additions and 3 deletions
+1
View File
@@ -306,6 +306,7 @@ class _FocusableWrapperState extends State<FocusableWrapper> with SingleTickerPr
scrollDelta -= (_focusDecorationPadding - projectedItemTop);
}
if (!position.maxScrollExtent.isFinite) return;
final targetOffset = (currentOffset + scrollDelta).clamp(position.minScrollExtent, position.maxScrollExtent);
position.animateTo(targetOffset, duration: const Duration(milliseconds: 200), curve: Curves.easeInOut);
@@ -998,7 +998,12 @@ class _LibraryBrowseTabState extends BaseLibraryTabState<PlexMetadata, LibraryBr
final offset = _effectiveTopPadding + targetRow * rowHeight - _chipsBarHeight;
final gen = _jumpScrollGeneration;
final clampedOffset = offset.clamp(0.0, _scrollController.position.maxScrollExtent);
final maxExtent = _scrollController.position.maxScrollExtent;
if (!maxExtent.isFinite) {
_isJumpScrolling = false;
return;
}
final clampedOffset = offset.clamp(0.0, maxExtent);
// If a newer jump already superseded this one, skip the animation
// entirely — the next call will handle the final position.
@@ -1130,6 +1135,7 @@ class _LibraryBrowseTabState extends BaseLibraryTabState<PlexMetadata, LibraryBr
final offset = _scrollController.offset;
final viewportHeight = _scrollController.position.viewportDimension;
if (!viewportHeight.isFinite) return;
final firstIndex = _itemIndexFromScrollOffset(offset);
final itemWidth = _lastCrossAxisExtent / _currentColumnCount;
@@ -1179,6 +1185,7 @@ class _LibraryBrowseTabState extends BaseLibraryTabState<PlexMetadata, LibraryBr
final offset = _scrollController.offset;
final viewportHeight = _scrollController.position.viewportDimension;
if (!viewportHeight.isFinite) return;
final firstIndex = _itemIndexFromScrollOffset(offset);
final itemWidth = _lastCrossAxisExtent / _currentColumnCount;
@@ -1254,6 +1261,7 @@ class _LibraryBrowseTabState extends BaseLibraryTabState<PlexMetadata, LibraryBr
final offset = _scrollController.offset;
final viewportHeight = _scrollController.position.viewportDimension;
if (!viewportHeight.isFinite) return;
final firstVisible = _itemIndexFromScrollOffset(offset);
final itemWidth = _lastCrossAxisExtent / _currentColumnCount;
final itemHeight = itemWidth / GridLayoutConstants.posterAspectRatio;
+6 -2
View File
@@ -23,7 +23,9 @@ void scrollToCurrentItem(ScrollController controller, GlobalKey firstItemKey, in
if (!controller.hasClients) return;
final itemHeight = (firstItemKey.currentContext?.findRenderObject() as RenderBox?)?.size.height;
if (itemHeight == null) return;
final target = (currentIndex * itemHeight).clamp(0.0, controller.position.maxScrollExtent);
final maxExtent = controller.position.maxScrollExtent;
if (!maxExtent.isFinite) return;
final target = (currentIndex * itemHeight).clamp(0.0, maxExtent);
controller.jumpTo(target);
});
}
@@ -42,8 +44,10 @@ void scrollListToIndex(
if (controller.positions.length != 1 || itemExtent <= 0) return;
final viewport = controller.position.viewportDimension;
final maxExtent = controller.position.maxScrollExtent;
if (!viewport.isFinite || !maxExtent.isFinite) return;
final targetCenter = leadingPadding + (index * itemExtent) + (itemExtent / 2);
final desiredOffset = (targetCenter - (viewport / 2)).clamp(0.0, controller.position.maxScrollExtent);
final desiredOffset = (targetCenter - (viewport / 2)).clamp(0.0, maxExtent);
if (animate) {
controller.animateTo(desiredOffset, duration: const Duration(milliseconds: 150), curve: Curves.easeOut);