diff --git a/lib/widgets/download_service_picker.dart b/lib/widgets/download_service_picker.dart index 71295069..d1551ef2 100644 --- a/lib/widgets/download_service_picker.dart +++ b/lib/widgets/download_service_picker.dart @@ -1,7 +1,6 @@ import 'dart:async'; import 'dart:io'; import 'package:flutter/material.dart'; -import 'package:spotiflac_android/widgets/app_bottom_sheet.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:spotiflac_android/providers/extension_provider.dart'; import 'package:spotiflac_android/providers/settings_provider.dart'; @@ -13,7 +12,6 @@ class DownloadServicePicker extends ConsumerStatefulWidget { final String? coverUrl; final void Function(String quality, String service) onSelect; final String? recommendedService; - final ScrollController? scrollController; const DownloadServicePicker({ super.key, @@ -22,7 +20,6 @@ class DownloadServicePicker extends ConsumerStatefulWidget { this.coverUrl, required this.onSelect, this.recommendedService, - this.scrollController, }); @override @@ -44,15 +41,16 @@ class DownloadServicePicker extends ConsumerStatefulWidget { useRootNavigator: true, backgroundColor: colorScheme.surfaceContainerHigh, isScrollControlled: true, - builder: (context) => AppDraggableSheet( - builder: (context, scrollController) => DownloadServicePicker( - trackName: trackName, - artistName: artistName, - coverUrl: coverUrl, - onSelect: onSelect, - recommendedService: recommendedService, - scrollController: scrollController, - ), + showDragHandle: true, + constraints: BoxConstraints( + maxHeight: MediaQuery.sizeOf(context).height * 0.88, + ), + builder: (context) => DownloadServicePicker( + trackName: trackName, + artistName: artistName, + coverUrl: coverUrl, + onSelect: onSelect, + recommendedService: recommendedService, ), ); } @@ -126,7 +124,6 @@ class _DownloadServicePickerState extends ConsumerState { return SafeArea( top: false, child: SingleChildScrollView( - controller: widget.scrollController, physics: const ClampingScrollPhysics(), child: Column( mainAxisSize: MainAxisSize.min, @@ -142,8 +139,6 @@ class _DownloadServicePickerState extends ConsumerState { height: 1, color: colorScheme.outlineVariant.withValues(alpha: 0.5), ), - ] else ...[ - const AppSheetHandle(), ], Padding( @@ -513,7 +508,6 @@ class _TrackInfoHeaderState extends State<_TrackInfoHeader> { ), child: Column( children: [ - const AppSheetHandle(), Padding( padding: const EdgeInsets.fromLTRB(16, 12, 16, 12), child: Row( diff --git a/test/download_service_picker_drag_test.dart b/test/download_service_picker_drag_test.dart index fb989666..465d0ef9 100644 --- a/test/download_service_picker_drag_test.dart +++ b/test/download_service_picker_drag_test.dart @@ -8,6 +8,10 @@ import 'package:spotiflac_android/providers/settings_provider.dart'; import 'package:spotiflac_android/widgets/download_service_picker.dart'; class _Extensions extends ExtensionNotifier { + _Extensions(this.qualityCount); + + final int qualityCount; + @override ExtensionState build() => ExtensionState( extensions: [ @@ -21,7 +25,7 @@ class _Extensions extends ExtensionNotifier { status: 'loaded', hasDownloadProvider: true, qualityOptions: List.generate( - 16, + qualityCount, (index) => QualityOption(id: '$index', label: 'Quality $index'), ), ), @@ -38,48 +42,64 @@ class _Settings extends SettingsNotifier { } void main() { - testWidgets('iOS picker scrolls options and dismisses when pulled down', ( - tester, - ) async { - await tester.pumpWidget( - ProviderScope( - overrides: [ - extensionProvider.overrideWith(_Extensions.new), - settingsProvider.overrideWith(_Settings.new), - ], - child: MaterialApp( - theme: ThemeData(platform: TargetPlatform.iOS), - localizationsDelegates: AppLocalizations.localizationsDelegates, - supportedLocales: AppLocalizations.supportedLocales, - home: Scaffold( - body: Builder( - builder: (context) => TextButton( - onPressed: () => DownloadServicePicker.show( - context, - trackName: 'Example track', - onSelect: (_, _) {}, + for (final qualityCount in [3, 16]) { + testWidgets('iOS picker fits $qualityCount options and handle dismisses', ( + tester, + ) async { + await tester.pumpWidget( + ProviderScope( + overrides: [ + extensionProvider.overrideWith(() => _Extensions(qualityCount)), + settingsProvider.overrideWith(_Settings.new), + ], + child: MaterialApp( + theme: ThemeData(platform: TargetPlatform.iOS), + localizationsDelegates: AppLocalizations.localizationsDelegates, + supportedLocales: AppLocalizations.supportedLocales, + home: Scaffold( + body: Builder( + builder: (context) => TextButton( + onPressed: () => DownloadServicePicker.show( + context, + trackName: 'Example track', + onSelect: (_, _) {}, + ), + child: const Text('Open'), ), - child: const Text('Open'), ), ), ), ), - ), - ); - await tester.tap(find.text('Open')); - await tester.pumpAndSettle(); - final scroll = find.descendant( - of: find.byType(DownloadServicePicker), - matching: find.byType(SingleChildScrollView), - ); - await tester.drag(scroll, const Offset(0, -300)); - await tester.pumpAndSettle(); - expect(find.byType(DownloadServicePicker), findsOneWidget); - await tester.drag(scroll, const Offset(0, 1500)); - await tester.pumpAndSettle(); - await tester.drag(find.text('Example track'), const Offset(0, 600)); - await tester.pumpAndSettle(); - expect(find.byType(DownloadServicePicker), findsNothing); - expect(tester.takeException(), isNull); - }); + ); + await tester.tap(find.text('Open')); + await tester.pumpAndSettle(); + if (qualityCount == 3) { + final sheetBottom = tester.getBottomLeft(find.byType(BottomSheet)).dy; + final lastOptionBottom = tester + .getBottomLeft(find.text('Quality 2')) + .dy; + expect(sheetBottom - lastOptionBottom, lessThan(100)); + } + if (qualityCount == 16) { + final scroll = find.descendant( + of: find.byType(DownloadServicePicker), + matching: find.byType(SingleChildScrollView), + ); + await tester.drag(scroll, const Offset(0, -300)); + await tester.pumpAndSettle(); + expect(find.byType(DownloadServicePicker), findsOneWidget); + await tester.drag(scroll, const Offset(0, 1500)); + await tester.pumpAndSettle(); + } + final sheetTop = tester.getTopLeft(find.byType(BottomSheet)); + final sheetWidth = tester.getSize(find.byType(BottomSheet)).width; + await tester.dragFrom( + sheetTop + Offset(sheetWidth / 2, 16), + const Offset(0, 600), + ); + await tester.pumpAndSettle(); + expect(find.byType(DownloadServicePicker), findsNothing); + expect(tester.takeException(), isNull); + }); + } }