import 'package:flutter/material.dart'; import 'dart:io' show Platform; import 'package:audio_service/audio_service.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:permission_handler/permission_handler.dart'; import 'database/db_helper.dart'; import 'services/favoriten_service.dart'; import 'services/auth_service.dart'; import 'services/cloud_service.dart'; import 'services/melo_logger.dart'; import 'services/audio_handler.dart'; import 'services/musik_scanner.dart'; import 'utils/farb_theme.dart'; import 'screens/home_screen.dart'; import 'screens/login_screen.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); // Logger startet sofort – zeichnet ALLES auf MeloLogger().init('2.35'); try { await DbHelper().db; await FavoritenService().init(); // Hintergrund-Audio-Service starten await AudioService.init( builder: () => MeloAudioHandler(), config: const AudioServiceConfig( androidNotificationChannelId: 'de.baka.melo.audio', androidNotificationChannelName: 'Melo Wiedergabe', androidNotificationOngoing: true, ), ); MeloLogger().zustand('start_ok', {'db': 'ok', 'audio': 'ok'}); } catch (e, stack) { MeloLogger().fehler('App-Start', e, stack); } // Auth initialisieren (Token aus SharedPreferences laden + online validieren) await AuthService().initialisieren(); // Android-Berechtigungen beim Start abfragen (Issue #4) // Speicherzugriff für Musik-Scan (READ_MEDIA_AUDIO / Storage) await MusikScanner().frageSpeicherZugriff(); // POST_NOTIFICATIONS für Android 13+ (Notifications für Downloads, Player) if (Platform.isAndroid) { await Permission.notification.request(); } // Auto-Sync beim Start (wenn eingeloggt und Auto-Sync aktiv) _starteAutoSyncFallsNoetig(); runApp(const MeloApp()); } /// Führt Cloud-Auto-Sync beim App-Start aus, falls konfiguriert Future _starteAutoSyncFallsNoetig() async { try { final auth = AuthService(); if (!auth.istEingeloggt) return; // Prüfen, ob Auto-Sync aktiviert ist final SharedPreferences prefs = await SharedPreferences.getInstance(); final autoSync = prefs.getBool('cloud_auto') ?? true; if (!autoSync) return; final cloud = CloudService(); final ok = await cloud.login(auth.benutzer); if (!ok) return; // Letzten Sync prüfen — nur syncen wenn nötig final lastSync = prefs.getString('cloud_last_sync_ts'); final now = DateTime.now(); if (lastSync != null) { final last = DateTime.tryParse(lastSync); if (last != null) { final interval = prefs.getInt('cloud_interval') ?? 6; if (now.difference(last).inHours < interval) { return; // Noch nicht fällig } } } // Sync ausführen MeloLogger().aktion('auto_sync_start', {}); final st = await cloud.status(); if (st != null) { final serverSongs = await cloud.listSongs(); MeloLogger().aktion('auto_sync_done', {'songs': serverSongs.length}); } await prefs.setString('cloud_last_sync_ts', now.toIso8601String()); } catch (e) { MeloLogger().fehler('auto_sync_init', e); } } class MeloApp extends StatelessWidget { const MeloApp({super.key}); @override Widget build(BuildContext context) { final auth = AuthService(); return MaterialApp( title: 'Melo', debugShowCheckedModeBanner: false, theme: MeloTheme.theme, home: auth.istEingeloggt ? const Scaffold(body: MeloHome()) : const LoginScreen(), ); } }