Melo v2.10 - YouTube Proxy, Download-Screen, Logger, iOS

This commit is contained in:
Hermes (Server)
2026-07-26 14:24:10 +02:00
parent b4baef5875
commit 3e9389ab59
17 changed files with 1065 additions and 347 deletions
+51 -27
View File
@@ -52,7 +52,7 @@ class _NavidromeBrowserState extends State<NavidromeBrowser> {
else if (vm.navidromeAlben.isEmpty)
_platzhalter('"Alben laden" um Musik zu sehen')
else
_albumListe(context, vm.navidromeAlben as List<SubsonicAlbum>),
_albumListe(context, vm.navidromeAlben),
],
),
);
@@ -191,6 +191,11 @@ class _NavidromeBrowserState extends State<NavidromeBrowser> {
onTap: () => widget.vm.downloadNavidromeSong(s).then((_) => setState(() {})),
child: const Icon(Icons.download, size: 18, color: MeloTheme.rot),
),
const SizedBox(width: 8),
GestureDetector(
onTap: () => widget.vm.starteNavidromeStream(s),
child: const Icon(Icons.play_arrow, size: 18, color: Colors.greenAccent),
),
],
),
);
@@ -214,36 +219,55 @@ class _NavidromeBrowserState extends State<NavidromeBrowser> {
final urlCtrl = TextEditingController();
final userCtrl = TextEditingController();
final passCtrl = TextEditingController();
bool verbindet = false;
String? fehler;
showDialog(
context: context,
builder: (ctx) => AlertDialog(
backgroundColor: MeloTheme.dunkel1,
title: const Text('🌐 Navidrome', style: TextStyle(color: Colors.white, fontSize: 16)),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
TextField(controller: urlCtrl, style: const TextStyle(color: Colors.white),
decoration: const InputDecoration(labelText: 'Server-URL', hintText: 'https://musik.baka-net.de',
labelStyle: TextStyle(color: Colors.grey), hintStyle: TextStyle(color: Colors.grey), border: OutlineInputBorder())),
const SizedBox(height: 8),
TextField(controller: userCtrl, style: const TextStyle(color: Colors.white),
decoration: const InputDecoration(labelText: 'Benutzer', labelStyle: TextStyle(color: Colors.grey), border: OutlineInputBorder())),
const SizedBox(height: 8),
TextField(controller: passCtrl, style: const TextStyle(color: Colors.white), obscureText: true,
decoration: const InputDecoration(labelText: 'Passwort', labelStyle: TextStyle(color: Colors.grey), border: OutlineInputBorder())),
builder: (ctx) => StatefulBuilder(
builder: (ctx, setDialogState) => AlertDialog(
backgroundColor: MeloTheme.dunkel1,
title: const Text('🌐 Navidrome', style: TextStyle(color: Colors.white, fontSize: 16)),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
TextField(controller: urlCtrl, style: const TextStyle(color: Colors.white),
decoration: const InputDecoration(labelText: 'Server-URL', hintText: 'https://musik.baka-net.de',
labelStyle: TextStyle(color: Colors.grey), hintStyle: TextStyle(color: Colors.grey), border: OutlineInputBorder())),
const SizedBox(height: 8),
TextField(controller: userCtrl, style: const TextStyle(color: Colors.white),
decoration: const InputDecoration(labelText: 'Benutzer', labelStyle: TextStyle(color: Colors.grey), border: OutlineInputBorder())),
const SizedBox(height: 8),
TextField(controller: passCtrl, style: const TextStyle(color: Colors.white), obscureText: true,
decoration: const InputDecoration(labelText: 'Passwort', labelStyle: TextStyle(color: Colors.grey), border: OutlineInputBorder())),
if (fehler != null) ...[
const SizedBox(height: 8),
Text(fehler!, style: const TextStyle(color: Colors.red, fontSize: 12)),
],
if (verbindet)
const Padding(padding: EdgeInsets.only(top: 12), child: SizedBox(width: 20, height: 20, child: CircularProgressIndicator(strokeWidth: 2, color: MeloTheme.rot))),
],
),
actions: [
TextButton(onPressed: () => Navigator.pop(ctx), child: const Text('Abbrechen')),
TextButton(
onPressed: verbindet ? null : () async {
verbindet = true;
setDialogState(() {});
widget.vm.verbindeNavidrome(urlCtrl.text, userCtrl.text, passCtrl.text);
final ok = await widget.vm.ladeNavidromeAlben();
verbindet = false;
if (ok && ctx.mounted) {
Navigator.pop(ctx);
if (context.mounted) setState(() {});
} else if (ctx.mounted) {
setDialogState(() => fehler = '❌ Keine Verbindung\nPrüfe URL + Zugangsdaten');
}
},
child: const Text('Verbinden', style: TextStyle(color: MeloTheme.rot)),
),
],
),
actions: [
TextButton(onPressed: () => Navigator.pop(ctx), child: const Text('Abbrechen')),
TextButton(
onPressed: () {
widget.vm.verbindeNavidrome(urlCtrl.text, userCtrl.text, passCtrl.text);
Navigator.pop(ctx);
widget.vm.ladeNavidromeAlben().then((_) => setState(() {}));
},
child: const Text('Verbinden', style: TextStyle(color: MeloTheme.rot)),
),
],
),
);
}