part of '../chat_view.dart'; class _DragOverlay extends StatefulWidget { final PyramidTheme pt; final bool active; const _DragOverlay({required this.pt, required this.active}); @override State<_DragOverlay> createState() => _DragOverlayState(); } class _DragOverlayState extends State<_DragOverlay> with SingleTickerProviderStateMixin { // Sanftes Auf-und-ab des Icons, solange das Overlay aktiv ist. late final AnimationController _bob = AnimationController( vsync: this, duration: const Duration(milliseconds: 900), ); @override void initState() { super.initState(); if (widget.active) _bob.repeat(reverse: true); } @override void didUpdateWidget(_DragOverlay old) { super.didUpdateWidget(old); if (widget.active && !old.active) { _bob.repeat(reverse: true); } else if (!widget.active && old.active) { _bob.stop(); } } @override void dispose() { _bob.dispose(); super.dispose(); } @override Widget build(BuildContext context) { final pt = widget.pt; return Container( color: pt.bg0.withAlpha(200), child: Center( child: AnimatedScale( scale: widget.active ? 1.0 : 0.88, duration: const Duration(milliseconds: 220), curve: Curves.easeOutBack, child: Container( padding: const EdgeInsets.symmetric(horizontal: 40, vertical: 32), decoration: BoxDecoration( color: pt.bg2, borderRadius: BorderRadius.circular(20), border: Border.all(color: pt.accent, width: 2), boxShadow: [ BoxShadow( color: pt.accent.withAlpha(60), blurRadius: 32, spreadRadius: 4, ), ], ), child: Column( mainAxisSize: MainAxisSize.min, children: [ AnimatedBuilder( animation: _bob, builder: (_, child) => Transform.translate( offset: Offset( 0, -7 * Curves.easeInOut.transform(_bob.value)), child: child, ), child: Icon(Icons.upload_file_rounded, size: 56, color: pt.accent), ), const SizedBox(height: 16), Text( 'Datei hier ablegen', style: TextStyle( color: pt.fg, fontSize: 20, fontWeight: FontWeight.w600, ), ), const SizedBox(height: 8), Text( 'Loslassen zum Hochladen', style: TextStyle(color: pt.fgMuted, fontSize: 14), ), ], ), ), ), ), ); } } // Placeholder shown when no room is selected class NoChatSelected extends StatelessWidget { const NoChatSelected({super.key}); @override Widget build(BuildContext context) { final pt = PyramidTheme.of(context); return Container( color: pt.bg1, child: Center( child: Column( mainAxisSize: MainAxisSize.min, children: [ Icon(Icons.forum_outlined, size: 64, color: pt.fgDim), const SizedBox(height: 16), Text( 'Select a room to start chatting', style: TextStyle(color: pt.fgMuted, fontSize: 16), ), const SizedBox(height: 8), Text( 'Choose from the sidebar on the left', style: TextStyle(color: pt.fgDim, fontSize: 13), ), ], ), ), ); } }