mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-09-29 12:52:13 +02:00
fix(library): keep album batch actions alive after selection closes
Use the album screen context for ReplayGain and conversion so dismissing the selection overlay does not invalidate the pending operation. Cover local and downloaded albums in both themes.
This commit is contained in:
@@ -738,7 +738,7 @@ class _DownloadedAlbumScreenState extends ConsumerState<DownloadedAlbumScreen>
|
||||
label: context.l10n.selectionConvertCount(selectedCount),
|
||||
onPressed: selectedCount > 0
|
||||
? () => showBatchConvertSheet(
|
||||
context,
|
||||
this.context,
|
||||
ref,
|
||||
_selectedUnifiedItems(tracks),
|
||||
onExitSelectionMode: exitSelectionMode,
|
||||
@@ -751,7 +751,7 @@ class _DownloadedAlbumScreenState extends ConsumerState<DownloadedAlbumScreen>
|
||||
label: context.l10n.selectionReplayGainCount(selectedCount),
|
||||
onPressed: selectedCount > 0
|
||||
? () => runBatchReplayGain(
|
||||
context,
|
||||
this.context,
|
||||
_selectedUnifiedItems(tracks),
|
||||
onExitSelectionMode: exitSelectionMode,
|
||||
)
|
||||
|
||||
@@ -547,7 +547,7 @@ class _LocalAlbumScreenState extends ConsumerState<LocalAlbumScreen>
|
||||
label: context.l10n.selectionConvertCount(selectedCount),
|
||||
onPressed: selectedCount > 0
|
||||
? () => showBatchConvertSheet(
|
||||
context,
|
||||
this.context,
|
||||
ref,
|
||||
_selectedUnifiedItems(tracks),
|
||||
onExitSelectionMode: exitSelectionMode,
|
||||
@@ -563,7 +563,7 @@ class _LocalAlbumScreenState extends ConsumerState<LocalAlbumScreen>
|
||||
label: context.l10n.selectionReplayGainCount(selectedCount),
|
||||
onPressed: selectedCount > 0
|
||||
? () => runBatchReplayGain(
|
||||
context,
|
||||
this.context,
|
||||
_selectedUnifiedItems(tracks),
|
||||
onExitSelectionMode: exitSelectionMode,
|
||||
)
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:spotiflac_android/l10n/l10n.dart';
|
||||
import 'package:spotiflac_android/providers/download_history_provider.dart';
|
||||
import 'package:spotiflac_android/screens/downloaded_album_screen.dart';
|
||||
import 'package:spotiflac_android/screens/local_album_screen.dart';
|
||||
import 'package:spotiflac_android/services/library_database.dart';
|
||||
import 'package:spotiflac_android/theme/app_theme.dart';
|
||||
import 'package:spotiflac_android/theme/mornye_theme.dart';
|
||||
import 'package:spotiflac_android/widgets/app_alert_dialog.dart';
|
||||
import 'package:spotiflac_android/widgets/selection_bottom_bar.dart';
|
||||
|
||||
void main() {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
const channel = MethodChannel('com.zarz.spotiflac/backend');
|
||||
final messenger =
|
||||
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger;
|
||||
|
||||
for (final mornye in [false, true]) {
|
||||
for (final downloaded in [false, true]) {
|
||||
testWidgets(
|
||||
'ReplayGain survives hiding the album selection (Mornye: $mornye, downloaded: $downloaded)',
|
||||
(tester) async {
|
||||
SharedPreferences.setMockInitialValues({});
|
||||
var attempts = 0;
|
||||
messenger.setMockMethodCallHandler(channel, (call) async {
|
||||
if (call.method == 'safCopyToTemp') attempts++;
|
||||
// Simulate an inaccessible file. Reaching this call and showing
|
||||
// the result proves confirmation actually starts the operation.
|
||||
return null;
|
||||
});
|
||||
addTearDown(() => messenger.setMockMethodCallHandler(channel, null));
|
||||
const path = 'content://library/document/track.flac';
|
||||
final item = DownloadHistoryItem(
|
||||
id: 'track',
|
||||
trackName: 'Track',
|
||||
artistName: 'Artist',
|
||||
albumName: 'Album',
|
||||
filePath: path,
|
||||
service: 'provider-a',
|
||||
downloadedAt: DateTime(2026),
|
||||
);
|
||||
await tester.pumpWidget(
|
||||
ProviderScope(
|
||||
overrides: [
|
||||
downloadedAlbumTracksProvider(
|
||||
const DownloadedAlbumTracksRequest(
|
||||
albumName: 'Album',
|
||||
artistName: 'Artist',
|
||||
),
|
||||
).overrideWith((ref) async => [item]),
|
||||
],
|
||||
child: MaterialApp(
|
||||
theme: mornye
|
||||
? MornyeTheme.build(Brightness.light)
|
||||
: AppTheme.light(),
|
||||
localizationsDelegates: AppLocalizations.localizationsDelegates,
|
||||
supportedLocales: AppLocalizations.supportedLocales,
|
||||
home: SelectionOverlayHost(
|
||||
child: downloaded
|
||||
? const DownloadedAlbumScreen(
|
||||
albumName: 'Album',
|
||||
artistName: 'Artist',
|
||||
)
|
||||
: LocalAlbumScreen(
|
||||
albumName: 'Album',
|
||||
artistName: 'Artist',
|
||||
tracks: [
|
||||
LocalLibraryItem(
|
||||
id: 'track',
|
||||
trackName: 'Track',
|
||||
artistName: 'Artist',
|
||||
albumName: 'Album',
|
||||
filePath: path,
|
||||
scannedAt: DateTime(2026),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
await tester.scrollUntilVisible(find.text('Track'), 200);
|
||||
await tester.longPress(find.text('Track'));
|
||||
await tester.pumpAndSettle();
|
||||
final l10n = AppLocalizations.of(
|
||||
tester.element(find.byType(SelectionBottomBar)),
|
||||
);
|
||||
Future<void> openConfirmation() async {
|
||||
await tester.tap(find.text(l10n.selectionReplayGainCount(1)));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.byType(SelectionBottomBar), findsNothing);
|
||||
expect(find.byType(AppAlertDialog), findsOneWidget);
|
||||
}
|
||||
|
||||
await openConfirmation();
|
||||
await tester.tap(find.text(l10n.dialogCancel));
|
||||
await tester.pumpAndSettle();
|
||||
expect(attempts, 0);
|
||||
expect(find.byType(SelectionBottomBar), findsOneWidget);
|
||||
|
||||
await openConfirmation();
|
||||
await tester.tap(
|
||||
find.descendant(
|
||||
of: find.byType(AppDialogAction),
|
||||
matching: find.text(l10n.replayGainBatchConfirmTitle),
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
expect(attempts, 1);
|
||||
expect(find.text(l10n.replayGainBatchSuccess(0, 1)), findsOneWidget);
|
||||
expect(find.byType(SelectionBottomBar), findsNothing);
|
||||
expect(tester.takeException(), isNull);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user