import 'package:flutter/material.dart'; import '../models/session.dart'; import '../theme/app_theme.dart'; /// Side drawer showing session list with reordering, unread badges, and controls. class SessionDrawer extends StatelessWidget { final List sessions; final String? activeSessionId; final Map unreadCounts; final void Function(Session session) onSelect; final void Function(Session session) onRemove; final void Function(Session session, String newName) onRename; final void Function(int oldIndex, int newIndex) onReorder; final VoidCallback onNewSession; final VoidCallback onRefresh; const SessionDrawer({ super.key, required this.sessions, required this.activeSessionId, required this.unreadCounts, required this.onSelect, required this.onRemove, required this.onRename, required this.onReorder, required this.onNewSession, required this.onRefresh, }); @override Widget build(BuildContext context) { final isDark = Theme.of(context).brightness == Brightness.dark; return Drawer( child: SafeArea( child: Column( children: [ // Header Padding( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( 'Sessions', style: Theme.of(context).textTheme.titleLarge, ), IconButton( icon: const Icon(Icons.refresh, size: 22), onPressed: onRefresh, tooltip: 'Refresh sessions', ), ], ), ), const Divider(height: 1), // Session list Expanded( child: sessions.isEmpty ? const Center( child: Text( 'No sessions', style: TextStyle(color: AppColors.darkTextTertiary), ), ) : ReorderableListView.builder( itemCount: sessions.length, onReorder: onReorder, buildDefaultDragHandles: false, itemBuilder: (context, index) { final session = sessions[index]; final isActive = session.id == activeSessionId; final unread = unreadCounts[session.id] ?? 0; return Dismissible( key: ValueKey(session.id), direction: DismissDirection.endToStart, background: Container( color: AppColors.error, alignment: Alignment.centerRight, padding: const EdgeInsets.only(right: 16), child: const Icon(Icons.delete, color: Colors.white), ), confirmDismiss: (_) async { return await showDialog( context: context, builder: (ctx) => AlertDialog( title: const Text('Remove session?'), content: Text( 'Remove "${session.name}" from the list?'), actions: [ TextButton( onPressed: () => Navigator.pop(ctx, false), child: const Text('Cancel'), ), TextButton( onPressed: () => Navigator.pop(ctx, true), child: const Text('Remove', style: TextStyle( color: AppColors.error)), ), ], ), ); }, onDismissed: (_) => onRemove(session), child: ListTile( key: ValueKey('tile_${session.id}'), leading: Text( session.icon, style: const TextStyle(fontSize: 20), ), title: GestureDetector( onDoubleTap: () => _showRenameDialog(context, session), child: Text( session.name, style: TextStyle( fontWeight: isActive ? FontWeight.bold : FontWeight.normal, color: isActive ? AppColors.accent : null, ), maxLines: 1, overflow: TextOverflow.ellipsis, ), ), trailing: Row( mainAxisSize: MainAxisSize.min, children: [ if (unread > 0) Container( padding: const EdgeInsets.symmetric( horizontal: 6, vertical: 2), decoration: BoxDecoration( color: AppColors.unreadBadge, borderRadius: BorderRadius.circular(10), ), child: Text( '$unread', style: const TextStyle( color: Colors.white, fontSize: 11, fontWeight: FontWeight.bold, ), ), ), const SizedBox(width: 4), ReorderableDragStartListener( index: index, child: Icon( Icons.drag_handle, color: isDark ? AppColors.darkTextTertiary : Colors.grey.shade400, size: 20, ), ), ], ), selected: isActive, selectedTileColor: isDark ? Colors.white.withAlpha(10) : Colors.blue.withAlpha(15), onTap: () { onSelect(session); Navigator.pop(context); }, ), ); }, ), ), // New session button const Divider(height: 1), Padding( padding: const EdgeInsets.all(12), child: SizedBox( width: double.infinity, child: ElevatedButton.icon( onPressed: onNewSession, icon: const Icon(Icons.add, size: 20), label: const Text('New Session'), style: ElevatedButton.styleFrom( backgroundColor: AppColors.accent, foregroundColor: Colors.white, ), ), ), ), ], ), ), ); } void _showRenameDialog(BuildContext context, Session session) { final controller = TextEditingController(text: session.name); showDialog( context: context, builder: (ctx) => AlertDialog( title: const Text('Rename session'), content: TextField( controller: controller, autofocus: true, decoration: const InputDecoration(hintText: 'Session name'), onSubmitted: (value) { if (value.isNotEmpty) { onRename(session, value); } Navigator.pop(ctx); }, ), actions: [ TextButton( onPressed: () => Navigator.pop(ctx), child: const Text('Cancel'), ), TextButton( onPressed: () { if (controller.text.isNotEmpty) { onRename(session, controller.text); } Navigator.pop(ctx); }, child: const Text('Save'), ), ], ), ).then((_) => controller.dispose()); } }