Compare commits
16 Commits
refactorin
...
developmen
| Author | SHA1 | Date | |
|---|---|---|---|
| bbd41a65df | |||
| 2cadab004d | |||
| 6a3e184a95 | |||
| 5350113ee1 | |||
| db51990695 | |||
| 4019ed083f | |||
| 82ad2b74f8 | |||
| 4161e1e88b | |||
| d662680a34 | |||
| b69d2784df | |||
| d7f4b1c227 | |||
| ab06662397 | |||
| 1ebcfc9e57 | |||
| 22ce742d43 | |||
| 3ceae8341b | |||
| 76ce3af643 |
@@ -79,7 +79,7 @@
|
|||||||
"stats": "Statistiken",
|
"stats": "Statistiken",
|
||||||
"successfully_added_player": "Spieler:in {playerName} erfolgreich hinzugefügt",
|
"successfully_added_player": "Spieler:in {playerName} erfolgreich hinzugefügt",
|
||||||
"there_is_no_group_matching_your_search": "Es gibt keine Gruppe, die deiner Suche entspricht",
|
"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",
|
"today_at": "Heute um",
|
||||||
"undo": "Rückgängig",
|
"undo": "Rückgängig",
|
||||||
"unknown_exception": "Unbekannter Fehler (siehe Konsole)",
|
"unknown_exception": "Unbekannter Fehler (siehe Konsole)",
|
||||||
|
|||||||
@@ -356,7 +356,7 @@
|
|||||||
"stats": "Stats",
|
"stats": "Stats",
|
||||||
"successfully_added_player": "Successfully added player {playerName}",
|
"successfully_added_player": "Successfully added player {playerName}",
|
||||||
"there_is_no_group_matching_your_search": "There is no group matching your search",
|
"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",
|
"today_at": "Today at",
|
||||||
"undo": "Undo",
|
"undo": "Undo",
|
||||||
"unknown_exception": "Unknown Exception (see console)",
|
"unknown_exception": "Unknown Exception (see console)",
|
||||||
|
|||||||
@@ -575,7 +575,7 @@ abstract class AppLocalizations {
|
|||||||
/// Warning message for irreversible actions
|
/// Warning message for irreversible actions
|
||||||
///
|
///
|
||||||
/// In en, this message translates to:
|
/// In en, this message translates to:
|
||||||
/// **'This can\'t be undone'**
|
/// **'This can\'t be undone.'**
|
||||||
String get this_cannot_be_undone;
|
String get this_cannot_be_undone;
|
||||||
|
|
||||||
/// Date format for today
|
/// Date format for today
|
||||||
|
|||||||
@@ -262,7 +262,7 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String get this_cannot_be_undone =>
|
String get this_cannot_be_undone =>
|
||||||
'Dies kann nicht rückgängig gemacht werden';
|
'Dies kann nicht rückgängig gemacht werden.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get today_at => 'Heute um';
|
String get today_at => 'Heute um';
|
||||||
|
|||||||
@@ -261,7 +261,7 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||||||
'There is no group matching your search';
|
'There is no group matching your search';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get this_cannot_be_undone => 'This can\'t be undone';
|
String get this_cannot_be_undone => 'This can\'t be undone.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get today_at => 'Today at';
|
String get today_at => 'Today at';
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ import 'package:game_tracker/core/custom_theme.dart';
|
|||||||
import 'package:game_tracker/core/enums.dart';
|
import 'package:game_tracker/core/enums.dart';
|
||||||
import 'package:game_tracker/l10n/generated/app_localizations.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/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/presentation/widgets/tiles/settings_list_tile.dart';
|
||||||
import 'package:game_tracker/services/data_transfer_service.dart';
|
import 'package:game_tracker/services/data_transfer_service.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
@@ -114,33 +116,38 @@ class _SettingsViewState extends State<SettingsView> {
|
|||||||
suffixWidget: const Icon(Icons.arrow_forward_ios, size: 16),
|
suffixWidget: const Icon(Icons.arrow_forward_ios, size: 16),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
showDialog<bool>(
|
showDialog<bool>(
|
||||||
context: scaffoldMessengerContext,
|
context: context,
|
||||||
builder: (dialogContext) => AlertDialog(
|
builder: (context) => CustomAlertDialog(
|
||||||
title: Text('${loc.delete_all_data}?'),
|
title: '${loc.delete_all_data}?',
|
||||||
content: Text(loc.this_cannot_be_undone),
|
content: loc.this_cannot_be_undone,
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
AnimatedDialogButton(
|
||||||
onPressed: () =>
|
onPressed: () => Navigator.of(context).pop(false),
|
||||||
Navigator.of(dialogContext).pop(false),
|
child: Text(
|
||||||
child: Text(loc.cancel),
|
loc.cancel,
|
||||||
|
style: const TextStyle(
|
||||||
|
color: CustomTheme.textColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
AnimatedDialogButton(
|
||||||
|
onPressed: () => Navigator.of(context).pop(true),
|
||||||
|
child: Text(
|
||||||
|
loc.delete,
|
||||||
|
style: TextStyle(
|
||||||
|
color: CustomTheme.secondaryColor,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
TextButton(
|
|
||||||
onPressed: () =>
|
|
||||||
Navigator.of(dialogContext).pop(true),
|
|
||||||
child: Text(loc.delete),
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
).then((confirmed) {
|
).then((confirmed) {
|
||||||
if (confirmed == true &&
|
if (confirmed == true && context.mounted) {
|
||||||
scaffoldMessengerContext.mounted) {
|
DataTransferService.deleteAllData(context);
|
||||||
DataTransferService.deleteAllData(
|
|
||||||
scaffoldMessengerContext,
|
|
||||||
);
|
|
||||||
showSnackbar(
|
showSnackbar(
|
||||||
context: scaffoldMessengerContext,
|
context: scaffoldMessengerContext,
|
||||||
message: AppLocalizations.of(
|
message: AppLocalizations.of(
|
||||||
scaffoldMessengerContext,
|
context,
|
||||||
).data_successfully_deleted,
|
).data_successfully_deleted,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
50
lib/presentation/widgets/buttons/animated_dialog_button.dart
Normal file
50
lib/presentation/widgets/buttons/animated_dialog_button.dart
Normal file
@@ -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<AnimatedDialogButton> createState() => _AnimatedDialogButtonState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AnimatedDialogButtonState extends State<AnimatedDialogButton> {
|
||||||
|
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,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
39
lib/presentation/widgets/custom_alert_dialog.dart
Normal file
39
lib/presentation/widgets/custom_alert_dialog.dart
Normal file
@@ -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<Widget> 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),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
name: game_tracker
|
name: game_tracker
|
||||||
description: "Game Tracking App for Card Games"
|
description: "Game Tracking App for Card Games"
|
||||||
publish_to: 'none'
|
publish_to: 'none'
|
||||||
version: 0.0.6+209
|
version: 0.0.7+212
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ^3.8.1
|
sdk: ^3.8.1
|
||||||
|
|||||||
Reference in New Issue
Block a user