import 'package:flutter/material.dart'; import 'app_menu.dart'; import 'styles.dart'; import 'backend.dart'; import 'dart:async'; class Message { final String sender; final String text; final bool isFromUser; Message({required this.sender, required this.text}) : isFromUser = sender == "user"; Alignment get alignment => isFromUser ? Alignment.centerRight : Alignment.centerLeft; EdgeInsets get padding => isFromUser ? EdgeInsets.zero : const EdgeInsets.only(left: 10); } class ChatScreen extends StatefulWidget { final int chatId; ChatScreen({required this.chatId}); static Future> getChatMessages(int chatId) async { final response = await Backend.sendAction("get-chat-messages", {'chatId': chatId}); print("get-chat-messages response: $response"); List messageObjects = response['messages']; List messages = messageObjects.map((msg) => Message(sender: msg['sender'], text: msg['content'] as String)).toList(); return messages; } @override _ChatScreenState createState() => _ChatScreenState(); } class _ChatScreenState extends State { List _messages = []; final TextEditingController _textController = TextEditingController(); StreamSubscription? _chatSubscription; @override void initState() { super.initState(); _loadInitialMessages(); _chatSubscription = Backend.chatMessages(widget.chatId).listen((data) { final message = Message(sender: data['sender'], text: data['content']); if (!message.isFromUser) { addMessage(message); } }); } @override void dispose() { Backend.removeChatListener(widget.chatId); super.dispose(); } Future _loadInitialMessages() async { final initialMessages = await ChatScreen.getChatMessages(widget.chatId); setState(() { _messages.addAll(initialMessages); }); } void _handleNewMessage(Map message) { final newMessage = Message(sender: message['sender'], text: message['content'] as String); if (newMessage.sender!= "user") { setState(() { _messages.add(newMessage); }); } } void addMessage(Message message) { setState(() { _messages.add(message); }); } void sendMessage(String content) { _textController.clear(); final newMessage = Message(sender: "user", text: content); Backend.sendAction("send-chat-message", {'chatId': widget.chatId, 'content': content}).then((response) { if (response['error'] != null) { print("Error sending chat message: ${response['error']}"); } }); addMessage(newMessage); } Color getMessageColor(BuildContext context) { final backgroundColor = Theme.of(context).scaffoldBackgroundColor; final messageColor = Color.alphaBlend(Colors.white.withOpacity(0.1), backgroundColor); return messageColor; } @override Widget build(BuildContext context) { final isWideScreen = MediaQuery.of(context).size.width > 600; return Scaffold( appBar: AppBar( title: Text('Chat Room ${widget.chatId}'), actions: [ IconButton(icon: Icon(Icons.settings), onPressed: () { Navigator.push(context, MaterialPageRoute(builder: (_) => AppMenu())); }), ], ), body: Column( children: [ Expanded( child: ListView.builder( itemCount: _messages.length, itemBuilder: (context, index) { final message = _messages[index]; return Padding( padding: isWideScreen ? message.padding : EdgeInsets.zero, child: Align( alignment: isWideScreen ? Alignment.centerLeft : message.alignment, child: Container( margin: EdgeInsets.symmetric(vertical: 2, horizontal: 8), padding: EdgeInsets.all(10), decoration: BoxDecoration( color: getMessageColor(context), borderRadius: BorderRadius.circular(12), ), child: Text(message.text), ), ), ); }, ), ), Padding( padding: const EdgeInsets.all(8.0), child: Row( children: [ Expanded( child: TextField( controller: _textController, decoration: inputDecoration(), onSubmitted: sendMessage, // Send message on Enter key ), ), SizedBox(width: 8), ElevatedButton( onPressed: () { sendMessage(_textController.text); }, child: Text('Send'), ), ], ), ), ], ), ); } }