From e559a6125d21ecbf2bc63cf8f21d7636e265af06 Mon Sep 17 00:00:00 2001 From: edde746 <86283021+edde746@users.noreply.github.com> Date: Thu, 28 May 2026 00:29:13 +0200 Subject: [PATCH] fix(detail): isolate overlay sheet scrolling --- lib/screens/media_detail_screen.dart | 4 ++- lib/widgets/overlay_sheet.dart | 2 ++ test/widgets/overlay_sheet_test.dart | 54 ++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 test/widgets/overlay_sheet_test.dart diff --git a/lib/screens/media_detail_screen.dart b/lib/screens/media_detail_screen.dart index 22c75eef..3a4bff91 100644 --- a/lib/screens/media_detail_screen.dart +++ b/lib/screens/media_detail_screen.dart @@ -704,7 +704,9 @@ class _MediaDetailScreenState extends State } void _onScroll() { - _scrollOffset.value = _scrollController.offset; + final positions = _scrollController.positions; + if (positions.length != 1) return; + _scrollOffset.value = positions.first.pixels; } @override diff --git a/lib/widgets/overlay_sheet.dart b/lib/widgets/overlay_sheet.dart index 164dce5d..bb68a491 100644 --- a/lib/widgets/overlay_sheet.dart +++ b/lib/widgets/overlay_sheet.dart @@ -546,6 +546,8 @@ class _OverlaySheetHostState extends State with SingleTickerPr final colorScheme = Theme.of(context).colorScheme; Widget content = _pageStack.isNotEmpty ? Builder(builder: _pageStack.last.builder) : const SizedBox.shrink(); + // Keep sheet scrollables from attaching to the route's primary controller. + content = PrimaryScrollController.none(child: content); // Wrap content in NotificationListener for scroll-aware drag-to-dismiss if (showHandle) { diff --git a/test/widgets/overlay_sheet_test.dart b/test/widgets/overlay_sheet_test.dart new file mode 100644 index 00000000..62b450e0 --- /dev/null +++ b/test/widgets/overlay_sheet_test.dart @@ -0,0 +1,54 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:plezy/widgets/overlay_sheet.dart'; + +void main() { + testWidgets('scrollable sheet does not attach to parent primary controller', (tester) async { + final parentController = ScrollController(); + addTearDown(parentController.dispose); + + await tester.pumpWidget( + MaterialApp( + theme: ThemeData(platform: TargetPlatform.android), + home: PrimaryScrollController( + controller: parentController, + child: OverlaySheetHost( + child: Scaffold( + body: CustomScrollView( + primary: true, + slivers: [ + SliverFillRemaining( + child: Center( + child: Builder( + builder: (context) => ElevatedButton( + onPressed: () { + OverlaySheetController.of(context).show( + builder: (_) => ListView.builder( + itemCount: 30, + itemBuilder: (_, index) => ListTile(title: Text('Item $index')), + ), + ); + }, + child: const Text('Open'), + ), + ), + ), + ), + ], + ), + ), + ), + ), + ), + ); + + expect(parentController.positions.length, 1); + + await tester.tap(find.text('Open')); + await tester.pumpAndSettle(); + + expect(tester.takeException(), isNull); + expect(parentController.positions.length, 1); + expect(find.text('Item 0'), findsOneWidget); + }); +}