import 'dart:async'; import 'dart:convert'; import 'package:web_socket_channel/web_socket_channel.dart'; class ChatMessage { final String type; final String username; final String content; final String roomId; ChatMessage({required this.type, required this.username, required this.content, required this.roomId}); factory ChatMessage.fromJson(Map json) { return ChatMessage( type: json['type'] ?? 'chat', username: json['username'] ?? 'Anonymous', content: json['content'] ?? '', roomId: json['room_id'] ?? '', ); } Map toJson() => { 'type': type, 'username': username, 'content': content, 'room_id': roomId, }; } class ChatService { WebSocketChannel? _channel; final StreamController _messageController = StreamController.broadcast(); Stream get messages => _messageController.stream; void connect(String baseUrl, String roomId, String username) { final wsUri = Uri.parse(baseUrl).replace(scheme: 'ws', path: '/api/ws/room/$roomId', queryParameters: {'username': username}); _channel = WebSocketChannel.connect(wsUri); _channel!.stream.listen((data) { final json = jsonDecode(data); _messageController.add(ChatMessage.fromJson(json)); }, onError: (err) { print("[WS ERROR] $err"); }, onDone: () { print("[WS DONE] Connection closed"); }); } void sendMessage(String content, String username, String roomId, {String type = 'chat'}) { if (_channel != null) { final msg = ChatMessage(type: type, username: username, content: content, roomId: roomId); _channel!.sink.add(jsonEncode(msg.toJson())); } } void dispose() { _channel?.sink.close(); _messageController.close(); } }