diff --git a/lib/l10n/arb/app_de.arb b/lib/l10n/arb/app_de.arb index 6aee6ee..7091586 100644 --- a/lib/l10n/arb/app_de.arb +++ b/lib/l10n/arb/app_de.arb @@ -79,7 +79,7 @@ "stats": "Statistiken", "successfully_added_player": "Spieler:in {playerName} erfolgreich hinzugefügt", "there_is_no_group_matching_your_search": "Es gibt keine Gruppe, die deiner Suche entspricht", - "this_cannot_be_undone": "Dies kann nicht rückgängig gemacht werden", + "this_cannot_be_undone": "Dies kann nicht rückgängig gemacht werden.", "today_at": "Heute um", "undo": "Rückgängig", "unknown_exception": "Unbekannter Fehler (siehe Konsole)", diff --git a/lib/l10n/arb/app_en.arb b/lib/l10n/arb/app_en.arb index c311050..6eb7613 100644 --- a/lib/l10n/arb/app_en.arb +++ b/lib/l10n/arb/app_en.arb @@ -356,7 +356,7 @@ "stats": "Stats", "successfully_added_player": "Successfully added player {playerName}", "there_is_no_group_matching_your_search": "There is no group matching your search", - "this_cannot_be_undone": "This can't be undone", + "this_cannot_be_undone": "This can't be undone.", "today_at": "Today at", "undo": "Undo", "unknown_exception": "Unknown Exception (see console)", diff --git a/lib/l10n/generated/app_localizations.dart b/lib/l10n/generated/app_localizations.dart index 399dc85..e78d69b 100644 --- a/lib/l10n/generated/app_localizations.dart +++ b/lib/l10n/generated/app_localizations.dart @@ -575,7 +575,7 @@ abstract class AppLocalizations { /// Warning message for irreversible actions /// /// In en, this message translates to: - /// **'This can\'t be undone'** + /// **'This can\'t be undone.'** String get this_cannot_be_undone; /// Date format for today diff --git a/lib/l10n/generated/app_localizations_de.dart b/lib/l10n/generated/app_localizations_de.dart index f4d0f8c..8ecc0a7 100644 --- a/lib/l10n/generated/app_localizations_de.dart +++ b/lib/l10n/generated/app_localizations_de.dart @@ -262,7 +262,7 @@ class AppLocalizationsDe extends AppLocalizations { @override String get this_cannot_be_undone => - 'Dies kann nicht rückgängig gemacht werden'; + 'Dies kann nicht rückgängig gemacht werden.'; @override String get today_at => 'Heute um'; diff --git a/lib/l10n/generated/app_localizations_en.dart b/lib/l10n/generated/app_localizations_en.dart index 6c4ac74..b911676 100644 --- a/lib/l10n/generated/app_localizations_en.dart +++ b/lib/l10n/generated/app_localizations_en.dart @@ -261,7 +261,7 @@ class AppLocalizationsEn extends AppLocalizations { 'There is no group matching your search'; @override - String get this_cannot_be_undone => 'This can\'t be undone'; + String get this_cannot_be_undone => 'This can\'t be undone.'; @override String get today_at => 'Today at'; diff --git a/lib/presentation/views/main_menu/settings_view/settings_view.dart b/lib/presentation/views/main_menu/settings_view/settings_view.dart index e32696d..b51cad0 100644 --- a/lib/presentation/views/main_menu/settings_view/settings_view.dart +++ b/lib/presentation/views/main_menu/settings_view/settings_view.dart @@ -7,6 +7,8 @@ import 'package:game_tracker/core/custom_theme.dart'; import 'package:game_tracker/core/enums.dart'; import 'package:game_tracker/l10n/generated/app_localizations.dart'; import 'package:game_tracker/presentation/views/main_menu/settings_view/licenses_view.dart'; +import 'package:game_tracker/presentation/widgets/buttons/animated_dialog_button.dart'; +import 'package:game_tracker/presentation/widgets/custom_alert_dialog.dart'; import 'package:game_tracker/presentation/widgets/tiles/settings_list_tile.dart'; import 'package:game_tracker/services/data_transfer_service.dart'; import 'package:intl/intl.dart'; @@ -114,33 +116,38 @@ class _SettingsViewState extends State { suffixWidget: const Icon(Icons.arrow_forward_ios, size: 16), onPressed: () { showDialog( - context: scaffoldMessengerContext, - builder: (dialogContext) => AlertDialog( - title: Text('${loc.delete_all_data}?'), - content: Text(loc.this_cannot_be_undone), + context: context, + builder: (context) => CustomAlertDialog( + title: '${loc.delete_all_data}?', + content: loc.this_cannot_be_undone, actions: [ - TextButton( - onPressed: () => - Navigator.of(dialogContext).pop(false), - child: Text(loc.cancel), + AnimatedDialogButton( + onPressed: () => Navigator.of(context).pop(false), + child: Text( + loc.cancel, + style: const TextStyle( + color: CustomTheme.textColor, + ), + ), ), - TextButton( - onPressed: () => - Navigator.of(dialogContext).pop(true), - child: Text(loc.delete), + AnimatedDialogButton( + onPressed: () => Navigator.of(context).pop(true), + child: Text( + loc.delete, + style: TextStyle( + color: CustomTheme.secondaryColor, + ), + ), ), ], ), ).then((confirmed) { - if (confirmed == true && - scaffoldMessengerContext.mounted) { - DataTransferService.deleteAllData( - scaffoldMessengerContext, - ); + if (confirmed == true && context.mounted) { + DataTransferService.deleteAllData(context); showSnackbar( context: scaffoldMessengerContext, message: AppLocalizations.of( - scaffoldMessengerContext, + context, ).data_successfully_deleted, ); } diff --git a/lib/presentation/widgets/buttons/animated_dialog_button.dart b/lib/presentation/widgets/buttons/animated_dialog_button.dart new file mode 100644 index 0000000..65c0510 --- /dev/null +++ b/lib/presentation/widgets/buttons/animated_dialog_button.dart @@ -0,0 +1,50 @@ +import 'package:flutter/material.dart'; +import 'package:game_tracker/core/custom_theme.dart'; + +class AnimatedDialogButton extends StatefulWidget { + /// A custom animated button widget that provides a scaling and opacity effect + /// when pressed. + /// - [onPressed]: Callback function that is triggered when the button is pressed. + /// - [child]: The child widget to be displayed inside the button, typically a text or icon. + const AnimatedDialogButton({ + super.key, + required this.onPressed, + required this.child, + }); + + /// Callback function that is triggered when the button is pressed. + final VoidCallback onPressed; + + /// The child widget to be displayed inside the button, typically a text or icon. + final Widget child; + + @override + State createState() => _AnimatedDialogButtonState(); +} + +class _AnimatedDialogButtonState extends State { + bool _isPressed = false; + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTapDown: (_) => setState(() => _isPressed = true), + onTapUp: (_) => setState(() => _isPressed = false), + onTapCancel: () => setState(() => _isPressed = false), + onTap: widget.onPressed, + child: AnimatedScale( + scale: _isPressed ? 0.95 : 1.0, + duration: const Duration(milliseconds: 100), + child: AnimatedOpacity( + opacity: _isPressed ? 0.6 : 1.0, + duration: const Duration(milliseconds: 100), + child: Container( + decoration: CustomTheme.standardBoxDecoration, + padding: const EdgeInsets.symmetric(horizontal: 26, vertical: 6), + child: widget.child, + ), + ), + ), + ); + } +} diff --git a/lib/presentation/widgets/custom_alert_dialog.dart b/lib/presentation/widgets/custom_alert_dialog.dart new file mode 100644 index 0000000..af5b45a --- /dev/null +++ b/lib/presentation/widgets/custom_alert_dialog.dart @@ -0,0 +1,39 @@ +import 'package:flutter/material.dart'; +import 'package:game_tracker/core/custom_theme.dart'; + +class CustomAlertDialog extends StatelessWidget { + /// A custom alert dialog widget that provides a os unspecific AlertDialog, + /// with consistent colors, borders, and layout that match the app's custom theme. + /// - [title]: The title text displayed at the top of the dialog. + /// - [content]: The main content text displayed in the body of the dialog. + /// - [actions]: A list of action widgets (typically buttons) displayed at the bottom + /// of the dialog. These actions are horizontally spaced around the dialog's width. + const CustomAlertDialog({ + super.key, + required this.title, + required this.content, + required this.actions, + }); + + final String title; + final String content; + final List actions; + + @override + Widget build(BuildContext context) { + return AlertDialog( + title: Text(title, style: const TextStyle(color: CustomTheme.textColor)), + content: Text( + content, + style: const TextStyle(color: CustomTheme.textColor), + ), + actions: actions, + backgroundColor: CustomTheme.boxColor, + actionsAlignment: MainAxisAlignment.spaceAround, + shape: RoundedRectangleBorder( + borderRadius: CustomTheme.standardBorderRadiusAll, + side: BorderSide(color: CustomTheme.boxBorder), + ), + ); + } +} diff --git a/pubspec.yaml b/pubspec.yaml index 83d5079..e9fd894 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: game_tracker description: "Game Tracking App for Card Games" publish_to: 'none' -version: 0.0.6+209 +version: 0.0.7+212 environment: sdk: ^3.8.1