Files
BrandManager/lib/models/last_heard_item.dart
2026-01-29 08:48:58 +01:00

158 lines
4.5 KiB
Dart

class LastHeardItem {
final String linkName;
final String sessionID;
final int linkType;
final int contextID;
final int sessionType;
final int slot;
final int sourceID;
final int destinationID;
final String route;
final String linkCall;
final String sourceCall;
final String? sourceName;
final String destinationCall;
final String? destinationName;
final int start;
final int stop;
final int? rssi;
final int? ber;
final int reflectorID;
final String linkTypeName;
final List<String> callTypes;
final int lossCount;
final int totalCount;
final String master;
final String? talkerAlias;
final int flagSet;
final String event;
LastHeardItem({
required this.linkName,
required this.sessionID,
required this.linkType,
required this.contextID,
required this.sessionType,
required this.slot,
required this.sourceID,
required this.destinationID,
required this.route,
required this.linkCall,
required this.sourceCall,
this.sourceName,
required this.destinationCall,
this.destinationName,
required this.start,
required this.stop,
this.rssi,
this.ber,
required this.reflectorID,
required this.linkTypeName,
required this.callTypes,
required this.lossCount,
required this.totalCount,
required this.master,
this.talkerAlias,
required this.flagSet,
required this.event,
});
factory LastHeardItem.fromJson(Map<String, dynamic> json) {
int? _toInt(dynamic value) {
if (value == null) return null;
if (value is int) return value;
if (value is double) return value.toInt();
if (value is String) return int.tryParse(value);
return null;
}
String _toString(dynamic value) {
if (value == null) return '';
return value.toString();
}
String? _toStringOrNull(dynamic value) {
if (value == null) return null;
return value.toString();
}
return LastHeardItem(
linkName: _toString(json['LinkName']),
sessionID: _toString(json['SessionID']),
linkType: _toInt(json['LinkType']) ?? 0,
contextID: _toInt(json['ContextID']) ?? 0,
sessionType: _toInt(json['SessionType']) ?? 0,
slot: _toInt(json['Slot']) ?? 0,
sourceID: _toInt(json['SourceID']) ?? 0,
destinationID: _toInt(json['DestinationID']) ?? 0,
route: _toString(json['Route']),
linkCall: _toString(json['LinkCall']),
sourceCall: _toString(json['SourceCall']),
sourceName: _toStringOrNull(json['SourceName']),
destinationCall: _toString(json['DestinationCall']),
destinationName: _toStringOrNull(json['DestinationName']),
start: _toInt(json['Start']) ?? 0,
stop: _toInt(json['Stop']) ?? 0,
rssi: _toInt(json['RSSI']),
ber: _toInt(json['BER']),
reflectorID: _toInt(json['ReflectorID']) ?? 0,
linkTypeName: _toString(json['LinkTypeName']),
callTypes: (json['CallTypes'] as List<dynamic>?)
?.map((e) => e.toString())
.toList() ??
[],
lossCount: _toInt(json['LossCount']) ?? 0,
totalCount: _toInt(json['TotalCount']) ?? 0,
master: _toString(json['Master']),
talkerAlias: _toStringOrNull(json['TalkerAlias']),
flagSet: _toInt(json['FlagSet']) ?? 0,
event: _toString(json['Event']),
);
}
String get displayName {
if (sourceName != null && sourceName!.isNotEmpty) {
return '$sourceCall ($sourceName)';
}
return sourceCall;
}
String get destinationDisplayName {
if (destinationName != null && destinationName!.isNotEmpty) {
return 'TG $destinationID $destinationName';
}
return 'TG $destinationID';
}
String get durationDisplay {
final durationSeconds = stop - start;
if (durationSeconds < 0) return '';
if (durationSeconds < 60) {
return '${durationSeconds}s';
} else {
final minutes = durationSeconds ~/ 60;
final seconds = durationSeconds % 60;
return seconds > 0 ? '${minutes}m ${seconds}s' : '${minutes}m';
}
}
DateTime get timestamp {
return DateTime.fromMillisecondsSinceEpoch(start * 1000);
}
String get timeAgo {
final now = DateTime.now();
final difference = now.difference(timestamp);
if (difference.inSeconds < 60) {
return '${difference.inSeconds}s ago';
} else if (difference.inMinutes < 60) {
return '${difference.inMinutes}m ago';
} else if (difference.inHours < 24) {
return '${difference.inHours}h ago';
} else {
return '${difference.inDays}d ago';
}
}
}