423 lines
15 KiB
Dart
423 lines
15 KiB
Dart
// * Helper class for managing entry-related dialogs
|
|
// * Provides various dialog types:
|
|
// * - Template creation dialog
|
|
// * - Save options dialog
|
|
// * - Server error handling dialog
|
|
// * - Location settings dialog
|
|
// * - Route deletion confirmation dialog
|
|
|
|
import 'package:fforte/enums/databases.dart';
|
|
import 'package:fforte/screens/helper/snack_bar_helper.dart';
|
|
import 'package:fforte/screens/sharedMethods/http_request.dart';
|
|
import 'package:fforte/screens/sharedMethods/save_file.dart';
|
|
import 'package:fforte/screens/sharedMethods/save_template.dart';
|
|
import 'package:fforte/screens/sharedMethods/save_main_entry.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:fforte/l10n/app_localizations.dart';
|
|
import 'package:geolocator/geolocator.dart';
|
|
|
|
/// Helper class for managing various dialogs related to adding and saving entries
|
|
class AddEntriesDialogHelper {
|
|
/// Show dialog for saving current data as a template
|
|
/// @param context The BuildContext to show the dialog in
|
|
/// @param saveData Map containing the data to save
|
|
/// @param dbType The type of database (place/excursion)
|
|
static Future<void> showTemplateDialog(
|
|
BuildContext context,
|
|
Map<String, String> saveData,
|
|
DatabasesEnum dbType,
|
|
) async {
|
|
return showDialog(
|
|
context: context,
|
|
barrierDismissible: false, // User must make a choice
|
|
builder: (BuildContext context) {
|
|
return AlertDialog(
|
|
title: Text(AppLocalizations.of(context)!.fieldEmpty),
|
|
actions: <Widget>[
|
|
// Cancel button
|
|
TextButton(
|
|
onPressed: () {
|
|
Navigator.of(context).pop();
|
|
},
|
|
child: Text(AppLocalizations.of(context)!.cancel),
|
|
),
|
|
// Save as template button
|
|
TextButton(
|
|
onPressed: () {
|
|
saveTemplate(saveData, dbType);
|
|
Navigator.pushNamedAndRemoveUntil(
|
|
context,
|
|
'/home',
|
|
(route) => false,
|
|
);
|
|
},
|
|
child: Text(AppLocalizations.of(context)!.template),
|
|
),
|
|
],
|
|
);
|
|
},
|
|
);
|
|
}
|
|
|
|
/// Show error dialog when server communication fails
|
|
/// Offers options to retry or cancel
|
|
/// @param context The BuildContext to show the dialog in
|
|
/// @param saveData Map containing the data to save
|
|
/// @param isTemplate Whether this is a template entry
|
|
/// @param dbType The type of database (place/excursion)
|
|
static Future<dynamic> showServerErrorDialog(
|
|
BuildContext context,
|
|
Map<String, String> saveData,
|
|
bool isTemplate,
|
|
DatabasesEnum dbType,
|
|
) {
|
|
bool isLoading = false;
|
|
|
|
return showDialog(
|
|
context: context,
|
|
builder: (context) {
|
|
return StatefulBuilder(
|
|
builder: (BuildContext context, StateSetter setState) {
|
|
return AlertDialog(
|
|
title: Text(AppLocalizations.of(context)!.servererrortitle),
|
|
content:
|
|
isLoading
|
|
? const SizedBox(
|
|
height: 100,
|
|
child: Center(child: CircularProgressIndicator()),
|
|
)
|
|
: null,
|
|
actions: [
|
|
// Retry button
|
|
if (!isLoading)
|
|
TextButton(
|
|
onPressed: () async {
|
|
setState(() => isLoading = true);
|
|
int errorCode = await HttpRequestService.httpRequest(
|
|
saveDataMap: saveData,
|
|
);
|
|
setState(() => isLoading = false);
|
|
|
|
if (errorCode == 200 && context.mounted) {
|
|
Navigator.pop(context);
|
|
SaveMainEntryMethod.saveEntry(
|
|
entryData: saveData,
|
|
isTemplate: isTemplate,
|
|
dbType: dbType,
|
|
sent: true
|
|
);
|
|
showSuccessDialog(context);
|
|
}
|
|
},
|
|
child: Text(AppLocalizations.of(context)!.sendagain),
|
|
),
|
|
// Cancel button
|
|
if (!isLoading)
|
|
TextButton(
|
|
onPressed: () {
|
|
Navigator.pop(context);
|
|
},
|
|
child: Text(AppLocalizations.of(context)!.cancel),
|
|
),
|
|
],
|
|
);
|
|
},
|
|
);
|
|
},
|
|
);
|
|
}
|
|
|
|
/// Show dialog with various save options
|
|
/// Options include:
|
|
/// - Save as template
|
|
/// - Send to server
|
|
/// - Save as file
|
|
/// - Save locally only
|
|
/// @param context The BuildContext to show the dialog in
|
|
/// @param saveData Map containing the data to save
|
|
/// @param isTemplate Whether this is a template entry
|
|
/// @param dbType The type of database (place/excursion)
|
|
/// @return bool Whether the operation was completed successfully
|
|
static Future<bool> showSaveOptionsDialog(
|
|
BuildContext context,
|
|
Map<String, String> saveData,
|
|
bool isTemplate,
|
|
DatabasesEnum dbType,
|
|
) async {
|
|
bool isLoading = false;
|
|
bool pop = false;
|
|
|
|
await showDialog(
|
|
context: context,
|
|
barrierDismissible: false, // User must make a choice
|
|
builder: (BuildContext context) {
|
|
return StatefulBuilder(
|
|
builder: (context, setState) {
|
|
return AlertDialog(
|
|
title:
|
|
isLoading
|
|
? Text(AppLocalizations.of(context)!.loading)
|
|
: Text(AppLocalizations.of(context)!.savemethod),
|
|
content:
|
|
isLoading
|
|
? const SizedBox(
|
|
height: 100,
|
|
child: Center(child: CircularProgressIndicator()),
|
|
)
|
|
: null,
|
|
actions: [
|
|
// Save as template button
|
|
if (!isLoading)
|
|
TextButton(
|
|
onPressed: () async {
|
|
pop = true;
|
|
setState(() => isLoading = true);
|
|
saveTemplate(saveData, dbType);
|
|
Navigator.pushNamedAndRemoveUntil(
|
|
context,
|
|
'/home',
|
|
(route) => false,
|
|
);
|
|
|
|
if (context.mounted) {
|
|
SnackBarHelper.showSnackBarMessage(
|
|
context,
|
|
AppLocalizations.of(context)!.erfolgreich,
|
|
);
|
|
}
|
|
},
|
|
child: Text(AppLocalizations.of(context)!.template),
|
|
),
|
|
// Send to server button
|
|
if (!isLoading)
|
|
TextButton(
|
|
onPressed: () async {
|
|
setState(() => isLoading = true);
|
|
int errorCode = await HttpRequestService.httpRequest(
|
|
saveDataMap: saveData,
|
|
);
|
|
setState(() => isLoading = false);
|
|
|
|
if (errorCode != 200 || !context.mounted) {
|
|
SaveMainEntryMethod.saveEntry(
|
|
entryData: saveData,
|
|
isTemplate: isTemplate,
|
|
dbType: dbType,
|
|
);
|
|
if (context.mounted) {
|
|
AddEntriesDialogHelper.showServerErrorDialog(
|
|
context,
|
|
saveData,
|
|
isTemplate,
|
|
dbType,
|
|
);
|
|
}
|
|
} else {
|
|
SaveMainEntryMethod.saveEntry(
|
|
entryData: saveData,
|
|
isTemplate: isTemplate,
|
|
dbType: dbType,
|
|
sent: true,
|
|
);
|
|
showSuccessDialog(context);
|
|
pop = true;
|
|
}
|
|
},
|
|
child: Text(AppLocalizations.of(context)!.sendtoserver),
|
|
),
|
|
// Save as file button
|
|
if (!isLoading)
|
|
TextButton(
|
|
onPressed: () async {
|
|
setState(() => isLoading = true);
|
|
|
|
try {
|
|
int id = await SaveMainEntryMethod.saveEntry(
|
|
entryData: saveData,
|
|
isTemplate: isTemplate,
|
|
dbType: dbType,
|
|
);
|
|
try {
|
|
if (context.mounted) {
|
|
await SaveFileMethod.saveFile(
|
|
saveData,
|
|
id,
|
|
dbType == DatabasesEnum.place
|
|
? AppLocalizations.of(context)!.justplace
|
|
: AppLocalizations.of(context)!.excursion,
|
|
dbType,
|
|
);
|
|
if (context.mounted) {
|
|
Navigator.of(context).pop();
|
|
SnackBarHelper.showSnackBarMessage(
|
|
context,
|
|
AppLocalizations.of(context)!.erfolgreich,
|
|
);
|
|
}
|
|
pop = true;
|
|
}
|
|
} catch (_) {
|
|
// User cancelled the file save dialog
|
|
}
|
|
setState(() => isLoading = false);
|
|
} catch (e) {
|
|
if (context.mounted) {
|
|
Navigator.pop(context);
|
|
SnackBarHelper.showSnackBarMessage(
|
|
context,
|
|
AppLocalizations.of(context)!.savefilefailed,
|
|
);
|
|
}
|
|
}
|
|
},
|
|
child: Text(AppLocalizations.of(context)!.saveasfile),
|
|
),
|
|
// Save locally only button
|
|
if (!isLoading)
|
|
TextButton(
|
|
onPressed: () {
|
|
try {
|
|
SaveMainEntryMethod.saveEntry(
|
|
entryData: saveData,
|
|
isTemplate: isTemplate,
|
|
dbType: dbType,
|
|
);
|
|
Navigator.pushNamedAndRemoveUntil(
|
|
context,
|
|
'/home',
|
|
(route) => false,
|
|
);
|
|
pop = true;
|
|
if (context.mounted) {
|
|
SnackBarHelper.showSnackBarMessage(
|
|
context,
|
|
AppLocalizations.of(context)!.erfolgreich,
|
|
);
|
|
}
|
|
} catch (e) {
|
|
debugPrint(e.toString());
|
|
}
|
|
},
|
|
child: Text(AppLocalizations.of(context)!.justsave),
|
|
),
|
|
// Cancel button
|
|
if (!isLoading)
|
|
TextButton(
|
|
onPressed: () {
|
|
Navigator.pop(context);
|
|
},
|
|
child: Text(AppLocalizations.of(context)!.cancel),
|
|
),
|
|
],
|
|
);
|
|
},
|
|
);
|
|
},
|
|
);
|
|
|
|
return pop;
|
|
}
|
|
|
|
/// Show success dialog after successful save operation
|
|
/// @param context The BuildContext to show the dialog in
|
|
static Future<void> showSuccessDialog(BuildContext context) async {
|
|
return showDialog(
|
|
context: context,
|
|
builder: (context) {
|
|
return AlertDialog(
|
|
title: Text(AppLocalizations.of(context)!.successful),
|
|
actions: [
|
|
TextButton(
|
|
onPressed: () {
|
|
Navigator.pushNamedAndRemoveUntil(
|
|
context,
|
|
'/home',
|
|
(route) => false,
|
|
);
|
|
},
|
|
child: Text(AppLocalizations.of(context)!.continueB),
|
|
),
|
|
],
|
|
);
|
|
},
|
|
);
|
|
}
|
|
|
|
/// Show dialog requesting location permission settings
|
|
/// @param context The BuildContext to show the dialog in
|
|
/// @return bool Whether the settings were changed
|
|
static Future<bool> locationSettingsDialog(BuildContext context) async {
|
|
bool reload = false;
|
|
|
|
await showDialog(
|
|
context: context,
|
|
barrierDismissible: true,
|
|
builder: (BuildContext context) {
|
|
return AlertDialog(
|
|
content: Text(AppLocalizations.of(context)!.needsAlwaysLocation),
|
|
actions: [
|
|
// Open settings button
|
|
TextButton(
|
|
onPressed: () async {
|
|
await Geolocator.openAppSettings();
|
|
if (context.mounted) Navigator.pop(context);
|
|
reload = true;
|
|
},
|
|
child: Text("Ok"),
|
|
),
|
|
// Cancel button
|
|
TextButton(
|
|
onPressed: () {
|
|
Navigator.of(context).pop();
|
|
},
|
|
child: Text(AppLocalizations.of(context)!.cancel),
|
|
),
|
|
],
|
|
);
|
|
},
|
|
);
|
|
return reload;
|
|
}
|
|
|
|
/// Show confirmation dialog for deleting entire route
|
|
/// @param context The BuildContext to show the dialog in
|
|
/// @return bool Whether deletion was confirmed
|
|
static Future<bool> deleteCompleteRouteDialog(BuildContext context) async {
|
|
bool confirmed = false;
|
|
|
|
await showDialog(
|
|
context: context,
|
|
barrierDismissible: true,
|
|
builder: (BuildContext context) {
|
|
return AlertDialog(
|
|
title: Text(AppLocalizations.of(context)!.deleteEverything),
|
|
content: SingleChildScrollView(
|
|
child: ListBody(
|
|
children: <Widget>[
|
|
Text(AppLocalizations.of(context)!.deleteWholeRouteBody),
|
|
],
|
|
),
|
|
),
|
|
actions: [
|
|
// Confirm delete button
|
|
TextButton(
|
|
onPressed: () {
|
|
confirmed = true;
|
|
Navigator.of(context).pop();
|
|
},
|
|
child: Text("Ok"),
|
|
),
|
|
// Cancel button
|
|
TextButton(
|
|
onPressed: () => {Navigator.of(context).pop()},
|
|
child: Text(AppLocalizations.of(context)!.cancel),
|
|
),
|
|
],
|
|
);
|
|
},
|
|
);
|
|
|
|
return confirmed;
|
|
}
|
|
}
|