major refactor
All checks were successful
Release / meta (push) Successful in 7s
Release / linux-build (push) Successful in 6m36s
Release / android-build (push) Successful in 15m50s
Release / release-master (push) Successful in 23s
Release / release-dev (push) Successful in 25s

This commit is contained in:
2025-12-16 16:49:39 +00:00
parent 4a6aee8a15
commit 80be797322
23 changed files with 1517 additions and 1414 deletions

View File

@@ -8,8 +8,8 @@ import 'package:intl/intl.dart';
import 'package:mileograph_flutter/components/calculator/calculator.dart';
import 'package:mileograph_flutter/components/pages/traction.dart';
import 'package:mileograph_flutter/objects/objects.dart';
import 'package:mileograph_flutter/services/apiService.dart';
import 'package:mileograph_flutter/services/dataService.dart';
import 'package:mileograph_flutter/services/api_service.dart';
import 'package:mileograph_flutter/services/data_service.dart';
import 'package:mileograph_flutter/services/navigation_guard.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
@@ -131,7 +131,7 @@ class _NewEntryPageState extends State<NewEntryPage> {
final controller = TextEditingController();
final result = await showDialog<String>(
context: context,
builder: (context) => AlertDialog(
builder: (dialogContext) => AlertDialog(
title: const Text('New Trip'),
content: TextField(
controller: controller,
@@ -140,25 +140,28 @@ class _NewEntryPageState extends State<NewEntryPage> {
),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(),
onPressed: () => Navigator.of(dialogContext).pop(),
child: const Text('Cancel'),
),
ElevatedButton(
onPressed: () => Navigator.of(context).pop(controller.text.trim()),
onPressed: () => Navigator.of(dialogContext).pop(controller.text.trim()),
child: const Text('Add'),
),
],
),
);
if (!mounted) return;
if (!context.mounted) {
controller.dispose();
return;
}
if (result != null && result.isNotEmpty) {
final api = context.read<ApiService>();
final data = context.read<DataService>();
final messenger = ScaffoldMessenger.of(context);
final messenger = ScaffoldMessenger.maybeOf(context);
try {
await api.put('/trips/new', {"trip_name": result});
await data.fetchTrips();
if (!mounted) return;
if (!context.mounted) return;
final trips = data.tripList;
final match = trips.firstWhere(
(t) => t.tripName == result,
@@ -169,11 +172,15 @@ class _NewEntryPageState extends State<NewEntryPage> {
setState(() => _selectedTripId = match.tripId);
_saveDraft();
} catch (e) {
if (!mounted) return;
messenger.showSnackBar(
if (!context.mounted) return;
messenger?.showSnackBar(
SnackBar(content: Text('Failed to add trip: $e')),
);
} finally {
controller.dispose();
}
} else {
controller.dispose();
}
}
@@ -584,8 +591,11 @@ class _NewEntryPageState extends State<NewEntryPage> {
final confirmed = await _confirmDuplicateSubmission();
if (!confirmed) return;
}
setState(() => _submitting = true);
if (!mounted) return;
final api = context.read<ApiService>();
final dataService = context.read<DataService>();
final messenger = ScaffoldMessenger.maybeOf(context);
setState(() => _submitting = true);
final isEditingExisting = _isEditing && widget.editLegId != null;
try {
@@ -626,9 +636,9 @@ class _NewEntryPageState extends State<NewEntryPage> {
}
}
if (!mounted) return;
context.read<DataService>().refreshLegs();
dataService.refreshLegs();
if (!mounted) return;
ScaffoldMessenger.of(context).showSnackBar(
messenger?.showSnackBar(
SnackBar(
content: Text(
isEditingExisting ? 'Entry updated' : 'Entry submitted',
@@ -639,9 +649,9 @@ class _NewEntryPageState extends State<NewEntryPage> {
_activeDraftId = null;
} catch (e) {
if (!mounted) return;
ScaffoldMessenger.of(
context,
).showSnackBar(SnackBar(content: Text('Failed to submit: $e')));
messenger?.showSnackBar(
SnackBar(content: Text('Failed to submit: $e')),
);
} finally {
if (mounted) setState(() => _submitting = false);
}
@@ -1279,8 +1289,15 @@ class _NewEntryPageState extends State<NewEntryPage> {
);
}
return WillPopScope(
onWillPop: () => _handleExitIntent(),
return PopScope(
canPop: false,
onPopInvokedWithResult: (didPop, _) async {
if (didPop) return;
final allow = await _handleExitIntent();
if (allow && context.mounted) {
Navigator.of(context).maybePop();
}
},
child: Scaffold(
appBar: _isEditing
? AppBar(
@@ -1288,7 +1305,7 @@ class _NewEntryPageState extends State<NewEntryPage> {
icon: const Icon(Icons.arrow_back),
onPressed: () async {
if (!await _handleExitIntent()) return;
if (!mounted) return;
if (!context.mounted) return;
Navigator.of(context).maybePop();
},
),
@@ -1507,13 +1524,13 @@ class _DraftListBody extends StatefulWidget {
}
class _DraftListBodyState extends State<_DraftListBody> {
late List<_StoredDraft> _drafts = widget.drafts;
late final List<_StoredDraft> _drafts = List.of(widget.drafts);
@override
Widget build(BuildContext context) {
return ListView.separated(
itemCount: _drafts.length,
separatorBuilder: (_, __) => const Divider(height: 0),
separatorBuilder: (context, _) => const Divider(height: 0),
itemBuilder: (context, index) {
final draft = _drafts[index];
final routeLine = _draftSubtitle(draft);