From cbaa1a5b817d3f3434eac71b907695e272959c9d Mon Sep 17 00:00:00 2001 From: "Tibor Bossanyi (Freelancer)" Date: Sun, 13 Nov 2022 21:26:27 +0100 Subject: [PATCH] v1.1.26+110 android release --- android/app/build.gradle | 1 - lib/bloc/login/login_bloc.dart | 46 +++++++------ lib/bloc/session/session_bloc.dart | 3 +- lib/main.dart | 4 +- lib/service/firebase_api.dart | 101 +++++++++-------------------- lib/util/track.dart | 5 +- lib/widgets/home.dart | 14 +--- pubspec.lock | 13 +++- pubspec.yaml | 8 +-- 9 files changed, 77 insertions(+), 118 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 4ea19e5..dd0d120 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -54,7 +54,6 @@ android { android { compileSdkVersion 33 - } signingConfigs { diff --git a/lib/bloc/login/login_bloc.dart b/lib/bloc/login/login_bloc.dart index dd6e5d1..702ce3f 100644 --- a/lib/bloc/login/login_bloc.dart +++ b/lib/bloc/login/login_bloc.dart @@ -93,11 +93,10 @@ class LoginBloc extends Bloc with Trans { accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn!)); Track().track(TrackingEvent.login, eventValue: "email"); Cache().setLoginType(LoginType.email); + emit(LoginSuccess()); } on Exception catch (e) { emit(LoginError(message: e.toString())); - } finally { - emit(LoginSuccess()); - } + } } void _onLoginFB(LoginFB event, Emitter emit) async { @@ -107,11 +106,10 @@ class LoginBloc extends Bloc with Trans { await userRepository.getUserByFB(); accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn!)); Track().track(TrackingEvent.login, eventValue: "FB"); + emit(LoginSuccess()); } on Exception catch (e) { emit(LoginError(message: e.toString())); - } finally { - emit(LoginSuccess()); - } + } } void _onLoginGoogle(LoginGoogle event, Emitter emit) async { @@ -121,11 +119,10 @@ class LoginBloc extends Bloc with Trans { await userRepository.getUserByGoogle(); accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn!)); Track().track(TrackingEvent.login, eventValue: "Google"); + emit(LoginSuccess()); } on Exception catch (e) { emit(LoginError(message: e.toString())); - } finally { - emit(LoginSuccess()); - } + } } void _onLoginApple(LoginApple event, Emitter emit) async { @@ -135,10 +132,9 @@ class LoginBloc extends Bloc with Trans { await userRepository.getUserByApple(); accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn!)); Track().track(TrackingEvent.login, eventValue: "Apple"); + emit(LoginSuccess()); } on Exception catch (e) { emit(LoginError(message: e.toString())); - } finally { - emit(LoginSuccess()); } } @@ -154,12 +150,14 @@ class LoginBloc extends Bloc with Trans { customerRepository!.customer!.emailSubscription = emailSubscription == true ? 1 : 0; await afterRegistration("email"); Cache().setLoginType(LoginType.email); + emit(LoginSuccess()); } } on Exception catch (e) { emit(LoginError(message: e.toString())); - } finally { - emit(LoginSuccess()); - } + return; + } + + } void _onRegistrationFB(RegistrationFB event, Emitter emit) async { @@ -170,11 +168,12 @@ class LoginBloc extends Bloc with Trans { accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn!)); customerRepository!.customer!.emailSubscription = emailSubscription == true ? 1 : 0; await afterRegistration("FB"); + emit(LoginSuccess()); } on Exception catch (e) { emit(LoginError(message: e.toString())); - } finally { - emit(LoginSuccess()); - } + } + + } void _onRegistrationGoogle(RegistrationGoogle event, Emitter emit) async { @@ -185,11 +184,11 @@ class LoginBloc extends Bloc with Trans { accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn!)); customerRepository!.customer!.emailSubscription = emailSubscription == true ? 1 : 0; await afterRegistration("Google"); - } on Exception catch (e) { - emit(LoginError(message: e.toString())); - } finally { emit(LoginSuccess()); - } + } on Exception catch (e) { + emit(LoginError(message: e.toString())); + } + } void _onRegistrationApple(RegistrationApple event, Emitter emit) async { @@ -200,11 +199,10 @@ class LoginBloc extends Bloc with Trans { accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn!)); customerRepository!.customer!.emailSubscription = emailSubscription == true ? 1 : 0; await afterRegistration("Apple"); + emit(LoginSuccess()); } on Exception catch (e) { emit(LoginError(message: e.toString())); - } finally { - emit(LoginSuccess()); - } + } } void _onDataProtectionClicked(DataProtectionClicked event, Emitter emit) async { diff --git a/lib/bloc/session/session_bloc.dart b/lib/bloc/session/session_bloc.dart index 468a6fc..07d044a 100644 --- a/lib/bloc/session/session_bloc.dart +++ b/lib/bloc/session/session_bloc.dart @@ -37,10 +37,9 @@ class SessionBloc extends Bloc with Logging { resultsFuture.then((results) { print('iTunes results: $results'); }); + emit(SessionReady()); } on Exception catch (e) { emit(SessionFailure(message: e.toString())); - } finally { - emit(SessionReady()); } } diff --git a/lib/main.dart b/lib/main.dart index ed9c150..2f071ae 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -124,7 +124,7 @@ Future main() async { Posthog().setContext({ 'device': { - 'token': 'v1.26 test', + 'token': 'v1.1.26', } }); } @@ -292,7 +292,7 @@ class WorkoutTestApp extends StatelessWidget { )), navigatorObservers: [ FirebaseAnalyticsObserver(analytics: analytics), - //PosthogObserver(), + PosthogObserver(), ], home: AitrainerHome(), ); diff --git a/lib/service/firebase_api.dart b/lib/service/firebase_api.dart index e261514..9af1a46 100644 --- a/lib/service/firebase_api.dart +++ b/lib/service/firebase_api.dart @@ -3,6 +3,7 @@ import 'dart:convert'; import 'package:crypto/crypto.dart'; import 'package:aitrainer_app/model/cache.dart'; import 'package:aitrainer_app/service/logging.dart' as logging; +import 'package:sentry_flutter/sentry_flutter.dart'; import 'package:sign_in_with_apple/sign_in_with_apple.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:firebase_core/firebase_core.dart'; @@ -36,26 +37,7 @@ class FirebaseApi with logging.Logging { await Firebase.initializeApp(); this.appleSignInAvailable = await SignInWithApple.isAvailable(); - - /* AwesomeNotifications().initialize( - // set the icon to null if you want to use the default app icon - null, - [ - NotificationChannel( - channelKey: 'basic_channel', - channelName: 'Basic notifications', - channelDescription: 'Notification channel for basic tests', - defaultColor: Color(0xFF9D50DD), - ledColor: Colors.white) - ]); - - AwesomeNotifications().isNotificationAllowed().then((isAllowed) { - if (!isAllowed) { - // Insert here your friendly dialog box before call the request method - // This is very important to not harm the user experience - AwesomeNotifications().requestPermissionToSendNotifications(); - } - }); */ + await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions( alert: true, // Required to display a heads up notification @@ -77,6 +59,7 @@ class FirebaseApi with logging.Logging { }); } catch (e) { // Set `_error` state to true if Firebase initialization fails + Sentry.captureException(e); log("Error initializing Firebase"); } } @@ -93,6 +76,7 @@ class FirebaseApi with logging.Logging { userCredential = await FirebaseAuth.instance.signInWithEmailAndPassword(email: email, password: password); Cache().firebaseUid = userCredential.user!.uid; } on FirebaseAuthException catch (e) { + Sentry.captureException(e); if (e.code == 'user-not-found') { log('No user found for that email.'); rc = SIGN_IN_NOT_FOUND; @@ -112,6 +96,7 @@ class FirebaseApi with logging.Logging { userCredential = await FirebaseAuth.instance.createUserWithEmailAndPassword(email: email, password: password); Cache().firebaseUid = userCredential.user!.uid; } on FirebaseAuthException catch (e) { + Sentry.captureException(e); if (e.code == 'weak-password') { log('The password provided is too weak.'); rc = REGISTER_WEAK_PWD; @@ -123,6 +108,7 @@ class FirebaseApi with logging.Logging { } } catch (e) { log(e.toString()); + Sentry.captureException(e); throw Exception(e.toString()); } return rc; @@ -143,27 +129,7 @@ class FirebaseApi with logging.Logging { Future> signInWithApple() async { Map userData = Map(); - - /* final apple.AuthorizationResult result = await SignInWithApple.performRequests([ - apple.AppleIdRequest(requestedScopes: [apple.Scope.email, apple.Scope.fullName]) - ]); - switch (result.status) { - case apple.AuthorizationStatus.authorized: - print('User authorized'); - break; - case apple.AuthorizationStatus.error: - print('User error'); - throw Exception("Apple Sign-In failed"); - case apple.AuthorizationStatus.cancelled: - print('User cancelled'); - throw Exception("Apple Sign-In cancelled"); - } - - // Create an `OAuthCredential` from the credential returned by Apple. - final oauthCredential = OAuthProvider("apple.com").credential( - idToken: String.fromCharCodes(result.credential.identityToken), - accessToken: String.fromCharCodes(result.credential.authorizationCode!)); - */ + // To prevent replay attacks with the credential returned from Apple, we // include a nonce in the credential request. When signing in with // Firebase, the nonce in the id token returned by Apple, is expected to @@ -185,9 +151,15 @@ class FirebaseApi with logging.Logging { idToken: appleCredential.identityToken, rawNonce: rawNonce, ); - // Sign in the user with Firebase. If the nonce we generated earlier does - // not match the nonce in `appleCredential.identityToken`, sign in will fail. - UserCredential userCredential = await FirebaseAuth.instance.signInWithCredential(oauthCredential); + UserCredential? userCredential; + try { + // Sign in the user with Firebase. If the nonce we generated earlier does + // not match the nonce in `appleCredential.identityToken`, sign in will fail. + userCredential = await FirebaseAuth.instance.signInWithCredential(oauthCredential); + } on FirebaseAuthException catch(e) { + Sentry.captureException(e); + throw Exception(e); + } Cache().firebaseUid = userCredential.user!.uid; log("userCredential: " + userCredential.toString()); @@ -199,21 +171,7 @@ class FirebaseApi with logging.Logging { Future> registerWithApple() async { Map userData = Map(); - /* final apple.AuthorizationResult result = await apple.TheAppleSignIn.performRequests([ - apple.AppleIdRequest(requestedScopes: [apple.Scope.email, apple.Scope.fullName]) - ]); - switch (result.status) { - case apple.AuthorizationStatus.authorized: - print('Apple User authorized'); - break; - case apple.AuthorizationStatus.error: - print('Apple User error'); - throw Exception("Apple Sign-In failed"); - case apple.AuthorizationStatus.cancelled: - print('User cancelled'); - throw Exception("Apple Sign-In cancelled"); - } - */ + final rawNonce = generateNonce(); final nonce = sha256ofString(rawNonce); @@ -231,18 +189,19 @@ class FirebaseApi with logging.Logging { rawNonce: rawNonce, ); - /* // Create an `OAuthCredential` from the credential returned by Apple. - final oauthCredential = OAuthProvider("apple.com").credential( - idToken: String.fromCharCodes(result.credential.identityToken), - accessToken: String.fromCharCodes(result.credential.authorizationCode)); - */ - // Sign in the user with Firebase. If the nonce we generated earlier does - // not match the nonce in `appleCredential.identityToken`, sign in will fail. - UserCredential userCredential = await FirebaseAuth.instance.signInWithCredential(oauthCredential); + UserCredential? userCredential; + try { + // Sign in the user with Firebase. If the nonce we generated earlier does + // not match the nonce in `appleCredential.identityToken`, sign in will fail. + userCredential = await FirebaseAuth.instance.signInWithCredential(oauthCredential); + } on FirebaseAuthException catch(e) { + Sentry.captureException(e); + throw Exception(e); + } - Cache().firebaseUid = userCredential.user!.uid; + Cache().firebaseUid = userCredential!.user!.uid; - userData['email'] = userCredential.user!.email; + userData['email'] = userCredential!.user!.email; return userData; } @@ -260,6 +219,7 @@ class FirebaseApi with logging.Logging { final GoogleSignInAccount? googleUser = await _googleSignIn.signIn(); if (googleUser == null) { + Sentry.captureException(new Exception("Google Sign In failed")); throw Exception("Google Sign In failed"); } @@ -296,6 +256,7 @@ class FirebaseApi with logging.Logging { final GoogleSignInAccount? googleUser = await _googleSignIn.signIn(); if (googleUser == null) { + Sentry.captureException(new Exception("Google Sign In failed")); throw Exception("Google Sign In failed"); } @@ -332,6 +293,7 @@ class FirebaseApi with logging.Logging { Cache().firebaseUid = userData['id']; log(userData.toString()); } else { + Sentry.captureException(new Exception(result.message)); throw Exception("Facebook login was not successful"); } @@ -359,6 +321,7 @@ class FirebaseApi with logging.Logging { Cache().firebaseUid = userCredential.user!.uid; } else { + Sentry.captureException(new Exception(result.message)); throw Exception("Facebook login was not successful"); } diff --git a/lib/util/track.dart b/lib/util/track.dart index 4ef91d8..fa6c551 100644 --- a/lib/util/track.dart +++ b/lib/util/track.dart @@ -39,14 +39,15 @@ class Track with Logging { } else { MatomoTracker.instance.trackEvent(eventCategory: "wt", action: event.enumToString()); } - Posthog().capture( eventName: event.enumToString(), properties: { - 'action': eventValue, + 'eventValue': eventValue, 'customer': tracking.customerId, }, ); + } + } } diff --git a/lib/widgets/home.dart b/lib/widgets/home.dart index 95b7915..c2eaed0 100644 --- a/lib/widgets/home.dart +++ b/lib/widgets/home.dart @@ -1,9 +1,8 @@ -import 'dart:io'; - import 'package:aitrainer_app/bloc/session/session_bloc.dart'; import 'package:aitrainer_app/bloc/settings/settings_bloc.dart'; import 'package:aitrainer_app/model/cache.dart'; import 'package:aitrainer_app/service/logging.dart'; +import 'package:aitrainer_app/util/app_language.dart'; import 'package:aitrainer_app/util/trans.dart'; import 'package:aitrainer_app/view/customer_goal_page.dart'; import 'package:aitrainer_app/view/login.dart'; @@ -73,19 +72,12 @@ class _HomePageState extends State with Logging, Trans, Traceable setContext(context); final appcastURL = "https://raw.githubusercontent.com/bossanyit/appcast/main/android_rss.xml"; final cfg = AppcastConfiguration(url: appcastURL, supportedOS: ['android']); - print("Packageinfo ${Cache().packageInfo}"); - String minVersion = ""; - if (Platform.isAndroid) { - minVersion = "[Minimum supported app version: 1.1.26]"; - } else { - minVersion = "[:mav: 1.1.26]"; - } - + return Scaffold( key: _scaffoldKey, body: UpgradeAlert( upgrader: Upgrader( - countryCode: "hu", minAppVersion: minVersion, appcastConfig: cfg, messages: MyLocalizedUpgraderMessages(context: context)), + countryCode: AppLanguage().appLocal.toString(), appcastConfig: cfg, messages: MyLocalizedUpgraderMessages(context: context)), child: BlocConsumer(listener: (context, state) { if (state is SessionFailure) { showDialog( diff --git a/pubspec.lock b/pubspec.lock index 31c934d..3e76743 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -176,6 +176,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.3.0" + cli_util: + dependency: transitive + description: + name: cli_util + url: "https://pub.dartlang.org" + source: hosted + version: "0.3.5" clock: dependency: transitive description: @@ -574,12 +581,12 @@ packages: source: hosted version: "2.2.1" flutter_launcher_icons: - dependency: "direct dev" + dependency: "direct main" description: name: flutter_launcher_icons url: "https://pub.dartlang.org" source: hosted - version: "0.9.2" + version: "0.10.0" flutter_layout_grid: dependency: transitive description: @@ -811,7 +818,7 @@ packages: name: json_annotation url: "https://pub.dartlang.org" source: hosted - version: "4.4.0" + version: "4.7.0" keyboard_actions: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 2413958..7337e2a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.1.26+108 +version: 1.1.26+110 environment: sdk: ">=2.12.0 <3.9.0" @@ -54,6 +54,7 @@ dependencies: flutter_fancy_tree_view: ^0.5.1+1 flutter_facebook_auth: ^4.4.1+1 flutter_fadein: ^2.0.0 + flutter_launcher_icons: ^0.10.0 flutter_lints: ^2.0.1 flutter_radar_chart: ^0.2.1 flutter_secure_storage: ^5.0.2 @@ -123,12 +124,11 @@ dev_dependencies: intl: ^0.17.0 shared_preferences: ^2.0.5 - flutter_launcher_icons: ^0.9.0 - flutter_icons: android: "launcher_icon" image_path: "asset/icon/icon.png" - + ios: true + # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec