workouttest_app/lib/model/cache.dart
2021-03-09 15:49:15 +01:00

542 lines
19 KiB
Dart

import 'dart:collection';
import 'dart:convert';
import 'package:aitrainer_app/model/customer.dart';
import 'package:aitrainer_app/model/exercise_plan.dart';
import 'package:aitrainer_app/model/exercise_plan_detail.dart';
import 'package:aitrainer_app/model/exercise_plan_template.dart';
import 'package:aitrainer_app/model/exercise_tree.dart';
import 'package:aitrainer_app/model/exercise.dart';
import 'package:aitrainer_app/model/model_change.dart';
import 'package:aitrainer_app/model/product.dart' as wt_product;
import 'package:aitrainer_app/model/product_test.dart';
import 'package:aitrainer_app/model/property.dart';
import 'package:aitrainer_app/model/purchase.dart';
import 'package:aitrainer_app/model/workout_menu_tree.dart';
import 'package:aitrainer_app/repository/customer_repository.dart';
import 'package:aitrainer_app/service/firebase_api.dart';
import 'package:aitrainer_app/service/logging.dart';
import 'package:aitrainer_app/service/package_service.dart';
import 'package:aitrainer_app/util/enums.dart';
import 'package:aitrainer_app/util/env.dart';
import 'package:aitrainer_app/util/track.dart';
import 'package:flurry/flurry.dart';
import 'package:flutter_facebook_auth/flutter_facebook_auth.dart';
import 'package:package_info/package_info.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:aitrainer_app/model/exercise_type.dart';
import 'customer_exercise_device.dart';
import 'exercise_device.dart';
enum SharePrefsChange {
login,
registration,
logout,
}
/*
Auth flow of the app
1. During the login screen the authentication will be executed
- if not successful: message: Network error, try again later
- if successful
- get the stored shared preferences and customer id
- if customer_id not present -> registration page
- if present, check if the expiration_date > 10 days -> login page
- else get the API customer by the stored customer_id
- After registration / login store the preferences:
- AuthToken
- customer_id
- last_store_date
- is_registered
- is_logged_in
*/
class Cache with Logging {
static final Cache _singleton = Cache._internal();
// Keys to store and fetch data from SharedPreferences
static final String authTokenKey = 'auth_token';
static final String customerIdKey = 'customer_id';
static final String firebaseUidKey = 'firebase_uid';
static final String lastStoreDateKey = 'last_date';
static final String isRegisteredKey = 'is_registered';
static final String isLoggedInKey = 'is_logged_in';
static final String langKey = 'lang';
static final String serverKey = 'live';
static final String hardwareKey = 'hardware';
static final String loginTypeKey = 'login_type';
static final String timerDisplayKey = 'timer_display';
static final String activeExercisePlanKey = 'active_exercise_plan';
static final String activeExercisePlanDetailsKey = 'active_exercise_details_plan';
static String baseUrl = 'http://aitrainer.info:8888/api/';
static final String mediaUrl = 'https://aitrainer.info:4343/media/';
static final String username = 'bosi';
static final String password = 'andio2009';
String authToken = "";
AccessToken accessTokenFacebook;
Customer userLoggedIn;
String firebaseUid;
LoginType loginType;
PackageInfo packageInfo;
bool hasPurchased = false;
bool firstLoad = true;
List<ExerciseType> _exerciseTypes;
List<ExerciseTree> _exerciseTree;
List<Exercise> _exercises;
ExercisePlan _myExercisePlan;
List<Property> _properties;
List<wt_product.Product> _products;
List<Purchase> _purchases = List();
List<ProductTest> _productTests;
List<ExercisePlanTemplate> _exercisePlanTemplates = List();
ExercisePlan activeExercisePlan;
List<ExercisePlanDetail> activeExercisePlanDetails;
List<ExerciseDevice> _devices;
List<CustomerExerciseDevice> _customerDevices;
LinkedHashMap<int, ExercisePlanDetail> _myExercisesPlanDetails = LinkedHashMap<int, ExercisePlanDetail>();
LinkedHashMap _tree = LinkedHashMap<String, WorkoutMenuTree>();
double _percentExercises = -1;
Customer _trainee;
List<Exercise> _exercisesTrainee;
ExercisePlan _traineeExercisePlan;
List<ExercisePlanDetail> _traineeExercisesPlanDetail;
LinkedHashMap<String, int> _badges = LinkedHashMap();
List deviceLanguages;
String startPage = "home";
String testEnvironment;
bool liveServer = true;
bool hasHardware = false;
factory Cache() {
return _singleton;
}
Cache._internal() {
String testEnv = EnvironmentConfig.test_env;
this.testEnvironment = testEnv;
if (testEnv == "1") {
baseUrl = 'http://aitrainer.app:8899/api/';
liveServer = false;
}
}
void setTestBaseUrl() {
baseUrl = 'http://aitrainer.app:8899/api/';
}
String getAuthToken() {
return this.authToken;
}
Future<void> saveActiveExercisePlan(ExercisePlan exercisePlan, List<ExercisePlanDetail> exercisePlanDetails) async {
this.activeExercisePlan = exercisePlan;
this.activeExercisePlanDetails = exercisePlanDetails;
String exercisePlanJson = JsonEncoder().convert(exercisePlan.toJson());
String detailsJson = jsonEncode(exercisePlanDetails);
Future<SharedPreferences> prefs = SharedPreferences.getInstance();
SharedPreferences sharedPreferences;
sharedPreferences = await prefs;
sharedPreferences.setString(Cache.activeExercisePlanKey, exercisePlanJson);
sharedPreferences.setString(Cache.activeExercisePlanDetailsKey, detailsJson);
}
Future<void> getActiveExercisePlan() async {
Future<SharedPreferences> prefs = SharedPreferences.getInstance();
SharedPreferences sharedPreferences;
sharedPreferences = await prefs;
String exercisePlanJson = sharedPreferences.getString(Cache.activeExercisePlanKey);
if (exercisePlanJson != null) {
final Map<String, dynamic> map = JsonDecoder().convert(exercisePlanJson);
this.activeExercisePlan = ExercisePlan.fromJson(map);
}
String detailsJson = sharedPreferences.getString(Cache.activeExercisePlanDetailsKey);
if (detailsJson != null) {
Iterable json = jsonDecode(detailsJson);
this.activeExercisePlanDetails = json.map((details) => ExercisePlanDetail.fromJson(details)).toList();
}
}
Future<void> setServer(bool live) async {
if (this.testEnvironment == "1") {
liveServer = false;
live = false;
}
Future<SharedPreferences> prefs = SharedPreferences.getInstance();
SharedPreferences sharedPreferences;
sharedPreferences = await prefs;
liveServer = live;
sharedPreferences.setBool(Cache.serverKey, live);
}
void getHardware(SharedPreferences prefs) {
final bool hasHardware = prefs.getBool(Cache.hardwareKey);
this.hasHardware = hasHardware;
if (hasHardware == null) {
this.hasHardware = false;
}
}
Future<bool> selectedHardwareBefore() async {
Future<SharedPreferences> prefs = SharedPreferences.getInstance();
SharedPreferences sharedPreferences = await prefs;
final bool selectedHardware = sharedPreferences.getBool(Cache.hardwareKey);
return selectedHardware == null;
}
Future<void> setHardware(bool hasHardware) async {
Future<SharedPreferences> prefs = SharedPreferences.getInstance();
SharedPreferences sharedPreferences;
sharedPreferences = await prefs;
sharedPreferences.setBool(Cache.hardwareKey, hasHardware);
this.hasHardware = hasHardware;
}
void setServerAddress(SharedPreferences prefs) {
if (this.testEnvironment == "1") {
baseUrl = 'http://aitrainer.app:8899/api/';
return;
}
final bool live = prefs.getBool(Cache.serverKey);
if (live == null) {
return;
}
liveServer = live;
if (live) {
baseUrl = 'http://aitrainer.info:8888/api/';
} else {
baseUrl = 'http://aitrainer.app:8899/api/';
}
}
Future<void> setLoginTypeFromPrefs() async {
Future<SharedPreferences> 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);
}
static String getBaseUrl() {
return baseUrl;
}
static String getMediaUrl() {
return mediaUrl;
}
afterRegistration(Customer customer) async {
Future<SharedPreferences> prefs = SharedPreferences.getInstance();
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);
}
afterLogin(Customer customer) async {
Future<SharedPreferences> 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<SharedPreferences> 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<SharedPreferences> prefs = SharedPreferences.getInstance();
SharedPreferences sharedPreferences = await prefs;
sharedPreferences.setString(Cache.loginTypeKey, Cache().getLoginType().toString());
await setPreferences(prefs, SharePrefsChange.login, userLoggedIn.customerId, Cache().firebaseUid);
}
logout() async {
if (this.accessTokenFacebook != null) {
await FirebaseApi().logOutFacebook();
}
userLoggedIn = null;
firebaseUid = null;
authToken = "";
_trainee = null;
_percentExercises = -1;
_exercisesTrainee = null;
_traineeExercisePlan = null;
_exercises = List();
_myExercisesPlanDetails = LinkedHashMap();
log("Trainees is null? " + (_trainee == null).toString());
Future<SharedPreferences> prefs = SharedPreferences.getInstance();
await setPreferences(prefs, SharePrefsChange.logout, 0, "");
}
Future<void> setPreferences(Future<SharedPreferences> prefs, SharePrefsChange type, int customerId, String firebaseUid) async {
SharedPreferences sharedPreferences;
sharedPreferences = await prefs;
DateTime now = DateTime.now();
sharedPreferences.setString(Cache.lastStoreDateKey, now.toString());
if (type == SharePrefsChange.registration) {
sharedPreferences.setInt(Cache.customerIdKey, customerId);
sharedPreferences.setBool(Cache.isRegisteredKey, true);
sharedPreferences.setBool(Cache.isLoggedInKey, true);
sharedPreferences.setString(Cache.firebaseUidKey, firebaseUid);
await initCustomer(customerId);
} else if (type == SharePrefsChange.login) {
sharedPreferences.setInt(Cache.customerIdKey, customerId);
sharedPreferences.setString(Cache.firebaseUidKey, firebaseUid);
sharedPreferences.setBool(Cache.isLoggedInKey, true);
await initCustomer(customerId);
} else if (type == SharePrefsChange.logout) {
sharedPreferences.setBool(Cache.isLoggedInKey, false);
sharedPreferences.setInt(Cache.customerIdKey, 0);
sharedPreferences.setString(Cache.firebaseUidKey, null);
sharedPreferences.setString(authTokenKey, "");
}
await initBadges();
}
void setExerciseTypes(List<ExerciseType> exerciseTypes) {
this._exerciseTypes = exerciseTypes;
}
void setExerciseTree(List<ExerciseTree> exerciseTree) {
this._exerciseTree = exerciseTree;
}
void setExercises(List<Exercise> exercises) => this._exercises = exercises;
void setExercisesTrainee(List<Exercise> exercises) {
this._exercisesTrainee = exercises;
}
void setWorkoutMenuTree(LinkedHashMap<String, WorkoutMenuTree> tree) {
this._tree = tree;
}
List<ExerciseType> getExerciseTypes() => this._exerciseTypes;
ExerciseType getExerciseTypeById(int exerciseTypeId) {
ExerciseType exerciseType;
this._exerciseTypes.forEach((element) {
if (element.exerciseTypeId == exerciseTypeId) {
exerciseType = element;
}
});
return exerciseType;
}
List<ExerciseTree> getExerciseTree() => this._exerciseTree;
List<Exercise> getExercises() => this._exercises;
List<Exercise> getExercisesTrainee() => this._exercisesTrainee;
LinkedHashMap<String, WorkoutMenuTree> getWorkoutMenuTree() => this._tree;
void setPercentExercises(double percent) => this._percentExercises = percent;
double getPercentExercises() => this._percentExercises;
void addExercise(Exercise exercise) => _exercises.add(exercise);
void addExerciseTrainee(Exercise exercise) => _exercisesTrainee.add(exercise);
Customer getTrainee() => this._trainee;
void setTrainee(Customer trainee) => _trainee = trainee;
void setTraineeExercisePlan(ExercisePlan exercisePlan) => this._traineeExercisePlan = exercisePlan;
ExercisePlan getTraineesExercisePlan() => this._traineeExercisePlan;
void setMyExercisePlan(ExercisePlan exercisePlan) => _myExercisePlan = exercisePlan;
ExercisePlan getMyExercisePlan() => _myExercisePlan;
void setMyExercisePlanDetails(LinkedHashMap<int, ExercisePlanDetail> listExercisePlanDetail) =>
_myExercisesPlanDetails = listExercisePlanDetail;
void addToMyExercisePlanDetails(ExercisePlanDetail detail) => _myExercisesPlanDetails[detail.exerciseTypeId] = detail;
LinkedHashMap<int, ExercisePlanDetail> getMyExercisePlanDetails() => _myExercisesPlanDetails;
void resetMyExercisePlanDetails() => _myExercisesPlanDetails = LinkedHashMap<int, ExercisePlanDetail>();
void updateMyExercisePlanDetail(ExercisePlanDetail detail) {
this.addToMyExercisePlanDetails(detail);
}
void deleteMyExercisePlanDetail(ExercisePlanDetail detail) => this.deleteMyExercisePlanDetailByExerciseTypeId(detail.exerciseTypeId);
void deletedMyExercisePlanDetail(ExercisePlanDetail detail) =>
this._myExercisesPlanDetails[detail.exerciseTypeId].change = ModelChange.deleted;
void deleteMyExercisePlanDetailByExerciseTypeId(int exerciseTypeId) {
this._myExercisesPlanDetails[exerciseTypeId].change = ModelChange.delete;
}
void setProperties(List<Property> properties) => this._properties = properties;
List<Property> getProperties() => _properties;
void setDevices(List<ExerciseDevice> devices) => this._devices = devices;
List<ExerciseDevice> getDevices() => this._devices;
void setCustomerDevices(List<CustomerExerciseDevice> devices) => this._customerDevices = devices;
List<CustomerExerciseDevice> getCustomerDevices() => this._customerDevices;
LinkedHashMap getBadges() => _badges;
void setBadge(String key, bool inc) {
if (inc) {
if (_badges[key] != null) {
_badges[key]++;
} else {
_badges[key] = 1;
}
} else {
if (_badges[key] != null) {
if (_badges[key] == 1) {
_badges.remove(key);
} else {
_badges[key]--;
}
}
}
}
void setBadgeNr(String key, int counter) {
if (_badges[key] != null) {
_badges[key] += counter;
} else {
_badges[key] = counter;
}
}
Future<void> initBadges() async {
CustomerRepository customerRepository = CustomerRepository();
_badges = LinkedHashMap();
customerRepository.setCustomer(userLoggedIn);
int _ecto = customerRepository.getCustomerPropertyValue(PropertyEnum.Ectomorph.toStr()).toInt();
int _mezo = customerRepository.getCustomerPropertyValue(PropertyEnum.Mesomorph.toStr()).toInt();
int _endo = customerRepository.getCustomerPropertyValue(PropertyEnum.Endomorph.toStr()).toInt();
//print("endo " + _endo.toString() + " mezo " + _mezo.toString());
if (this.userLoggedIn != null) {
if (this.userLoggedIn.birthYear == null || this.userLoggedIn.birthYear == 0) {
setBadge("personalData", true);
setBadge("account", true);
}
if (this._customerDevices == null || this._customerDevices.isEmpty) {
setBadge("customerDevice", true);
setBadge("account", true);
}
if (userLoggedIn.properties == null || userLoggedIn.properties.isEmpty) {
setBadge("personalData", true);
setBadge("bodyType", true);
setBadge("Sizes", true);
setBadge("BMI", true);
setBadge("BMR", true);
setBadgeNr("My Body", 3);
setBadgeNr("home", 3);
} else if (customerRepository.getWeight() == 0) {
setBadge("BMI", true);
setBadge("BMR", true);
setBadge("My Body", true);
setBadgeNr("home", 1);
}
if (_ecto == 0 && _mezo == 0 && _endo == 0) {
setBadge("account", true);
setBadge("bodyType", true);
}
if (this._exercises == null || this._exercises.length == 0) {
setBadge("home", true);
setBadge("Strength", true);
setBadge("Cardio", true);
}
if (customerRepository.getHeight() == 0) {
setBadge("BMI", true);
setBadge("BMR", true);
setBadge("My Body", true);
setBadgeNr("home", 1);
}
if (userLoggedIn.goal == null) {
setBadge("Goal", true);
setBadge("account", true);
}
if (userLoggedIn.fitnessLevel == null) {
setBadge("FitnessLevel", true);
setBadge("account", true);
}
}
log("Badges: " + _badges.toString());
}
List get products => _products;
void setProducts(List value) => _products = value;
List get purchases => _purchases;
setPurchases(List value) => _purchases = value;
List get productTests => _productTests;
set productTests(List value) => _productTests = value;
Future<void> initCustomer(int customerId) async {
log(" *** initCustomer");
await PackageApi().getCustomerPackage(customerId);
Flurry.setUserId(customerId.toString());
await setLoginTypeFromPrefs();
await getActiveExercisePlan();
Cache().startPage = "home";
Track().track(TrackingEvent.enter);
}
AccessToken get getAccessTokenFacebook => accessTokenFacebook;
set setAccessTokenFacebook(AccessToken accessTokenFacebook) => this.accessTokenFacebook = accessTokenFacebook;
LoginType getLoginType() => loginType;
void setLoginType(LoginType type) => this.loginType = type;
List get exercisePlanTemplates => this._exercisePlanTemplates;
setExercisePlanTemplates(value) => this._exercisePlanTemplates = value;
}