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