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>
68 lines
2.2 KiB
Dart
68 lines
2.2 KiB
Dart
import 'package:logger/logger.dart';
|
|
|
|
import '../../domain/entities/function_button_config.dart';
|
|
import 'bridge_service.dart';
|
|
import 'coordination_service.dart';
|
|
|
|
/// Executes function button actions (F1-F7).
|
|
/// Ported from legacy FunctionButtonsService.cs.
|
|
class FunctionButtonService {
|
|
final BridgeService _bridgeService;
|
|
final CoordinationService _coordinationService;
|
|
final Logger _logger = Logger();
|
|
|
|
FunctionButtonConfig _config = const FunctionButtonConfig();
|
|
|
|
FunctionButtonService({
|
|
required BridgeService bridgeService,
|
|
required CoordinationService coordinationService,
|
|
}) : _bridgeService = bridgeService,
|
|
_coordinationService = coordinationService;
|
|
|
|
/// Load function button configuration.
|
|
void loadConfig(FunctionButtonConfig config) {
|
|
_config = config;
|
|
_logger.i('Loaded function button config: ${config.walls.length} walls');
|
|
}
|
|
|
|
/// Execute all actions for a button on a specific wall.
|
|
/// Actions are executed sequentially (like legacy).
|
|
Future<bool> execute(String wallId, String buttonKey) async {
|
|
final actions = _config.getActions(wallId, buttonKey);
|
|
if (actions.isEmpty) {
|
|
_logger.d('No actions for $buttonKey on wall $wallId');
|
|
return false;
|
|
}
|
|
|
|
_logger.i('Executing $buttonKey on wall $wallId (${actions.length} actions)');
|
|
|
|
for (final action in actions) {
|
|
try {
|
|
switch (action.type) {
|
|
case FunctionButtonActionType.crossSwitch:
|
|
await _bridgeService.viewerConnectLive(
|
|
action.viewerId, action.sourceId);
|
|
_logger.d(
|
|
'CrossSwitch: viewer ${action.viewerId} -> camera ${action.sourceId}');
|
|
|
|
case FunctionButtonActionType.sequenceStart:
|
|
await _coordinationService.startSequence(
|
|
action.viewerId, action.sourceId);
|
|
_logger.d(
|
|
'SequenceStart: viewer ${action.viewerId} -> sequence ${action.sourceId}');
|
|
}
|
|
} catch (e) {
|
|
_logger.e(
|
|
'Function button action failed: ${action.type.name} - $e');
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/// Check if a button has actions for a given wall.
|
|
bool hasActions(String wallId, String buttonKey) {
|
|
return _config.hasActions(wallId, buttonKey);
|
|
}
|
|
}
|