WT1.1.10+1 Compact Test Edit
This commit is contained in:
parent
9c84714822
commit
2e0d7fc37d
BIN
asset/menu/machine_test.jpg
Normal file
BIN
asset/menu/machine_test.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 134 KiB |
BIN
asset/menu/own_body.jpg
Normal file
BIN
asset/menu/own_body.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 143 KiB |
BIN
asset/menu/test_center.jpg
Normal file
BIN
asset/menu/test_center.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 80 KiB |
BIN
asset/menu/under_body.jpg
Normal file
BIN
asset/menu/under_body.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 109 KiB |
BIN
asset/menu/upper_body.jpg
Normal file
BIN
asset/menu/upper_body.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 164 KiB |
BIN
asset/menu/weight_test.jpg
Normal file
BIN
asset/menu/weight_test.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 142 KiB |
@ -388,7 +388,7 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||
CURRENT_PROJECT_VERSION = 5;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = SFJJBDCU6Z;
|
||||
ENABLE_BITCODE = NO;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
@ -405,7 +405,7 @@
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Flutter",
|
||||
);
|
||||
MARKETING_VERSION = 1.1.7;
|
||||
MARKETING_VERSION = 1.1.10;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.aitrainer.app;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||
@ -531,7 +531,7 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||
CURRENT_PROJECT_VERSION = 5;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = SFJJBDCU6Z;
|
||||
ENABLE_BITCODE = NO;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
@ -548,7 +548,7 @@
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Flutter",
|
||||
);
|
||||
MARKETING_VERSION = 1.1.7;
|
||||
MARKETING_VERSION = 1.1.10;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.aitrainer.app;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||
@ -566,7 +566,7 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||
CURRENT_PROJECT_VERSION = 5;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = SFJJBDCU6Z;
|
||||
ENABLE_BITCODE = NO;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
@ -583,7 +583,7 @@
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Flutter",
|
||||
);
|
||||
MARKETING_VERSION = 1.1.7;
|
||||
MARKETING_VERSION = 1.1.10;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.aitrainer.app;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||
|
@ -173,6 +173,11 @@ class MenuBloc extends Bloc<MenuEvent, MenuState> with Trans, Logging {
|
||||
ability = ExerciseAbility.endurance;
|
||||
break;
|
||||
case "Cardio":
|
||||
ability = ExerciseAbility.running;
|
||||
break;
|
||||
case "Test Center":
|
||||
ability = ExerciseAbility.mini_test;
|
||||
break;
|
||||
case "My Body":
|
||||
ability = ExerciseAbility.none;
|
||||
break;
|
||||
|
83
lib/bloc/test_set_edit/test_set_edit_bloc.dart
Normal file
83
lib/bloc/test_set_edit/test_set_edit_bloc.dart
Normal file
@ -0,0 +1,83 @@
|
||||
import 'dart:async';
|
||||
import 'dart:collection';
|
||||
|
||||
import 'package:aitrainer_app/bloc/menu/menu_bloc.dart';
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:aitrainer_app/model/exercise_ability.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_type.dart';
|
||||
import 'package:aitrainer_app/repository/workout_tree_repository.dart';
|
||||
import 'package:aitrainer_app/service/exercise_plan_service.dart';
|
||||
import 'package:bloc/bloc.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
|
||||
part 'test_set_edit_event.dart';
|
||||
part 'test_set_edit_state.dart';
|
||||
|
||||
class TestSetEditBloc extends Bloc<TestSetEditEvent, TestSetEditState> {
|
||||
final String templateName;
|
||||
final WorkoutTreeRepository workoutTreeRepository;
|
||||
final MenuBloc menuBloc;
|
||||
final List<ExerciseType> _exerciseTypes = List();
|
||||
final HashMap<int, ExerciseType> _exercisePlanDetails = HashMap();
|
||||
|
||||
TestSetEditBloc({this.templateName, this.workoutTreeRepository, this.menuBloc}) : super(TestSetEditInitial()) {
|
||||
if (Cache().exercisePlanTemplates.isNotEmpty) {
|
||||
Cache().exercisePlanTemplates.forEach((element) {
|
||||
final ExercisePlanTemplate template = element as ExercisePlanTemplate;
|
||||
if (template.name == templateName) {
|
||||
template.exerciseTypes.forEach((id) {
|
||||
final ExerciseType exerciseType = Cache().getExerciseTypeById(id);
|
||||
_exerciseTypes.add(exerciseType);
|
||||
_exercisePlanDetails[exerciseType.exerciseTypeId] = exerciseType;
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Stream<TestSetEditState> mapEventToState(TestSetEditEvent event) async* {
|
||||
try {
|
||||
if (event is TestSetEditChangeExerciseType) {
|
||||
final List<ExerciseType> alternatives = workoutTreeRepository.getExerciseTypeAlternatives(event.exerciseTypeId);
|
||||
final ExerciseType exerciseType = Cache().getExerciseTypeById(event.exerciseTypeId);
|
||||
if (event.index > alternatives.length) {
|
||||
/// skip
|
||||
_exercisePlanDetails[exerciseType.exerciseTypeId] = null;
|
||||
} else if (event.index == 0) {
|
||||
_exercisePlanDetails[exerciseType.exerciseTypeId] = exerciseType;
|
||||
} else {
|
||||
final changedExerciseType = alternatives[event.index - 1];
|
||||
_exercisePlanDetails[exerciseType.exerciseTypeId] = changedExerciseType;
|
||||
}
|
||||
} else if (event is TestSetEditSubmit) {
|
||||
yield TestSetEditLoading();
|
||||
ExercisePlan exercisePlan = ExercisePlan(templateName, Cache().userLoggedIn.customerId);
|
||||
exercisePlan.private = true;
|
||||
exercisePlan.type = ExerciseAbility.mini_test.toString();
|
||||
exercisePlan.dateAdd = DateTime.now();
|
||||
ExercisePlan savedExercisePlan = await ExercisePlanApi().saveExercisePlan(exercisePlan);
|
||||
|
||||
List<ExercisePlanDetail> details = List();
|
||||
for (var entry in _exercisePlanDetails.entries) {
|
||||
if (entry.value != null) {
|
||||
ExercisePlanDetail exercisePlanDetail = ExercisePlanDetail(entry.value.exerciseTypeId);
|
||||
exercisePlanDetail.exercisePlanId = savedExercisePlan.exercisePlanId;
|
||||
exercisePlanDetail.serie = 1;
|
||||
ExercisePlanDetail savedDetail = await ExercisePlanApi().saveExercisePlanDetail(exercisePlanDetail);
|
||||
details.add(savedDetail);
|
||||
}
|
||||
}
|
||||
Cache().saveActiveExercisePlan(exercisePlan, details);
|
||||
yield TestSetEditSaved();
|
||||
}
|
||||
} on Exception catch (e) {
|
||||
yield TestSetEditError(message: e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
List get exerciseTypes => this._exerciseTypes;
|
||||
}
|
33
lib/bloc/test_set_edit/test_set_edit_event.dart
Normal file
33
lib/bloc/test_set_edit/test_set_edit_event.dart
Normal file
@ -0,0 +1,33 @@
|
||||
part of 'test_set_edit_bloc.dart';
|
||||
|
||||
abstract class TestSetEditEvent extends Equatable {
|
||||
const TestSetEditEvent();
|
||||
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class TestSetEditLoad extends TestSetEditEvent {
|
||||
const TestSetEditLoad();
|
||||
}
|
||||
|
||||
class TestSetEditChangeExerciseType extends TestSetEditEvent {
|
||||
final int index;
|
||||
final int exerciseTypeId;
|
||||
const TestSetEditChangeExerciseType({this.index, this.exerciseTypeId});
|
||||
|
||||
@override
|
||||
List<Object> get props => [index, exerciseTypeId];
|
||||
}
|
||||
|
||||
class TestSetEditSkipExerciseType extends TestSetEditEvent {
|
||||
final int exerciseTypeId;
|
||||
const TestSetEditSkipExerciseType({this.exerciseTypeId});
|
||||
|
||||
@override
|
||||
List<Object> get props => [exerciseTypeId];
|
||||
}
|
||||
|
||||
class TestSetEditSubmit extends TestSetEditEvent {
|
||||
const TestSetEditSubmit();
|
||||
}
|
32
lib/bloc/test_set_edit/test_set_edit_state.dart
Normal file
32
lib/bloc/test_set_edit/test_set_edit_state.dart
Normal file
@ -0,0 +1,32 @@
|
||||
part of 'test_set_edit_bloc.dart';
|
||||
|
||||
abstract class TestSetEditState extends Equatable {
|
||||
const TestSetEditState();
|
||||
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class TestSetEditInitial extends TestSetEditState {
|
||||
const TestSetEditInitial();
|
||||
}
|
||||
|
||||
class TestSetEditReady extends TestSetEditState {
|
||||
const TestSetEditReady();
|
||||
}
|
||||
|
||||
class TestSetEditSaved extends TestSetEditState {
|
||||
const TestSetEditSaved();
|
||||
}
|
||||
|
||||
class TestSetEditLoading extends TestSetEditState {
|
||||
const TestSetEditLoading();
|
||||
}
|
||||
|
||||
class TestSetEditError extends TestSetEditState {
|
||||
final String message;
|
||||
const TestSetEditError({this.message});
|
||||
|
||||
@override
|
||||
List<Object> get props => [message];
|
||||
}
|
@ -1,7 +1,9 @@
|
||||
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';
|
||||
@ -63,6 +65,8 @@ class Cache with Logging {
|
||||
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/';
|
||||
@ -89,6 +93,10 @@ class Cache with Logging {
|
||||
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;
|
||||
@ -132,6 +140,38 @@ class Cache with Logging {
|
||||
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;
|
||||
@ -146,7 +186,6 @@ class Cache with Logging {
|
||||
|
||||
void getHardware(SharedPreferences prefs) {
|
||||
final bool hasHardware = prefs.getBool(Cache.hardwareKey);
|
||||
//log("Has Hardware: " + hasHardware.toString());
|
||||
this.hasHardware = hasHardware;
|
||||
if (hasHardware == null) {
|
||||
this.hasHardware = false;
|
||||
@ -301,9 +340,7 @@ class Cache with Logging {
|
||||
this._exerciseTree = exerciseTree;
|
||||
}
|
||||
|
||||
void setExercises(List<Exercise> exercises) {
|
||||
this._exercises = exercises;
|
||||
}
|
||||
void setExercises(List<Exercise> exercises) => this._exercises = exercises;
|
||||
|
||||
void setExercisesTrainee(List<Exercise> exercises) {
|
||||
this._exercisesTrainee = exercises;
|
||||
@ -485,10 +522,10 @@ class Cache with Logging {
|
||||
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);
|
||||
}
|
||||
@ -498,4 +535,7 @@ class Cache with Logging {
|
||||
|
||||
LoginType getLoginType() => loginType;
|
||||
void setLoginType(LoginType type) => this.loginType = type;
|
||||
|
||||
List get exercisePlanTemplates => this._exercisePlanTemplates;
|
||||
setExercisePlanTemplates(value) => this._exercisePlanTemplates = value;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
enum ExerciseAbility { oneRepMax, endurance, running, none }
|
||||
enum ExerciseAbility { oneRepMax, endurance, running, mini_test, none }
|
||||
|
||||
extension ExerciseAbilityExt on ExerciseAbility {
|
||||
bool equalsTo(ExerciseAbility ability) => this.toString() == ability.toString();
|
||||
|
@ -8,6 +8,8 @@ class ExercisePlan {
|
||||
bool private;
|
||||
DateTime dateAdd;
|
||||
DateTime dateUpd;
|
||||
String type;
|
||||
int exercisePlanTemplateId;
|
||||
|
||||
ExercisePlan(String name, int customerId) {
|
||||
this.customerId = customerId;
|
||||
@ -23,6 +25,8 @@ class ExercisePlan {
|
||||
this.description = json['description'];
|
||||
this.dateAdd = json['dateAdd'] == null ? null : DateTime.parse(json['dateAdd']);
|
||||
this.dateUpd = json['dateUpd'] == null ? null : DateTime.parse(json['dateUpd']);
|
||||
this.type = json['type'];
|
||||
this.exercisePlanTemplateId = json['exercisePlanTemplateId'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
@ -40,6 +44,8 @@ class ExercisePlan {
|
||||
"private": private,
|
||||
"dateAdd": formattedDateAdd,
|
||||
"dateUpd": formattedDateUpd,
|
||||
"type": type,
|
||||
"exercisePlanTemplateId": exercisePlanTemplateId
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
@ -50,6 +56,8 @@ class ExercisePlan {
|
||||
"private": private,
|
||||
"dateAdd": formattedDateAdd,
|
||||
"dateUpd": formattedDateUpd,
|
||||
"type": type,
|
||||
"exercisePlanTemplateId": exercisePlanTemplateId
|
||||
};
|
||||
}
|
||||
}
|
||||
|
37
lib/model/exercise_plan_template.dart
Normal file
37
lib/model/exercise_plan_template.dart
Normal file
@ -0,0 +1,37 @@
|
||||
class ExercisePlanTemplate {
|
||||
int exercisePlanTemplateId;
|
||||
String name;
|
||||
String description;
|
||||
String templateType;
|
||||
String nameTranslation;
|
||||
String descriptionTranslation;
|
||||
List<int> exerciseTypes = List();
|
||||
|
||||
ExercisePlanTemplate.fromJson(Map json) {
|
||||
this.exercisePlanTemplateId = json['exercisePlanId'];
|
||||
this.name = json['name'];
|
||||
this.description = json['description'];
|
||||
this.templateType = json['templateType'];
|
||||
this.nameTranslation = json['translations'] != null && (json['translations']).length > 0 ? json['translations'][0]['name'] : this.name;
|
||||
this.descriptionTranslation =
|
||||
json['translations'] != null && (json['translations']).length > 0 ? json['translations'][0]['description'] : this.description;
|
||||
if (json['details'] != null && (json['details']).length > 0) {
|
||||
List details = json['details'];
|
||||
details.forEach((element) {
|
||||
exerciseTypes.add(element['exerciseTypeId']);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
"exercisePlanTemplateId": exercisePlanTemplateId,
|
||||
"name": name,
|
||||
"description": "description",
|
||||
"templateType": templateType,
|
||||
"nameTranslation": nameTranslation,
|
||||
"descriptionTranslation": descriptionTranslation,
|
||||
"exerciseTypes": exerciseTypes.toString()
|
||||
};
|
||||
}
|
||||
}
|
@ -5,6 +5,7 @@ class ExerciseTree {
|
||||
String imageUrl;
|
||||
bool active;
|
||||
String nameTranslation;
|
||||
int sort;
|
||||
|
||||
ExerciseTree();
|
||||
|
||||
@ -25,6 +26,7 @@ class ExerciseTree {
|
||||
"imageUrl": imageUrl,
|
||||
"active": active.toString(),
|
||||
"nameTranslation": nameTranslation,
|
||||
"sort": sort,
|
||||
};
|
||||
}
|
||||
|
||||
@ -38,6 +40,7 @@ class ExerciseTree {
|
||||
newTree.parentId = parentId;
|
||||
}
|
||||
newTree.active = this.active;
|
||||
newTree.sort = this.sort;
|
||||
|
||||
return newTree;
|
||||
}
|
||||
|
@ -2,10 +2,12 @@ class ExerciseTreeParents {
|
||||
int exerciseTreeParentsId;
|
||||
int exerciseTreeParentId;
|
||||
int exerciseTreeChildId;
|
||||
int sort;
|
||||
|
||||
ExerciseTreeParents.fromJson(Map json) {
|
||||
this.exerciseTreeParentsId = json['exerciseTreeParentsId'];
|
||||
this.exerciseTreeParentId = json['exerciseTreeParentId'];
|
||||
this.exerciseTreeChildId = json['exerciseTreeChildId'];
|
||||
this.sort = json['sort'];
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ class ExerciseType {
|
||||
String descriptionTranslation = "";
|
||||
List<int> devices = List();
|
||||
List<int> parents = List();
|
||||
List<int> alternatives = List();
|
||||
|
||||
ExerciseAbility ability;
|
||||
|
||||
@ -55,6 +56,14 @@ class ExerciseType {
|
||||
this.parents.add(parent['exerciseTreeId']);
|
||||
});
|
||||
}
|
||||
|
||||
if (json['alternatives'].length > 0) {
|
||||
final List jsonAlternatives = json['alternatives'];
|
||||
|
||||
jsonAlternatives.forEach((alternative) {
|
||||
this.alternatives.add(alternative['exerciseTypeChildId']);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
|
@ -40,6 +40,7 @@ class WorkoutMenuTree {
|
||||
String nameEnglish;
|
||||
String parentName;
|
||||
String parentNameEnglish;
|
||||
int sort;
|
||||
|
||||
WorkoutMenuTree(
|
||||
this.id,
|
||||
@ -57,7 +58,8 @@ class WorkoutMenuTree {
|
||||
this.isRunning,
|
||||
this.nameEnglish,
|
||||
this.parentName,
|
||||
this.parentNameEnglish);
|
||||
this.parentNameEnglish,
|
||||
this.sort);
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
@ -73,6 +75,7 @@ class WorkoutMenuTree {
|
||||
"is1RM": is1RM.toString(),
|
||||
"isEndurance": isEndurance.toString(),
|
||||
"isRunning": isRunning.toString(),
|
||||
"sort": sort,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -103,7 +103,8 @@ class WorkoutTreeRepository with Logging {
|
||||
isRunning,
|
||||
treeItem.name,
|
||||
parent != null ? parent.name : "",
|
||||
parent != null ? parent.nameEnglish : "");
|
||||
parent != null ? parent.nameEnglish : "",
|
||||
treeItem.sort);
|
||||
menuItem = this.setWorkoutTypes(menuItem, treeItem);
|
||||
this.tree[treeItem.name + "_" + treeItem.parentId.toString()] = menuItem;
|
||||
//log("WorkoutMenuTree item " + menuItem.toJson().toString());
|
||||
@ -141,7 +142,8 @@ class WorkoutTreeRepository with Logging {
|
||||
isRunning,
|
||||
exerciseType.name,
|
||||
parent != null ? parent.name : "",
|
||||
parent != null ? parent.nameEnglish : "");
|
||||
parent != null ? parent.nameEnglish : "",
|
||||
0);
|
||||
this.tree[exerciseType.name] = menuItem;
|
||||
menuAsExercise.add(menuItem);
|
||||
//log("WorkoutMenuTree item " + menuItem.toJson().toString());
|
||||
@ -283,6 +285,56 @@ class WorkoutTreeRepository with Logging {
|
||||
return parentItem;
|
||||
}
|
||||
|
||||
WorkoutMenuTree getMenuItemByExerciseTypeId(int exerciseTypeId) {
|
||||
WorkoutMenuTree menuItem;
|
||||
this.menuAsExercise.forEach((element) {
|
||||
if (element.exerciseTypeId == exerciseTypeId) {
|
||||
menuItem = element;
|
||||
}
|
||||
});
|
||||
return menuItem;
|
||||
}
|
||||
|
||||
List<WorkoutMenuTree> getWorkoutTreeAlternatives(WorkoutMenuTree workoutMenuTree) {
|
||||
if (workoutMenuTree == null) {
|
||||
return null;
|
||||
}
|
||||
if (workoutMenuTree.exerciseType == null) {
|
||||
return null;
|
||||
}
|
||||
final List<ExerciseType> alternatives = this.getExerciseTypeAlternatives(workoutMenuTree.exerciseTypeId);
|
||||
if (alternatives == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<WorkoutMenuTree> list = List();
|
||||
list.add(workoutMenuTree);
|
||||
alternatives.forEach((element) {
|
||||
final WorkoutMenuTree alternativeMenuItem = this.getMenuItemByExerciseTypeId(element.exerciseTypeId);
|
||||
list.add(alternativeMenuItem);
|
||||
});
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
List<ExerciseType> getExerciseTypeAlternatives(int exerciseTypeId) {
|
||||
if (exerciseTypeId == null || exerciseTypeId <= 0) {
|
||||
return null;
|
||||
}
|
||||
List<ExerciseType> list = List();
|
||||
Cache().getExerciseTypes().forEach((exerciseType) {
|
||||
if (exerciseType.alternatives.isNotEmpty) {
|
||||
exerciseType.alternatives.forEach((childId) {
|
||||
if (childId == exerciseTypeId) {
|
||||
list.add(exerciseType);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
void sortByMuscleType() {
|
||||
sortedTree = SplayTreeMap<String, List<WorkoutMenuTree>>();
|
||||
tree.forEach((key, value) {
|
||||
|
@ -56,18 +56,16 @@ class ExerciseTreeApi with Logging {
|
||||
if (index > 0) {
|
||||
ExerciseTree newElement = element.copy(parent.exerciseTreeParentId);
|
||||
exerciseTree.add(newElement);
|
||||
//print("ExerciseTree " + newElement.toJson().toString());
|
||||
} else {
|
||||
element.parentId = parent.exerciseTreeParentId;
|
||||
element.sort = parent.sort;
|
||||
exerciseTree[treeIndex].parentId = parent.exerciseTreeParentId;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
});
|
||||
//print("ExerciseTree " + element.toJson().toString());
|
||||
treeIndex++;
|
||||
});
|
||||
|
||||
return exerciseTree;
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@ import 'package:aitrainer_app/model/customer_exercise_device.dart';
|
||||
import 'package:aitrainer_app/model/customer_property.dart';
|
||||
import 'package:aitrainer_app/model/exercise.dart';
|
||||
import 'package:aitrainer_app/model/exercise_device.dart';
|
||||
import 'package:aitrainer_app/model/exercise_plan_template.dart';
|
||||
import 'package:aitrainer_app/model/exercise_result.dart';
|
||||
import 'package:aitrainer_app/model/exercise_tree.dart';
|
||||
import 'package:aitrainer_app/model/exercise_tree_parents.dart';
|
||||
@ -53,6 +54,10 @@ class PackageApi {
|
||||
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();
|
||||
}
|
||||
|
@ -1,9 +1,30 @@
|
||||
import 'package:aitrainer_app/widgets/app_bar.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'dart:convert';
|
||||
|
||||
class TestSetEdit extends StatelessWidget {
|
||||
import 'package:aitrainer_app/bloc/menu/menu_bloc.dart';
|
||||
import 'package:aitrainer_app/bloc/test_set_edit/test_set_edit_bloc.dart';
|
||||
import 'package:aitrainer_app/library/custom_icon_icons.dart';
|
||||
import 'package:aitrainer_app/model/workout_menu_tree.dart';
|
||||
import 'package:aitrainer_app/util/trans.dart';
|
||||
import 'package:aitrainer_app/widgets/app_bar.dart';
|
||||
import 'package:aitrainer_app/widgets/dialog_common.dart';
|
||||
import 'package:carousel_slider/carousel_slider.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:modal_progress_hud/modal_progress_hud.dart';
|
||||
import 'package:transparent_image/transparent_image.dart';
|
||||
import 'package:aitrainer_app/library/image_cache.dart' as wt;
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class TestSetEdit extends StatelessWidget with Trans {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final String templateName = ModalRoute.of(context).settings.arguments;
|
||||
// ignore: close_sinks
|
||||
final MenuBloc menuBloc = BlocProvider.of<MenuBloc>(context);
|
||||
TestSetEditBloc bloc;
|
||||
|
||||
setContext(context);
|
||||
return Scaffold(
|
||||
appBar: AppBarNav(depth: 1),
|
||||
body: Container(
|
||||
@ -15,6 +36,222 @@ class TestSetEdit extends StatelessWidget {
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
),
|
||||
child: Text("H")));
|
||||
child: BlocProvider(
|
||||
create: (context) =>
|
||||
TestSetEditBloc(templateName: templateName, workoutTreeRepository: menuBloc.menuTreeRepository, menuBloc: menuBloc),
|
||||
child: BlocConsumer<TestSetEditBloc, TestSetEditState>(listener: (context, state) {
|
||||
if (state is TestSetEditError) {
|
||||
Scaffold.of(context).showSnackBar(
|
||||
SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white))));
|
||||
} else if (state is TestSetEditSaved) {
|
||||
Navigator.of(context).pushNamed("home");
|
||||
}
|
||||
}, builder: (context, state) {
|
||||
bloc = BlocProvider.of<TestSetEditBloc>(context);
|
||||
return ModalProgressHUD(
|
||||
child: getTestSetWidget(bloc, templateName),
|
||||
inAsyncCall: state is TestSetEditLoading,
|
||||
opacity: 0.5,
|
||||
color: Colors.black54,
|
||||
progressIndicator: CircularProgressIndicator(),
|
||||
);
|
||||
}))),
|
||||
floatingActionButton: FloatingActionButton.extended(
|
||||
onPressed: () => showDialog(
|
||||
context: context,
|
||||
barrierDismissible: false,
|
||||
builder: (BuildContext context) {
|
||||
return DialogCommon(
|
||||
title: "Start!",
|
||||
descriptions: "GO",
|
||||
text: "OK",
|
||||
onTap: () => {
|
||||
Navigator.of(context).pop(),
|
||||
if (bloc != null)
|
||||
{
|
||||
bloc.add(TestSetEditSubmit()),
|
||||
}
|
||||
},
|
||||
onCancel: () => {Navigator.of(context).pop()},
|
||||
);
|
||||
}),
|
||||
backgroundColor: Colors.orange[800],
|
||||
icon: Icon(CustomIcon.clock),
|
||||
label: Text(
|
||||
"Start training",
|
||||
style: GoogleFonts.inter(fontWeight: FontWeight.bold, fontSize: 16),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget getTestSetWidget(TestSetEditBloc bloc, String templateName) {
|
||||
return Container(
|
||||
padding: EdgeInsets.only(left: 10, right: 10),
|
||||
child: CustomScrollView(scrollDirection: Axis.vertical, slivers: [
|
||||
SliverAppBar(
|
||||
toolbarHeight: 135,
|
||||
automaticallyImplyLeading: false,
|
||||
backgroundColor: Colors.transparent,
|
||||
title: Column(mainAxisAlignment: MainAxisAlignment.start, children: [
|
||||
RichText(
|
||||
textAlign: TextAlign.center,
|
||||
text: TextSpan(
|
||||
style: GoogleFonts.archivoBlack(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.white,
|
||||
shadows: <Shadow>[
|
||||
Shadow(
|
||||
offset: Offset(5.0, 5.0),
|
||||
blurRadius: 12.0,
|
||||
color: Colors.black54,
|
||||
),
|
||||
Shadow(
|
||||
offset: Offset(-3.0, 3.0),
|
||||
blurRadius: 12.0,
|
||||
color: Colors.black54,
|
||||
),
|
||||
],
|
||||
),
|
||||
children: [
|
||||
TextSpan(text: t("Edit Your Training Test Set"), style: GoogleFonts.inter(color: Colors.white, fontSize: 18)),
|
||||
TextSpan(text: "\n", style: GoogleFonts.inter(color: Colors.white, fontSize: 18)),
|
||||
TextSpan(text: t(templateName), style: GoogleFonts.archivoBlack(color: Colors.yellow[300], fontSize: 18)),
|
||||
])),
|
||||
Divider(
|
||||
color: Colors.transparent,
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () => showDialog(
|
||||
context: context,
|
||||
barrierDismissible: false,
|
||||
builder: (BuildContext context) {
|
||||
return DialogCommon(
|
||||
title: "Own Body",
|
||||
descriptions: t("execute these exercises with maximum repeats. Leave at least 3 min rest time between time"),
|
||||
text: "OK",
|
||||
onTap: () => {Navigator.of(context).pop()},
|
||||
onCancel: () => {Navigator.of(context).pop()},
|
||||
);
|
||||
}),
|
||||
child: Icon(
|
||||
CustomIcon.question_circle,
|
||||
color: Colors.orange[400],
|
||||
size: 40,
|
||||
)),
|
||||
]),
|
||||
centerTitle: true,
|
||||
),
|
||||
SliverList(delegate: SliverChildListDelegate(getExerciseTypeWidgets(bloc))),
|
||||
]));
|
||||
}
|
||||
|
||||
List<Widget> imageSliders(List<WorkoutMenuTree> alternatives, MenuBloc menuBloc) {
|
||||
final List<Widget> list = List();
|
||||
alternatives.forEach((element) {
|
||||
list.add(getImageStack(element, menuBloc));
|
||||
});
|
||||
list.add(Container(
|
||||
padding: EdgeInsets.only(top: 25, bottom: 25),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(24.0),
|
||||
child: Container(
|
||||
color: Colors.red[600],
|
||||
child: Center(
|
||||
child: Text(
|
||||
"X",
|
||||
style: GoogleFonts.archivoBlack(
|
||||
color: Colors.white,
|
||||
fontSize: 80,
|
||||
),
|
||||
),
|
||||
)))));
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
Stack getImageStack(WorkoutMenuTree element, MenuBloc menuBloc) {
|
||||
print(element.toJson());
|
||||
return Stack(alignment: Alignment.bottomLeft, children: [
|
||||
_getButtonImage(element, menuBloc),
|
||||
Container(
|
||||
padding: EdgeInsets.only(left: 15, bottom: 15, right: 15),
|
||||
child: Text(
|
||||
element.name,
|
||||
maxLines: 4,
|
||||
style: GoogleFonts.archivoBlack(color: element.color, fontSize: 16, height: 1.1),
|
||||
),
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
List<Widget> getExerciseTypeWidgets(TestSetEditBloc bloc) {
|
||||
final List<Widget> widgets = List();
|
||||
bloc.exerciseTypes.forEach((element) {
|
||||
final WorkoutMenuTree workoutTree = bloc.menuBloc.menuTreeRepository.getMenuItemByExerciseTypeId(element.exerciseTypeId);
|
||||
|
||||
final List<WorkoutMenuTree> alternativeMenuItems = bloc.menuBloc.menuTreeRepository.getWorkoutTreeAlternatives(workoutTree);
|
||||
if (workoutTree != null && alternativeMenuItems != null) {
|
||||
final Widget widget = CarouselSlider(
|
||||
options: CarouselOptions(
|
||||
viewportFraction: 0.80,
|
||||
reverse: false,
|
||||
enableInfiniteScroll: false,
|
||||
autoPlay: false,
|
||||
aspectRatio: 2,
|
||||
enlargeCenterPage: true,
|
||||
onPageChanged: (index, reason) =>
|
||||
bloc.add(TestSetEditChangeExerciseType(index: index, exerciseTypeId: element.exerciseTypeId)),
|
||||
enlargeStrategy: CenterPageEnlargeStrategy.scale),
|
||||
items: imageSliders(alternativeMenuItems, bloc.menuBloc),
|
||||
);
|
||||
widgets.add(widget);
|
||||
}
|
||||
});
|
||||
return widgets;
|
||||
}
|
||||
|
||||
Widget _getButtonImage(WorkoutMenuTree workoutTree, MenuBloc menuBloc) {
|
||||
if (workoutTree == null) {
|
||||
return Offstage();
|
||||
}
|
||||
String imageString = menuBloc.getImage(workoutTree.id, workoutTree.imageName);
|
||||
Widget widget;
|
||||
if (imageString != null) {
|
||||
widget = ClipRRect(
|
||||
borderRadius: BorderRadius.circular(24.0),
|
||||
child: Container(
|
||||
color: Colors.transparent,
|
||||
child: FadeInImage(
|
||||
fadeInDuration: Duration(milliseconds: 100),
|
||||
image: MemoryImage(base64Decode(imageString)),
|
||||
placeholder: MemoryImage(kTransparentImage),
|
||||
),
|
||||
));
|
||||
} else {
|
||||
if (workoutTree.imageName.contains("https")) {
|
||||
if (!wt.ImageCache().existsImageInMap(workoutTree.id, workoutTree.imageName)) {
|
||||
widget = ClipRRect(
|
||||
borderRadius: BorderRadius.circular(24.0),
|
||||
child: Container(
|
||||
color: Colors.transparent,
|
||||
child: FadeInImage(
|
||||
fadeInDuration: Duration(milliseconds: 500),
|
||||
image: NetworkImage(workoutTree.imageName),
|
||||
placeholder: MemoryImage(kTransparentImage),
|
||||
),
|
||||
));
|
||||
}
|
||||
} else {
|
||||
widget = ClipRRect(
|
||||
borderRadius: BorderRadius.circular(24.0),
|
||||
child: Container(
|
||||
color: Colors.transparent,
|
||||
child: Image.asset(workoutTree.imageName),
|
||||
));
|
||||
}
|
||||
}
|
||||
return widget;
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ import 'package:aitrainer_app/service/logging.dart';
|
||||
import 'package:aitrainer_app/util/trans.dart';
|
||||
import 'package:aitrainer_app/widgets/dialog_common.dart';
|
||||
import 'package:badges/badges.dart';
|
||||
import 'package:ezanimation/ezanimation.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/painting.dart';
|
||||
@ -24,7 +25,6 @@ import 'package:transparent_image/transparent_image.dart';
|
||||
import 'package:aitrainer_app/library/image_cache.dart' as wt;
|
||||
|
||||
import 'dialog_html.dart';
|
||||
import 'menu_info_widget.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class MenuPageWidget extends StatefulWidget {
|
||||
@ -39,14 +39,24 @@ class MenuPageWidget extends StatefulWidget {
|
||||
class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
|
||||
final double baseWidth = 312;
|
||||
final double baseHeight = 675.2;
|
||||
bool isFirst = true;
|
||||
bool wait = false;
|
||||
MenuBloc menuBloc;
|
||||
final scrollController = ScrollController();
|
||||
final bool activeExercisePlan = Cache().activeExercisePlan != null;
|
||||
final EzAnimation animation = EzAnimation(35.0, 10.0, Duration(seconds: 2), reverseCurve: Curves.linear);
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
isFirst = true;
|
||||
if (activeExercisePlan) {
|
||||
animation.start();
|
||||
animation.addStatusListener((status) {
|
||||
if (status == AnimationStatus.completed || status == AnimationStatus.dismissed) {
|
||||
animation.reverse();
|
||||
}
|
||||
});
|
||||
animation.addListener(() {
|
||||
setState(() {});
|
||||
});
|
||||
}
|
||||
|
||||
/// We require the initializers to run after the loading screen is rendered
|
||||
SchedulerBinding.instance.addPostFrameCallback((_) {
|
||||
@ -88,7 +98,8 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
|
||||
padding: EdgeInsets.only(top: 15.0),
|
||||
child: Center(
|
||||
child: Stack(alignment: Alignment.bottomLeft, children: [
|
||||
Text(t("All Exercises has been filtered out"), style: GoogleFonts.inter(color: Colors.white)),
|
||||
Text(AppLocalizations.of(context).translate("All Exercises has been filtered out"),
|
||||
style: GoogleFonts.inter(color: Colors.white)),
|
||||
]))));
|
||||
} else {
|
||||
menuBloc.getFilteredBranch(menuBloc.parent).forEach((treeName, value) {
|
||||
@ -103,7 +114,7 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
|
||||
animationType: BadgeAnimationType.slide,
|
||||
badgeColor: Colors.orange[800],
|
||||
showBadge: workoutTree.base,
|
||||
badgeContent: Text(t("base"),
|
||||
badgeContent: Text(AppLocalizations.of(context).translate("base"),
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 12,
|
||||
@ -120,7 +131,9 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
|
||||
builder: (BuildContext context) {
|
||||
return DialogHTML(
|
||||
title: workoutTree.name,
|
||||
htmlData: workoutTree.nameEnglish == "Endurance" ? t("Endurance_desc") : t("OneRepMax_desc"),
|
||||
htmlData: workoutTree.nameEnglish == "Endurance"
|
||||
? AppLocalizations.of(context).translate("Endurance_desc")
|
||||
: AppLocalizations.of(context).translate("OneRepMax_desc"),
|
||||
);
|
||||
})
|
||||
},
|
||||
@ -171,7 +184,7 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
|
||||
delegate: SliverChildListDelegate([
|
||||
Column(mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [
|
||||
Text(
|
||||
t("Equipment Filter"),
|
||||
AppLocalizations.of(context).translate("Equipment Filter"),
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.archivoBlack(
|
||||
fontSize: 24,
|
||||
@ -241,6 +254,7 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
|
||||
menuBloc.setMenuInfo();
|
||||
|
||||
SliverAppBar sliverAppBar = SliverAppBar(
|
||||
automaticallyImplyLeading: false,
|
||||
backgroundColor: Colors.transparent,
|
||||
title: Row(mainAxisAlignment: MainAxisAlignment.spaceAround, children: [
|
||||
SizedBox(
|
||||
@ -283,6 +297,35 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
|
||||
}
|
||||
},
|
||||
),
|
||||
activeExercisePlan
|
||||
? GestureDetector(
|
||||
onTap: () => showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return DialogCommon(
|
||||
title: t("You have an acive Compact Test"),
|
||||
descriptions: t("Press OK to continue!"),
|
||||
text: "OK",
|
||||
onTap: () => {
|
||||
Navigator.of(context).pop(),
|
||||
},
|
||||
onCancel: () => {
|
||||
Navigator.of(context).pop(),
|
||||
},
|
||||
);
|
||||
}),
|
||||
child: AnimatedBuilder(
|
||||
animation: animation,
|
||||
builder: (context, snapshot) {
|
||||
return Center(
|
||||
child: Container(
|
||||
width: animation.value,
|
||||
height: animation.value,
|
||||
child: Image.asset("asset/image/pict_reps_volumen_db.png"),
|
||||
),
|
||||
);
|
||||
}))
|
||||
: Offstage(),
|
||||
SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
@ -292,6 +335,9 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
|
||||
|
||||
void menuClick(WorkoutMenuTree workoutTree, MenuBloc menuBloc, BuildContext context) {
|
||||
if (workoutTree.child == false) {
|
||||
if (ExerciseAbility.mini_test.equalsTo(menuBloc.ability) && workoutTree.parent != 0) {
|
||||
Navigator.of(context).pushNamed('testSetEdit', arguments: workoutTree.nameEnglish);
|
||||
}
|
||||
menuBloc.add(MenuTreeDown(item: workoutTree, parent: workoutTree.id));
|
||||
} else {
|
||||
menuBloc.add(MenuClickExercise(exerciseTypeId: workoutTree.id));
|
||||
|
14
pubspec.lock
14
pubspec.lock
@ -141,6 +141,13 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "7.1.0"
|
||||
carousel_slider:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: carousel_slider
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.0.0"
|
||||
characters:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -274,6 +281,13 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.5"
|
||||
ezanimation:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: ezanimation
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.4.1"
|
||||
fake_async:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
11
pubspec.yaml
11
pubspec.yaml
@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
||||
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
||||
# Read more about iOS versioning at
|
||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||
version: 1.1.9+59
|
||||
version: 1.1.10+60
|
||||
|
||||
environment:
|
||||
sdk: ">=2.7.0 <3.0.0"
|
||||
@ -54,6 +54,7 @@ dependencies:
|
||||
liquid_progress_indicator: ^0.3.2
|
||||
dropdown_search: ^0.4.9
|
||||
audioplayer: ^0.8.1
|
||||
ezanimation: ^0.4.1
|
||||
|
||||
|
||||
firebase_core: ^0.5.0
|
||||
@ -66,6 +67,7 @@ dependencies:
|
||||
crypto: ^2.1.5
|
||||
transparent_image: ^1.0.0
|
||||
#auto_animated: ^2.1.0
|
||||
carousel_slider: ^3.0.0
|
||||
|
||||
flurry: ^0.0.7
|
||||
|
||||
@ -299,10 +301,12 @@ flutter:
|
||||
- asset/menu/lying_scissors.jpg
|
||||
- asset/menu/lying_triceps_extension.jpg
|
||||
- asset/menu/machine_shoulder_press.jpg
|
||||
- asset/menu/machine_test.jpg
|
||||
- asset/menu/oblique_crunch.jpg
|
||||
- asset/menu/olympic_squat.jpg
|
||||
- asset/menu/one_arm_row.jpg
|
||||
- asset/menu/overhead_dumbbell_triceps_extension.jpg
|
||||
- asset/menu/own_body.jpg
|
||||
- asset/menu/peck_deck_flyes.jpg
|
||||
- asset/menu/plank.jpg
|
||||
- asset/menu/pull_up.jpg
|
||||
@ -348,16 +352,21 @@ flutter:
|
||||
- asset/menu/stiff_legged_deadlift.jpg
|
||||
- asset/menu/straight-arm_rope_pull-down.jpg
|
||||
- asset/menu/t_bar_rows.jpg
|
||||
- asset/menu/test_center.jpg
|
||||
- asset/menu/thigh_adductor.jpg
|
||||
- asset/menu/triceps_extension_on_cable_with_rope.jpg
|
||||
- asset/menu/triceps_kickback.jpg
|
||||
- asset/menu/triceps_pushdown.jpg
|
||||
- asset/menu/twisted_crunches.jpg
|
||||
- asset/menu/under_body.jpg
|
||||
- asset/menu/upper_body.jpg
|
||||
- asset/menu/v_ups.jpg
|
||||
- asset/menu/wall_sit.jpg
|
||||
- asset/menu/weight_test.jpg
|
||||
- asset/menu/weighted_bench_dip.jpg
|
||||
- asset/menu/wide_grip_behind_the_neck_pull_ups.jpg
|
||||
- asset/menu/wide_grip_front_lat_pulldown.jpg
|
||||
|
||||
- asset/wine-glass.mp3
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user