Einzelne Server-Titel offline nehmen und wieder entfernen
This commit is contained in:
@@ -5,6 +5,7 @@ import 'package:provider/provider.dart';
|
||||
import '../library/database.dart';
|
||||
import '../library/song_media.dart';
|
||||
import '../player/audio_handler.dart';
|
||||
import '../services/download_service.dart';
|
||||
import '../services/navidrome_service.dart';
|
||||
import '../shared/cover.dart';
|
||||
import '../shared/lauf_balken.dart';
|
||||
@@ -69,6 +70,45 @@ class _ServerTitelScreenState extends State<ServerTitelScreen> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Nach Laden oder Entfernen ist der Einmal-Schnappschuss [_geladen] veraltet
|
||||
/// — hier wird er nachgezogen.
|
||||
Future<void> _aktualisiereGeladen() async {
|
||||
final geladen = await context.read<MeloDb>().downloadIds();
|
||||
if (mounted) setState(() => _geladen = geladen);
|
||||
}
|
||||
|
||||
Future<void> _offlineNehmen(SubsonicSong song) async {
|
||||
final dienst = context.read<DownloadService>();
|
||||
final messenger = ScaffoldMessenger.of(context);
|
||||
if (dienst.laeuft) {
|
||||
messenger.showSnackBar(
|
||||
const SnackBar(content: Text('Es läuft schon ein Download')),
|
||||
);
|
||||
return;
|
||||
}
|
||||
final neu = await dienst.ladeEinzelnenTitel(song);
|
||||
await _aktualisiereGeladen();
|
||||
if (!mounted) return;
|
||||
messenger.showSnackBar(SnackBar(
|
||||
content: Text(neu
|
||||
? 'Offline: ${song.titel}'
|
||||
: (dienst.fehler ?? 'War schon heruntergeladen')),
|
||||
));
|
||||
}
|
||||
|
||||
Future<void> _offlineEntfernen(SubsonicSong song) async {
|
||||
final dienst = context.read<DownloadService>();
|
||||
final messenger = ScaffoldMessenger.of(context);
|
||||
final weg = await dienst.entferne(song.id);
|
||||
await _aktualisiereGeladen();
|
||||
if (!mounted) return;
|
||||
messenger.showSnackBar(SnackBar(
|
||||
content: Text(weg
|
||||
? 'Vom Gerät entfernt: ${song.titel}'
|
||||
: (dienst.fehler ?? 'Ließ sich nicht entfernen')),
|
||||
));
|
||||
}
|
||||
|
||||
Future<void> _spiele(List<SubsonicSong> songs, int ab) async {
|
||||
final handler = context.read<MeloAudioHandler>();
|
||||
final messenger = ScaffoldMessenger.of(context);
|
||||
@@ -130,6 +170,8 @@ class _ServerTitelScreenState extends State<ServerTitelScreen> {
|
||||
nummer: i,
|
||||
geladen: _geladen.contains(song.id),
|
||||
onTap: () => _spiele(songs, i - 1),
|
||||
onOffline: () => _offlineNehmen(song),
|
||||
onEntfernen: () => _offlineEntfernen(song),
|
||||
);
|
||||
},
|
||||
),
|
||||
@@ -230,12 +272,16 @@ class _Zeile extends StatelessWidget {
|
||||
required this.nummer,
|
||||
required this.geladen,
|
||||
required this.onTap,
|
||||
required this.onOffline,
|
||||
required this.onEntfernen,
|
||||
});
|
||||
|
||||
final SubsonicSong song;
|
||||
final int nummer;
|
||||
final bool geladen;
|
||||
final VoidCallback onTap;
|
||||
final VoidCallback onOffline;
|
||||
final VoidCallback onEntfernen;
|
||||
|
||||
static String _dauer(int sekunden) {
|
||||
final m = (sekunden ~/ 60).toString();
|
||||
@@ -286,12 +332,21 @@ class _Zeile extends StatelessWidget {
|
||||
trailing: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
if (geladen)
|
||||
const Padding(
|
||||
padding: EdgeInsets.only(right: MeloSpace.sm),
|
||||
child: Icon(Icons.download_done,
|
||||
size: 16, color: MeloTheme.text3),
|
||||
),
|
||||
// Bisher gab es den Lade-Knopf nur je Album — einen einzelnen
|
||||
// Titel mitzunehmen ging gar nicht.
|
||||
geladen
|
||||
? IconButton(
|
||||
tooltip: 'Vom Gerät entfernen',
|
||||
icon: const Icon(Icons.download_done,
|
||||
size: 20, color: MeloTheme.red),
|
||||
onPressed: onEntfernen,
|
||||
)
|
||||
: IconButton(
|
||||
tooltip: 'Offline nehmen',
|
||||
icon: const Icon(Icons.download_outlined,
|
||||
size: 20, color: MeloTheme.text3),
|
||||
onPressed: onOffline,
|
||||
),
|
||||
Text(_dauer(song.dauerSekunden),
|
||||
style: const TextStyle(color: MeloTheme.text3)),
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user