diff --git a/lib/screens/login_screen.dart b/lib/screens/login_screen.dart index 72c4653..66515ce 100644 --- a/lib/screens/login_screen.dart +++ b/lib/screens/login_screen.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import '../services/auth_service.dart'; import '../services/navidrome_service.dart'; import '../utils/farb_theme.dart'; +import '../config/app_config.dart'; import 'home_screen.dart'; /// Melo Login-Screen – Schwarz+Rot Design @@ -16,27 +17,14 @@ class LoginScreen extends StatefulWidget { class _LoginScreenState extends State with SingleTickerProviderStateMixin { final AuthService _auth = AuthService(); - final NavidromeService _navidrome = NavidromeService(); final _userCtrl = TextEditingController(); final _passCtrl = TextEditingController(); - final _urlCtrl = TextEditingController(); - final _navUserCtrl = TextEditingController(); - final _navPassCtrl = TextEditingController(); bool _ladt = false; String? _status; bool _statusOk = false; - bool _zeigeNavidrome = false; - bool _zeigeRegistrierung = false; bool _passSichtbar = false; - bool _navPassSichtbar = false; - bool _regPassSichtbar = false; - - // Registrierungs-Felder - final _regEmailCtrl = TextEditingController(); - final _regUserCtrl = TextEditingController(); - final _regPassCtrl = TextEditingController(); late final AnimationController _animCtrl; late final Animation _fadeAnim; @@ -50,29 +38,12 @@ class _LoginScreenState extends State ); _fadeAnim = CurvedAnimation(parent: _animCtrl, curve: Curves.easeOut); _animCtrl.forward(); - _ladeGespeicherteDaten(); - } - - Future _ladeGespeicherteDaten() async { - await _navidrome.ladeGespeicherteZugangsdaten(); - // Navidrome-Daten für Anzeige vorbereiten - if (_navidrome.istVerbunden) { - setState(() { - _zeigeNavidrome = true; - }); - } } @override void dispose() { _userCtrl.dispose(); _passCtrl.dispose(); - _urlCtrl.dispose(); - _navUserCtrl.dispose(); - _navPassCtrl.dispose(); - _regEmailCtrl.dispose(); - _regUserCtrl.dispose(); - _regPassCtrl.dispose(); _animCtrl.dispose(); super.dispose(); } @@ -102,16 +73,9 @@ class _LoginScreenState extends State if (result.erfolg) { _setzeStatus('✅ Login erfolgreich!', ok: true); - // Navidrome-Credentials speichern falls eingegeben - if (_zeigeNavidrome) { - final url = _urlCtrl.text.trim(); - final nUser = _navUserCtrl.text.trim(); - final nPass = _navPassCtrl.text.trim(); - if (url.isNotEmpty && nUser.isNotEmpty && nPass.isNotEmpty) { - await _navidrome.speichereZugangsdaten(url, nUser, nPass); - } - } - // Kurz warten, dann navigieren + // Navidrome automatisch mit gleichen Credentials syncen + await NavidromeService().speichereZugangsdaten( + AppConfig.navidromeUrl, user, pass); await Future.delayed(const Duration(milliseconds: 600)); if (mounted) { Navigator.of(context).pushReplacement( @@ -124,37 +88,6 @@ class _LoginScreenState extends State } } - Future _registrieren() async { - final user = _regUserCtrl.text.trim(); - final pass = _regPassCtrl.text.trim(); - final email = _regEmailCtrl.text.trim(); - - if (user.isEmpty || pass.isEmpty) { - _setzeStatus('Bitte alle Felder ausfüllen'); - return; - } - - setState(() => _ladt = true); - _setzeStatus('Registriere...'); - - final result = await _auth.registrieren(user, pass, email); - - if (!mounted) return; - - if (result.erfolg) { - _setzeStatus('✅ Registrierung erfolgreich!', ok: true); - await Future.delayed(const Duration(milliseconds: 600)); - if (mounted) { - Navigator.of(context).pushReplacement( - MaterialPageRoute(builder: (_) => const MeloHome()), - ); - } - } else { - _setzeStatus('❌ ${result.fehler ?? "Registrierung fehlgeschlagen"}'); - setState(() => _ladt = false); - } - } - @override Widget build(BuildContext context) { return Scaffold( @@ -165,7 +98,7 @@ class _LoginScreenState extends State padding: const EdgeInsets.symmetric(horizontal: 28, vertical: 24), child: FadeTransition( opacity: _fadeAnim, - child: _zeigeRegistrierung ? _buildRegister() : _buildLogin(), + child: _buildLogin(), ), ), ), @@ -280,32 +213,6 @@ class _LoginScreenState extends State ), const SizedBox(height: 20), - // ─── Navidrome (optional) ─── - _navidromeBereich(), - const SizedBox(height: 20), - - // ─── Registrieren Link ─── - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Text( - 'Noch keinen Account? ', - style: TextStyle(color: MeloTheme.textSekundaer, fontSize: 13), - ), - GestureDetector( - onTap: () => setState(() => _zeigeRegistrierung = true), - child: const Text( - 'Registrieren', - style: TextStyle( - color: MeloTheme.rot, - fontSize: 13, - fontWeight: FontWeight.w600, - ), - ), - ), - ], - ), - // ─── Offline-Modus ─── const SizedBox(height: 16), GestureDetector( @@ -324,98 +231,6 @@ class _LoginScreenState extends State ); } - Widget _buildRegister() { - return Column( - mainAxisSize: MainAxisSize.min, - children: [ - _logoBereich(klein: true), - const SizedBox(height: 28), - - Container( - width: double.infinity, - padding: const EdgeInsets.all(24), - decoration: BoxDecoration( - color: MeloTheme.dunkel1, - borderRadius: BorderRadius.circular(20), - border: Border.all(color: MeloTheme.dunkel2), - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const Text( - 'Registrieren', - style: TextStyle(color: Colors.white, fontSize: 20, fontWeight: FontWeight.w700), - ), - const SizedBox(height: 20), - - _eingabeFeld( - controller: _regUserCtrl, - label: 'Benutzername', - icon: Icons.person_outline, - ), - const SizedBox(height: 14), - _eingabeFeld( - controller: _regEmailCtrl, - label: 'E-Mail (optional)', - icon: Icons.email_outlined, - keyboardType: TextInputType.emailAddress, - ), - const SizedBox(height: 14), - _eingabeFeld( - controller: _regPassCtrl, - label: 'Passwort', - icon: Icons.lock_outline, - istPasswort: true, - passSichtbar: _regPassSichtbar, - onPasswortToggle: () => setState(() => _regPassSichtbar = !_regPassSichtbar), - ), - const SizedBox(height: 24), - - SizedBox( - width: double.infinity, - height: 50, - child: ElevatedButton( - onPressed: _ladt ? null : _registrieren, - style: ElevatedButton.styleFrom( - backgroundColor: MeloTheme.rot, - disabledBackgroundColor: MeloTheme.dunkel2, - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(14)), - elevation: 0, - ), - child: _ladt - ? const SizedBox( - width: 22, height: 22, - child: CircularProgressIndicator(strokeWidth: 2.5, color: Colors.white), - ) - : const Text('Registrieren', - style: TextStyle(color: Colors.white, fontSize: 16, fontWeight: FontWeight.w600)), - ), - ), - - if (_status != null) ...[ - const SizedBox(height: 16), - _statusWidget(), - ], - ], - ), - ), - const SizedBox(height: 16), - GestureDetector( - onTap: () { - setState(() { - _zeigeRegistrierung = false; - _status = null; - }); - }, - child: const Text( - '← Zurück zum Login', - style: TextStyle(color: MeloTheme.rot, fontSize: 13, fontWeight: FontWeight.w600), - ), - ), - ], - ); - } - Widget _logoBereich({bool klein = false}) { return Column( children: [ @@ -469,88 +284,6 @@ class _LoginScreenState extends State ); } - Widget _navidromeBereich() { - return Column( - children: [ - // Toggle - GestureDetector( - onTap: () => setState(() => _zeigeNavidrome = !_zeigeNavidrome), - child: Container( - padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10), - decoration: BoxDecoration( - color: MeloTheme.dunkel1, - borderRadius: BorderRadius.circular(12), - border: Border.all(color: MeloTheme.dunkel2), - ), - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - Icon( - _zeigeNavidrome ? Icons.dns : Icons.dns_outlined, - color: _zeigeNavidrome ? MeloTheme.rot : MeloTheme.textSekundaer, - size: 18, - ), - const SizedBox(width: 8), - Text( - '🌐 Navidrome Server', - style: TextStyle( - color: _zeigeNavidrome ? Colors.white : MeloTheme.textSekundaer, - fontSize: 13, - ), - ), - const SizedBox(width: 6), - Icon( - _zeigeNavidrome ? Icons.keyboard_arrow_up : Icons.keyboard_arrow_down, - color: MeloTheme.textSekundaer, - size: 16, - ), - ], - ), - ), - ), - - // Erweiterte Navidrome-Felder - if (_zeigeNavidrome) ...[ - const SizedBox(height: 12), - Container( - width: double.infinity, - padding: const EdgeInsets.all(16), - decoration: BoxDecoration( - color: MeloTheme.dunkel1, - borderRadius: BorderRadius.circular(14), - border: Border.all(color: MeloTheme.dunkel2), - ), - child: Column( - children: [ - _eingabeFeld( - controller: _urlCtrl, - label: 'Server-URL', - icon: Icons.link, - hint: 'https://musik.baka-net.de', - ), - const SizedBox(height: 12), - _eingabeFeld( - controller: _navUserCtrl, - label: 'Navidrome Benutzer', - icon: Icons.person_outline, - ), - const SizedBox(height: 12), - _eingabeFeld( - controller: _navPassCtrl, - label: 'Navidrome Passwort', - icon: Icons.lock_outline, - istPasswort: true, - passSichtbar: _navPassSichtbar, - onPasswortToggle: () => setState(() => _navPassSichtbar = !_navPassSichtbar), - ), - ], - ), - ), - ], - ], - ); - } - Widget _statusWidget() { return Container( width: double.infinity,