Initial commit: COPILOT D6 Flutter keyboard controller
Flutter web app replacing legacy WPF CCTV surveillance keyboard controller. Includes wall overview, section view with monitor grid, camera input, PTZ control, alarm/lock/sequence BLoCs, and legacy-matching UI styling. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,120 @@
|
||||
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<ConnectionEvent, ConnectionState> {
|
||||
final BridgeService _bridgeService;
|
||||
final AppConfig _config;
|
||||
StreamSubscription? _statusSubscription;
|
||||
|
||||
ConnectionBloc({
|
||||
required BridgeService bridgeService,
|
||||
required AppConfig config,
|
||||
}) : _bridgeService = bridgeService,
|
||||
_config = config,
|
||||
super(const ConnectionState()) {
|
||||
on<ConnectAll>(_onConnectAll);
|
||||
on<ConnectServer>(_onConnectServer);
|
||||
on<DisconnectServer>(_onDisconnectServer);
|
||||
on<DisconnectAll>(_onDisconnectAll);
|
||||
on<RetryConnections>(_onRetryConnections);
|
||||
on<ConnectionStatusUpdated>(_onConnectionStatusUpdated);
|
||||
|
||||
// Subscribe to connection status changes
|
||||
_statusSubscription = _bridgeService.connectionStatus.listen((status) {
|
||||
add(ConnectionStatusUpdated(status));
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _onConnectAll(
|
||||
ConnectAll event,
|
||||
Emitter<ConnectionState> emit,
|
||||
) async {
|
||||
emit(state.copyWith(overallStatus: ConnectionOverallStatus.connecting));
|
||||
|
||||
try {
|
||||
await _bridgeService.connectAll();
|
||||
} catch (e) {
|
||||
emit(state.copyWith(
|
||||
overallStatus: ConnectionOverallStatus.disconnected,
|
||||
error: e.toString(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _onConnectServer(
|
||||
ConnectServer event,
|
||||
Emitter<ConnectionState> emit,
|
||||
) async {
|
||||
try {
|
||||
await _bridgeService.connect(event.serverId);
|
||||
} catch (e) {
|
||||
emit(state.copyWith(error: 'Failed to connect to ${event.serverId}: $e'));
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _onDisconnectServer(
|
||||
DisconnectServer event,
|
||||
Emitter<ConnectionState> emit,
|
||||
) async {
|
||||
await _bridgeService.disconnect(event.serverId);
|
||||
}
|
||||
|
||||
Future<void> _onDisconnectAll(
|
||||
DisconnectAll event,
|
||||
Emitter<ConnectionState> emit,
|
||||
) async {
|
||||
await _bridgeService.disconnectAll();
|
||||
emit(state.copyWith(overallStatus: ConnectionOverallStatus.disconnected));
|
||||
}
|
||||
|
||||
Future<void> _onRetryConnections(
|
||||
RetryConnections event,
|
||||
Emitter<ConnectionState> 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<ConnectionState> 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<void> close() {
|
||||
_statusSubscription?.cancel();
|
||||
return super.close();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user