diff --git a/lib/screens/local_album_screen.dart b/lib/screens/local_album_screen.dart index 27200391..e35bf843 100644 --- a/lib/screens/local_album_screen.dart +++ b/lib/screens/local_album_screen.dart @@ -23,6 +23,7 @@ import 'package:spotiflac_android/providers/music_player_provider.dart'; import 'package:spotiflac_android/providers/player_motion_artwork_provider.dart'; import 'package:spotiflac_android/screens/collapsing_header_scroll_mixin.dart'; import 'package:spotiflac_android/screens/selection_mode_mixin.dart'; +import 'package:spotiflac_android/screens/track_metadata_screen.dart'; import 'package:spotiflac_android/widgets/collection_scaffold.dart'; import 'package:spotiflac_android/widgets/album_track_tile.dart'; import 'package:spotiflac_android/widgets/animation_utils.dart'; @@ -159,6 +160,19 @@ class _LocalAlbumScreenState extends ConsumerState } } + Future _openMetadata(LocalLibraryItem track) async { + final tracks = _sortedTracksCache; + await Navigator.of(context).push( + slidePageRoute( + page: TrackMetadataScreen( + localItem: track, + localNavigationItems: tracks, + navigationIndex: tracks.indexWhere((item) => item.id == track.id), + ), + ), + ); + } + @override Widget build(BuildContext context) { if (context.isMornye) { @@ -442,7 +456,7 @@ class _LocalAlbumScreenState extends ConsumerState isSelected: selectedIds.contains(track.id), colorScheme: colorScheme, onToggleSelection: () => toggleSelection(track.id), - onOpen: () => _openFile(track), + onOpen: () => _openMetadata(track), onEnterSelectionMode: () => enterSelectionMode(track.id), onPlay: () => _openFile(track), ); diff --git a/test/local_album_metadata_navigation_test.dart b/test/local_album_metadata_navigation_test.dart new file mode 100644 index 00000000..776c5974 --- /dev/null +++ b/test/local_album_metadata_navigation_test.dart @@ -0,0 +1,95 @@ +import 'package:flutter/material.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/playback_provider.dart'; +import 'package:spotiflac_android/screens/local_album_screen.dart'; +import 'package:spotiflac_android/screens/track_metadata_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/album_track_tile.dart'; + +class _Playback extends PlaybackController { + final played = []; + + @override + Future playLocalLibraryQueue( + List items, { + required LocalLibraryItem startItem, + }) async { + played.add(startItem.id); + } +} + +void main() { + for (final mornye in [false, true]) { + testWidgets('album row opens metadata, Play plays ($mornye)', ( + tester, + ) async { + SharedPreferences.setMockInitialValues({}); + tester.view.physicalSize = const Size(430, 1200); + tester.view.devicePixelRatio = 1; + addTearDown(tester.view.reset); + final playback = _Playback(); + final navigator = GlobalKey(); + final tracks = [ + for (final number in [2, 1]) + LocalLibraryItem( + id: '$number', + trackName: 'Song $number', + artistName: 'Artist', + albumName: 'Album', + filePath: '/missing/song-$number.flac', + trackNumber: number, + scannedAt: DateTime(2026), + ), + ]; + await tester.pumpWidget( + ProviderScope( + overrides: [playbackProvider.overrideWith(() => playback)], + child: MaterialApp( + navigatorKey: navigator, + theme: mornye + ? MornyeTheme.build(Brightness.light) + : AppTheme.light(), + localizationsDelegates: AppLocalizations.localizationsDelegates, + supportedLocales: AppLocalizations.supportedLocales, + home: LocalAlbumScreen( + albumName: 'Album', + artistName: 'Artist', + tracks: tracks, + ), + ), + ), + ); + await tester.pumpAndSettle(); + await tester.scrollUntilVisible(find.text('Song 2'), 150); + await tester.tap(find.text('Song 2')); + await tester.pumpAndSettle(); + final metadata = tester.widget( + find.byType(TrackMetadataScreen), + ); + expect(metadata.localItem!.id, '2'); + expect(metadata.localNavigationItems!.map((track) => track.id), [ + '1', + '2', + ]); + expect(metadata.navigationIndex, 1); + expect(playback.played, isEmpty); + navigator.currentState!.pop(); + await tester.pumpAndSettle(); + final row = find.byWidgetPredicate( + (widget) => widget is AlbumTrackTile && widget.trackName == 'Song 2', + ); + await tester.tap( + find.descendant(of: row, matching: find.byType(IconButton)), + ); + await tester.pumpAndSettle(); + expect(playback.played, ['2']); + expect(find.byType(TrackMetadataScreen), findsNothing); + expect(tester.takeException(), isNull); + }); + } +}