import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:web_socket_channel/web_socket_channel.dart'; import 'package:web_socket_channel/status.dart' as status; // Estado del WebSocket class WSState { final bool connected; final String? error; final dynamic lastMessage; const WSState({ this.connected = false, this.error, this.lastMessage, }); WSState copyWith({ bool? connected, String? error, dynamic lastMessage, }) { return WSState( connected: connected ?? this.connected, error: error, lastMessage: lastMessage ?? this.lastMessage, ); } } class WSNotifier extends StateNotifier { WebSocketChannel? _channel; final String baseUrl; WSNotifier(this.baseUrl) : super(const WSState()); // Conectar a WebSocket de una dirección Future connect(String token, int addressId) async { try { final wsUrl = baseUrl.replaceFirst('https', 'wss').replaceFirst('http', 'ws'); final url = Uri.parse('$wsUrl/eta/ws/$addressId'); _channel = WebSocketChannel.connect(url); // Escuchar mensajes _channel?.stream.listen( (message) { state = state.copyWith( lastMessage: message, connected: true, error: null, ); }, onError: (error) { state = state.copyWith( connected: false, error: error.toString(), ); }, onDone: () { state = state.copyWith(connected: false); }, ); state = state.copyWith(connected: true, error: null); } catch (e) { state = state.copyWith(connected: false, error: e.toString()); } } // Enviar mensaje void send(String message) { if (_channel != null && state.connected) { _channel!.sink.add(message); } } // Desconectar void disconnect() { _channel?.sink.close(status.goingAway); state = state.copyWith(connected: false); } } final wsProvider = StateNotifierProvider((ref) { return WSNotifier('http://localhost:8000'); // Cambiar a URL de producción });