feat(playlists): add play actions (#506)

This commit is contained in:
Padma Dev
2026-08-11 17:32:20 +07:00
committed by zarzet
parent 48dbe3679d
commit 7e429f8373
2 changed files with 58 additions and 16 deletions
+29 -16
View File
@@ -17,6 +17,7 @@ import 'package:spotiflac_android/utils/file_access.dart';
import 'package:spotiflac_android/providers/download_queue_provider.dart';
import 'package:spotiflac_android/providers/extension_provider.dart';
import 'package:spotiflac_android/providers/library_collections_provider.dart';
import 'package:spotiflac_android/providers/music_player_provider.dart';
import 'package:spotiflac_android/providers/playback_provider.dart';
import 'package:spotiflac_android/providers/local_library_provider.dart';
import 'package:spotiflac_android/providers/settings_provider.dart';
@@ -595,11 +596,9 @@ class _LibraryTracksFolderScreenState
? Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
_buildHeaderActionPlaceholder(),
const SizedBox(width: 12),
_buildDownloadAllCenterButton(entries),
const SizedBox(width: 12),
_buildHeaderActionPlaceholder(),
Flexible(child: _buildPlayAllCenterButton(entries)),
const SizedBox(width: 8),
Flexible(child: _buildDownloadAllCenterButton(entries)),
],
)
: null,
@@ -678,24 +677,38 @@ class _LibraryTracksFolderScreenState
);
}
Widget _buildHeaderActionPlaceholder() =>
const SizedBox(width: 48, height: 48);
Widget _buildPlayAllCenterButton(List<CollectionTrackEntry> entries) {
final tracks = entries.map((e) => e.track).toList(growable: false);
return HeaderFilledButton(
icon: Icons.play_arrow_rounded,
label: context.l10n.tooltipPlay,
onPressed: tracks.isEmpty ? null : () => _playAll(tracks),
);
}
Widget _buildDownloadAllCenterButton(List<CollectionTrackEntry> entries) {
final tracks = entries.map((e) => e.track).toList(growable: false);
return FilledButton.icon(
return HeaderFilledButton(
icon: Icons.download_rounded,
label: context.l10n.downloadAllCount(tracks.length),
onPressed: tracks.isEmpty ? null : () => _confirmDownloadAll(tracks),
icon: const Icon(Icons.download_rounded, size: 18),
label: Text(context.l10n.downloadAllCount(tracks.length)),
style: FilledButton.styleFrom(
backgroundColor: Colors.white,
foregroundColor: Colors.black87,
minimumSize: const Size(0, 48),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(24)),
),
);
}
Future<void> _playAll(List<Track> tracks) async {
if (tracks.isEmpty) return;
try {
await ref.read(musicPlayerControllerProvider).setShuffle(false);
await ref.read(playbackProvider.notifier).playTrackList(tracks);
} catch (e) {
if (!mounted) return;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(context.l10n.snackbarCannotOpenFile('$e'))),
);
}
}
void _confirmDownloadAll(List<Track> tracks) {
confirmDownloadAllDialog(
context,
+29
View File
@@ -11,6 +11,8 @@ import 'package:spotiflac_android/models/track.dart';
import 'package:spotiflac_android/providers/download_queue_provider.dart';
import 'package:spotiflac_android/providers/extension_provider.dart';
import 'package:spotiflac_android/providers/library_collections_provider.dart';
import 'package:spotiflac_android/providers/music_player_provider.dart';
import 'package:spotiflac_android/providers/playback_provider.dart';
import 'package:spotiflac_android/utils/image_cache_utils.dart';
import 'package:spotiflac_android/utils/cover_art_utils.dart';
import 'package:spotiflac_android/utils/adaptive_layout.dart';
@@ -338,6 +340,8 @@ class _PlaylistScreenState extends ConsumerState<PlaylistScreen>
children: [
_buildLoveAllButton(),
const SizedBox(width: 12),
Flexible(child: _buildPlayDownloadedButton(context)),
const SizedBox(width: 8),
Flexible(child: _buildDownloadAllCenterButton(context)),
const SizedBox(width: 12),
_buildAddToPlaylistButton(context),
@@ -489,6 +493,16 @@ class _PlaylistScreenState extends ConsumerState<PlaylistScreen>
);
}
Widget _buildPlayDownloadedButton(BuildContext context) {
return HeaderFilledButton(
icon: Icons.play_arrow_rounded,
label: context.l10n.tooltipPlay,
onPressed: _tracks.isEmpty
? null
: () => _playDownloadedPlaylist(context),
);
}
Widget _buildDownloadAllCenterButton(BuildContext context) {
return HeaderFilledButton(
icon: Icons.download_rounded,
@@ -523,6 +537,21 @@ class _PlaylistScreenState extends ConsumerState<PlaylistScreen>
Future<void> _loveAll(List<Track> tracks) =>
loveAllTracks(context, ref, tracks);
Future<void> _playDownloadedPlaylist(BuildContext context) async {
final tracks = List<Track>.from(_tracks, growable: false);
if (tracks.isEmpty) return;
try {
await ref.read(musicPlayerControllerProvider).setShuffle(false);
await ref.read(playbackProvider.notifier).playTrackList(tracks);
} catch (e) {
if (!mounted || !context.mounted) return;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(context.l10n.snackbarCannotOpenFile('$e'))),
);
}
}
void _downloadAll(BuildContext context) {
_downloadTracks(context, _tracks);
}