v1.0.0 outsourced from aitrainer_app
This commit is contained in:
@@ -0,0 +1,141 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
import 'package:workouttest_util/util/logging.dart';
|
||||
import 'package:workouttest_util/util/common.dart';
|
||||
import 'package:workouttest_util/util/not_found_exception.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:workouttest_util/model/cache.dart';
|
||||
|
||||
class APIClient with Common, Logging {
|
||||
static final APIClient _singleton = APIClient._internal();
|
||||
late bool cert;
|
||||
|
||||
factory APIClient() {
|
||||
return _singleton;
|
||||
}
|
||||
|
||||
APIClient._internal() {
|
||||
cert = false;
|
||||
}
|
||||
|
||||
dynamic authenticateUser(String email, String password) async {
|
||||
var url = Cache().getBaseUrl() + "authenticate";
|
||||
|
||||
try {
|
||||
ByteData data = await rootBundle.load('asset/data/aitrainer_server.crt.pem');
|
||||
SecurityContext context = SecurityContext.defaultContext;
|
||||
if (cert == false) {
|
||||
print("Set CERT $cert");
|
||||
context.setTrustedCertificatesBytes(data.buffer.asUint8List(), password: "[xxxx]");
|
||||
cert = true;
|
||||
}
|
||||
|
||||
HttpClient client = new HttpClient(); //context: context Todo provide the right certificate
|
||||
client.badCertificateCallback = ((X509Certificate cert, String host, int port) {
|
||||
print("Host: $host Port: $port");
|
||||
return true;
|
||||
});
|
||||
var uri = Uri.parse(url);
|
||||
final HttpClientRequest request = await client.postUrl(uri);
|
||||
request.headers.set('Content-Type', 'application/json');
|
||||
request.headers.set('Authorization', '1');
|
||||
|
||||
final body = '{"username":"$email", "password":"$password"}';
|
||||
request.write(body);
|
||||
HttpClientResponse result = await request.close();
|
||||
client.close();
|
||||
if (result.statusCode != 200) {
|
||||
trace("authentication response: ${result.statusCode} with URL: $url");
|
||||
throw Exception("Authentication error: ${result.statusCode}");
|
||||
}
|
||||
return jsonDecode(await result.transform(utf8.decoder).join());
|
||||
} catch (exception) {
|
||||
print(exception.toString());
|
||||
try {
|
||||
await Sentry.captureException(exception);
|
||||
} on Exception catch (e) {
|
||||
print(e);
|
||||
}
|
||||
|
||||
throw Exception("Network error, try again later!");
|
||||
}
|
||||
}
|
||||
|
||||
Future<String> post(String endPoint, String body) async {
|
||||
final url = Cache().getBaseUrl() + endPoint;
|
||||
trace(" ------------ http/post body $body - url: $url ");
|
||||
try {
|
||||
String authToken = Cache().getAuthToken();
|
||||
if (authToken.length == 0) {
|
||||
var responseJson = await this.authenticateUser(Cache.username, Cache.password);
|
||||
authToken = responseJson['token'];
|
||||
Cache().authToken = authToken;
|
||||
}
|
||||
var uri = Uri.parse(url);
|
||||
HttpClient client = new HttpClient();
|
||||
|
||||
client.badCertificateCallback = ((X509Certificate cert, String host, int port) => true);
|
||||
|
||||
final HttpClientRequest request = await client.postUrl(uri);
|
||||
request.headers.contentType = new ContentType("application", "json", charset: "utf-8");
|
||||
request.headers.set('Authorization', 'Bearer $authToken');
|
||||
//request.contentLength = body.length;
|
||||
request.write(body);
|
||||
HttpClientResponse result = await request.close();
|
||||
client.close();
|
||||
trace(" ------------post response code: " + result.statusCode.toString());
|
||||
if (result.statusCode == 200) {
|
||||
return await result.transform(utf8.decoder).join();
|
||||
} else if (result.statusCode == 404) {
|
||||
throw NotFoundException(message: "Not Found");
|
||||
} else {
|
||||
throw Exception("Network Error, please try again later");
|
||||
}
|
||||
} on NotFoundException catch(e) {
|
||||
throw NotFoundException(message: "Not Found");
|
||||
} on Exception catch (e) {
|
||||
print("Post Exception: $e");
|
||||
await Sentry.captureException(e);
|
||||
throw Exception("Network Error, please try again later");
|
||||
}
|
||||
}
|
||||
|
||||
Future<String> get(String endPoint, String param) async {
|
||||
final url = Cache().getBaseUrl() + endPoint + param;
|
||||
try {
|
||||
trace("-------- API get " + url);
|
||||
String authToken = Cache().getAuthToken();
|
||||
if (authToken.length == 0) {
|
||||
var responseJson = await this.authenticateUser(Cache.username, Cache.password);
|
||||
authToken = responseJson['token'];
|
||||
Cache().authToken = authToken;
|
||||
}
|
||||
var uri = Uri.parse(url);
|
||||
|
||||
HttpClient client = new HttpClient();
|
||||
|
||||
client.badCertificateCallback = ((X509Certificate cert, String host, int port) => true);
|
||||
|
||||
final HttpClientRequest request = await client.getUrl(uri);
|
||||
request.headers.set('Content-Type', 'application/json');
|
||||
request.headers.set('Authorization', 'Bearer $authToken');
|
||||
HttpClientResponse result = await request.close();
|
||||
client.close();
|
||||
trace(" ------------get response code: " + result.statusCode.toString());
|
||||
if (result.statusCode == 200) {
|
||||
return await result.transform(utf8.decoder).join();
|
||||
} else if (result.statusCode == 404) {
|
||||
throw NotFoundException(message: "Not Found");
|
||||
} else {
|
||||
throw Exception("Network Error, please try again later");
|
||||
}
|
||||
} on NotFoundException catch(e) {
|
||||
throw NotFoundException(message: "Not Found");
|
||||
} on Exception catch (e) {
|
||||
print("Post Exception: $e");
|
||||
await Sentry.captureException(e);
|
||||
throw Exception("Network Error, please try again later");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
import 'package:workouttest_util/model/customer_exercise_device.dart';
|
||||
import 'package:workouttest_util/util/logging.dart';
|
||||
import 'package:workouttest_util/util/not_found_exception.dart';
|
||||
import 'dart:convert';
|
||||
|
||||
import 'api.dart';
|
||||
|
||||
class CustomerExerciseDeviceApi with Logging {
|
||||
final APIClient _client = APIClient();
|
||||
|
||||
Future<List<CustomerExerciseDevice>> getDevices(int customerId) async {
|
||||
List<CustomerExerciseDevice> devices = [];
|
||||
try {
|
||||
log(" --- get customer_exercise_devices: ");
|
||||
final body = await _client.get("customer_exercise_device/customer/" + customerId.toString(), "");
|
||||
final Iterable json = jsonDecode(body);
|
||||
devices = json.map((device) => CustomerExerciseDevice.fromJson(device)).toList();
|
||||
} on NotFoundException catch (_) {
|
||||
log("No devices found");
|
||||
devices = [];
|
||||
}
|
||||
return devices;
|
||||
}
|
||||
|
||||
Future<CustomerExerciseDevice> addDevice(CustomerExerciseDevice device) async {
|
||||
CustomerExerciseDevice savedDevice;
|
||||
try {
|
||||
final String body = JsonEncoder().convert(device.toJson());
|
||||
log(" --- add customer_exercise_device: " + body);
|
||||
final String responseBody = await _client.post("customer_exercise_device", body);
|
||||
savedDevice = CustomerExerciseDevice.fromJson(jsonDecode(responseBody));
|
||||
} on Exception catch (e) {
|
||||
throw new Exception(e.toString());
|
||||
}
|
||||
return savedDevice;
|
||||
}
|
||||
|
||||
Future<void> removeDevice(int id) async {
|
||||
try {
|
||||
log(" --- delete customer_exercise_device: " + id.toString());
|
||||
await _client.post("customer_exercise_device/delete/" + id.toString(), "");
|
||||
} on Exception catch (e) {
|
||||
throw new Exception(e.toString());
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,240 @@
|
||||
import 'dart:collection';
|
||||
import 'dart:convert';
|
||||
import 'package:workouttest_util/model/customer.dart';
|
||||
import 'package:workouttest_util/model/customer_property.dart';
|
||||
import 'package:workouttest_util/model/property.dart';
|
||||
import 'package:workouttest_util/model/user.dart';
|
||||
import 'package:workouttest_util/service/api.dart';
|
||||
import 'package:workouttest_util/model/cache.dart';
|
||||
import 'package:workouttest_util/util/logging.dart';
|
||||
import 'package:workouttest_util/util/not_found_exception.dart';
|
||||
|
||||
class CustomerApi with Logging {
|
||||
final APIClient _client = APIClient();
|
||||
|
||||
Future<List<Customer>> getRealCustomers(String param) async {
|
||||
final body = await _client.get("customers/", param);
|
||||
final Iterable json = jsonDecode(body);
|
||||
final List<Customer> customers = json.map((customer) => Customer.fromJson(customer)).toList();
|
||||
|
||||
return customers;
|
||||
}
|
||||
|
||||
Future<void> saveCustomer(Customer customer) async {
|
||||
customer.dateChange = DateTime.now();
|
||||
String body = JsonEncoder().convert(customer.toJson());
|
||||
log(" ===== saving customer id: " + customer.customerId.toString() + ":" + body);
|
||||
await _client.post("customers/" + customer.customerId.toString(), body);
|
||||
}
|
||||
|
||||
Future<void> updateFirebaseUid(int customerId, String uid) async {
|
||||
log(" ===== update Firebase uid : " + customerId.toString() + ": " + uid);
|
||||
await _client.post("customers/update_firebase_uid/" + customerId.toString(), uid);
|
||||
}
|
||||
|
||||
Future<void> deactivateCustomer(int customerId) async {
|
||||
log(" ===== deactivate : $customerId");
|
||||
await _client.post("customers/deactivate/$customerId", "");
|
||||
}
|
||||
|
||||
Future<void> addCustomer(Customer customer) async {
|
||||
customer.dateAdd = DateTime.now();
|
||||
customer.dateChange = DateTime.now();
|
||||
String body = JsonEncoder().convert(customer.toJson());
|
||||
log(" ===== add new customer: " + body);
|
||||
await _client.post("customers", body);
|
||||
}
|
||||
|
||||
Future<void> addUser(User user) async {
|
||||
String body = JsonEncoder().convert(user.toJson());
|
||||
log(" ===== add new user: " + body);
|
||||
final String responseBody = await _client.post("registration", body);
|
||||
Customer customer;
|
||||
try {
|
||||
int? status = jsonDecode(responseBody)['status'];
|
||||
if (status != null) {
|
||||
String error = jsonDecode(responseBody)['error'];
|
||||
throw new Exception(error);
|
||||
} else {
|
||||
customer = Customer.fromJson(jsonDecode(responseBody));
|
||||
await Cache().afterRegistration(customer);
|
||||
}
|
||||
} on FormatException {
|
||||
if (responseBody == "Customer exists") {
|
||||
throw WorkoutTestException(code: WorkoutTestException.CUSTOMER_EXISTS, message: responseBody);
|
||||
}
|
||||
throw new Exception(responseBody);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> getUser(User user) async {
|
||||
String body = JsonEncoder().convert(user.toJson());
|
||||
log(" ===== login the user: " + body);
|
||||
final String responseBody = await _client.post("login", body);
|
||||
Customer customer;
|
||||
try {
|
||||
customer = Customer.fromJson(jsonDecode(responseBody));
|
||||
await Cache().afterLogin(customer);
|
||||
} on FormatException {
|
||||
throw new Exception(responseBody);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> getUserByEmail(String email) async {
|
||||
log(" ===== User getByEmail : " + email);
|
||||
final String responseBody = await _client.get("customers/find_by_email/" + email, "");
|
||||
Customer customer;
|
||||
try {
|
||||
customer = Customer.fromJson(jsonDecode(responseBody));
|
||||
if (customer.firebaseUid == null) {
|
||||
await this.updateFirebaseUid(customer.customerId!, Cache().firebaseUid!);
|
||||
}
|
||||
Cache().userLoggedIn = customer;
|
||||
final List<CustomerProperty>? properties = await this.getActualProperties(customer.customerId!);
|
||||
if (properties != null) {
|
||||
this.initProperties(properties);
|
||||
}
|
||||
} on FormatException {
|
||||
throw new Exception(responseBody);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> getCustomer(int customerId) async {
|
||||
String body = "";
|
||||
log(" ===== get the customer by id: " + customerId.toString());
|
||||
try {
|
||||
final String responseBody = await _client.get("customers/" + customerId.toString(), body);
|
||||
Customer customer = Customer.fromJson(jsonDecode(responseBody));
|
||||
log(" --- Customer: " + customer.toJson().toString());
|
||||
Cache().userLoggedIn = customer;
|
||||
final List<CustomerProperty>? properties = await this.getActualProperties(customerId);
|
||||
//log(" ---- Props: " + properties.toJson().toString());
|
||||
//await Cache().initCustomer(customerId);
|
||||
if (properties != null) {
|
||||
this.initProperties(properties);
|
||||
}
|
||||
} on Exception catch (exception) {
|
||||
log("Exception: " + exception.toString());
|
||||
log(" === go to registration ");
|
||||
Cache().logout();
|
||||
Cache().startPage = "registration";
|
||||
}
|
||||
}
|
||||
|
||||
void initProperties(final List<CustomerProperty>? customerProperties) {
|
||||
List<Property>? properties = Cache().getProperties();
|
||||
Customer customer = Cache().userLoggedIn!;
|
||||
customer.properties = LinkedHashMap<String, CustomerProperty>();
|
||||
|
||||
if (properties != null) {
|
||||
// reset Properties
|
||||
properties.forEach((property) {
|
||||
CustomerProperty customerProperty =
|
||||
CustomerProperty(propertyId: property.propertyId, customerId: customer.customerId!, dateAdd: DateTime.now(), propertyValue: 0);
|
||||
customer.properties[property.propertyName] = customerProperty;
|
||||
});
|
||||
|
||||
customerProperties!.forEach((customerProperty) {
|
||||
properties.forEach((property) {
|
||||
if (customerProperty.propertyId == property.propertyId) {
|
||||
customer.properties[property.propertyName] = customerProperty;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Future<Customer> getTrainee(int customerId) async {
|
||||
String body = "";
|
||||
Customer customer;
|
||||
log(" ===== get Trainee customer by id: " + customerId.toString());
|
||||
try {
|
||||
final String responseBody = await _client.get("customers/" + customerId.toString(), body);
|
||||
customer = Customer.fromJson(jsonDecode(responseBody));
|
||||
log(" --- Trainee: " + customer.toJson().toString());
|
||||
} catch (exception) {
|
||||
log("Exception: " + exception.toString());
|
||||
throw Exception(exception);
|
||||
}
|
||||
return customer;
|
||||
}
|
||||
|
||||
Future<List<Customer>> getTrainees(int trainerId) async {
|
||||
List<Customer> trainees = [];
|
||||
log("Get trainees list");
|
||||
try {
|
||||
String body = "";
|
||||
final String responseBody = await _client.get("customers/trainees/" + trainerId.toString(), body);
|
||||
final Iterable json = jsonDecode(responseBody);
|
||||
trainees = json.map((customer) => Customer.fromJson(customer)).toList();
|
||||
} catch (exception) {
|
||||
log("Exception: " + exception.toString());
|
||||
throw Exception(exception);
|
||||
}
|
||||
return trainees;
|
||||
}
|
||||
|
||||
Future<List<CustomerProperty>> getAllProperties(int customerId) async {
|
||||
final body = await _client.get("customer_property/", customerId.toString());
|
||||
final Iterable json = jsonDecode(body);
|
||||
final List<CustomerProperty> properties = json.map((property) => CustomerProperty.fromJson(property)).toList();
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
Future<List<CustomerProperty>?> getActualProperties(int customerId) async {
|
||||
List<CustomerProperty>? properties;
|
||||
try {
|
||||
final body = await _client.get("customer_property/last/", customerId.toString());
|
||||
final Iterable json = jsonDecode(body);
|
||||
properties = json.map((property) => CustomerProperty.fromJson(property)).toList();
|
||||
} on Exception catch (ex) {
|
||||
log(ex.toString());
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
|
||||
Future<CustomerProperty> addProperty(CustomerProperty property) async {
|
||||
String body = JsonEncoder().convert(property.toJson());
|
||||
log(" ===== add new customer property: " + body);
|
||||
CustomerProperty customerProperty;
|
||||
String? responseBody;
|
||||
try {
|
||||
responseBody = await _client.post("customer_property", body);
|
||||
log(" responseBody: " + responseBody);
|
||||
int? status = jsonDecode(responseBody)['status'];
|
||||
if (status != null) {
|
||||
throw new Exception(jsonDecode(responseBody)['error']);
|
||||
} else {
|
||||
customerProperty = CustomerProperty.fromJson(jsonDecode(responseBody));
|
||||
}
|
||||
} on FormatException {
|
||||
throw new Exception(responseBody);
|
||||
} on Exception catch (e) {
|
||||
throw new Exception(e);
|
||||
}
|
||||
return customerProperty;
|
||||
}
|
||||
|
||||
Future<CustomerProperty> updateProperty(CustomerProperty property) async {
|
||||
String body = JsonEncoder().convert(property.toJson());
|
||||
CustomerProperty? customerProperty;
|
||||
log(" ===== update customer property: " + body);
|
||||
String? responseBody;
|
||||
try {
|
||||
responseBody = await _client.post("customer_property/update/" + property.customerPropertyId.toString(), body);
|
||||
log(" responseBody: " + responseBody);
|
||||
int? status = jsonDecode(responseBody)['status'];
|
||||
if (status != null) {
|
||||
throw new Exception(jsonDecode(responseBody)['error']);
|
||||
} else {
|
||||
customerProperty = CustomerProperty.fromJson(jsonDecode(responseBody));
|
||||
}
|
||||
} on FormatException {
|
||||
throw new Exception(responseBody);
|
||||
} on Exception catch (e) {
|
||||
throw new Exception(e);
|
||||
}
|
||||
return customerProperty;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import 'package:workouttest_util/model/cache.dart';
|
||||
import 'dart:convert';
|
||||
import 'package:workouttest_util/model/exercise_device.dart';
|
||||
|
||||
import 'api.dart';
|
||||
|
||||
class ExerciseDeviceApi {
|
||||
final APIClient _client = APIClient();
|
||||
|
||||
Future<List<ExerciseDevice>> getDevices() async {
|
||||
final body = await _client.get("exercise_device/", "");
|
||||
final Iterable json = jsonDecode(body);
|
||||
final List<ExerciseDevice> devices = json.map((device) => ExerciseDevice.fromJson(device)).toList();
|
||||
Cache().setDevices(devices);
|
||||
return devices;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
import 'dart:convert';
|
||||
import 'package:workouttest_util/model/exercise.dart';
|
||||
import 'package:workouttest_util/service/api.dart';
|
||||
import 'package:workouttest_util/util/logging.dart';
|
||||
|
||||
class ExerciseApi with Logging {
|
||||
final APIClient _client = APIClient();
|
||||
|
||||
Future<void> saveExercise(Exercise exercise) async {
|
||||
String body = JsonEncoder().convert(exercise.toJson());
|
||||
log(" ===== saving exercise id: " + exercise.exerciseId.toString() + ":" + body);
|
||||
await _client.post("exercises/" + exercise.exerciseId.toString(), body);
|
||||
}
|
||||
|
||||
Future<List<Exercise>> getExercisesByCustomer(int customerId) async {
|
||||
final body = await _client.get("exercises/customer/", customerId.toString());
|
||||
final Iterable json = jsonDecode(body);
|
||||
final List<Exercise> exercises = json.map((exercise) {
|
||||
Exercise item = Exercise.fromJson(exercise);
|
||||
return item;
|
||||
}).toList();
|
||||
//exercises.sort( (a, b) => b.dateAdd.compareTo(a.dateAdd) );
|
||||
|
||||
return exercises;
|
||||
}
|
||||
|
||||
Future<Exercise> addExercise(Exercise exercise) async {
|
||||
String body = JsonEncoder().convert(exercise.toJson());
|
||||
log(" ===== add new exercise: " + body);
|
||||
final String response = await _client.post("exercises", body);
|
||||
final Exercise savedExercise = Exercise.fromJson(jsonDecode(response));
|
||||
return savedExercise;
|
||||
}
|
||||
|
||||
Future<void> deleteExercise(Exercise exercise) async {
|
||||
if (exercise.exerciseId == null) {
|
||||
return;
|
||||
}
|
||||
int exerciseId = exercise.exerciseId!;
|
||||
log(" ===== delete exercise: " + exerciseId.toString());
|
||||
await _client.post("exercises/" + exerciseId.toString(), "");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:workouttest_util/model/cache.dart';
|
||||
import 'package:workouttest_util/model/exercise_tree.dart';
|
||||
import 'package:workouttest_util/model/exercise_tree_parents.dart';
|
||||
import 'package:workouttest_util/util/logging.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'api.dart';
|
||||
|
||||
class ExerciseTreeApi with Logging {
|
||||
final APIClient _client = APIClient();
|
||||
|
||||
Future<List<ExerciseTree>> getExerciseTree() async {
|
||||
final String body = await _client.get("exercise_tree", "");
|
||||
Iterable json = jsonDecode(body);
|
||||
List<ExerciseTree>? exerciseTrees = json.map((exerciseTree) => ExerciseTree.fromJson(exerciseTree)).toList();
|
||||
|
||||
exerciseTrees = await getExerciseTreeParents(exerciseTrees);
|
||||
|
||||
await Future.forEach(exerciseTrees, (element) async {
|
||||
ExerciseTree exerciseTree = element as ExerciseTree;
|
||||
exerciseTree.imageUrl = await buildImage(exerciseTree.imageUrl, exerciseTree.treeId);
|
||||
});
|
||||
exerciseTrees = await getExerciseTreeParents(exerciseTrees);
|
||||
log("ExerciseTree downloaded $exerciseTrees");
|
||||
Cache().setExerciseTree(exerciseTrees);
|
||||
|
||||
return exerciseTrees;
|
||||
}
|
||||
|
||||
Future<String> buildImage(String imageUrl, int treeId) async {
|
||||
String assetImage = 'asset/menu/' + imageUrl.substring(7);
|
||||
print("asset image $assetImage");
|
||||
return await rootBundle.load(assetImage).then((value) {
|
||||
return assetImage;
|
||||
}).catchError((_) {
|
||||
String imagePath = assetImage.substring(10);
|
||||
String url = Cache.mediaUrl + 'images' + imagePath;
|
||||
return url;
|
||||
});
|
||||
}
|
||||
|
||||
Future<List<ExerciseTree>> getExerciseTreeParents(List<ExerciseTree> exerciseTree) async {
|
||||
List<ExerciseTree> copyList = this.copyList(exerciseTree);
|
||||
|
||||
final String body = await _client.get("exercise_tree_parents", "");
|
||||
Iterable json = jsonDecode(body);
|
||||
final List<ExerciseTreeParents> exerciseTreeParents =
|
||||
json.map((exerciseTreeParent) => ExerciseTreeParents.fromJson(exerciseTreeParent)).toList();
|
||||
|
||||
int treeIndex = 0;
|
||||
copyList.forEach((element) async {
|
||||
int index = 0;
|
||||
exerciseTreeParents.forEach((parent) {
|
||||
if (parent.exerciseTreeChildId == element.treeId) {
|
||||
if (index > 0) {
|
||||
ExerciseTree newElement = element.copy(parent.exerciseTreeParentId);
|
||||
newElement.sort = parent.sort;
|
||||
exerciseTree.add(newElement);
|
||||
} else {
|
||||
element.parentId = parent.exerciseTreeParentId;
|
||||
element.sort = parent.sort;
|
||||
exerciseTree[treeIndex].parentId = parent.exerciseTreeParentId;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
});
|
||||
treeIndex++;
|
||||
});
|
||||
return exerciseTree;
|
||||
}
|
||||
|
||||
List<ExerciseTree> copyList(List<ExerciseTree> tree) {
|
||||
final List<ExerciseTree> copyList = [];
|
||||
tree.forEach((element) {
|
||||
final ExerciseTree copy = element.copy(-1);
|
||||
copyList.add(copy);
|
||||
});
|
||||
|
||||
return copyList;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
import 'dart:convert';
|
||||
import 'package:workouttest_util/model/cache.dart';
|
||||
import 'package:workouttest_util/model/exercise_type.dart';
|
||||
import 'package:workouttest_util/service/api.dart';
|
||||
import 'package:workouttest_util/util/logging.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
class ExerciseTypeApi with Logging {
|
||||
final APIClient _client = APIClient();
|
||||
|
||||
Future<List<ExerciseType>> getExerciseTypes() async {
|
||||
final body = await _client.get("exercise_type", "");
|
||||
final Iterable json = jsonDecode(body);
|
||||
final List<ExerciseType> exerciseTypes = json.map((exerciseType) => ExerciseType.fromJson(exerciseType)).toList();
|
||||
|
||||
await Future.forEach(exerciseTypes, (element) async {
|
||||
ExerciseType exerciseType = element as ExerciseType;
|
||||
exerciseType.imageUrl = await buildImage(exerciseType.imageUrl, exerciseType.exerciseTypeId);
|
||||
});
|
||||
log("ExerciseTypes downloaded");
|
||||
Cache().setExerciseTypes(exerciseTypes);
|
||||
|
||||
return exerciseTypes;
|
||||
}
|
||||
|
||||
Future<String> buildImage(String imageUrl, int exerciseTypeId) async {
|
||||
if (imageUrl.length > 8) {
|
||||
String assetImage = 'asset/menu/' + imageUrl.substring(7);
|
||||
return rootBundle.load(assetImage).then((value) {
|
||||
return assetImage;
|
||||
}).catchError((_) {
|
||||
String imagePath = assetImage.substring(10);
|
||||
String url = Cache.mediaUrl + 'images' + imagePath;
|
||||
return url;
|
||||
});
|
||||
} else {
|
||||
return imageUrl;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,403 @@
|
||||
import 'dart:math' as math;
|
||||
import 'dart:convert';
|
||||
// ignore: depend_on_referenced_packages
|
||||
import 'package:crypto/crypto.dart';
|
||||
import 'package:workouttest_util/model/cache.dart';
|
||||
import 'package:workouttest_util/util/logging.dart' as logger;
|
||||
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';
|
||||
// ignore: depend_on_referenced_packages
|
||||
import 'package:firebase_core/firebase_core.dart';
|
||||
import 'package:firebase_messaging/firebase_messaging.dart';
|
||||
import 'package:firebase_remote_config/firebase_remote_config.dart';
|
||||
import 'package:flutter_facebook_auth/flutter_facebook_auth.dart';
|
||||
import 'package:google_sign_in/google_sign_in.dart';
|
||||
|
||||
class FirebaseApi with logger.Logging {
|
||||
bool appleSignInAvailable = false;
|
||||
|
||||
static final FirebaseAuth auth = FirebaseAuth.instance;
|
||||
|
||||
static const String SIGN_IN_OK = "OK";
|
||||
static const String SIGN_IN_NOT_FOUND = "user-not-found";
|
||||
static const String SIGN_IN_WRONG_PWD = "wrong-password";
|
||||
static const String REGISTER_WEAK_PWD = "weak-password";
|
||||
static const String REGISTER_EMAIL_IN_USE = "email-already-in-use";
|
||||
|
||||
late UserCredential userCredential;
|
||||
String? firebaseRegToken;
|
||||
|
||||
factory FirebaseApi() => FirebaseApi._internal();
|
||||
|
||||
FirebaseApi._internal();
|
||||
|
||||
// Define an async function to initialize FlutterFire
|
||||
Future<void> initializeFlutterFire() async {
|
||||
try {
|
||||
// Wait for Firebase to initialize and set `_initialized` state to true
|
||||
await Firebase.initializeApp();
|
||||
|
||||
this.appleSignInAvailable = await SignInWithApple.isAvailable();
|
||||
|
||||
|
||||
await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(
|
||||
alert: true, // Required to display a heads up notification
|
||||
badge: true,
|
||||
sound: true,
|
||||
);
|
||||
this.firebaseRegToken = await FirebaseMessaging.instance.getToken();
|
||||
Cache().firebaseMessageToken = firebaseRegToken;
|
||||
log("FirebaseMessaging token $firebaseRegToken");
|
||||
|
||||
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
|
||||
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
|
||||
print('Got a message whilst in the foreground!');
|
||||
print('Message data: ${message.data}');
|
||||
|
||||
if (message.notification != null) {
|
||||
print('Message also contained a notification: ${message.notification}');
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
// Set `_error` state to true if Firebase initialization fails
|
||||
Sentry.captureException(e);
|
||||
log("Error initializing Firebase");
|
||||
}
|
||||
}
|
||||
|
||||
Future<String> signInEmail(String? email, String? password) async {
|
||||
if (email == null) {
|
||||
throw Exception("Please type an email address");
|
||||
}
|
||||
if (password == null) {
|
||||
throw Exception("Password too short");
|
||||
}
|
||||
String rc = SIGN_IN_OK;
|
||||
try {
|
||||
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;
|
||||
} else if (e.code == 'wrong-password') {
|
||||
log('Wrong password provided for that user.');
|
||||
rc = SIGN_IN_WRONG_PWD;
|
||||
throw Exception("Customer does not exist or the password is wrong");
|
||||
}
|
||||
return e.code;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
Future<String> registerEmail(String email, String password) async {
|
||||
String rc = SIGN_IN_OK;
|
||||
try {
|
||||
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;
|
||||
throw Exception("Password too short");
|
||||
} else if (e.code == 'email-already-in-use') {
|
||||
log('The account already exists for that email.');
|
||||
rc = REGISTER_EMAIL_IN_USE;
|
||||
throw Exception("The email address has been registered already");
|
||||
}
|
||||
} catch (e) {
|
||||
log(e.toString());
|
||||
Sentry.captureException(e);
|
||||
throw Exception(e.toString());
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
String generateNonce([int length = 32]) {
|
||||
final charset = '0123456789ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz-._';
|
||||
final random = math.Random.secure();
|
||||
return List.generate(length, (_) => charset[random.nextInt(charset.length)]).join();
|
||||
}
|
||||
|
||||
/// Returns the sha256 hash of [input] in hex notation.
|
||||
String sha256ofString(String input) {
|
||||
final bytes = utf8.encode(input);
|
||||
final digest = sha256.convert(bytes);
|
||||
return digest.toString();
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> signInWithApple() async {
|
||||
Map<String, dynamic> userData = Map();
|
||||
|
||||
// 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
|
||||
// match the sha256 hash of `rawNonce`.
|
||||
final rawNonce = generateNonce();
|
||||
final nonce = sha256ofString(rawNonce);
|
||||
|
||||
// Request credential for the currently signed in Apple account.
|
||||
final appleCredential = await SignInWithApple.getAppleIDCredential(
|
||||
scopes: [
|
||||
AppleIDAuthorizationScopes.email,
|
||||
AppleIDAuthorizationScopes.fullName,
|
||||
],
|
||||
nonce: nonce,
|
||||
);
|
||||
|
||||
// Create an `OAuthCredential` from the credential returned by Apple.
|
||||
final oauthCredential = OAuthProvider("apple.com").credential(
|
||||
idToken: appleCredential.identityToken,
|
||||
rawNonce: rawNonce,
|
||||
);
|
||||
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());
|
||||
|
||||
log("Apple Credentials: ${appleCredential.userIdentifier} state ${appleCredential.state} email ${userCredential.user!.email!}");
|
||||
userData['email'] = userCredential.user!.email;
|
||||
|
||||
return userData;
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> registerWithApple() async {
|
||||
Map<String, dynamic> userData = Map();
|
||||
|
||||
final rawNonce = generateNonce();
|
||||
final nonce = sha256ofString(rawNonce);
|
||||
|
||||
// Request credential for the currently signed in Apple account.
|
||||
final appleCredential = await SignInWithApple.getAppleIDCredential(
|
||||
scopes: [
|
||||
AppleIDAuthorizationScopes.email,
|
||||
AppleIDAuthorizationScopes.fullName,
|
||||
],
|
||||
nonce: nonce,
|
||||
);
|
||||
|
||||
final oauthCredential = OAuthProvider("apple.com").credential(
|
||||
idToken: appleCredential.identityToken,
|
||||
rawNonce: rawNonce,
|
||||
);
|
||||
|
||||
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;
|
||||
|
||||
userData['email'] = userCredential.user!.email;
|
||||
|
||||
return userData;
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> signInWithGoogle() async {
|
||||
Map<String, dynamic> userData = Map();
|
||||
|
||||
// Trigger the authentication flow
|
||||
GoogleSignIn _googleSignIn = GoogleSignIn(
|
||||
scopes: [
|
||||
'email',
|
||||
'https://www.googleapis.com/auth/contacts.readonly',
|
||||
],
|
||||
);
|
||||
final GoogleSignInAccount? googleUser = await _googleSignIn.signIn();
|
||||
|
||||
if (googleUser == null) {
|
||||
Sentry.captureException(new Exception("Google Sign In failed"));
|
||||
throw Exception("Google Sign In failed");
|
||||
}
|
||||
|
||||
// Obtain the auth details from the request
|
||||
final GoogleSignInAuthentication googleAuth = await googleUser.authentication;
|
||||
|
||||
// Create a new credential
|
||||
final OAuthCredential credential = GoogleAuthProvider.credential(
|
||||
accessToken: googleAuth.accessToken,
|
||||
idToken: googleAuth.idToken,
|
||||
);
|
||||
|
||||
UserCredential userCredential = await FirebaseAuth.instance.signInWithCredential(credential);
|
||||
Cache().firebaseUid = userCredential.user!.uid;
|
||||
|
||||
log("GoogleUser: " + googleUser.toString());
|
||||
userData['email'] = googleUser.email;
|
||||
userData['id'] = googleUser.id;
|
||||
userData['name'] = googleUser.displayName;
|
||||
|
||||
return userData;
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> registerWithGoogle() async {
|
||||
Map<String, dynamic> userData = Map();
|
||||
|
||||
// Trigger the authentication flow
|
||||
GoogleSignIn _googleSignIn = GoogleSignIn(
|
||||
scopes: [
|
||||
'email',
|
||||
'https://www.googleapis.com/auth/contacts.readonly',
|
||||
],
|
||||
);
|
||||
final GoogleSignInAccount? googleUser = await _googleSignIn.signIn();
|
||||
|
||||
if (googleUser == null) {
|
||||
Sentry.captureException(new Exception("Google Sign In failed"));
|
||||
throw Exception("Google Sign In failed");
|
||||
}
|
||||
|
||||
// Obtain the auth details from the request
|
||||
final GoogleSignInAuthentication googleAuth = await googleUser.authentication;
|
||||
|
||||
// Create a new credential
|
||||
final OAuthCredential credential = GoogleAuthProvider.credential(
|
||||
accessToken: googleAuth.accessToken,
|
||||
idToken: googleAuth.idToken,
|
||||
);
|
||||
|
||||
final userCredential = await FirebaseAuth.instance.signInWithCredential(credential);
|
||||
|
||||
log("Google credentials: " + credential.toString() + " GoogleUser: " + googleUser.toString());
|
||||
Cache().firebaseUid = userCredential.user!.uid;
|
||||
|
||||
userData['email'] = googleUser.email;
|
||||
|
||||
return userData;
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> signInWithFacebook() async {
|
||||
Map<String, dynamic> userData;
|
||||
|
||||
// by default the login method has the next permissions ['email','public_profile']
|
||||
final LoginResult result = await FacebookAuth.instance.login();
|
||||
if (result.status == LoginStatus.success) {
|
||||
final AccessToken accessToken = result.accessToken!;
|
||||
log(accessToken.toJson().toString());
|
||||
Cache().accessTokenFacebook = accessToken;
|
||||
// get the user data
|
||||
userData = await FacebookAuth.instance.getUserData();
|
||||
Cache().firebaseUid = userData['id'];
|
||||
log(userData.toString());
|
||||
} else {
|
||||
Sentry.captureException(new Exception(result.message));
|
||||
throw Exception("Facebook login was not successful");
|
||||
}
|
||||
|
||||
return userData;
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> registerWithFacebook() async {
|
||||
Map<String, dynamic> userData;
|
||||
|
||||
// by default the login method has the next permissions ['email','public_profile']
|
||||
final LoginResult result = await FacebookAuth.instance.login();
|
||||
if (result.status == LoginStatus.success) {
|
||||
final AccessToken accessToken = result.accessToken!;
|
||||
Cache().accessTokenFacebook = accessToken;
|
||||
// get the user data
|
||||
userData = await FacebookAuth.instance.getUserData();
|
||||
log("FB user data: " + userData.toString());
|
||||
|
||||
// Create a credential from the access token
|
||||
final OAuthCredential facebookAuthCredential = FacebookAuthProvider.credential(accessToken.token);
|
||||
|
||||
// Once signed in, return the UserCredential
|
||||
final userCredential = await FirebaseAuth.instance.signInWithCredential(facebookAuthCredential);
|
||||
log("Email by FB: " + userData['email'] + " FB credential: " + userCredential.toString());
|
||||
|
||||
Cache().firebaseUid = userCredential.user!.uid;
|
||||
} else {
|
||||
Sentry.captureException(new Exception(result.message));
|
||||
throw Exception("Facebook login was not successful");
|
||||
}
|
||||
|
||||
return userData;
|
||||
}
|
||||
|
||||
Future<void> logOutFacebook() async {
|
||||
await FacebookAuth.instance.logOut();
|
||||
Cache().accessTokenFacebook = null;
|
||||
}
|
||||
|
||||
Future<void> signOut() async {
|
||||
await FirebaseAuth.instance.signOut();
|
||||
}
|
||||
|
||||
Future<void> resetPassword(String email) async {
|
||||
await FirebaseAuth.instance.sendPasswordResetEmail(email: email);
|
||||
}
|
||||
|
||||
Future<void> setupRemoteConfig() async {
|
||||
//initializeFlutterFire();
|
||||
FirebaseRemoteConfig? remoteConfig;
|
||||
try {
|
||||
remoteConfig = FirebaseRemoteConfig.instance;
|
||||
await remoteConfig.setConfigSettings(RemoteConfigSettings(
|
||||
fetchTimeout: const Duration(seconds: 10),
|
||||
minimumFetchInterval: const Duration(seconds: 1),
|
||||
));
|
||||
|
||||
//RemoteConfigValue(null, ValueSource.valueStatic);
|
||||
//Cache().setRemoteConfig(remoteConfig);
|
||||
} on Exception catch (e) {
|
||||
print('Unable to fetch remote config. Cached or default values will be used: $e');
|
||||
if (remoteConfig != null) {
|
||||
await remoteConfig.setDefaults(<String, dynamic>{
|
||||
'sales_page_text_a': '',
|
||||
'product_set_2': '',
|
||||
'registration_skip_color': '',
|
||||
'email_checkbox': '',
|
||||
});
|
||||
Cache().setRemoteConfig(remoteConfig);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
|
||||
// If you're going to use other Firebase services in the background, such as Firestore,
|
||||
// make sure you call `initializeApp` before using other Firebase services.
|
||||
print('Handling a background message ${message.messageId}');
|
||||
}
|
||||
|
||||
/* Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
|
||||
print('Handling a background message: ${message.messageId}');
|
||||
|
||||
if (!StringUtils.isNullOrEmpty(message.notification?.title, considerWhiteSpaceAsEmpty: true) ||
|
||||
!StringUtils.isNullOrEmpty(message.notification?.body, considerWhiteSpaceAsEmpty: true)) {
|
||||
print('message also contained a notification: ${message.notification}');
|
||||
|
||||
String? imageUrl;
|
||||
imageUrl ??= message.notification!.android?.imageUrl;
|
||||
imageUrl ??= message.notification!.apple?.imageUrl;
|
||||
|
||||
Map<String, dynamic> notificationAdapter = {
|
||||
NOTIFICATION_CHANNEL_KEY: 'basic_channel',
|
||||
NOTIFICATION_ID: message.data[NOTIFICATION_CONTENT]?[NOTIFICATION_ID] ?? message.messageId ?? math.Random().nextInt(2147483647),
|
||||
NOTIFICATION_TITLE: message.data[NOTIFICATION_CONTENT]?[NOTIFICATION_TITLE] ?? message.notification?.title,
|
||||
NOTIFICATION_BODY: message.data[NOTIFICATION_CONTENT]?[NOTIFICATION_BODY] ?? message.notification?.body,
|
||||
NOTIFICATION_LAYOUT: StringUtils.isNullOrEmpty(imageUrl) ? 'Default' : 'BigPicture',
|
||||
NOTIFICATION_BIG_PICTURE: imageUrl
|
||||
};
|
||||
|
||||
AwesomeNotifications().createNotificationFromJsonData(notificationAdapter);
|
||||
} else {
|
||||
AwesomeNotifications().createNotificationFromJsonData(message.data);
|
||||
}
|
||||
} */
|
||||
@@ -0,0 +1,29 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:workouttest_util/model/mautic.dart';
|
||||
import 'package:workouttest_util/util/logging.dart';
|
||||
|
||||
class MauticApi with Logging {
|
||||
final String mauticUrl = "https://mautic.workouttest.org/form/submit?formId=";
|
||||
|
||||
Future<void> sendMauticForm(Mautic model) async {
|
||||
final String body = model.toForm();
|
||||
log(" ===== mautic subscription: $body");
|
||||
HttpClient client = HttpClient();
|
||||
|
||||
String url = mauticUrl + model.formId.toString();
|
||||
|
||||
var uri = Uri.parse(url);
|
||||
final HttpClientRequest request = await client.postUrl(uri);
|
||||
request.headers.set('Content-Type', 'application/x-www-form-urlencoded');
|
||||
request.headers.set('cache-control', 'no-cache');
|
||||
|
||||
request.write(body);
|
||||
HttpClientResponse result = await request.close();
|
||||
client.close();
|
||||
if (!(result.statusCode == 200 || result.statusCode == 302)) {
|
||||
trace("mautic response: ${result.statusCode}");
|
||||
//throw Exception("Network error, try again later!");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,210 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:workouttest_util/model/cache.dart';
|
||||
import 'package:workouttest_util/model/customer.dart';
|
||||
import 'package:workouttest_util/model/customer_activity.dart';
|
||||
import 'package:workouttest_util/model/customer_exercise_device.dart';
|
||||
import 'package:workouttest_util/model/customer_property.dart';
|
||||
import 'package:workouttest_util/model/description.dart';
|
||||
import 'package:workouttest_util/model/evaluation.dart';
|
||||
import 'package:workouttest_util/model/exercise.dart';
|
||||
import 'package:workouttest_util/model/exercise_device.dart';
|
||||
import 'package:workouttest_util/model/exercise_plan_template.dart';
|
||||
import 'package:workouttest_util/model/exercise_tree.dart';
|
||||
import 'package:workouttest_util/model/exercise_tree_parents.dart';
|
||||
import 'package:workouttest_util/model/exercise_type.dart';
|
||||
import 'package:workouttest_util/model/faq.dart';
|
||||
import 'package:workouttest_util/model/product.dart';
|
||||
import 'package:workouttest_util/model/property.dart';
|
||||
import 'package:workouttest_util/model/purchase.dart';
|
||||
import 'package:workouttest_util/model/split_test.dart';
|
||||
import 'package:workouttest_util/model/training_plan.dart';
|
||||
import 'package:workouttest_util/model/training_plan_day.dart';
|
||||
import 'package:workouttest_util/model/tutorial.dart';
|
||||
import 'package:workouttest_util/repository/training_plan_day_repository.dart';
|
||||
import 'package:workouttest_util/service/api.dart';
|
||||
import 'package:workouttest_util/service/exercise_type_service.dart';
|
||||
import 'package:workouttest_util/util/not_found_exception.dart';
|
||||
|
||||
import '../model/sport.dart';
|
||||
import 'customer_service.dart';
|
||||
import 'exercise_tree_service.dart';
|
||||
|
||||
class PackageApi {
|
||||
final APIClient _client = APIClient();
|
||||
|
||||
Future<void> getPackage() async {
|
||||
late List<ExerciseTree> exerciseTree;
|
||||
late List<ExerciseTreeParents> exerciseTreeParents;
|
||||
final body = await _client.get("app_package/", "");
|
||||
|
||||
final List<String> models = body.split("|||");
|
||||
await Future.forEach(models, (elem) async {
|
||||
final String element = elem as String;
|
||||
final List<String> headRecord = element.split("***");
|
||||
final Iterable json = jsonDecode(headRecord[1]);
|
||||
if (headRecord[0] == "ExerciseDevice") {
|
||||
final List<ExerciseDevice> devices = json.map((device) => ExerciseDevice.fromJson(device)).toList();
|
||||
Cache().setDevices(devices);
|
||||
} else if (headRecord[0] == "Product") {
|
||||
final List<Product> products = json.map((product) => Product.fromJson(product)).toList();
|
||||
Cache().setProducts(products);
|
||||
} else if (headRecord[0] == "Property") {
|
||||
final List<Property> properties = json.map((property) => Property.fromJson(property)).toList();
|
||||
Cache().setProperties(properties);
|
||||
} else if (headRecord[0] == "ExerciseTree") {
|
||||
exerciseTree = json.map((exerciseTree) => ExerciseTree.fromJson(exerciseTree)).toList();
|
||||
} else if (headRecord[0] == "ExerciseType") {
|
||||
final List<ExerciseType> exerciseTypes = json.map((exerciseType) => ExerciseType.fromJson(exerciseType)).toList();
|
||||
await Future.forEach(exerciseTypes, (elem) async {
|
||||
final ExerciseType exerciseType = elem as ExerciseType;
|
||||
exerciseType.imageUrl = await ExerciseTypeApi().buildImage(exerciseType.imageUrl, exerciseType.exerciseTypeId);
|
||||
});
|
||||
Cache().setExerciseTypes(exerciseTypes);
|
||||
} else if (headRecord[0] == "ExerciseAbility") {
|
||||
} else if (headRecord[0] == "ExercisePlanTemplate") {
|
||||
final List<ExercisePlanTemplate> exercisePlanTemplates =
|
||||
json.map((exercisePlanTemplate) => ExercisePlanTemplate.fromJson(exercisePlanTemplate)).toList();
|
||||
Cache().setExercisePlanTemplates(exercisePlanTemplates);
|
||||
} else if (headRecord[0] == "ExerciseTreeParents") {
|
||||
exerciseTreeParents = json.map((exerciseTreeParent) => ExerciseTreeParents.fromJson(exerciseTreeParent)).toList();
|
||||
} else if (headRecord[0] == "Evaluation") {
|
||||
final List<Evaluation> evaluations = json.map((evaluation) => Evaluation.fromJson(evaluation)).toList();
|
||||
Cache().evaluations = evaluations;
|
||||
} else if (headRecord[0] == "Sport") {
|
||||
final List<Sport> sports = json.map((sport) => Sport.fromJson(sport)).toList();
|
||||
Cache().setSports(sports);
|
||||
} else if (headRecord[0] == "Tutorial") {
|
||||
final Iterable json = jsonDecode(headRecord[1]);
|
||||
final List<Tutorial> tutorials = json.map((tutorial) => Tutorial.fromJson(tutorial)).toList();
|
||||
|
||||
Cache().setTutorials(tutorials);
|
||||
} else if (headRecord[0] == "Description") {
|
||||
final Iterable json = jsonDecode(headRecord[1]);
|
||||
final List<Description>? descriptions = json.map((description) => Description.fromJson(description)).toList();
|
||||
//print("Description: $descriptions");
|
||||
Cache().setDescriptions(descriptions);
|
||||
} else if (headRecord[0] == "Faq") {
|
||||
final Iterable json = jsonDecode(headRecord[1]);
|
||||
final List<Faq>? faqs = json.map((faq) => Faq.fromJson(faq)).toList();
|
||||
//print("Faq: $faqs");
|
||||
Cache().setFaqs(faqs);
|
||||
} else if (headRecord[0] == "TrainingPlan") {
|
||||
final Iterable json = jsonDecode(headRecord[1]);
|
||||
final List<TrainingPlan>? plans = json.map((plan) => TrainingPlan.fromJson(plan)).toList();
|
||||
|
||||
List<TrainingPlan> activePlans = [];
|
||||
if (plans != null) {
|
||||
plans.forEach((element) {
|
||||
if (element.active) {
|
||||
activePlans.add(element);
|
||||
}
|
||||
});
|
||||
}
|
||||
Cache().setTrainingPlans(activePlans);
|
||||
} else if (headRecord[0] == "SplitTests") {
|
||||
final Iterable json = jsonDecode(headRecord[1]);
|
||||
final List<SplitTest>? tests = json.map((test) => SplitTest.fromJson(test)).toList();
|
||||
//print("A/B tests: $tests");
|
||||
Cache().setSplitTests(tests);
|
||||
} else if (headRecord[0] == "TrainingPlanDay") {
|
||||
final Iterable json = jsonDecode(headRecord[1]);
|
||||
final List<TrainingPlanDay>? days = json.map((day) => TrainingPlanDay.fromJson(day)).toList();
|
||||
Cache().setTrainingPlanDays(days);
|
||||
}
|
||||
});
|
||||
|
||||
exerciseTree = this.getExerciseTreeParents(exerciseTree, exerciseTreeParents);
|
||||
|
||||
await Future.forEach(exerciseTree, (element) async {
|
||||
ExerciseTree tree = element as ExerciseTree;
|
||||
tree.imageUrl = await ExerciseTreeApi().buildImage(tree.imageUrl, tree.treeId);
|
||||
});
|
||||
Cache().setExerciseTree(exerciseTree);
|
||||
|
||||
TrainingPlanDayRepository trainingPlanDayRepository = TrainingPlanDayRepository();
|
||||
trainingPlanDayRepository.assignTrainingPlanDays();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
List<ExerciseTree> getExerciseTreeParents(final List<ExerciseTree> exerciseTree, final List<ExerciseTreeParents> exerciseTreeParents) {
|
||||
List<ExerciseTree> copyList = ExerciseTreeApi().copyList(exerciseTree);
|
||||
|
||||
int treeIndex = 0;
|
||||
copyList.forEach((element) async {
|
||||
int index = 0;
|
||||
exerciseTreeParents.forEach((parent) {
|
||||
if (parent.exerciseTreeChildId == element.treeId) {
|
||||
if (index > 0) {
|
||||
ExerciseTree newElement = element.copy(parent.exerciseTreeParentId);
|
||||
newElement.sort = parent.sort;
|
||||
exerciseTree.add(newElement);
|
||||
} else {
|
||||
element.parentId = parent.exerciseTreeParentId;
|
||||
element.sort = parent.sort;
|
||||
exerciseTree[treeIndex].parentId = parent.exerciseTreeParentId;
|
||||
exerciseTree[treeIndex].sort = parent.sort;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
});
|
||||
|
||||
treeIndex++;
|
||||
});
|
||||
|
||||
return exerciseTree;
|
||||
}
|
||||
|
||||
Future<void> getCustomerPackage(int customerId) async {
|
||||
try {
|
||||
final body = await _client.get("app_customer_package/" + customerId.toString(), "");
|
||||
|
||||
final List<String> models = body.split("|||");
|
||||
await Future.forEach(models, (elem) async {
|
||||
final String element = elem as String;
|
||||
final List<String> headRecord = element.split("***");
|
||||
//print("Class " + headRecord[0]);
|
||||
if (headRecord[0] == "Customer") {
|
||||
Customer customer = Customer.fromJson(jsonDecode(headRecord[1]));
|
||||
Cache().userLoggedIn = customer;
|
||||
} else if (headRecord[0] == "CustomerExerciseDevice") {
|
||||
final Iterable json = jsonDecode(headRecord[1]);
|
||||
final List<CustomerExerciseDevice> devices = json.map((device) => CustomerExerciseDevice.fromJson(device)).toList();
|
||||
Cache().setCustomerDevices(devices);
|
||||
// ToDo
|
||||
} else if (headRecord[0] == "Exercises") {
|
||||
final Iterable json = jsonDecode(headRecord[1]);
|
||||
final List<Exercise> exercises = json.map((exerciseType) => Exercise.fromJson(exerciseType)).toList();
|
||||
Cache().setExercises(exercises);
|
||||
} else if (headRecord[0] == "Purchase") {
|
||||
final Iterable json = jsonDecode(headRecord[1]);
|
||||
final List<Purchase> purchases = json.map((purchase) => Purchase.fromJson(purchase)).toList();
|
||||
Cache().setPurchases(purchases);
|
||||
} else if (headRecord[0] == "CustomerProperty") {
|
||||
final Iterable json = jsonDecode(headRecord[1]);
|
||||
final List<CustomerProperty> customerProperties = json.map((property) => CustomerProperty.fromJson(property)).toList();
|
||||
CustomerApi().initProperties(customerProperties);
|
||||
} else if (headRecord[0] == "CustomerPropertyAll") {
|
||||
final Iterable json = jsonDecode(headRecord[1]);
|
||||
final List<CustomerProperty> allCustomerProperties = json.map((property) => CustomerProperty.fromJson(property)).toList();
|
||||
print(" All Properties ---- $allCustomerProperties");
|
||||
Cache().setCustomerPropertyAll(allCustomerProperties);
|
||||
} else if (headRecord[0] == "ExerciseResult") {
|
||||
/*final Iterable json = jsonDecode(headRecord[1]);
|
||||
final List<ExerciseResult> exerciseResults = json.map((exerciseResult) {
|
||||
ExerciseResult item = ExerciseResult.fromJson(exerciseResult);
|
||||
return item;
|
||||
}).toList();
|
||||
// ToDo */
|
||||
} else if (headRecord[0] == "CustomerActivity") {
|
||||
final Iterable json = jsonDecode(headRecord[1]);
|
||||
final List<CustomerActivity> customerActivities = json.map((activity) => CustomerActivity.fromJson(activity)).toList();
|
||||
Cache().setCustomerActivities(customerActivities);
|
||||
}
|
||||
});
|
||||
} on NotFoundException catch (e) {
|
||||
throw Exception("Please log in $e");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:workouttest_util/model/cache.dart';
|
||||
import 'package:workouttest_util/model/product.dart';
|
||||
import 'package:workouttest_util/service/api.dart';
|
||||
|
||||
class ProductApi {
|
||||
final APIClient _client = APIClient();
|
||||
|
||||
Future<List<Product>> getProducts() async {
|
||||
final body = await _client.get("product/", "");
|
||||
final Iterable json = jsonDecode(body);
|
||||
final List<Product> products = json.map((product) => Product.fromJson(product)).toList();
|
||||
Cache().setProducts(products);
|
||||
return products;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:workouttest_util/model/cache.dart';
|
||||
import 'package:workouttest_util/service/api.dart';
|
||||
|
||||
import 'package:workouttest_util/model/property.dart';
|
||||
|
||||
class PropertyApi {
|
||||
final APIClient _client = APIClient();
|
||||
|
||||
Future<List<Property>> getProperties() async {
|
||||
final body = await _client.get("property/", "");
|
||||
final Iterable json = jsonDecode(body);
|
||||
final List<Property> properties = json.map((property) => Property.fromJson(property)).toList();
|
||||
Cache().setProperties(properties);
|
||||
return properties;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
import 'package:workouttest_util/model/cache.dart';
|
||||
import 'package:workouttest_util/model/purchase.dart';
|
||||
import 'package:workouttest_util/util/logging.dart';
|
||||
import 'package:workouttest_util/util/not_found_exception.dart';
|
||||
import 'dart:convert';
|
||||
import 'api.dart';
|
||||
|
||||
class PurchaseApi with Logging {
|
||||
final APIClient _client = APIClient();
|
||||
|
||||
Future<List<Purchase>> getPurchasesByCustomer(int customerId) async {
|
||||
List<Purchase> purchases = [];
|
||||
try {
|
||||
final body = await _client.get("purchase/customer/" + customerId.toString(), "");
|
||||
final Iterable json = jsonDecode(body);
|
||||
final List<Purchase> purchases = json.map((purchase) => Purchase.fromJson(purchase)).toList();
|
||||
Cache().setPurchases(purchases);
|
||||
} on NotFoundException catch (_) {
|
||||
log("No purchases found");
|
||||
}
|
||||
return purchases;
|
||||
}
|
||||
|
||||
Future<void> savePurchase(Purchase purchase) async {
|
||||
String body = JsonEncoder().convert(purchase.toJson());
|
||||
log(" ===== saving purchase:" + body);
|
||||
await _client.post("purchase/", body);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import 'package:workouttest_util/model/tracking.dart';
|
||||
import 'package:workouttest_util/util/logging.dart';
|
||||
import 'dart:convert';
|
||||
import 'api.dart';
|
||||
|
||||
class TrackingApi with Logging {
|
||||
final APIClient _client = APIClient();
|
||||
|
||||
Future<void> saveTracking(Tracking tracking) async {
|
||||
try {
|
||||
String body = const JsonEncoder().convert(tracking.toJson());
|
||||
log(" ===== saving tracking: $body");
|
||||
await _client.post("tracking/", body);
|
||||
} catch (exception) {
|
||||
log("exception in tracking: ${exception.toString()}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:workouttest_util/model/customer_training_plan.dart';
|
||||
import 'package:workouttest_util/model/customer_training_plan_exercise.dart';
|
||||
import 'package:workouttest_util/service/api.dart';
|
||||
import 'package:workouttest_util/util/logging.dart';
|
||||
|
||||
class TrainingPlanApi with Logging {
|
||||
final APIClient _client = APIClient();
|
||||
|
||||
Future<CustomerTrainingPlan> saveCustomerTrainingPlan(CustomerTrainingPlan plan) async {
|
||||
String body = JsonEncoder().convert(plan.toJson());
|
||||
log(" ===== saving customer training plan:" + body);
|
||||
final String response = await _client.post("customer_training_plan/", body);
|
||||
final CustomerTrainingPlan saved = CustomerTrainingPlan.fromJson(jsonDecode(response));
|
||||
return saved;
|
||||
}
|
||||
|
||||
Future<CustomerTrainingPlanExercise> saveCustomerTrainingPlanExercise(CustomerTrainingPlanExercise planExercise) async {
|
||||
String body = JsonEncoder().convert(planExercise.toJson());
|
||||
log(" ===== saving customer training plan exercise:" + body);
|
||||
final String response = await _client.post("customer_training_plan_exercise/", body);
|
||||
final CustomerTrainingPlanExercise saved = CustomerTrainingPlanExercise.fromJson(jsonDecode(response));
|
||||
return saved;
|
||||
}
|
||||
|
||||
Future<CustomerTrainingPlan> updateCustomerTrainingPlan(CustomerTrainingPlan plan, int customerTrainingPlanId) async {
|
||||
String body = JsonEncoder().convert(plan.toJson());
|
||||
log(" ===== update customer training plan:" + body);
|
||||
final String response = await _client.post("customer_training_plan/update/$customerTrainingPlanId", body);
|
||||
final CustomerTrainingPlan saved = CustomerTrainingPlan.fromJson(jsonDecode(response));
|
||||
return saved;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user