diff --git a/analysis_options.yaml b/analysis_options.yaml index 2ce6b52..f9adae0 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -11,6 +11,5 @@ linter: prefer_const_literals_to_create_immutables: true unnecessary_const: true lines_longer_than_80_chars: false + constant_identifier_names: false -# Additional information about this file can be found at -# https://dart.dev/guides/language/analysis-options diff --git a/lib/presentation/views/main_menu_view.dart b/lib/presentation/views/main_menu_view.dart index 05665ce..ea330e5 100644 --- a/lib/presentation/views/main_menu_view.dart +++ b/lib/presentation/views/main_menu_view.dart @@ -9,6 +9,7 @@ import 'package:cabo_counter/services/config_service.dart'; import 'package:cabo_counter/services/local_storage_service.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:url_launcher/url_launcher.dart' as url; class MainMenuView extends StatefulWidget { const MainMenuView({super.key}); @@ -20,6 +21,9 @@ class MainMenuView extends StatefulWidget { class _MainMenuViewState extends State { bool _isLoading = true; + static const int RATING_DIALOG_YES = 1; + static const int RATING_DIALOG_NO = 0; + static const int RATING_DIALOG_CANCEL = -1; @override initState() { @@ -33,8 +37,11 @@ class _MainMenuViewState extends State { WidgetsBinding.instance.addPostFrameCallback((_) async { await Globals.rateMyApp.init(); - if (mounted && Globals.rateMyApp.shouldOpenDialog) { - Globals.rateMyApp.showStarRateDialog(context); + + if (Globals.rateMyApp.shouldOpenDialog) { + await Future.delayed(const Duration(milliseconds: 600)); + if (!mounted) return; + _handleFeedbackDialog(context); } }); } @@ -248,6 +255,63 @@ class _MainMenuViewState extends State { return shouldDelete; } + Future _showPreRatingDialog(BuildContext context) async { + int? answer = await showCupertinoDialog( + context: context, + builder: (BuildContext context) { + return CupertinoAlertDialog( + title: const Text('Gefällt dir die App?'), + content: const Text('Dein Feedback hilft uns weiter.'), + actions: [ + CupertinoDialogAction( + child: const Text('Ja'), + onPressed: () { + Navigator.of(context).pop(RATING_DIALOG_YES); + }, + ), + CupertinoDialogAction( + child: const Text('Nein'), + onPressed: () { + Navigator.of(context).pop(RATING_DIALOG_NO); + }, + ), + CupertinoDialogAction( + isDestructiveAction: true, + onPressed: () { + Navigator.of(context).pop(RATING_DIALOG_CANCEL); + }, + child: Text(AppLocalizations.of(context).cancel), + ), + ], + ); + }, + ); + return answer ?? RATING_DIALOG_CANCEL; + } + + /// Handles the feedback dialog when the conditions for rating are met. + /// It shows a dialog asking the user if they like the app, + /// and based on their response, it either opens the rating dialog or an email client for feedback. + Future _handleFeedbackDialog(BuildContext context) async { + int decision = await _showPreRatingDialog(context); + + final Uri emailUri = Uri( + scheme: 'mailto', + path: 'cabo-counter@felixkirchner.de', + query: 'subject=Feedback: Cabo Counter App' + '&body=Ich habe folgendes Feedback...', + ); + + switch (decision) { + case RATING_DIALOG_YES: + Globals.rateMyApp.showStarRateDialog(context); + case RATING_DIALOG_NO: + url.launchUrl(emailUri, mode: url.LaunchMode.externalApplication); + case RATING_DIALOG_CANCEL: + break; + } + } + @override void dispose() { gameManager.removeListener(_updateView); diff --git a/pubspec.yaml b/pubspec.yaml index 92ed456..bb9ffcf 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -2,7 +2,7 @@ name: cabo_counter description: "Mobile app for the card game Cabo" publish_to: 'none' -version: 0.4.0+411 +version: 0.4.0+437 environment: sdk: ^3.5.4