WT1.1.11 Null-Safe migration

This commit is contained in:
bossanyit
2021-04-02 11:42:26 +02:00
parent a656562c49
commit 01148c6e39
219 changed files with 3208 additions and 5334 deletions
+3 -3
View File
@@ -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")) {
+4 -5
View File
@@ -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
View File
@@ -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
View File
@@ -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 {
+2 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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);
}
}
}