WT1.1.11 Null-Safe migration
This commit is contained in:
@@ -7,7 +7,7 @@ import 'package:shared_preferences/shared_preferences.dart';
|
||||
class AppLanguage with Logging {
|
||||
static final AppLanguage _singleton = AppLanguage._internal();
|
||||
|
||||
Locale _appLocale = Locale('en');
|
||||
Locale? _appLocale = Locale('en');
|
||||
|
||||
factory AppLanguage() {
|
||||
return _singleton;
|
||||
@@ -23,7 +23,7 @@ class AppLanguage with Logging {
|
||||
|
||||
Future<void> fetchLocale() async {
|
||||
var prefs = await SharedPreferences.getInstance();
|
||||
String langCode = prefs.getString('language_code');
|
||||
String? langCode = prefs.getString('language_code');
|
||||
log(" ---- lang code $langCode");
|
||||
if (langCode == null) {
|
||||
_appLocale = Locale('en');
|
||||
@@ -34,7 +34,7 @@ class AppLanguage with Logging {
|
||||
}
|
||||
|
||||
getLocale(SharedPreferences prefs) {
|
||||
String langCode = prefs.getString('language_code');
|
||||
String? langCode = prefs.getString('language_code');
|
||||
if (langCode == null) {
|
||||
final String localName = Platform.localeName;
|
||||
if (localName.endsWith("HU")) {
|
||||
|
||||
@@ -6,22 +6,21 @@ import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
class AppLocalizations with Logging {
|
||||
Locale locale;
|
||||
late Locale locale;
|
||||
bool isTest;
|
||||
late Map<String, String> _localizedStrings;
|
||||
|
||||
AppLocalizations(this.locale, {this.isTest = false});
|
||||
|
||||
// Helper method to keep the code in the widgets concise
|
||||
// Localizations are accessed using an InheritedWidget "of" syntax
|
||||
static AppLocalizations of(BuildContext context) {
|
||||
static AppLocalizations? of(BuildContext context) {
|
||||
return Localizations.of<AppLocalizations>(context, AppLocalizations);
|
||||
}
|
||||
|
||||
// Static member to have a simple access to the delegate from the MaterialApp
|
||||
static const LocalizationsDelegate<AppLocalizations> delegate = AppLocalizationsDelegate();
|
||||
|
||||
Map<String, String> _localizedStrings;
|
||||
|
||||
setLocale(Locale locale) {
|
||||
this.locale = locale;
|
||||
}
|
||||
@@ -46,7 +45,7 @@ class AppLocalizations with Logging {
|
||||
// This method will be called from every widget which needs a localized text
|
||||
String translate(String key) {
|
||||
if (isTest) return key;
|
||||
String translated = _localizedStrings[key];
|
||||
String? translated = _localizedStrings[key];
|
||||
return translated != null ? translated : key;
|
||||
}
|
||||
}
|
||||
|
||||
+10
-20
@@ -8,7 +8,6 @@ import 'package:badges/badges.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:sentry/sentry.dart';
|
||||
|
||||
class DateRate {
|
||||
static String daily = "daily";
|
||||
@@ -18,8 +17,8 @@ class DateRate {
|
||||
}
|
||||
|
||||
mixin Common {
|
||||
final EMAIL_ERROR = "Please type a right email address here.";
|
||||
final PASSWORD_ERROR = "The password must have at least 8 characters.";
|
||||
final emailError = "Please type a right email address here.";
|
||||
final passwordError = "The password must have at least 8 characters.";
|
||||
|
||||
String toJson(Map<String, String> map) {
|
||||
String rc = "{";
|
||||
@@ -30,9 +29,9 @@ mixin Common {
|
||||
return rc;
|
||||
}
|
||||
|
||||
ExerciseType getExerciseType(int exerciseTypeId) {
|
||||
ExerciseType returnElement;
|
||||
List<ExerciseType> listExerciseType = Cache().getExerciseTypes();
|
||||
ExerciseType? getExerciseType(int exerciseTypeId) {
|
||||
ExerciseType? returnElement;
|
||||
List<ExerciseType>? listExerciseType = Cache().getExerciseTypes();
|
||||
if (listExerciseType != null) {
|
||||
for (var element in listExerciseType) {
|
||||
if (exerciseTypeId == element.exerciseTypeId) {
|
||||
@@ -65,7 +64,7 @@ mixin Common {
|
||||
}
|
||||
|
||||
bool validateEmail(UserRepository userRepository) {
|
||||
final String email = userRepository.user.email;
|
||||
final String email = userRepository.user.email!;
|
||||
final RegExp _emailRegExp = RegExp(
|
||||
r'^[a-zA-Z0-9._-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$',
|
||||
);
|
||||
@@ -73,7 +72,7 @@ mixin Common {
|
||||
}
|
||||
|
||||
bool validatePassword(UserRepository userRepository) {
|
||||
final password = userRepository.user.password;
|
||||
final password = userRepository.user.password!;
|
||||
final RegExp _passwordRegExp = RegExp(r'^(?=.*[A-Za-z0-9])(?=.*\d)[A-Za-z\d]{7,}$');
|
||||
|
||||
return _passwordRegExp.hasMatch(password);
|
||||
@@ -99,12 +98,12 @@ mixin Common {
|
||||
return datePart;
|
||||
}
|
||||
|
||||
static String emailValidation(String email) {
|
||||
static String? emailValidation(String email) {
|
||||
bool emailValid = RegExp(r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+@[a-zA-Z0-9]+\.[a-zA-Z]+").hasMatch(email);
|
||||
return emailValid ? null : "Please type an email address";
|
||||
}
|
||||
|
||||
static String passwordValidation(String value) {
|
||||
static String? passwordValidation(String? value) {
|
||||
if (value == null || value.length == 0) {
|
||||
return null;
|
||||
}
|
||||
@@ -114,7 +113,7 @@ mixin Common {
|
||||
|
||||
static Widget badgedIcon(Color color, IconData icon, String badgeKey) {
|
||||
//print("BadgetIcon: " + Cache().getBadges().toString());
|
||||
int badgeValue = Cache().getBadges()[badgeKey];
|
||||
int? badgeValue = Cache().getBadges()[badgeKey];
|
||||
bool show = (badgeValue != null);
|
||||
int counter = show ? badgeValue : 0;
|
||||
//print("show $show BadgeKey $badgeKey count $counter");
|
||||
@@ -134,13 +133,4 @@ mixin Common {
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
static Future<void> sendMessage(String message) async {
|
||||
// Sends a full Sentry event payload to show the different parts of the UI.
|
||||
await Sentry.captureMessage(
|
||||
message,
|
||||
level: SentryLevel.info,
|
||||
template: 'Message: %s, customerId: ' + Cache().userLoggedIn.customerId.toString(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -47,7 +47,7 @@ enum TrackingEvent {
|
||||
}
|
||||
|
||||
T enumFromString<T>(Iterable<T> values, String value) {
|
||||
return values.firstWhere((type) => type.toString().split(".").last == value, orElse: () => null);
|
||||
return values.firstWhere((type) => type.toString().split(".").last == value);
|
||||
}
|
||||
|
||||
extension TrackingEventExt on TrackingEvent {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
class NotFoundException implements Exception {
|
||||
final String message;
|
||||
const NotFoundException({this.message});
|
||||
const NotFoundException({required this.message});
|
||||
}
|
||||
|
||||
class WorkoutTestException implements Exception {
|
||||
@@ -9,5 +9,5 @@ class WorkoutTestException implements Exception {
|
||||
|
||||
final String message;
|
||||
final String code;
|
||||
const WorkoutTestException({this.message, this.code});
|
||||
const WorkoutTestException({required this.message, required this.code});
|
||||
}
|
||||
|
||||
+14
-21
@@ -2,15 +2,14 @@ import 'dart:io';
|
||||
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:aitrainer_app/service/logging.dart';
|
||||
import 'package:aitrainer_app/util/common.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:purchases_flutter/purchases_flutter.dart';
|
||||
import 'package:aitrainer_app/model/product.dart' as wtproduct;
|
||||
|
||||
class RevenueCatPurchases with Logging {
|
||||
static final RevenueCatPurchases _singleton = RevenueCatPurchases._internal();
|
||||
Offering _offering;
|
||||
String appUserId;
|
||||
Offering? _offering;
|
||||
String? appUserId;
|
||||
|
||||
factory RevenueCatPurchases() {
|
||||
return _singleton;
|
||||
@@ -18,14 +17,14 @@ class RevenueCatPurchases with Logging {
|
||||
|
||||
RevenueCatPurchases._internal();
|
||||
|
||||
Offering get offering => _offering;
|
||||
Offering? get offering => _offering;
|
||||
|
||||
Future<void> initPlatform() async {
|
||||
if (Cache().userLoggedIn != null) {
|
||||
await Purchases.setDebugLogsEnabled(true);
|
||||
await Purchases.setup("yLxGFWaeRtThLImqznvBnUEKjgArSsZE", appUserId: Cache().userLoggedIn.customerId.toString());
|
||||
await Purchases.setup("yLxGFWaeRtThLImqznvBnUEKjgArSsZE", appUserId: Cache().userLoggedIn!.customerId.toString());
|
||||
appUserId = await Purchases.appUserID;
|
||||
log("AppUserId: " + appUserId);
|
||||
log("AppUserId: $appUserId");
|
||||
await Purchases.setAllowSharingStoreAccount(true);
|
||||
await this.restore();
|
||||
}
|
||||
@@ -36,9 +35,7 @@ class RevenueCatPurchases with Logging {
|
||||
try {
|
||||
//PurchaserInfo purchaserInfo = await Purchases.restoreTransactions();
|
||||
PurchaserInfo purchaserInfo = await Purchases.getPurchaserInfo();
|
||||
if (purchaserInfo != null &&
|
||||
purchaserInfo.entitlements.all["wt_subscription"] != null &&
|
||||
purchaserInfo.entitlements.all["wt_subscription"].isActive) {
|
||||
if (purchaserInfo.entitlements.all["wt_subscription"] != null && purchaserInfo.entitlements.all["wt_subscription"]!.isActive) {
|
||||
Cache().hasPurchased = true;
|
||||
log(" ******************************************** ");
|
||||
log(" Purchase active ! ");
|
||||
@@ -49,24 +46,23 @@ class RevenueCatPurchases with Logging {
|
||||
log("Purchaserinfo not reachable " + e.toString());
|
||||
}
|
||||
}
|
||||
if (Cache().userLoggedIn.admin == 1) {
|
||||
if (Cache().userLoggedIn!.admin == 1) {
|
||||
Cache().hasPurchased = true;
|
||||
}
|
||||
}
|
||||
|
||||
Future<Offering> getOfferings() async {
|
||||
Future<Offering?> getOfferings() async {
|
||||
if (appUserId == null) {
|
||||
await initPlatform();
|
||||
}
|
||||
log(" .. acessing offerings...");
|
||||
try {
|
||||
Offerings offerings = await Purchases.getOfferings();
|
||||
if (offerings.current != null && offerings.current.availablePackages.isNotEmpty) {
|
||||
if (offerings.current != null && offerings.current!.availablePackages.isNotEmpty) {
|
||||
// Display packages for sale
|
||||
_offering = offerings.current;
|
||||
} else {
|
||||
log("No current offerings");
|
||||
Common.sendMessage("No Current offerings");
|
||||
}
|
||||
} on PlatformException catch (e) {
|
||||
// optional error handling
|
||||
@@ -81,10 +77,10 @@ class RevenueCatPurchases with Logging {
|
||||
_offering = await getOfferings();
|
||||
}
|
||||
if (_offering != null) {
|
||||
String productId = Platform.isAndroid ? product.productIdAndroid : product.productIdIos;
|
||||
Package selectedPackage;
|
||||
log("Nr of packages: " + _offering.availablePackages.length.toString() + " ProductId: " + productId);
|
||||
for (var package in _offering.availablePackages) {
|
||||
String productId = Platform.isAndroid ? product.productIdAndroid! : product.productIdIos!;
|
||||
Package? selectedPackage;
|
||||
log("Nr of packages: " + _offering!.availablePackages.length.toString() + " ProductId: " + productId);
|
||||
for (var package in _offering!.availablePackages) {
|
||||
log("package to check " + package.product.identifier.toString());
|
||||
if (package.product.identifier == productId) {
|
||||
selectedPackage = package;
|
||||
@@ -94,12 +90,11 @@ class RevenueCatPurchases with Logging {
|
||||
}
|
||||
if (selectedPackage != null) {
|
||||
PurchaserInfo purchaserInfo = await Purchases.purchasePackage(selectedPackage);
|
||||
if (purchaserInfo.entitlements.all["wt_subscription"].isActive) {
|
||||
if (purchaserInfo.entitlements.all["wt_subscription"] != null && purchaserInfo.entitlements.all["wt_subscription"]!.isActive) {
|
||||
Cache().hasPurchased = true;
|
||||
}
|
||||
} else {
|
||||
log("!!!! No Selected package to purchase");
|
||||
Common.sendMessage("No Selected package to purchase");
|
||||
throw Exception("Purchase was not successful");
|
||||
}
|
||||
} else {
|
||||
@@ -114,10 +109,8 @@ class RevenueCatPurchases with Logging {
|
||||
}
|
||||
log(e.toString());
|
||||
if (errorCode == PurchasesErrorCode.purchaseCancelledError) {
|
||||
Common.sendMessage("Purchase was cancelled");
|
||||
throw Exception("Purchase was cancelled");
|
||||
} else {
|
||||
Common.sendMessage("Purchase was not successful");
|
||||
throw Exception("Purchase was not successful");
|
||||
}
|
||||
}
|
||||
|
||||
+27
-22
@@ -15,7 +15,7 @@ import 'package:aitrainer_app/model/cache.dart';
|
||||
class Session with Logging {
|
||||
Future<SharedPreferences> _prefs = SharedPreferences.getInstance();
|
||||
|
||||
SharedPreferences _sharedPreferences;
|
||||
late SharedPreferences _sharedPreferences;
|
||||
|
||||
fetchSessionAndNavigate() async {
|
||||
log(" -- Session: await prefs..");
|
||||
@@ -35,8 +35,8 @@ class Session with Logging {
|
||||
}
|
||||
|
||||
Future<void> initDeviceLocale() async {
|
||||
List languages;
|
||||
String currentLocale;
|
||||
List? languages;
|
||||
String? currentLocale;
|
||||
|
||||
// Platform messages may fail, so we use a try/catch PlatformException.
|
||||
try {
|
||||
@@ -48,7 +48,7 @@ class Session with Logging {
|
||||
}
|
||||
try {
|
||||
currentLocale = await Devicelocale.currentLocale;
|
||||
log("Device currentlocale " + currentLocale);
|
||||
log("Device currentlocale $currentLocale");
|
||||
} on PlatformException {
|
||||
log("Error obtaining current locale");
|
||||
}
|
||||
@@ -59,14 +59,14 @@ class Session with Logging {
|
||||
*/
|
||||
_fetchToken(SharedPreferences prefs) async {
|
||||
var responseJson = await APIClient().authenticateUser(Cache.username, Cache.password);
|
||||
int customerId = 0;
|
||||
int? customerId = 0;
|
||||
log("--- Lang: " + AppLanguage().appLocal.toString());
|
||||
if (responseJson['error'] != null) {
|
||||
log("************** Here big error - no authentication");
|
||||
} else if (responseJson['token'] != null) {
|
||||
prefs.setString(Cache.authTokenKey, responseJson['token']);
|
||||
Cache().authToken = responseJson['token'];
|
||||
Cache().firebaseUid = prefs.get(Cache.firebaseUidKey);
|
||||
Cache().firebaseUid = prefs.getString(Cache.firebaseUidKey);
|
||||
await PackageApi().getPackage();
|
||||
|
||||
if (prefs.get(Cache.customerIdKey) == null) {
|
||||
@@ -76,25 +76,30 @@ class Session with Logging {
|
||||
Cache().startPage = "registration";
|
||||
} else {
|
||||
DateTime now = DateTime.now();
|
||||
DateTime lastStoreDate = DateTime.parse(prefs.get(Cache.lastStoreDateKey));
|
||||
DateTime minStoreDate = now.add(Duration(days: -10));
|
||||
String? lastStore = prefs.getString(Cache.lastStoreDateKey);
|
||||
if (lastStore != null) {
|
||||
DateTime lastStoreDate = DateTime.parse(lastStore);
|
||||
DateTime minStoreDate = now.add(Duration(days: -10));
|
||||
|
||||
if (lastStoreDate == null ||
|
||||
lastStoreDate.difference(minStoreDate) > Duration(days: 10) ||
|
||||
prefs.get(Cache.isLoggedInKey) == null ||
|
||||
prefs.get(Cache.isLoggedInKey) == false) {
|
||||
log("************* Login");
|
||||
Cache().startPage = "login";
|
||||
} else {
|
||||
// only
|
||||
if (Cache().firebaseUid == null) {
|
||||
log("************* firebaseUid is null, Login");
|
||||
if (lastStoreDate.difference(minStoreDate) > Duration(days: 10) ||
|
||||
prefs.get(Cache.isLoggedInKey) == null ||
|
||||
prefs.get(Cache.isLoggedInKey) == false) {
|
||||
log("************* Login");
|
||||
Cache().startPage = "login";
|
||||
} else {
|
||||
// get API customer
|
||||
customerId = prefs.getInt(Cache.customerIdKey);
|
||||
Cache().startPage = "home";
|
||||
await Cache().initCustomer(customerId);
|
||||
if (Cache().firebaseUid == null) {
|
||||
log("************* firebaseUid is null, Login");
|
||||
Cache().startPage = "login";
|
||||
} else {
|
||||
// get API customer
|
||||
customerId = prefs.getInt(Cache.customerIdKey);
|
||||
if (customerId == null) {
|
||||
customerId = 0;
|
||||
}
|
||||
Cache().startPage = "home";
|
||||
log("Customer in the preferences $customerId");
|
||||
await Cache().initCustomer(customerId);
|
||||
}
|
||||
}
|
||||
}
|
||||
log("--- Session finished");
|
||||
|
||||
+2
-2
@@ -3,7 +3,7 @@ import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:aitrainer_app/service/logging.dart';
|
||||
import 'package:aitrainer_app/service/tracking_service.dart';
|
||||
import 'package:aitrainer_app/util/enums.dart';
|
||||
import 'package:flurry/flurry.dart';
|
||||
import 'package:aitrainer_app/library/flurry.dart';
|
||||
import 'package:aitrainer_app/model/tracking.dart' as model;
|
||||
import 'package:smartlook/smartlook.dart';
|
||||
|
||||
@@ -21,7 +21,7 @@ class Track with Logging {
|
||||
Flurry.logEvent(event.toString());
|
||||
Smartlook.setGlobalEventProperty(event.toString(), eventValue, false);
|
||||
model.Tracking tracking = model.Tracking();
|
||||
tracking.customerId = Cache().userLoggedIn.customerId;
|
||||
tracking.customerId = Cache().userLoggedIn!.customerId!;
|
||||
tracking.event = event.enumToString();
|
||||
if (eventValue.isNotEmpty) {
|
||||
tracking.eventValue = eventValue;
|
||||
|
||||
+3
-5
@@ -2,14 +2,12 @@ import 'package:aitrainer_app/util/app_localization.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
|
||||
mixin Trans {
|
||||
BuildContext context;
|
||||
late BuildContext context;
|
||||
void setContext(BuildContext context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
String t(String text) {
|
||||
return AppLocalizations.of(context).translate(text);
|
||||
return AppLocalizations.of(context)!.translate(text);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user