diff --git a/i18n/en.json b/i18n/en.json index 3e47569..e4aba0a 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -337,5 +337,7 @@ "Or type the time manually:":"Or type the time manually", "sec":"sec", - "min":"min" + "min":"min", + "Please provide us some personal data":"Please provide us some personal data", + "To lift your experience using the app":"To lift your experience using the app" } \ No newline at end of file diff --git a/i18n/hu.json b/i18n/hu.json index 11c663d..2931d04 100644 --- a/i18n/hu.json +++ b/i18n/hu.json @@ -333,5 +333,7 @@ "Step": "Lépés:", "Or type the time manually:":"Vagy jelöld ki az időt kézzel", "sec":"mp", - "min":"perc" + "min":"perc", + "Please provide us some personal data":"Kérlek adj meg néhány adatot,", + "To lift your experience using the app":"Hogy emelni tudjuk az app élményét" } \ No newline at end of file diff --git a/ios/Flutter/AppFrameworkInfo.plist b/ios/Flutter/AppFrameworkInfo.plist index cae6543..3158eba 100644 --- a/ios/Flutter/AppFrameworkInfo.plist +++ b/ios/Flutter/AppFrameworkInfo.plist @@ -21,6 +21,6 @@ CFBundleVersion 1.0 MinimumOSVersion - 12.0 + 10.0 diff --git a/ios/Podfile b/ios/Podfile index b981d5d..4a8b85d 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -1,5 +1,5 @@ # Uncomment this line to define a global platform for your project -platform :ios, '11.0' +platform :ios, '10.0' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 9aa07f3..ad35364 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -312,6 +312,6 @@ SPEC CHECKSUMS: wakelock: bfc7955c418d0db797614075aabbc58a39ab5107 webview_flutter: d2b4d6c66968ad042ad94cbb791f5b72b4678a96 -PODFILE CHECKSUM: ac11fc852a681d8d7d22e344055d0c36b734cfc2 +PODFILE CHECKSUM: ffdd26129895d158b3c89ac44e19a7e054386b90 COCOAPODS: 1.10.0 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 8f27583..417a41e 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -388,7 +388,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 4; + CURRENT_PROJECT_VERSION = 5; DEVELOPMENT_TEAM = SFJJBDCU6Z; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( @@ -531,7 +531,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 4; + CURRENT_PROJECT_VERSION = 5; DEVELOPMENT_TEAM = SFJJBDCU6Z; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( @@ -566,7 +566,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 4; + CURRENT_PROJECT_VERSION = 5; DEVELOPMENT_TEAM = SFJJBDCU6Z; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( diff --git a/lib/bloc/customer_change/customer_change_bloc.dart b/lib/bloc/customer_change/customer_change_bloc.dart index 104a41b..fd9b401 100644 --- a/lib/bloc/customer_change/customer_change_bloc.dart +++ b/lib/bloc/customer_change/customer_change_bloc.dart @@ -94,11 +94,12 @@ class CustomerChangeBloc extends Bloc } bool validation() { - print("f " + customerRepository.customer.firstname); + return true; + /* print("f " + customerRepository.customer.firstname); return (emailValidation(customerRepository.customer.email) == null) && (passwordValidation(customerRepository.customer.password) == null) && (nameValidation(customerRepository.customer.firstname) == null) && - (nameValidation(customerRepository.customer.name) == null); + (nameValidation(customerRepository.customer.name) == null); */ } String emailValidation(String email) { diff --git a/lib/bloc/login/login_bloc.dart b/lib/bloc/login/login_bloc.dart index 13e291d..7a09816 100644 --- a/lib/bloc/login/login_bloc.dart +++ b/lib/bloc/login/login_bloc.dart @@ -7,6 +7,7 @@ import 'package:aitrainer_app/repository/user_repository.dart'; import 'package:aitrainer_app/service/exercise_tree_service.dart'; import 'package:aitrainer_app/service/exercisetype_service.dart'; import 'package:aitrainer_app/util/common.dart'; +import 'package:aitrainer_app/util/enums.dart'; import 'package:aitrainer_app/util/trans.dart'; import 'package:bloc/bloc.dart'; import 'package:equatable/equatable.dart'; @@ -51,9 +52,11 @@ class LoginBloc extends Bloc with Trans { await userRepository.getUser(); accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn)); Flurry.logEvent("Login"); + Cache().setLoginType(LoginType.email); yield LoginSuccess(); } else if (event is LoginFB) { yield LoginLoading(); + Cache().setLoginType(LoginType.fb); await userRepository.getUserByFB(); accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn)); Flurry.logEvent("Login"); @@ -61,6 +64,7 @@ class LoginBloc extends Bloc with Trans { yield LoginSuccess(); } else if (event is LoginGoogle) { yield LoginLoading(); + Cache().setLoginType(LoginType.google); await userRepository.getUserByGoogle(); accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn)); Flurry.logEvent("Login"); @@ -68,6 +72,7 @@ class LoginBloc extends Bloc with Trans { yield LoginSuccess(); } else if (event is LoginApple) { yield LoginLoading(); + Cache().setLoginType(LoginType.apple); await userRepository.getUserByApple(); accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn)); Flurry.logEvent("Login"); @@ -83,7 +88,7 @@ class LoginBloc extends Bloc with Trans { accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn)); await saveCustomer(); Flurry.logEvent("Registration"); - + Cache().setLoginType(LoginType.email); yield LoginSuccess(); } else if (event is RegistrationFB) { yield LoginLoading(); @@ -91,6 +96,7 @@ class LoginBloc extends Bloc with Trans { yield LoginError(); throw Exception("Please accept our data policy"); } + Cache().setLoginType(LoginType.fb); await userRepository.addUserFB(); accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn)); await saveCustomer(); @@ -103,6 +109,7 @@ class LoginBloc extends Bloc with Trans { yield LoginError(); throw Exception("Please accept our data policy"); } + Cache().setLoginType(LoginType.google); await userRepository.addUserGoogle(); accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn)); await saveCustomer(); @@ -115,8 +122,9 @@ class LoginBloc extends Bloc with Trans { yield LoginError(); throw Exception("Please accept our data policy"); } + Cache().setLoginType(LoginType.apple); await userRepository.addUserApple(); - accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn)); + accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn)); await saveCustomer(); Flurry.logEvent("RegistrationApple"); Flurry.logEvent("Registration"); diff --git a/lib/model/cache.dart b/lib/model/cache.dart index 19eb043..e943f88 100644 --- a/lib/model/cache.dart +++ b/lib/model/cache.dart @@ -19,6 +19,7 @@ import 'package:aitrainer_app/service/exercise_tree_service.dart'; import 'package:aitrainer_app/service/exercisetype_service.dart'; import 'package:aitrainer_app/service/firebase_api.dart'; import 'package:aitrainer_app/service/logging.dart'; +import 'package:aitrainer_app/util/enums.dart'; import 'package:aitrainer_app/util/env.dart'; import 'package:flurry/flurry.dart'; import 'package:flutter_facebook_auth/flutter_facebook_auth.dart'; @@ -63,6 +64,7 @@ class Cache with Logging { static final String langKey = 'lang'; static final String serverKey = 'live'; static final String hardwareKey = 'hardware'; + static final String loginTypeKey = 'login_type'; static String baseUrl = 'http://aitrainer.info:8888/api/'; static final String mediaUrl = 'https://aitrainer.info:4343/media/'; @@ -73,6 +75,7 @@ class Cache with Logging { AccessToken accessTokenFacebook; Customer userLoggedIn; String firebaseUid; + LoginType loginType; bool hasPurchased = false; @@ -184,6 +187,24 @@ class Cache with Logging { } } + Future setLoginTypeFromPrefs() async { + Future prefs = SharedPreferences.getInstance(); + SharedPreferences sharedPreferences = await prefs; + final String loginType = sharedPreferences.getString(Cache.loginTypeKey); + LoginType type = LoginType.email; + if (loginType == LoginType.apple.toString()) { + type = LoginType.apple; + } else if (loginType == LoginType.google.toString()) { + type = LoginType.google; + } else if (loginType == LoginType.fb.toString()) { + type = LoginType.fb; + } else if (loginType == LoginType.email.toString()) { + type = LoginType.email; + } + print("LoginType: " + loginType == null ? "NULL" : loginType); + Cache().setLoginType(type); + } + static String getToken(SharedPreferences prefs) { return prefs.getString(authTokenKey); } @@ -201,6 +222,8 @@ class Cache with Logging { userLoggedIn = customer; final String uid = Cache().firebaseUid; + SharedPreferences sharedPreferences = await prefs; + sharedPreferences.setString(Cache.loginTypeKey, Cache().getLoginType().toString()); await setPreferences(prefs, SharePrefsChange.registration, customer.customerId, uid); } @@ -208,16 +231,22 @@ class Cache with Logging { Future prefs = SharedPreferences.getInstance(); userLoggedIn = customer; + SharedPreferences sharedPreferences = await prefs; + sharedPreferences.setString(Cache.loginTypeKey, Cache().getLoginType().toString()); await setPreferences(prefs, SharePrefsChange.login, customer.customerId, Cache().firebaseUid); } afterFirebaseLogin() async { Future prefs = SharedPreferences.getInstance(); + SharedPreferences sharedPreferences = await prefs; + sharedPreferences.setString(Cache.loginTypeKey, Cache().getLoginType().toString()); await setPreferences(prefs, SharePrefsChange.login, userLoggedIn.customerId, Cache().firebaseUid); } afterFacebookLogin() async { Future prefs = SharedPreferences.getInstance(); + SharedPreferences sharedPreferences = await prefs; + sharedPreferences.setString(Cache.loginTypeKey, Cache().getLoginType().toString()); await setPreferences(prefs, SharePrefsChange.login, userLoggedIn.customerId, Cache().firebaseUid); } @@ -392,7 +421,7 @@ class Cache with Logging { _badges = LinkedHashMap(); customerRepository.setCustomer(userLoggedIn); if (this.userLoggedIn != null) { - if (this.userLoggedIn.firstname == null || userLoggedIn.firstname.length == 0) { + if (this.userLoggedIn.birthYear == null || this.userLoggedIn.birthYear == 0) { setBadge("personalData", true); setBadge("account", true); } @@ -457,9 +486,13 @@ class Cache with Logging { await customerRepository.getProductTests(); //this.hasPurchased = this._purchases.isNotEmpty; + await setLoginTypeFromPrefs(); Cache().startPage = "home"; } AccessToken get getAccessTokenFacebook => accessTokenFacebook; set setAccessTokenFacebook(AccessToken accessTokenFacebook) => this.accessTokenFacebook = accessTokenFacebook; + + LoginType getLoginType() => loginType; + void setLoginType(LoginType type) => this.loginType = type; } diff --git a/lib/util/enums.dart b/lib/util/enums.dart new file mode 100644 index 0000000..35f9fe8 --- /dev/null +++ b/lib/util/enums.dart @@ -0,0 +1,6 @@ +enum LoginType { email, fb, google, apple } + +extension LoginTypeExt on LoginType { + bool equalsTo(LoginType type) => this.toString() == type.toString(); + bool equalsStringTo(String type) => this.toString() == type; +} diff --git a/lib/view/account.dart b/lib/view/account.dart index 463897f..7ba89e3 100644 --- a/lib/view/account.dart +++ b/lib/view/account.dart @@ -37,18 +37,32 @@ class AccountPage extends StatelessWidget with Trans { }, builder: (context, state) { if (state is AccountInitial) { String customerName = accountBloc.customerRepository.firstName + " " + accountBloc.customerRepository.name; + if (customerName.length < 3) { + customerName = t("Personal data"); + } + return accountWidget(context, customerName, accountBloc); } else if (state is AccountLoggedIn) { String customerName = accountBloc.customerRepository.firstName + " " + accountBloc.customerRepository.name; + + if (customerName.length < 3) { + customerName = t("Personal data"); + } return accountWidget(context, customerName, accountBloc); } else if (state is AccountLoggedOut) { String customerName = ""; + if (customerName.length < 3) { + customerName = t("Personal data"); + } return accountWidget(context, customerName, accountBloc); } else if (state is AccountReady) { String customerName = accountBloc.customerRepository.firstName + " " + accountBloc.customerRepository.name; + if (customerName.length < 3) { + customerName = t("Personal data"); + } return accountWidget(context, customerName, accountBloc); } else { - return accountWidget(context, "", accountBloc); + return accountWidget(context, t("Personal data"), accountBloc); } }), ), diff --git a/lib/view/customer_modify_page.dart b/lib/view/customer_modify_page.dart index 3107d4a..f3df99c 100644 --- a/lib/view/customer_modify_page.dart +++ b/lib/view/customer_modify_page.dart @@ -1,12 +1,15 @@ import 'package:aitrainer_app/bloc/account/account_bloc.dart'; import 'package:aitrainer_app/bloc/customer_change/customer_change_bloc.dart'; import 'package:aitrainer_app/library/numberpicker.dart'; +import 'package:aitrainer_app/model/cache.dart'; +import 'package:aitrainer_app/util/enums.dart'; import 'package:aitrainer_app/util/trans.dart'; import 'package:aitrainer_app/widgets/app_bar_min.dart'; import 'package:flutter/material.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:google_fonts/google_fonts.dart'; import 'package:modal_progress_hud/modal_progress_hud.dart'; import 'package:toggle_switch/toggle_switch.dart'; @@ -80,103 +83,118 @@ class CustomerModifyPage extends StatelessWidget with Trans { alignment: Alignment.center, child: Column( children: [ - TextFormField( - key: LibraryKeys.loginEmailField, - decoration: InputDecoration( - contentPadding: EdgeInsets.only(left: 15, top: 15, bottom: 15), - labelText: t('Email'), - fillColor: Colors.white24, - filled: true, - border: OutlineInputBorder( - gapPadding: 4.0, - borderRadius: BorderRadius.circular(12.0), - borderSide: BorderSide(color: Colors.green[50], width: 0.4), - ), - ), - initialValue: customerBloc.customerRepository.customer.email, - autovalidateMode: AutovalidateMode.always, - validator: (val) { - return customerBloc.emailValidation(val); - }, - keyboardType: TextInputType.emailAddress, - style: new TextStyle(fontSize: 16, color: Colors.indigo), - ), + Text(t("Please provide us some personal data"), + style: GoogleFonts.inter(color: Colors.indigo, fontSize: 16), textAlign: TextAlign.center), + Text(t("To lift your experience using the app"), + style: GoogleFonts.inter(color: Colors.orange[700], fontSize: 16), textAlign: TextAlign.center), Divider( color: Colors.transparent, ), - TextFormField( - key: LibraryKeys.loginPasswordField, - obscureText: true, - decoration: InputDecoration( - labelStyle: TextStyle(fontSize: 14), - contentPadding: EdgeInsets.only(left: 15, top: 15, bottom: 15), - suffixIcon: IconButton( - onPressed: () => {customerBloc.add(CustomerChangePasswordObscure())}, - icon: Icon(Icons.remove_red_eye), - ), - labelText: t('Password (Leave empty if no change)'), - fillColor: Colors.white24, - filled: true, - border: OutlineInputBorder( - gapPadding: 1.0, - borderRadius: BorderRadius.circular(12.0), - borderSide: BorderSide(color: Colors.green[50], width: 0.4), - ), - ), - initialValue: customerBloc.customerRepository.customer.password, - autovalidateMode: AutovalidateMode.always, - validator: (val) { - return customerBloc.passwordValidation(val); - }, - keyboardType: TextInputType.visiblePassword, - style: new TextStyle(fontSize: 16, color: Colors.indigo), - ), + Cache().getLoginType() == LoginType.email + ? TextFormField( + key: LibraryKeys.loginEmailField, + decoration: InputDecoration( + contentPadding: EdgeInsets.only(left: 15, top: 15, bottom: 15), + labelText: t('Email'), + fillColor: Colors.white24, + filled: true, + border: OutlineInputBorder( + gapPadding: 4.0, + borderRadius: BorderRadius.circular(12.0), + borderSide: BorderSide(color: Colors.green[50], width: 0.4), + ), + ), + initialValue: customerBloc.customerRepository.customer.email, + autovalidateMode: AutovalidateMode.always, + validator: (val) { + return customerBloc.emailValidation(val); + }, + keyboardType: TextInputType.emailAddress, + style: new TextStyle(fontSize: 16, color: Colors.indigo), + ) + : Offstage(), Divider( color: Colors.transparent, ), - TextFormField( - decoration: InputDecoration( - contentPadding: EdgeInsets.only(left: 15, top: 15, bottom: 15), - labelText: t('Name'), - fillColor: Colors.white24, - filled: true, - border: OutlineInputBorder( - gapPadding: 1.0, - borderRadius: BorderRadius.circular(12.0), - borderSide: BorderSide(color: Colors.green[50], width: 0.4), - ), - ), - initialValue: customerBloc.customerRepository.customer.name, - autovalidateMode: AutovalidateMode.always, - validator: (val) { - return customerBloc.nameValidation(val); - }, - keyboardType: TextInputType.name, - style: new TextStyle(fontSize: 16, color: Colors.indigo), - onChanged: (value) => {customerBloc.add(CustomerNameChange(name: value))}), + Cache().getLoginType() == LoginType.email + ? TextFormField( + key: LibraryKeys.loginPasswordField, + obscureText: true, + decoration: InputDecoration( + labelStyle: TextStyle(fontSize: 14), + contentPadding: EdgeInsets.only(left: 15, top: 15, bottom: 15), + suffixIcon: IconButton( + onPressed: () => {customerBloc.add(CustomerChangePasswordObscure())}, + icon: Icon(Icons.remove_red_eye), + ), + labelText: t('Password (Leave empty if no change)'), + fillColor: Colors.white24, + filled: true, + border: OutlineInputBorder( + gapPadding: 1.0, + borderRadius: BorderRadius.circular(12.0), + borderSide: BorderSide(color: Colors.green[50], width: 0.4), + ), + ), + initialValue: customerBloc.customerRepository.customer.password, + autovalidateMode: AutovalidateMode.always, + validator: (val) { + return customerBloc.passwordValidation(val); + }, + keyboardType: TextInputType.visiblePassword, + style: new TextStyle(fontSize: 16, color: Colors.indigo), + ) + : Offstage(), Divider( color: Colors.transparent, ), - TextFormField( - decoration: InputDecoration( - contentPadding: EdgeInsets.only(left: 15, top: 15, bottom: 15), - labelText: t('First Name'), - fillColor: Colors.white24, - filled: true, - border: OutlineInputBorder( - gapPadding: 2.0, - borderRadius: BorderRadius.circular(12.0), - borderSide: BorderSide(color: Colors.green[50], width: 0.4), - ), - ), - initialValue: customerBloc.customerRepository.customer.firstname, - autovalidateMode: AutovalidateMode.always, - validator: (val) { - return customerBloc.nameValidation(val); - }, - keyboardType: TextInputType.name, - style: new TextStyle(fontSize: 16, color: Colors.indigo), - onChanged: (value) => {customerBloc.add(CustomerFirstNameChange(firstName: value))}), + Cache().getLoginType() != LoginType.apple + ? TextFormField( + decoration: InputDecoration( + contentPadding: EdgeInsets.only(left: 15, top: 15, bottom: 15), + labelText: t('Name'), + fillColor: Colors.white24, + filled: true, + border: OutlineInputBorder( + gapPadding: 1.0, + borderRadius: BorderRadius.circular(12.0), + borderSide: BorderSide(color: Colors.green[50], width: 0.4), + ), + ), + initialValue: customerBloc.customerRepository.customer.name, + autovalidateMode: AutovalidateMode.always, + validator: (val) { + return customerBloc.nameValidation(val); + }, + keyboardType: TextInputType.name, + style: new TextStyle(fontSize: 16, color: Colors.indigo), + onChanged: (value) => {customerBloc.add(CustomerNameChange(name: value))}) + : Offstage(), + Divider( + color: Colors.transparent, + ), + Cache().getLoginType() != LoginType.apple + ? TextFormField( + decoration: InputDecoration( + contentPadding: EdgeInsets.only(left: 15, top: 15, bottom: 15), + labelText: t('First Name'), + fillColor: Colors.white24, + filled: true, + border: OutlineInputBorder( + gapPadding: 2.0, + borderRadius: BorderRadius.circular(12.0), + borderSide: BorderSide(color: Colors.green[50], width: 0.4), + ), + ), + initialValue: customerBloc.customerRepository.customer.firstname, + autovalidateMode: AutovalidateMode.always, + validator: (val) { + return customerBloc.nameValidation(val); + }, + keyboardType: TextInputType.name, + style: new TextStyle(fontSize: 16, color: Colors.indigo), + onChanged: (value) => {customerBloc.add(CustomerFirstNameChange(firstName: value))}) + : Offstage(), Divider( color: Colors.transparent, ), diff --git a/pubspec.yaml b/pubspec.yaml index 6789594..70e8f20 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.5+52 +version: 1.1.5+54 environment: sdk: ">=2.7.0 <3.0.0"