From 3c66f1375f2a51f05b31e4afdaa6eaf2c6fbf02e Mon Sep 17 00:00:00 2001 From: Richard Shackleton Date: Tue, 31 Mar 2026 17:14:53 +0100 Subject: [PATCH] feat: add album download button --- lib/screens/album_screen.dart | 56 +++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/lib/screens/album_screen.dart b/lib/screens/album_screen.dart index abd3e8b..9c9ad84 100644 --- a/lib/screens/album_screen.dart +++ b/lib/screens/album_screen.dart @@ -9,6 +9,7 @@ import '../theme/app_theme.dart'; import '../widgets/widgets.dart'; import 'artist_screen.dart'; import '../l10n/app_localizations.dart'; +import '../services/offline_service.dart'; class AlbumScreen extends StatefulWidget { final String albumId; @@ -23,6 +24,7 @@ class _AlbumScreenState extends State { Album? _album; List _songs = []; bool _isLoading = true; + bool _isDownloading = false; @override void initState() { @@ -81,6 +83,42 @@ class _AlbumScreenState extends State { playerProvider.playSong(playlist.first, playlist: playlist, startIndex: 0); } + Future _downloadAlbum() async { + if (_songs.isEmpty) return; + + final subsonicService = Provider.of( + context, + listen: false, + ); + final offlineService = OfflineService(); + await offlineService.initialize(); + + setState(() => _isDownloading = true); + + offlineService.startBackgroundDownload(_songs, subsonicService).then((_) { + if (mounted) { + setState(() => _isDownloading = false); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + 'Downloaded ${_songs.length} songs from ${_album!.name}', + ), + duration: const Duration(seconds: 3), + ), + ); + } + }); + + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Downloading ${_songs.length} songs in background…'), + duration: const Duration(seconds: 2), + ), + ); + } + } + @override Widget build(BuildContext context) { final theme = Theme.of(context); @@ -160,6 +198,10 @@ class _AlbumScreenState extends State { final hours = totalDuration ~/ 3600; final minutes = (totalDuration % 3600) ~/ 60; + final isOffline = + Provider.of(context, listen: false).state == + AuthState.offlineMode; + return Scaffold( body: Stack( children: [ @@ -205,6 +247,20 @@ class _AlbumScreenState extends State { ], ), ), + actions: [ + if (!isOffline) + IconButton( + tooltip: 'Download album', + onPressed: _isDownloading ? null : _downloadAlbum, + icon: _isDownloading + ? const SizedBox( + width: 20, + height: 20, + child: CircularProgressIndicator(strokeWidth: 2), + ) + : const Icon(CupertinoIcons.cloud_download), + ), + ], ), SliverToBoxAdapter( child: Padding(