Files
PilotVault/Fly Agent App/lib/ui/format.dart
T
tajniak81andClaude Opus 5.5 3dd31b257a Add the Fly Agent App, a Remote ID companion to DJI Fly
A Flutter app that runs next to DJI Fly without the DJI SDK. It receives the
aircraft's Remote ID (Bluetooth, BT5, Wi-Fi NaN and Beacon) in a foreground
service, streams the paired aircraft to the hub over /ws/device, and turns
take-off to landing into a logbook entry filed through /api/flights, queued
when offline. Covers phases A0-A3 of the Fly Agent plan; needs no server change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 19:25:52 +02:00

55 lines
1.7 KiB
Dart

// Display formatting shared by the screens. Unknown values render as "—"
// rather than 0, so a missing Remote ID field never reads as a real reading.
String fmtMeters(double? m, {int digits = 0}) => m == null ? '—' : '${m.toStringAsFixed(digits)} m';
String fmtDistance(double? m) {
if (m == null) return '—';
if (m < 1000) return '${m.round()} m';
return '${(m / 1000).toStringAsFixed(2)} km';
}
String fmtSpeed(double? ms) => ms == null ? '—' : '${ms.toStringAsFixed(1)} m/s';
String fmtDuration(Duration d) {
final int h = d.inHours;
final String m = (d.inMinutes % 60).toString().padLeft(2, '0');
final String s = (d.inSeconds % 60).toString().padLeft(2, '0');
return h > 0 ? '$h:$m:$s' : '$m:$s';
}
String fmtAgo(DateTime t, [DateTime? now]) {
final Duration d = (now ?? DateTime.now()).difference(t);
if (d.inSeconds < 2) return 'now';
if (d.inSeconds < 60) return '${d.inSeconds} s ago';
if (d.inMinutes < 60) return '${d.inMinutes} min ago';
return '${d.inHours} h ago';
}
String fmtClock(DateTime t) {
final DateTime l = t.toLocal();
return '${l.hour.toString().padLeft(2, '0')}:${l.minute.toString().padLeft(2, '0')}';
}
const Map<String, String> purposeLabels = <String, String>{
'commercial': 'Commercial',
'hobby': 'Hobby',
'research': 'Research',
'public': 'Public service',
'club_area': 'Club area',
};
const Map<String, String> categoryLabels = <String, String>{
'open': 'Open',
'specific': 'Specific',
'certified': 'Certified',
};
String transportLabel(String t) => switch (t) {
'ble' => 'Bluetooth',
'ble5' => 'Bluetooth 5 LR',
'nan' => 'Wi-Fi NaN',
'beacon' => 'Wi-Fi Beacon',
_ => t,
};