import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import '../providers/auth_provider.dart'; import '../providers/chat_provider.dart'; import '../widgets/message_bubble.dart'; import '../services/chat_service.dart'; import 'sessions_screen.dart'; class ChatScreen extends StatefulWidget { const ChatScreen({super.key}); @override State createState() => _ChatScreenState(); } class _ChatScreenState extends State { final _messageController = TextEditingController(); final _scrollController = ScrollController(); final _focusNode = FocusNode(); @override void dispose() { _messageController.dispose(); _scrollController.dispose(); _focusNode.dispose(); super.dispose(); } void _sendMessage() { final message = _messageController.text.trim(); if (message.isEmpty) return; context.read().sendMessage(message); _messageController.clear(); _scrollToBottom(); } void _scrollToBottom() { WidgetsBinding.instance.addPostFrameCallback((_) { if (_scrollController.hasClients) { _scrollController.animateTo( _scrollController.position.maxScrollExtent, duration: const Duration(milliseconds: 300), curve: Curves.easeOut, ); } }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Captain Claude'), actions: [ // Connection status Consumer( builder: (context, chat, _) { final color = switch (chat.connectionState) { ChatConnectionState.connected => Colors.green, ChatConnectionState.connecting => Colors.orange, _ => Colors.red, }; return Padding( padding: const EdgeInsets.only(right: 8), child: Icon(Icons.circle, size: 12, color: color), ); }, ), // Terminal sessions IconButton( icon: const Icon(Icons.terminal), onPressed: () { Navigator.push( context, MaterialPageRoute(builder: (_) => const SessionsScreen()), ); }, tooltip: 'Screen Sessions', ), // New conversation IconButton( icon: const Icon(Icons.add), onPressed: () { context.read().clearMessages(); }, tooltip: 'New Conversation', ), // Logout PopupMenuButton( itemBuilder: (context) => [ const PopupMenuItem( value: 'logout', child: Row( children: [ Icon(Icons.logout), SizedBox(width: 8), Text('Logout'), ], ), ), ], onSelected: (value) { if (value == 'logout') { context.read().logout(); } }, ), ], ), body: Column( children: [ // Messages Expanded( child: Consumer( builder: (context, chat, _) { if (chat.messages.isEmpty) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( Icons.chat_bubble_outline, size: 64, color: Colors.grey.shade600, ), const SizedBox(height: 16), Text( 'Start a conversation', style: TextStyle( color: Colors.grey.shade500, fontSize: 16, ), ), ], ), ); } WidgetsBinding.instance.addPostFrameCallback((_) { _scrollToBottom(); }); return ListView.builder( controller: _scrollController, padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), itemCount: chat.messages.length, itemBuilder: (context, index) { final message = chat.messages[index]; return MessageBubble(message: message); }, ); }, ), ), // Typing indicator Consumer( builder: (context, chat, _) { if (!chat.isTyping) return const SizedBox.shrink(); return Container( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), alignment: Alignment.centerLeft, child: Row( children: [ SizedBox( width: 16, height: 16, child: CircularProgressIndicator( strokeWidth: 2, color: Theme.of(context).colorScheme.primary, ), ), const SizedBox(width: 8), Text( 'Captain is typing...', style: TextStyle(color: Colors.grey.shade500), ), ], ), ); }, ), // Input Container( padding: const EdgeInsets.all(8), decoration: BoxDecoration( color: const Color(0xFF2D2D2D), border: Border( top: BorderSide(color: Colors.grey.shade800), ), ), child: SafeArea( child: Row( children: [ // Attach file button IconButton( icon: const Icon(Icons.attach_file), onPressed: () { // TODO: Implement file picker ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('File attachment coming soon')), ); }, ), // Text input Expanded( child: TextField( controller: _messageController, focusNode: _focusNode, decoration: const InputDecoration( hintText: 'Message Captain Claude...', border: InputBorder.none, contentPadding: EdgeInsets.symmetric( horizontal: 16, vertical: 12, ), ), maxLines: 5, minLines: 1, textInputAction: TextInputAction.send, onSubmitted: (_) => _sendMessage(), ), ), // Send button Consumer( builder: (context, chat, _) { return IconButton( icon: const Icon(Icons.send), onPressed: chat.isConnected ? _sendMessage : null, color: Theme.of(context).colorScheme.primary, ); }, ), ], ), ), ), ], ), ); } }