import 'dart:async'; import 'package:flutter/material.dart'; import 'package:just_audio/just_audio.dart'; import '../services/player_service.dart'; import '../utils/farb_theme.dart'; class MiniPlayer extends StatefulWidget { const MiniPlayer({super.key}); @override State createState() => _MiniPlayerState(); } class _MiniPlayerState extends State { final PlayerService _player = PlayerService(); Duration _position = Duration.zero; Duration _dauer = Duration.zero; bool _spielt = false; StreamSubscription? _posSub; StreamSubscription? _stateSub; @override void initState() { super.initState(); _posSub = _player.positionStream.listen((pos) { if (mounted) { setState(() => _position = pos); } }); _stateSub = _player.stateStream.listen((state) { if (mounted) { setState(() { _spielt = state.playing; _dauer = state.processingState == ProcessingState.ready ? (_player.dauer) : Duration.zero; }); } }); } @override void dispose() { _posSub?.cancel(); _stateSub?.cancel(); super.dispose(); } @override Widget build(BuildContext context) { final song = _player.aktuellerSong; if (song == null) return const SizedBox.shrink(); final progress = _dauer.inSeconds > 0 ? _position.inSeconds / _dauer.inSeconds : 0.0; return Container( margin: const EdgeInsets.symmetric(horizontal: 16), decoration: BoxDecoration( color: const Color(0xFF1A0A0A), borderRadius: BorderRadius.circular(16), border: Border.all(color: const Color(0xFF2A1515)), ), child: Column( mainAxisSize: MainAxisSize.min, children: [ Padding( padding: const EdgeInsets.fromLTRB(12, 10, 12, 6), child: Row( children: [ // Cover ClipRRect( borderRadius: BorderRadius.circular(10), child: Container( width: 36, height: 36, color: MeloTheme.rot, child: const Center(child: Text('♪', style: TextStyle(fontSize: 16))), ), ), const SizedBox(width: 10), // Titel + Künstler Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(song.titel, style: const TextStyle(fontSize: 13, fontWeight: FontWeight.w600, color: Colors.white)), Text(song.kuenstler, style: const TextStyle(fontSize: 11, color: MeloTheme.textSekundaer)), ], ), ), // Steuerung _btn(Icons.skip_previous, _player.vorheriges), _playBtn(), _btn(Icons.skip_next, _player.naechstes), ], ), ), // Fortschritt if (_dauer.inSeconds > 0) Padding( padding: const EdgeInsets.fromLTRB(12, 0, 12, 8), child: ClipRRect( borderRadius: BorderRadius.circular(2), child: LinearProgressIndicator( value: progress, backgroundColor: const Color(0xFF2A2A2A), valueColor: const AlwaysStoppedAnimation(MeloTheme.rot), minHeight: 2, ), ), ), ], ), ); } Widget _btn(IconData icon, VoidCallback onTap) { return Material( color: Colors.transparent, child: InkWell( borderRadius: BorderRadius.circular(50), onTap: onTap, child: Container( width: 32, height: 32, alignment: Alignment.center, child: Icon(icon, size: 18, color: Colors.white), ), ), ); } Widget _playBtn() { return Material( color: MeloTheme.rot, borderRadius: BorderRadius.circular(50), child: InkWell( borderRadius: BorderRadius.circular(50), onTap: _player.playPause, child: Container( width: 36, height: 36, alignment: Alignment.center, child: Icon(_spielt ? Icons.pause : Icons.play_arrow, size: 20, color: Colors.white), ), ), ); } }