import 'package:flutter/material.dart'; import '../utils/farb_theme.dart'; class MeloHeader extends StatelessWidget { final VoidCallback onDownload; final VoidCallback onSearch; final VoidCallback? onServer; final VoidCallback? onSettings; /// Musikserver-Status (☁️ Musikserver + Statuspunkt): /// `null` = kein Chip (alter Cloud-Button wird gezeigt). final bool? serverVerbunden; /// true = Sync läuft → Statuspunkt pulsiert. final bool? serverSyncLaeuft; const MeloHeader({ super.key, required this.onDownload, required this.onSearch, this.onServer, this.onSettings, this.serverVerbunden, this.serverSyncLaeuft, }); @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.fromLTRB(20, 12, 20, 4), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ ShaderMask( shaderCallback: (bounds) => const LinearGradient( colors: [Colors.white, MeloTheme.rot], ).createShader(bounds), child: const Text('Melo', style: TextStyle( fontSize: 28, fontWeight: FontWeight.w700, color: Colors.white)), ), const Text('Deine Musik. Deine Art.', style: TextStyle(fontSize: 12, color: MeloTheme.textSekundaer)), ], ), Row(children: [ if (serverVerbunden != null) ...[ _ServerStatusChip( verbunden: serverVerbunden!, syncLaeuft: serverSyncLaeuft ?? false, onTap: onServer, ), const SizedBox(width: 8), ] else if (onServer != null) ...[ _btn(Icons.cloud, onServer!), const SizedBox(width: 8), ], _btn(Icons.download, onDownload), const SizedBox(width: 8), _btn(Icons.search, onSearch), if (onSettings != null) ...[ const SizedBox(width: 8), _btn(Icons.settings, onSettings!), ], ]), ], ), const SizedBox(height: 8), // Suchleiste – immer sichtbar TextField( onSubmitted: (wert) { if (wert.isNotEmpty) onSearch(); }, style: const TextStyle(color: Colors.white, fontSize: 14), decoration: InputDecoration( hintText: '🔍 Song, Künstler oder Tag suchen...', hintStyle: TextStyle(color: Colors.grey.shade600, fontSize: 13), prefixIcon: Icon(Icons.search, size: 18, color: MeloTheme.rot.withValues(alpha: 0.6)), filled: true, fillColor: MeloTheme.dunkel1, border: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: BorderSide.none, ), contentPadding: const EdgeInsets.symmetric(vertical: 10, horizontal: 12), ), ), ], ), ); } Widget _btn(IconData icon, VoidCallback onTap) { return Container( width: 40, height: 40, decoration: BoxDecoration( color: MeloTheme.dunkel1, borderRadius: BorderRadius.circular(12), ), child: IconButton( icon: Icon(icon, size: 18, color: MeloTheme.rot), onPressed: onTap, ), ); } } /// Kompakter „☁️ Musikserver“-Chip mit Statuspunkt. /// Grün = verbunden, Rot = offline, pulsierend = Sync läuft. class _ServerStatusChip extends StatefulWidget { final bool verbunden; final bool syncLaeuft; final VoidCallback? onTap; const _ServerStatusChip({ required this.verbunden, required this.syncLaeuft, this.onTap, }); @override State<_ServerStatusChip> createState() => _ServerStatusChipState(); } class _ServerStatusChipState extends State<_ServerStatusChip> with SingleTickerProviderStateMixin { late final AnimationController _controller; @override void initState() { super.initState(); _controller = AnimationController( vsync: this, duration: const Duration(milliseconds: 900), ); if (widget.syncLaeuft) _controller.repeat(reverse: true); } @override void didUpdateWidget(covariant _ServerStatusChip oldWidget) { super.didUpdateWidget(oldWidget); if (widget.syncLaeuft && !oldWidget.syncLaeuft) { _controller.repeat(reverse: true); } else if (!widget.syncLaeuft && oldWidget.syncLaeuft) { _controller.stop(); _controller.value = 0; } } @override void dispose() { _controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { final farbe = widget.verbunden ? const Color(0xFF4CAF50) : const Color(0xFFEF5350); return GestureDetector( onTap: widget.onTap, child: Container( height: 40, padding: const EdgeInsets.symmetric(horizontal: 12), decoration: BoxDecoration( color: MeloTheme.dunkel1, borderRadius: BorderRadius.circular(12), border: Border.all(color: MeloTheme.dunkel2), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ const Text('☁️', style: TextStyle(fontSize: 13)), const SizedBox(width: 6), const Text( 'Musikserver', style: TextStyle(fontSize: 11, color: Colors.white70, fontWeight: FontWeight.w500), ), const SizedBox(width: 6), AnimatedBuilder( animation: _controller, builder: (_, child) { // Pulsierende Größe während des Syncs final skala = widget.syncLaeuft ? 0.7 + (0.5 * _controller.value) : 1.0; return Transform.scale( scale: skala, child: child, ); }, child: Container( width: 9, height: 9, decoration: BoxDecoration( shape: BoxShape.circle, color: farbe, boxShadow: [ BoxShadow( color: farbe.withValues(alpha: 0.6), blurRadius: widget.syncLaeuft ? 10 : 5, ), ], ), ), ), ], ), ), ); } }