import 'package:audio_service/audio_service.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'library/database.dart'; import 'library/library_screen.dart'; import 'library/library_service.dart'; import 'library/playlist_service.dart'; import 'library/search_screen.dart'; import 'player/audio_handler.dart'; import 'player/mini_player.dart'; import 'player/now_playing_screen.dart'; import 'playlists/playlists_screen.dart'; import 'shared/theme.dart'; late final MeloAudioHandler _handler; late final MeloDb _db; late final LibraryService _library; late final PlaylistService _playlists; Future main() async { WidgetsFlutterBinding.ensureInitialized(); _db = MeloDb(); _library = LibraryService(_db); _playlists = PlaylistService(_db); _handler = await AudioService.init( builder: () => MeloAudioHandler(db: _db), config: const AudioServiceConfig( androidNotificationChannelId: 'de.baka.melo.audio', androidNotificationChannelName: 'Melo', androidNotificationOngoing: true, ), ); runApp(const MeloApp()); } class MeloApp extends StatelessWidget { const MeloApp({super.key}); @override Widget build(BuildContext context) { return MultiProvider( providers: [ Provider.value(value: _handler), Provider.value(value: _db), ChangeNotifierProvider.value(value: _library), ChangeNotifierProvider.value(value: _playlists), ], child: MaterialApp( title: 'Melo', debugShowCheckedModeBanner: false, theme: MeloTheme.dark, home: const HomeShell(), ), ); } } class HomeShell extends StatefulWidget { const HomeShell({super.key}); @override State createState() => _HomeShellState(); } class _HomeShellState extends State { int _index = 0; static const _tabs = [ NowPlayingScreen(), LibraryScreen(), PlaylistsScreen(), SearchScreen(), _Placeholder(label: 'Settings', hint: 'Kommt in Kürze'), ]; @override Widget build(BuildContext context) { return Scaffold( body: Column( children: [ Expanded(child: IndexedStack(index: _index, children: _tabs)), if (_index != 0) const MiniPlayer(), ], ), bottomNavigationBar: BottomNavigationBar( currentIndex: _index, onTap: (i) => setState(() => _index = i), items: const [ BottomNavigationBarItem( icon: Icon(Icons.play_circle_outline), label: 'Player'), BottomNavigationBarItem( icon: Icon(Icons.library_music), label: 'Bibliothek'), BottomNavigationBarItem( icon: Icon(Icons.playlist_play), label: 'Playlisten'), BottomNavigationBarItem(icon: Icon(Icons.search), label: 'Suche'), BottomNavigationBarItem(icon: Icon(Icons.settings), label: 'Settings'), ], ), ); } } class _Placeholder extends StatelessWidget { const _Placeholder({required this.label, required this.hint}); final String label; final String hint; @override Widget build(BuildContext context) { return Center( child: Column( mainAxisSize: MainAxisSize.min, children: [ Text(label, style: Theme.of(context).textTheme.headlineSmall), const SizedBox(height: 8), Text(hint, style: const TextStyle(color: Colors.white54)), ], ), ); } }