aves_mio0.31/lib/widgets/activity/activity_files_page.dart.ok
2026-07-18 13:39:22 +02:00

164 lines
4.2 KiB
Text

// lib/widgets/activity/activity_files_page.dart
import 'dart:io';
import 'dart:typed_data';
import 'package:aves/model/activity/activity_track.dart';
import 'package:aves/utils/activity_file_parser.dart';
import 'package:aves/widgets/activity/activity_map_page.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
class ActivityFilesPage extends StatefulWidget {
static const routeName = '/activity';
const ActivityFilesPage({super.key});
@override
State<ActivityFilesPage> createState() => _ActivityFilesPageState();
}
class _ActivityFilesPageState extends State<ActivityFilesPage> {
final List<ActivityTrack> _activities = [];
Future<void> _pickActivityFile() async {
try {
final result = await FilePicker.platform.pickFiles(
type: FileType.any,
withData: true,
);
final pickedFile = result?.files.single;
if (pickedFile == null) return;
if (!ActivityFileParser.isSupportedFileName(pickedFile.name)) {
if (!mounted) return;
_showMessage('Seleziona un file GPX, TCX o FIT.');
return;
}
final bytes = await _readPickedFileBytes(pickedFile);
/*
final activity = await ActivityFileParser.parse(
bytes,
fileName: pickedFile.name,
);
if (activity.isEmpty) {
if (!mounted) return;
_showMessage('Nessuna traccia GPS valida trovata nel file.');
return;
}
if (!mounted) return;
setState(() {
_activities.add(activity);
});
*/
final activity = await ActivityFileParser.parse(
bytes,
fileName: pickedFile.name,
);
// 1) Controllo null
if (activity == null) {
if (!mounted) return;
_showMessage('Impossibile leggere il file attività.');
return;
}
// 2) Controllo traccia vuota
if (activity.isEmpty) {
if (!mounted) return;
_showMessage('Nessuna traccia GPS valida trovata nel file.');
return;
}
// 3) Ora activity è NON-null → si può aggiungere
if (!mounted) return;
setState(() {
_activities.add(activity!);
});
} catch (e) {
if (!mounted) return;
_showMessage('Impossibile leggere il file attività: $e');
}
}
Future<Uint8List> _readPickedFileBytes(PlatformFile pickedFile) async {
final bytes = pickedFile.bytes;
if (bytes != null) return bytes;
final path = pickedFile.path;
if (path == null) {
throw Exception('percorso file non disponibile');
}
return File(path).readAsBytes();
}
void _openActivity(ActivityTrack activity) {
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => ActivityMapPage(activity: activity),
),
);
}
void _showMessage(String message) {
ScaffoldMessenger.maybeOf(context)?.showSnackBar(
SnackBar(
content: Text(message),
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Attività'),
actions: [
IconButton(
icon: const Icon(Icons.add),
tooltip: 'Apri file attività',
onPressed: _pickActivityFile,
),
],
),
body: _activities.isEmpty
? Center(
child: TextButton.icon(
onPressed: _pickActivityFile,
icon: const Icon(Icons.upload_file),
label: const Text('Apri file GPX, TCX o FIT'),
),
)
: ListView.builder(
itemCount: _activities.length,
itemBuilder: (context, index) {
final activity = _activities[index];
return ListTile(
leading: const Icon(Icons.route),
title: Text(activity.name),
subtitle: Text(
[
activity.sportLabel,
activity.distanceLabel,
activity.elevationGainLabel,
activity.durationLabel,
'${activity.pointCount} punti',
].join(' · '),
),
onTap: () => _openActivity(activity),
);
},
),
);
}
}