import 'dart:async'; import 'package:flutter_bloc/flutter_bloc.dart'; import '../../../config/app_config.dart'; import '../../../data/services/bridge_service.dart'; import 'connection_event.dart'; import 'connection_state.dart'; class ConnectionBloc extends Bloc { final BridgeService _bridgeService; final AppConfig _config; StreamSubscription? _statusSubscription; ConnectionBloc({ required BridgeService bridgeService, required AppConfig config, }) : _bridgeService = bridgeService, _config = config, super(const ConnectionState()) { on(_onConnectAll); on(_onConnectServer); on(_onDisconnectServer); on(_onDisconnectAll); on(_onRetryConnections); on(_onConnectionStatusUpdated); // Subscribe to connection status changes _statusSubscription = _bridgeService.connectionStatus.listen((status) { add(ConnectionStatusUpdated(status)); }); } Future _onConnectAll( ConnectAll event, Emitter emit, ) async { emit(state.copyWith(overallStatus: ConnectionOverallStatus.connecting)); try { await _bridgeService.connectAll(); } catch (e) { emit(state.copyWith( overallStatus: ConnectionOverallStatus.disconnected, error: e.toString(), )); } } Future _onConnectServer( ConnectServer event, Emitter emit, ) async { try { await _bridgeService.connect(event.serverId); } catch (e) { emit(state.copyWith(error: 'Failed to connect to ${event.serverId}: $e')); } } Future _onDisconnectServer( DisconnectServer event, Emitter emit, ) async { await _bridgeService.disconnect(event.serverId); } Future _onDisconnectAll( DisconnectAll event, Emitter emit, ) async { await _bridgeService.disconnectAll(); emit(state.copyWith(overallStatus: ConnectionOverallStatus.disconnected)); } Future _onRetryConnections( RetryConnections event, Emitter emit, ) async { // Retry only disconnected servers final disconnected = state.serverStatus.entries .where((e) => !e.value) .map((e) => e.key) .toList(); for (final serverId in disconnected) { await _bridgeService.connect(serverId); } } void _onConnectionStatusUpdated( ConnectionStatusUpdated event, Emitter emit, ) { final status = event.status; ConnectionOverallStatus overall; if (status.isEmpty) { overall = ConnectionOverallStatus.disconnected; } else if (status.values.every((v) => v)) { overall = ConnectionOverallStatus.connected; } else if (status.values.any((v) => v)) { overall = ConnectionOverallStatus.partial; } else { overall = ConnectionOverallStatus.disconnected; } emit(state.copyWith( overallStatus: overall, serverStatus: status, error: null, )); } @override Future close() { _statusSubscription?.cancel(); return super.close(); } }