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:
123
copilot_keyboard/lib/domain/entities/camera_lock.dart
Normal file
123
copilot_keyboard/lib/domain/entities/camera_lock.dart
Normal file
@@ -0,0 +1,123 @@
|
||||
/// Camera lock entity matching the coordinator's CameraLock model.
|
||||
class CameraLock {
|
||||
final int cameraId;
|
||||
final CameraLockPriority priority;
|
||||
final String ownerName;
|
||||
final DateTime ownedSince;
|
||||
final DateTime expiresAt;
|
||||
|
||||
const CameraLock({
|
||||
required this.cameraId,
|
||||
required this.priority,
|
||||
required this.ownerName,
|
||||
required this.ownedSince,
|
||||
required this.expiresAt,
|
||||
});
|
||||
|
||||
factory CameraLock.fromJson(Map<String, dynamic> json) {
|
||||
return CameraLock(
|
||||
cameraId: json['cameraId'] as int? ?? json['CameraId'] as int? ?? 0,
|
||||
priority: CameraLockPriority.fromString(
|
||||
json['priority'] as String? ?? json['Priority'] as String? ?? 'Low'),
|
||||
ownerName:
|
||||
json['ownerName'] as String? ?? json['OwnerName'] as String? ?? '',
|
||||
ownedSince: DateTime.parse(
|
||||
json['ownedSince'] as String? ?? json['OwnedSince'] as String? ?? ''),
|
||||
expiresAt: DateTime.parse(
|
||||
json['expiresAt'] as String? ?? json['ExpiresAt'] as String? ?? ''),
|
||||
);
|
||||
}
|
||||
|
||||
Duration get timeRemaining {
|
||||
final remaining = expiresAt.difference(DateTime.now().toUtc());
|
||||
return remaining.isNegative ? Duration.zero : remaining;
|
||||
}
|
||||
|
||||
bool get isExpiringSoon => timeRemaining.inSeconds <= 60;
|
||||
bool get isExpired => timeRemaining == Duration.zero;
|
||||
bool isOwnedBy(String keyboardId) =>
|
||||
ownerName.toLowerCase() == keyboardId.toLowerCase();
|
||||
}
|
||||
|
||||
enum CameraLockPriority {
|
||||
none,
|
||||
high,
|
||||
low;
|
||||
|
||||
static CameraLockPriority fromString(String value) {
|
||||
switch (value.toLowerCase()) {
|
||||
case 'high':
|
||||
return CameraLockPriority.high;
|
||||
case 'low':
|
||||
return CameraLockPriority.low;
|
||||
default:
|
||||
return CameraLockPriority.none;
|
||||
}
|
||||
}
|
||||
|
||||
String get name {
|
||||
switch (this) {
|
||||
case CameraLockPriority.high:
|
||||
return 'High';
|
||||
case CameraLockPriority.low:
|
||||
return 'Low';
|
||||
case CameraLockPriority.none:
|
||||
return 'None';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum CameraLockNotificationType {
|
||||
acquired,
|
||||
takenOver,
|
||||
confirmTakeOver,
|
||||
confirmed,
|
||||
rejected,
|
||||
expireSoon,
|
||||
unlocked;
|
||||
|
||||
static CameraLockNotificationType fromString(String value) {
|
||||
switch (value) {
|
||||
case 'Acquired':
|
||||
return CameraLockNotificationType.acquired;
|
||||
case 'TakenOver':
|
||||
return CameraLockNotificationType.takenOver;
|
||||
case 'ConfirmTakeOver':
|
||||
return CameraLockNotificationType.confirmTakeOver;
|
||||
case 'Confirmed':
|
||||
return CameraLockNotificationType.confirmed;
|
||||
case 'Rejected':
|
||||
return CameraLockNotificationType.rejected;
|
||||
case 'ExpireSoon':
|
||||
return CameraLockNotificationType.expireSoon;
|
||||
case 'Unlocked':
|
||||
return CameraLockNotificationType.unlocked;
|
||||
default:
|
||||
return CameraLockNotificationType.acquired;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Lock notification from the coordinator (sent via WebSocket)
|
||||
class CameraLockNotification {
|
||||
final CameraLockNotificationType type;
|
||||
final int cameraId;
|
||||
final String copilotName;
|
||||
|
||||
const CameraLockNotification({
|
||||
required this.type,
|
||||
required this.cameraId,
|
||||
required this.copilotName,
|
||||
});
|
||||
|
||||
factory CameraLockNotification.fromJson(Map<String, dynamic> json) {
|
||||
return CameraLockNotification(
|
||||
type: CameraLockNotificationType.fromString(
|
||||
json['type'] as String? ?? json['Type'] as String? ?? ''),
|
||||
cameraId: json['cameraId'] as int? ?? json['CameraId'] as int? ?? 0,
|
||||
copilotName: json['copilotName'] as String? ??
|
||||
json['CopilotName'] as String? ??
|
||||
'',
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user