218 lines
6.8 KiB
Dart
218 lines
6.8 KiB
Dart
// lib/widgets/activity/dialogs/activity_db_fields_dialog.dart
|
|
import 'package:aves/model/activity/activity_entry.dart';
|
|
import 'package:aves/widgets/activity/utils/activity_formatters.dart';
|
|
import 'package:flutter/material.dart';
|
|
|
|
Future<void> showActivityDbFieldsDialog({
|
|
required BuildContext context,
|
|
required ActivityEntry entry,
|
|
}) async {
|
|
final rows = _activityEntryDbRows(entry);
|
|
|
|
await showDialog<void>(
|
|
context: context,
|
|
builder: (context) {
|
|
return AlertDialog(
|
|
title: const Text('Dettagli DB attività'),
|
|
content: SizedBox(
|
|
width: double.maxFinite,
|
|
child: SingleChildScrollView(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: rows
|
|
.map(
|
|
(row) => _DbFieldLine(
|
|
label: row.$1,
|
|
value: row.$2,
|
|
),
|
|
)
|
|
.toList(),
|
|
),
|
|
),
|
|
),
|
|
actions: [
|
|
TextButton(
|
|
onPressed: () => Navigator.of(context).pop(),
|
|
child: const Text('Chiudi'),
|
|
),
|
|
],
|
|
);
|
|
},
|
|
);
|
|
}
|
|
|
|
List<(String, String)> _activityEntryDbRows(ActivityEntry e) {
|
|
String v(Object? value) {
|
|
if (value == null) return '-';
|
|
if (value is String && value.isEmpty) return '-';
|
|
return '$value';
|
|
}
|
|
|
|
String millisDate(int? millis) {
|
|
if (millis == null) return '-';
|
|
|
|
final date = DateTime.fromMillisecondsSinceEpoch(millis).toLocal();
|
|
|
|
final day = date.day.toString().padLeft(2, '0');
|
|
final month = date.month.toString().padLeft(2, '0');
|
|
final year = date.year.toString().padLeft(4, '0');
|
|
final hour = date.hour.toString().padLeft(2, '0');
|
|
final minute = date.minute.toString().padLeft(2, '0');
|
|
final second = date.second.toString().padLeft(2, '0');
|
|
|
|
return '$day/$month/$year $hour:$minute:$second';
|
|
}
|
|
|
|
String millisValue(int? millis) {
|
|
if (millis == null) return '-';
|
|
return '$millis (${millisDate(millis)})';
|
|
}
|
|
|
|
String bytes(int? value) {
|
|
if (value == null) return '-';
|
|
|
|
if (value >= 1024 * 1024) {
|
|
return '${(value / (1024 * 1024)).toStringAsFixed(2)} MB ($value bytes)';
|
|
}
|
|
|
|
if (value >= 1024) {
|
|
return '${(value / 1024).toStringAsFixed(2)} KB ($value bytes)';
|
|
}
|
|
|
|
return '$value bytes';
|
|
}
|
|
|
|
String distance(double? meters) {
|
|
if (meters == null) return '-';
|
|
return '${(meters / 1000).toStringAsFixed(3)} km (${meters.toStringAsFixed(2)} m)';
|
|
}
|
|
|
|
String elevation(double? meters) {
|
|
if (meters == null) return '-';
|
|
return '${meters.toStringAsFixed(2)} m';
|
|
}
|
|
|
|
String speed(double? mps) {
|
|
if (mps == null) return '-';
|
|
|
|
final kmh = mps * 3.6;
|
|
return '${mps.toStringAsFixed(3)} m/s (${kmh.toStringAsFixed(2)} km/h)';
|
|
}
|
|
|
|
String pace(double? secPerKm) {
|
|
if (secPerKm == null) return '-';
|
|
|
|
final totalSeconds = secPerKm.round();
|
|
final minutes = totalSeconds ~/ 60;
|
|
final seconds = totalSeconds % 60;
|
|
|
|
return '${minutes}m ${seconds.toString().padLeft(2, '0')}s / km (${secPerKm.toStringAsFixed(2)} s/km)';
|
|
}
|
|
|
|
String coordinate(double? value) {
|
|
if (value == null) return '-';
|
|
return value.toStringAsFixed(7);
|
|
}
|
|
|
|
return [
|
|
('id', v(e.id)),
|
|
('origin', v(e.origin)),
|
|
('uri', v(e.uri)),
|
|
('relativePath', v(e.relativePath)),
|
|
('directoryName', v(e.directoryName)),
|
|
('fileName', v(e.fileName)),
|
|
('fileExtension', v(e.fileExtension)),
|
|
('format', v(e.format)),
|
|
('bestName', v(e.bestName)),
|
|
('displayName', v(e.displayName)),
|
|
('routeName', v(e.routeName)),
|
|
('title', v(e.title)),
|
|
('description', v(e.description)),
|
|
('notes', v(e.notes)),
|
|
('sport', v(e.sport)),
|
|
('activityType', v(e.activityType)),
|
|
('deviceManufacturer', v(e.deviceManufacturer)),
|
|
('deviceModel', v(e.deviceModel)),
|
|
('sourceApp', v(e.sourceApp)),
|
|
('startTimeMillis', millisValue(e.startTimeMillis)),
|
|
('endTimeMillis', millisValue(e.endTimeMillis)),
|
|
('durationMillis', v(e.durationMillis)),
|
|
('durationFormatted', ActivityFormatters.entryDuration(e.durationMillis)),
|
|
('distanceMeters', distance(e.distanceMeters)),
|
|
('elevationGainMeters', elevation(e.elevationGainMeters)),
|
|
('elevationLossMeters', elevation(e.elevationLossMeters)),
|
|
('minElevationMeters', elevation(e.minElevationMeters)),
|
|
('maxElevationMeters', elevation(e.maxElevationMeters)),
|
|
('fileDistanceMeters', distance(e.fileDistanceMeters)),
|
|
('fileElevationGainMeters', elevation(e.fileElevationGainMeters)),
|
|
('computedDistanceMeters', distance(e.computedDistanceMeters)),
|
|
('computedElevationGainMeters', elevation(e.computedElevationGainMeters)),
|
|
('averageSpeedMps', speed(e.averageSpeedMps)),
|
|
('maxSpeedMps', speed(e.maxSpeedMps)),
|
|
('averagePaceSecPerKm', pace(e.averagePaceSecPerKm)),
|
|
('averageHeartRate', v(e.averageHeartRate)),
|
|
('maxHeartRate', v(e.maxHeartRate)),
|
|
('averageCadence', v(e.averageCadence)),
|
|
('maxCadence', v(e.maxCadence)),
|
|
('calories', v(e.calories)),
|
|
('powerAvg', v(e.powerAvg)),
|
|
('powerMax', v(e.powerMax)),
|
|
('pointCount', v(e.pointCount)),
|
|
('segmentCount', v(e.segmentCount)),
|
|
('lapCount', v(e.lapCount)),
|
|
('minLatitude', coordinate(e.minLatitude)),
|
|
('maxLatitude', coordinate(e.maxLatitude)),
|
|
('minLongitude', coordinate(e.minLongitude)),
|
|
('maxLongitude', coordinate(e.maxLongitude)),
|
|
('centerLatitude', coordinate(e.centerLatitude)),
|
|
('centerLongitude', coordinate(e.centerLongitude)),
|
|
('sizeBytes', bytes(e.sizeBytes)),
|
|
('lastModifiedMillis', millisValue(e.lastModifiedMillis)),
|
|
('dateAddedMillis', millisValue(e.dateAddedMillis)),
|
|
('dateModifiedMillis', millisValue(e.dateModifiedMillis)),
|
|
('lastScanMillis', millisValue(e.lastScanMillis)),
|
|
('isFavorite', v(e.isFavorite)),
|
|
('isHidden', v(e.isHidden)),
|
|
('rating', v(e.rating)),
|
|
('tags', v(e.tags)),
|
|
('scanStatus', v(e.scanStatus)),
|
|
('scanError', v(e.scanError)),
|
|
('diagnostics', v(e.diagnostics)),
|
|
];
|
|
}
|
|
|
|
class _DbFieldLine extends StatelessWidget {
|
|
final String label;
|
|
final String value;
|
|
|
|
const _DbFieldLine({
|
|
required this.label,
|
|
required this.value,
|
|
});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final theme = Theme.of(context);
|
|
|
|
return Padding(
|
|
padding: const EdgeInsets.symmetric(vertical: 4),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(
|
|
label,
|
|
style: theme.textTheme.labelMedium?.copyWith(
|
|
fontWeight: FontWeight.w700,
|
|
),
|
|
),
|
|
const SizedBox(height: 2),
|
|
SelectableText(
|
|
value,
|
|
style: theme.textTheme.bodySmall,
|
|
),
|
|
const Divider(height: 12),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|