fix: guard scroll operations against infinite extents
This commit is contained in:
@@ -306,6 +306,7 @@ class _FocusableWrapperState extends State<FocusableWrapper> with SingleTickerPr
|
|||||||
scrollDelta -= (_focusDecorationPadding - projectedItemTop);
|
scrollDelta -= (_focusDecorationPadding - projectedItemTop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!position.maxScrollExtent.isFinite) return;
|
||||||
final targetOffset = (currentOffset + scrollDelta).clamp(position.minScrollExtent, position.maxScrollExtent);
|
final targetOffset = (currentOffset + scrollDelta).clamp(position.minScrollExtent, position.maxScrollExtent);
|
||||||
|
|
||||||
position.animateTo(targetOffset, duration: const Duration(milliseconds: 200), curve: Curves.easeInOut);
|
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 offset = _effectiveTopPadding + targetRow * rowHeight - _chipsBarHeight;
|
||||||
|
|
||||||
final gen = _jumpScrollGeneration;
|
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
|
// If a newer jump already superseded this one, skip the animation
|
||||||
// entirely — the next call will handle the final position.
|
// entirely — the next call will handle the final position.
|
||||||
@@ -1130,6 +1135,7 @@ class _LibraryBrowseTabState extends BaseLibraryTabState<PlexMetadata, LibraryBr
|
|||||||
|
|
||||||
final offset = _scrollController.offset;
|
final offset = _scrollController.offset;
|
||||||
final viewportHeight = _scrollController.position.viewportDimension;
|
final viewportHeight = _scrollController.position.viewportDimension;
|
||||||
|
if (!viewportHeight.isFinite) return;
|
||||||
final firstIndex = _itemIndexFromScrollOffset(offset);
|
final firstIndex = _itemIndexFromScrollOffset(offset);
|
||||||
|
|
||||||
final itemWidth = _lastCrossAxisExtent / _currentColumnCount;
|
final itemWidth = _lastCrossAxisExtent / _currentColumnCount;
|
||||||
@@ -1179,6 +1185,7 @@ class _LibraryBrowseTabState extends BaseLibraryTabState<PlexMetadata, LibraryBr
|
|||||||
|
|
||||||
final offset = _scrollController.offset;
|
final offset = _scrollController.offset;
|
||||||
final viewportHeight = _scrollController.position.viewportDimension;
|
final viewportHeight = _scrollController.position.viewportDimension;
|
||||||
|
if (!viewportHeight.isFinite) return;
|
||||||
final firstIndex = _itemIndexFromScrollOffset(offset);
|
final firstIndex = _itemIndexFromScrollOffset(offset);
|
||||||
|
|
||||||
final itemWidth = _lastCrossAxisExtent / _currentColumnCount;
|
final itemWidth = _lastCrossAxisExtent / _currentColumnCount;
|
||||||
@@ -1254,6 +1261,7 @@ class _LibraryBrowseTabState extends BaseLibraryTabState<PlexMetadata, LibraryBr
|
|||||||
|
|
||||||
final offset = _scrollController.offset;
|
final offset = _scrollController.offset;
|
||||||
final viewportHeight = _scrollController.position.viewportDimension;
|
final viewportHeight = _scrollController.position.viewportDimension;
|
||||||
|
if (!viewportHeight.isFinite) return;
|
||||||
final firstVisible = _itemIndexFromScrollOffset(offset);
|
final firstVisible = _itemIndexFromScrollOffset(offset);
|
||||||
final itemWidth = _lastCrossAxisExtent / _currentColumnCount;
|
final itemWidth = _lastCrossAxisExtent / _currentColumnCount;
|
||||||
final itemHeight = itemWidth / GridLayoutConstants.posterAspectRatio;
|
final itemHeight = itemWidth / GridLayoutConstants.posterAspectRatio;
|
||||||
|
|||||||
@@ -23,7 +23,9 @@ void scrollToCurrentItem(ScrollController controller, GlobalKey firstItemKey, in
|
|||||||
if (!controller.hasClients) return;
|
if (!controller.hasClients) return;
|
||||||
final itemHeight = (firstItemKey.currentContext?.findRenderObject() as RenderBox?)?.size.height;
|
final itemHeight = (firstItemKey.currentContext?.findRenderObject() as RenderBox?)?.size.height;
|
||||||
if (itemHeight == null) return;
|
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);
|
controller.jumpTo(target);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -42,8 +44,10 @@ void scrollListToIndex(
|
|||||||
if (controller.positions.length != 1 || itemExtent <= 0) return;
|
if (controller.positions.length != 1 || itemExtent <= 0) return;
|
||||||
|
|
||||||
final viewport = controller.position.viewportDimension;
|
final viewport = controller.position.viewportDimension;
|
||||||
|
final maxExtent = controller.position.maxScrollExtent;
|
||||||
|
if (!viewport.isFinite || !maxExtent.isFinite) return;
|
||||||
final targetCenter = leadingPadding + (index * itemExtent) + (itemExtent / 2);
|
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) {
|
if (animate) {
|
||||||
controller.animateTo(desiredOffset, duration: const Duration(milliseconds: 150), curve: Curves.easeOut);
|
controller.animateTo(desiredOffset, duration: const Duration(milliseconds: 150), curve: Curves.easeOut);
|
||||||
|
|||||||
Reference in New Issue
Block a user