Refactor excursion_main.dart to implement a confirmation dialog on page exit, allowing users to save templates or exit without saving. Update TrackingService to support instance reset for better state management.
This commit is contained in:
@@ -458,96 +458,148 @@ class _ExcursionMainState extends State<ExcursionMain> {
|
||||
),
|
||||
];
|
||||
|
||||
// Begin of widget tree
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(AppLocalizations.of(context)!.excursion),
|
||||
actions: [
|
||||
// Text(TrackingService().isTracking ? "Tracking" : "Not tracking")
|
||||
Image.asset(
|
||||
TrackingService().isTracking ? "assets/icons/tracking_on.png" : "assets/icons/tracking_off.png",
|
||||
width: 40,
|
||||
),
|
||||
],
|
||||
),
|
||||
body: PageTransitionSwitcher(
|
||||
duration: const Duration(microseconds: 800),
|
||||
transitionBuilder: (
|
||||
Widget child,
|
||||
Animation<double> animation,
|
||||
Animation<double> secondaryAnimation,
|
||||
) {
|
||||
return SharedAxisTransition(
|
||||
animation: animation,
|
||||
secondaryAnimation: secondaryAnimation,
|
||||
transitionType: SharedAxisTransitionType.vertical,
|
||||
child: child,
|
||||
);
|
||||
},
|
||||
child: Stepper(
|
||||
key: ValueKey<int>(currentStep),
|
||||
steps: getSteps(),
|
||||
currentStep: currentStep,
|
||||
onStepTapped: (value) {
|
||||
setState(() {
|
||||
currentStep = value;
|
||||
});
|
||||
return PopScope(
|
||||
canPop: false,
|
||||
onPopInvoked: (didPop) async {
|
||||
if (didPop) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Show confirmation dialog
|
||||
final result = await showDialog<int>(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog(
|
||||
title: const Text('Seite verlassen?'),
|
||||
content: const Text('Möchten Sie die Seite wirklich verlassen?'),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.of(context).pop(0),
|
||||
child: const Text('Nein'),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () => Navigator.of(context).pop(1),
|
||||
child: const Text('Ja und Template speichern'),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () => Navigator.of(context).pop(2),
|
||||
child: const Text('Ja ohne Template'),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
if (result == null || result == 0) {
|
||||
return;
|
||||
} else if (result == 1) {
|
||||
// Save as template and leave
|
||||
if (context.mounted) {
|
||||
saveTemplate(
|
||||
getFieldsText(),
|
||||
DatabasesEnum.excursion,
|
||||
);
|
||||
}
|
||||
TrackingService.resetInstance();
|
||||
if (context.mounted) {
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
} else {
|
||||
// Just leave without saving
|
||||
TrackingService.resetInstance();
|
||||
if (context.mounted) {
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
}
|
||||
},
|
||||
child: Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(AppLocalizations.of(context)!.excursion),
|
||||
actions: [
|
||||
// Text(TrackingService().isTracking ? "Tracking" : "Not tracking")
|
||||
Image.asset(
|
||||
TrackingService().isTracking ? "assets/icons/tracking_on.png" : "assets/icons/tracking_off.png",
|
||||
width: 40,
|
||||
),
|
||||
],
|
||||
),
|
||||
body: PageTransitionSwitcher(
|
||||
duration: const Duration(microseconds: 800),
|
||||
transitionBuilder: (
|
||||
Widget child,
|
||||
Animation<double> animation,
|
||||
Animation<double> secondaryAnimation,
|
||||
) {
|
||||
return SharedAxisTransition(
|
||||
animation: animation,
|
||||
secondaryAnimation: secondaryAnimation,
|
||||
transitionType: SharedAxisTransitionType.vertical,
|
||||
child: child,
|
||||
);
|
||||
},
|
||||
onStepContinue: () async {
|
||||
final isLastStep = currentStep == getSteps().length - 1;
|
||||
|
||||
if (!isLastStep) {
|
||||
var res = await saveTemplate(
|
||||
getFieldsText(),
|
||||
DatabasesEnum.excursion,
|
||||
);
|
||||
|
||||
isTemplate = true;
|
||||
child: Stepper(
|
||||
key: ValueKey<int>(currentStep),
|
||||
steps: getSteps(),
|
||||
currentStep: currentStep,
|
||||
onStepTapped: (value) {
|
||||
setState(() {
|
||||
rmap["ID"]!["controller"]!.text = res.toString();
|
||||
currentStep += 1;
|
||||
currentStep = value;
|
||||
});
|
||||
} else {
|
||||
if (widget.isSent) {
|
||||
Navigator.pushNamedAndRemoveUntil(
|
||||
context,
|
||||
'/home',
|
||||
(route) => false,
|
||||
);
|
||||
return;
|
||||
}
|
||||
},
|
||||
onStepContinue: () async {
|
||||
final isLastStep = currentStep == getSteps().length - 1;
|
||||
|
||||
bool empty = CheckRequired.checkRequired(rmap);
|
||||
// for debugging always false
|
||||
// empty = false;
|
||||
|
||||
if (empty) {
|
||||
AddEntriesDialogHelper.showTemplateDialog(
|
||||
context,
|
||||
if (!isLastStep) {
|
||||
var res = await saveTemplate(
|
||||
getFieldsText(),
|
||||
DatabasesEnum.excursion,
|
||||
);
|
||||
return;
|
||||
|
||||
isTemplate = true;
|
||||
setState(() {
|
||||
rmap["ID"]!["controller"]!.text = res.toString();
|
||||
currentStep += 1;
|
||||
});
|
||||
} else {
|
||||
bool pop = await AddEntriesDialogHelper.showSaveOptionsDialog(
|
||||
context,
|
||||
getFieldsText(),
|
||||
widget.isTemplate,
|
||||
DatabasesEnum.excursion,
|
||||
);
|
||||
if (pop && context.mounted) Navigator.of(context).pop();
|
||||
if (widget.isSent) {
|
||||
Navigator.pushNamedAndRemoveUntil(
|
||||
context,
|
||||
'/home',
|
||||
(route) => false,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
bool empty = CheckRequired.checkRequired(rmap);
|
||||
// for debugging always false
|
||||
// empty = false;
|
||||
|
||||
if (empty) {
|
||||
AddEntriesDialogHelper.showTemplateDialog(
|
||||
context,
|
||||
getFieldsText(),
|
||||
DatabasesEnum.excursion,
|
||||
);
|
||||
return;
|
||||
} else {
|
||||
bool pop = await AddEntriesDialogHelper.showSaveOptionsDialog(
|
||||
context,
|
||||
getFieldsText(),
|
||||
widget.isTemplate,
|
||||
DatabasesEnum.excursion,
|
||||
);
|
||||
if (pop && context.mounted) Navigator.of(context).pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
onStepCancel: () {
|
||||
if (currentStep == 0) {
|
||||
Navigator.pop(context);
|
||||
} else {
|
||||
setState(() {
|
||||
currentStep -= 1;
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
onStepCancel: () {
|
||||
if (currentStep == 0) {
|
||||
Navigator.pop(context);
|
||||
} else {
|
||||
setState(() {
|
||||
currentStep -= 1;
|
||||
});
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -9,10 +9,22 @@ import 'package:latlong2/latlong.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
class TrackingService {
|
||||
static final TrackingService _instance = TrackingService._internal();
|
||||
factory TrackingService() => _instance;
|
||||
static TrackingService? _instance;
|
||||
|
||||
factory TrackingService() {
|
||||
_instance ??= TrackingService._internal();
|
||||
return _instance!;
|
||||
}
|
||||
|
||||
TrackingService._internal();
|
||||
|
||||
static void resetInstance() {
|
||||
if (_instance != null) {
|
||||
_instance!.dispose();
|
||||
_instance = null;
|
||||
}
|
||||
}
|
||||
|
||||
List<LatLng> pathList = [];
|
||||
List<double> accuracyList = [];
|
||||
Timer? _positionTimer;
|
||||
|
||||
Reference in New Issue
Block a user