v1.26 ios v2

This commit is contained in:
bossanyit
2022-10-29 10:01:00 +02:00
parent 208ada4251
commit 621d766335
50 changed files with 593 additions and 679 deletions
@@ -133,25 +133,28 @@ class CustomerChangeBloc extends Bloc<CustomerChangeEvent, CustomerChangeState>
void _onSaveFitness(CustomerSaveFitness event, Emitter<CustomerChangeState> emit) {
emit(CustomerChangeLoading());
if (customerRepository.customer!.fitnessLevel == null) {
throw Exception("Please select your fitness level");
emit(CustomerSaveError(message: "Please selectyour fitness level"));
} else {
emit(CustomerSaveSuccess());
}
emit(CustomerSaveSuccess());
}
void _onSaveGoal(CustomerSaveGoal event, Emitter<CustomerChangeState> emit) {
emit(CustomerChangeLoading());
if (customerRepository.customer!.goal == null) {
throw Exception("Please select your goal");
emit(CustomerSaveError(message: "Please select your goal"));
} else {
emit(CustomerSaveSuccess());
}
emit(CustomerSaveSuccess());
}
void _onSaveSex(CustomerSaveSex event, Emitter<CustomerChangeState> emit) {
emit(CustomerChangeLoading());
if (customerRepository.customer!.sex == null) {
throw Exception("Please select your biologial gender");
emit(CustomerSaveError(message: "Please selectyour biological gender"));
} else {
emit(CustomerSaveSuccess());
}
emit(CustomerSaveSuccess());
}
void _onSaveWeight(CustomerSaveWeight event, Emitter<CustomerChangeState> emit) {
@@ -166,25 +169,29 @@ class CustomerChangeBloc extends Bloc<CustomerChangeEvent, CustomerChangeState>
void _onSave(CustomerSave event, Emitter<CustomerChangeState> emit) async {
emit(CustomerSaving());
if (validation()) {
if (selectedFitnessItem != null) {
customerRepository.setFitnessLevel(selectedFitnessItem!);
}
if (selectedSport != null) {
customerRepository.customer!.sportId = selectedSport!.sportId;
}
try {
if (validation()) {
if (selectedFitnessItem != null) {
customerRepository.setFitnessLevel(selectedFitnessItem!);
}
if (selectedSport != null) {
customerRepository.customer!.sportId = selectedSport!.sportId;
}
if (customerRepository.customer!.lang == null) {
customerRepository.customer!.lang = AppLanguage().appLocal.languageCode;
}
if (customerRepository.customer!.lang == null) {
customerRepository.customer!.lang = AppLanguage().appLocal.languageCode;
}
await customerRepository.saveCustomer();
MauticRepository mauticRepository = MauticRepository(customerRepository: customerRepository);
await mauticRepository.sendMauticDataChange();
Cache().initBadges();
emit(CustomerSaveSuccess());
} else {
emit(CustomerSaveError(message: "Please provide the necessary information"));
await customerRepository.saveCustomer();
MauticRepository mauticRepository = MauticRepository(customerRepository: customerRepository);
await mauticRepository.sendMauticDataChange();
Cache().initBadges();
emit(CustomerSaveSuccess());
} else {
emit(CustomerSaveError(message: "Please provide the necessary information"));
}
} on Exception catch (e) {
emit(CustomerSaveError(message: e.toString()));
}
}
+2 -2
View File
@@ -182,7 +182,7 @@ class ExerciseNewBloc extends Bloc<ExerciseNewEvent, ExerciseNewState> with Logg
menuBloc.add(MenuTreeDown(parent: 0));
Cache().initBadges();
Track().track(TrackingEvent.exercise_new, eventValue: exerciseRepository.exerciseType!.name);
emit(ExerciseNewReady());
emit(ExerciseNewSaved());
}
void _onSubmitNoRegistration(ExerciseNewSubmitNoRegistration event, Emitter<ExerciseNewState> emit) async {
@@ -190,7 +190,7 @@ class ExerciseNewBloc extends Bloc<ExerciseNewEvent, ExerciseNewState> with Logg
exerciseRepository.addExerciseNoRegistration();
menuBloc.add(MenuTreeDown(parent: 0));
Track().track(TrackingEvent.exercise_new_no_registration, eventValue: exerciseRepository.exerciseType!.name);
emit(ExerciseNewReady());
emit(ExerciseNewSaved());
}
void _onBMIAnimate(ExerciseNewBMIAnimate event, Emitter<ExerciseNewState> emit) async {
+52 -33
View File
@@ -93,7 +93,7 @@ class LoginBloc extends Bloc<LoginEvent, LoginState> with Trans {
accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn!));
Track().track(TrackingEvent.login, eventValue: "email");
Cache().setLoginType(LoginType.email);
} on Exception catch(e) {
} on Exception catch (e) {
emit(LoginError(message: e.toString()));
} finally {
emit(LoginSuccess());
@@ -107,7 +107,7 @@ class LoginBloc extends Bloc<LoginEvent, LoginState> with Trans {
await userRepository.getUserByFB();
accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn!));
Track().track(TrackingEvent.login, eventValue: "FB");
} on Exception catch(e) {
} on Exception catch (e) {
emit(LoginError(message: e.toString()));
} finally {
emit(LoginSuccess());
@@ -121,8 +121,7 @@ class LoginBloc extends Bloc<LoginEvent, LoginState> with Trans {
await userRepository.getUserByGoogle();
accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn!));
Track().track(TrackingEvent.login, eventValue: "Google");
} on Exception catch(e) {
} on Exception catch (e) {
emit(LoginError(message: e.toString()));
} finally {
emit(LoginSuccess());
@@ -136,7 +135,7 @@ class LoginBloc extends Bloc<LoginEvent, LoginState> with Trans {
await userRepository.getUserByApple();
accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn!));
Track().track(TrackingEvent.login, eventValue: "Apple");
} on Exception catch(e) {
} on Exception catch (e) {
emit(LoginError(message: e.toString()));
} finally {
emit(LoginSuccess());
@@ -145,47 +144,67 @@ class LoginBloc extends Bloc<LoginEvent, LoginState> with Trans {
void _onRegistrationSubmit(RegistrationSubmit event, Emitter<LoginState> emit) async {
emit(LoginLoading());
final String? validationError = this.validate();
if (validationError != null) {
emit(LoginError(message: validationError));
} else {
await userRepository.addUser();
accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn!));
customerRepository!.customer!.emailSubscription = emailSubscription == true ? 1 : 0;
await afterRegistration("email");
Cache().setLoginType(LoginType.email);
try {
final String? validationError = this.validate();
if (validationError != null) {
emit(LoginError(message: validationError));
} else {
await userRepository.addUser();
accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn!));
customerRepository!.customer!.emailSubscription = emailSubscription == true ? 1 : 0;
await afterRegistration("email");
Cache().setLoginType(LoginType.email);
}
} on Exception catch (e) {
emit(LoginError(message: e.toString()));
} finally {
emit(LoginSuccess());
}
emit(LoginSuccess());
}
void _onRegistrationFB(RegistrationFB event, Emitter<LoginState> emit) async {
emit(LoginLoading());
Cache().setLoginType(LoginType.fb);
await userRepository.addUserFB();
accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn!));
customerRepository!.customer!.emailSubscription = emailSubscription == true ? 1 : 0;
await afterRegistration("FB");
emit(LoginSuccess());
try {
Cache().setLoginType(LoginType.fb);
await userRepository.addUserFB();
accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn!));
customerRepository!.customer!.emailSubscription = emailSubscription == true ? 1 : 0;
await afterRegistration("FB");
} on Exception catch (e) {
emit(LoginError(message: e.toString()));
} finally {
emit(LoginSuccess());
}
}
void _onRegistrationGoogle(RegistrationGoogle event, Emitter<LoginState> emit) async {
emit(LoginLoading());
Cache().setLoginType(LoginType.google);
await userRepository.addUserGoogle();
accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn!));
customerRepository!.customer!.emailSubscription = emailSubscription == true ? 1 : 0;
await afterRegistration("Google");
emit(LoginSuccess());
try {
Cache().setLoginType(LoginType.google);
await userRepository.addUserGoogle();
accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn!));
customerRepository!.customer!.emailSubscription = emailSubscription == true ? 1 : 0;
await afterRegistration("Google");
} on Exception catch (e) {
emit(LoginError(message: e.toString()));
} finally {
emit(LoginSuccess());
}
}
void _onRegistrationApple(RegistrationApple event, Emitter<LoginState> emit) async {
emit(LoginLoading());
Cache().setLoginType(LoginType.apple);
await userRepository.addUserApple();
accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn!));
customerRepository!.customer!.emailSubscription = emailSubscription == true ? 1 : 0;
await afterRegistration("Apple");
emit(LoginSuccess());
try {
Cache().setLoginType(LoginType.apple);
await userRepository.addUserApple();
accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn!));
customerRepository!.customer!.emailSubscription = emailSubscription == true ? 1 : 0;
await afterRegistration("Apple");
} on Exception catch (e) {
emit(LoginError(message: e.toString()));
} finally {
emit(LoginSuccess());
}
}
void _onDataProtectionClicked(DataProtectionClicked event, Emitter<LoginState> emit) async {
-97
View File
@@ -113,103 +113,6 @@ class MenuBloc extends Bloc<MenuEvent, MenuState> with Trans, Logging {
this.context = context;
}
/* @override
Stream<MenuState> mapEventToState(
MenuEvent event,
) async* {
try {
if (event is MenuCreate) {
yield MenuLoading();
//await menuTreeRepository.createTree();
//menuTreeRepository.getBranch(this.parent);
//setMenuInfo();
if (Cache().getDevices() != null) {
exerciseDeviceRepository.setDevices(Cache().getDevices()!);
}
yield MenuReady();
} else if (event is MenuRecreateTree) {
yield MenuLoading();
// ie. at language changes
menuTreeRepository.createTree();
yield MenuReady();
} else if (event is MenuTreeDown) {
yield MenuLoading();
parent = event.parent;
workoutItem = event.item;
if (workoutItem != null) {
setAbility(workoutItem!.internalName);
}
final LinkedHashMap<String, WorkoutMenuTree> branch = menuTreeRepository.getBranch(event.parent);
await getImages(branch);
yield MenuReady();
} else if (event is MenuTreeUp) {
yield MenuLoading();
// get parent menus or exercises
parent = event.parent;
workoutItem = menuTreeRepository.getParentItem(parent);
LinkedHashMap<String, WorkoutMenuTree> branch;
if (workoutItem != null) {
setAbility(workoutItem!.internalName);
branch = menuTreeRepository.getBranch(workoutItem!.parent);
await getImages(branch);
}
yield MenuReady();
} else if (event is MenuTreeJump) {
yield MenuLoading();
parent = event.parent;
workoutItem = menuTreeRepository.getParentItem(parent);
if (workoutItem != null) {
setAbility(workoutItem!.internalName);
}
final LinkedHashMap<String, WorkoutMenuTree> branch = menuTreeRepository.getBranch(workoutItem!.parent);
await getImages(branch);
yield MenuReady();
} else if (event is MenuClickExercise) {
yield MenuLoading();
// get exercise page
yield MenuReady();
} else if (event is MenuFilterExerciseType) {
yield MenuLoading();
final int deviceId = event.deviceId;
if (selectedDevice(deviceId)) {
listFilterDevice.add(deviceId);
} else {
listFilterDevice.remove(deviceId);
}
yield MenuReady();
} else if (event is MenuStartTrial) {
yield MenuLoading();
final DateTime start = event.start;
CustomerRepository customerRepository = CustomerRepository();
customerRepository.customer = Cache().userLoggedIn;
customerRepository.customer!.trialDate = start;
Cache().userLoggedIn!.trialDate = start;
customerRepository.saveCustomer();
if (DateTime.now().difference(start).inHours < 1) {
Cache().hasPurchased = true;
log("Trial mode on!");
Track().track(TrackingEvent.trial, eventValue: DateFormat('yyyy-MM-dd HH:mm:ss').format(start));
if (!isInDebugMode) {
MauticRepository mauticRepository = MauticRepository(customerRepository: customerRepository);
await mauticRepository.sendMauticTrial();
}
}
yield MenuReady();
}
} on Exception catch (ex) {
yield MenuError(message: ex.toString());
}
} */
void setAbility(String name) {
switch (name) {
case "one_rep_max":
+3 -3
View File
@@ -161,10 +161,10 @@ class SalesBloc extends Bloc<SalesEvent, SalesState> with Logging {
return;
}
String productSetString = splitTestRepository.getSplitTestValue("product_set_5");
log("ProductSetString: $productSetString");
//String productSetString = splitTestRepository.getSplitTestValue("product_set_5");
//log("ProductSetString: $productSetString");
try {
productSet = int.parse(productSetString);
productSet = 5;
} on Exception catch (e) {
log("Define the right productset! $e");
productSet = 2;
+6
View File
@@ -7,6 +7,7 @@ import 'package:aitrainer_app/service/logging.dart';
import 'package:aitrainer_app/util/session.dart';
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:upgrader/upgrader.dart';
part 'session_event.dart';
part 'session_state.dart';
@@ -30,6 +31,11 @@ class SessionBloc extends Bloc<SessionEvent, SessionState> with Logging {
String lang = AppLanguage().appLocal.languageCode;
log("Change lang to $lang");
settingsBloc!.add(SettingsChangeLanguage(language: lang));
final iTunes = ITunesSearchAPI();
final resultsFuture = iTunes.lookupByBundleId('com.aitrainer.app');
resultsFuture.then((results) {
print('iTunes results: $results');
});
emit(SessionReady());
}
@@ -17,7 +17,7 @@ class TrainingEvaluationBloc extends Bloc<TrainingEvaluationEvent, TrainingEvalu
final String day;
TrainingEvaluationBloc({required this.trainingPlanBloc, required this.day}) : super(TrainingEvaluationInitial()) {
_load();
//on<TrainingEvaluationLoad>(_onLoad);
on<TrainingEvaluationLoad>(_onLoad);
}
String duration = "-";
+3 -2
View File
@@ -1,5 +1,5 @@
import 'dart:io';
//import 'dart:io';
/*
import 'package:sqflite/sqflite.dart';
class DB {
@@ -35,3 +35,4 @@ class DB {
Database getDB() => this._db;
}
*/
+4 -4
View File
@@ -121,7 +121,7 @@ class AnimatedButton extends StatefulWidget {
this.borderWidth = 1,
this.blurColor = Colors.black,
this.shadowColor,
}) : super(key: key);
}) : super(key: key);
@override
_AnimatedButtonState createState() => _AnimatedButtonState(
@@ -145,7 +145,7 @@ class _AnimatedButtonState extends State<AnimatedButton> {
_AnimatedButtonState({
this.type,
this.color,
this.shadowColor,
//this.shadowColor,
this.borderColor,
this.blurColor,
});
@@ -159,14 +159,14 @@ class _AnimatedButtonState extends State<AnimatedButton> {
int index = type!.index;
setState(() {
color = definedColors[index]["color"];
shadowColor = definedColors[index]["shadowColor"];
//shadowColor = definedColors[index]["shadowColor"];
blurColor = definedColors[index]["blurColor"];
borderColor = definedColors[index]["borderColor"];
});
} else {
setState(() {
color = widget.color;
shadowColor = widget.shadowColor;
//shadowColor = widget.shadowColor;
blurColor = widget.blurColor;
borderColor = widget.borderColor;
});
-9
View File
@@ -44,15 +44,6 @@ class ImageCache with Logging {
_images[imageKey] = imageString;
_imageMap[imageKey] = true;
/* final String imageString = await getImageAs64BaseString(id, url);
if (imageString != null) {
_imageMap[imageKey] = imageString;
_imageDown[imageKey] = true;
}
}
_images[imageKey] = imageString;
_imageMap[imageKey] = true; */
}
Future<void> saveImageToPrefs(String key, String value) async {
-1
View File
@@ -1,7 +1,6 @@
library network_image_to_byte;
import 'dart:io';
import 'dart:typed_data';
import 'package:flutter/foundation.dart';
+1 -1
View File
@@ -76,7 +76,7 @@ class __TreeViewDataState extends State<_TreeViewData> {
super.initState();
/// We require the initializers to run after the loading screen is rendered
SchedulerBinding.instance!.addPostFrameCallback((_) {
SchedulerBinding.instance.addPostFrameCallback((_) {
final double cHeight = MediaQuery.of(context).size.height;
subscription = stream.listen((value) {
if (value) {
+69 -84
View File
@@ -1,5 +1,3 @@
// ignore_for_file: must_be_immutable
import 'dart:async';
import 'dart:io';
import 'package:aitrainer_app/bloc/test_set_execute/test_set_execute_bloc.dart';
@@ -48,17 +46,16 @@ import 'package:aitrainer_app/widgets/development_diagram.dart';
import 'package:aitrainer_app/widgets/home.dart';
import 'package:aitrainer_app/library/facebook_app_events/facebook_app_events.dart';
import 'package:firebase_analytics/firebase_analytics.dart';
//import 'package:flurry_data/flurry_data.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:aitrainer_app/util/app_localization.dart';
//import 'package:flutter_uxcam/flutter_uxcam.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:matomo_tracker/matomo_tracker.dart';
import 'package:sentry_flutter/sentry_flutter.dart';
//import 'package:flutter_smartlook/flutter_smartlook.dart';
import 'package:posthog_flutter/posthog_flutter.dart';
import 'package:upgrader/upgrader.dart';
import 'bloc/account/account_bloc.dart';
import 'bloc/body_development/body_development_bloc.dart';
@@ -72,7 +69,8 @@ import 'model/cache.dart';
import 'view/training_evaluation_page.dart';
import 'package:syncfusion_localizations/syncfusion_localizations.dart';
const dsn = 'https://0f635b7225564abc9089f8106f25eb5c@sentry.aitrainer.app/1';
const dsn = 'https://2309523cf2374c089fa1143d19209bc1@glitch.workouttest.org/2';
//const dsn = 'https://be8b4f90398a45e68b6798c32c4e6baf@app.glitchtip.com/1992';
/// Whether the VM is running in debug mode.
///
@@ -99,16 +97,10 @@ Future<Null> _reportError(dynamic error, dynamic stackTrace) async {
}
print('Reporting to Sentry.io...');
final String customerId = Cache().userLoggedIn != null ? Cache().userLoggedIn!.customerId.toString() : "0";
Sentry.configureScope(
(scope) => scope.user = SentryUser(id: customerId),
);
final String platform = Platform.isAndroid ? "Android" : "iOS";
final String version = Cache().packageInfo != null ? Cache().packageInfo!.version + "+" + Cache().packageInfo!.buildNumber : "";
final sentryId =
await Sentry.captureException(error, stackTrace: stackTrace, hint: "Platform: $platform, Version: $version, User: $customerId");
final sentryId = await Sentry.captureException(error, stackTrace: stackTrace);
print('Capture exception result : SentryId : $sentryId');
MatomoTracker.instance.trackEvent(eventCategory: "error", action: error.toString());
print('Track error to Matomo');
}
Future<Null> main() async {
@@ -117,13 +109,31 @@ Future<Null> main() async {
if (isInDebugMode) {
// In development mode simply print to console.
FlutterError.dumpErrorToConsole(details);
} else {
//} else {
// In production mode report to the application zone to report to
// Sentry.
Zone.current.handleUncaughtError(details.exception, details.stack!);
}
};
Future<void> initThirdParty() async {
if (!isInDebugMode) {
await MatomoTracker.instance.initialize(
siteId: 3,
url: 'https://matomo.workouttest.org/matomo.php',
);
Posthog().setContext({
'device': {
'token': 'v1.26 test',
}
});
}
print(" -- FireBase init..");
await FirebaseApi().initializeFlutterFire();
}
// This creates a [Zone] that contains the Flutter application and stablishes
// an error handler that captures errors and reports them.
//
@@ -136,80 +146,54 @@ Future<Null> main() async {
// - https://api.dartlang.org/stable/1.24.2/dart-async/Zone-class.html
// - https://www.dartlang.org/articles/libraries/zones
runZonedGuarded<Future<Null>>(() async {
if (!isInDebugMode) {
await SentryFlutter.init(
(options) {
options.dsn = dsn;
options.release = Cache().packageInfo != null ? Cache().packageInfo!.version + "+" + Cache().packageInfo!.buildNumber : "";
options.enableAutoSessionTracking = true;
},
);
}
Future<void> initThirdParty() async {
if (!isInDebugMode) {
//await FlurryData.initialize(androidKey: "JNYCTCWBT34FM3J8TV36", iosKey: "3QBG7BSMGPDH24S8TRQP", enableLog: true);
await MatomoTracker.instance.initialize(
siteId: 3,
url: 'https://matomo.workouttest.com/matomo.php',
//visitorId: 'customer_1',
);
//FlutterUxcam.optIntoSchematicRecordings();
}
await FirebaseApi().initializeFlutterFire();
}
final WorkoutTreeRepository menuTreeRepository = WorkoutTreeRepository();
WidgetsFlutterBinding.ensureInitialized();
if (!isInDebugMode) {
//FlutterUxcam.startWithKey("wvdstyoml4tiwfd");
//SetupOptions options = (new SetupOptionsBuilder('682883e5cd71a46160c4f6ed070530ee593f49c6')).build();
//Smartlook.setupAndStartRecording(options);
//Smartlook.setEventTrackingMode(EventTrackingMode.FULL_TRACKING);
}
await initThirdParty();
final FirebaseAnalytics analytics = FirebaseAnalytics.instance;
print(" -- FireBase init..");
runApp(MultiBlocProvider(
providers: [
BlocProvider<SessionBloc>(
create: (BuildContext context) => SessionBloc(session: Session()),
),
BlocProvider<MenuBloc>(
create: (BuildContext context) => MenuBloc(menuTreeRepository: menuTreeRepository),
),
BlocProvider<SettingsBloc>(
create: (BuildContext context) => SettingsBloc(context: context),
),
BlocProvider<AccountBloc>(
create: (BuildContext context) => AccountBloc(customerRepository: CustomerRepository()),
),
BlocProvider<ExercisePlanBloc>(
create: (BuildContext context) => ExercisePlanBloc(menuTreeRepository: menuTreeRepository),
),
BlocProvider<DevelopmentByMuscleBloc>(
create: (BuildContext context) => DevelopmentByMuscleBloc(workoutTreeRepository: menuTreeRepository),
),
BlocProvider<BodyDevelopmentBloc>(
create: (BuildContext context) => BodyDevelopmentBloc(workoutTreeRepository: menuTreeRepository),
),
BlocProvider<TimerBloc>(
create: (BuildContext context) => TimerBloc(),
),
BlocProvider<TestSetExecuteBloc>(
create: (BuildContext context) => TestSetExecuteBloc(),
),
BlocProvider<TutorialBloc>(
create: (BuildContext context) => TutorialBloc(tutorialName: ActivityDone.tutorialExecuteFirstTest.toStr())),
BlocProvider<TrainingPlanBloc>(create: (context) {
final MenuBloc menuBloc = BlocProvider.of<MenuBloc>(context);
return TrainingPlanBloc(menuBloc: menuBloc, trainingPlanRepository: TrainingPlanRepository());
}),
],
child: WorkoutTestApp(analytics: analytics),
));
await SentryFlutter.init(
(options) => options
..dsn = dsn
..debug = true,
appRunner: () => runApp(MultiBlocProvider(
providers: [
BlocProvider<SessionBloc>(
create: (BuildContext context) => SessionBloc(session: Session()),
),
BlocProvider<MenuBloc>(
create: (BuildContext context) => MenuBloc(menuTreeRepository: menuTreeRepository),
),
BlocProvider<SettingsBloc>(
create: (BuildContext context) => SettingsBloc(context: context),
),
BlocProvider<AccountBloc>(
create: (BuildContext context) => AccountBloc(customerRepository: CustomerRepository()),
),
BlocProvider<ExercisePlanBloc>(
create: (BuildContext context) => ExercisePlanBloc(menuTreeRepository: menuTreeRepository),
),
BlocProvider<DevelopmentByMuscleBloc>(
create: (BuildContext context) => DevelopmentByMuscleBloc(workoutTreeRepository: menuTreeRepository),
),
BlocProvider<BodyDevelopmentBloc>(
create: (BuildContext context) => BodyDevelopmentBloc(workoutTreeRepository: menuTreeRepository),
),
BlocProvider<TimerBloc>(
create: (BuildContext context) => TimerBloc(),
),
BlocProvider<TestSetExecuteBloc>(
create: (BuildContext context) => TestSetExecuteBloc(),
),
BlocProvider<TutorialBloc>(
create: (BuildContext context) => TutorialBloc(tutorialName: ActivityDone.tutorialExecuteFirstTest.toStr())),
BlocProvider<TrainingPlanBloc>(create: (context) {
final MenuBloc menuBloc = BlocProvider.of<MenuBloc>(context);
return TrainingPlanBloc(menuBloc: menuBloc, trainingPlanRepository: TrainingPlanRepository());
}),
],
child: WorkoutTestApp(analytics: analytics),
)));
}, (error, stackTrace) async {
await _reportError(error, stackTrace);
});
@@ -312,6 +296,7 @@ class WorkoutTestApp extends StatelessWidget {
)),
navigatorObservers: [
FirebaseAnalyticsObserver(analytics: analytics),
//PosthogObserver(),
],
home: AitrainerHome(),
);
+4 -4
View File
@@ -117,8 +117,8 @@ class Cache with Logging {
static final String activeExercisePlanDetailsKey = "active_exercise_details_plan";
static final String myTrainingPlanKey = "myTrainingPlan";
static String baseUrlLive = 'https://aitrainer.info:8943/api/';
static String baseUrlTest = 'https://aitrainer.info:8843/api/';
static String baseUrlLive = 'https://api.workouttest.org/api/';
static String baseUrlTest = 'https://api-test.workouttest.org/api/';
late String baseUrl;
static final String mediaUrl = 'https://admin.aitrainer.app/media/';
static final String username = 'bosi';
@@ -702,8 +702,8 @@ class Cache with Logging {
//Smartlook.setUserIdentifier(customerId.toString());
//Smartlook.instance.
Track().track(TrackingEvent.enter);
MatomoTracker.instance
.trackEvent(eventName: TrackingEvent.enter.enumToString(), eventCategory: "", action: TrackingEvent.enter.enumToString(), eventValue: customerId);
MatomoTracker.instance.setVisitorUserId(customerId.toString());
MatomoTracker.instance.trackEvent(eventCategory: "wt", action: TrackingEvent.enter.enumToString());
}
await Future.forEach(ActivityDone.values, (element) async {
+2 -2
View File
@@ -23,7 +23,7 @@ class CustomerRepository with Logging {
Customer? _trainee;
List<Customer>? _trainees;
List<CustomerProperty>? _properties;
List<CustomerProperty>? _allCustomerProperties;
//List<CustomerProperty>? _allCustomerProperties;
final PropertyRepository propertyRepository = PropertyRepository();
final List<Property> womanSizes = [];
final List<Property> manSizes = [];
@@ -45,7 +45,7 @@ class CustomerRepository with Logging {
isMan = (Cache().userLoggedIn!.sex == "m");
}
_allCustomerProperties = Cache().getCustomerPropertyAll();
//_allCustomerProperties = Cache().getCustomerPropertyAll();
}
String? getGenderByName(String name) {
+32 -24
View File
@@ -5,6 +5,7 @@ import 'package:aitrainer_app/util/common.dart';
import 'package:aitrainer_app/util/not_found_exception.dart';
import 'package:flutter/services.dart';
import 'package:aitrainer_app/model/cache.dart';
import 'package:sentry_flutter/sentry_flutter.dart';
class APIClient with Common, Logging {
static final APIClient _singleton = APIClient._internal();
@@ -45,12 +46,13 @@ class APIClient with Common, Logging {
HttpClientResponse result = await request.close();
client.close();
if (result.statusCode != 200) {
trace("authentication response: ${result.statusCode}");
throw Exception("Network error, try again later!");
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());
await Sentry.captureException(exception);
throw Exception("Network error, try again later!");
}
}
@@ -87,37 +89,43 @@ class APIClient with Common, Logging {
}
} 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);
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();
HttpClient client = new HttpClient();
client.badCertificateCallback = ((X509Certificate cert, String host, int port) => true);
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 {
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 Exception catch (e) {
print("Post Exception: $e");
await Sentry.captureException(e);
throw Exception("Network Error, please try again later");
}
}
+5 -7
View File
@@ -62,10 +62,10 @@ class FirebaseApi with logging.Logging {
badge: true,
sound: true,
);
this.firebaseRegToken = await FirebaseMessaging.instance.getToken();
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!');
@@ -75,7 +75,6 @@ class FirebaseApi with logging.Logging {
print('Message also contained a notification: ${message.notification}');
}
});
} catch (e) {
// Set `_error` state to true if Firebase initialization fails
log("Error initializing Firebase");
@@ -381,11 +380,10 @@ class FirebaseApi with logging.Logging {
Future<void> setupRemoteConfig() async {
//initializeFlutterFire();
RemoteConfig? remoteConfig;
FirebaseRemoteConfig? remoteConfig;
try {
remoteConfig = RemoteConfig.instance;
await remoteConfig.setConfigSettings(
RemoteConfigSettings(
remoteConfig = FirebaseRemoteConfig.instance;
await remoteConfig.setConfigSettings(RemoteConfigSettings(
fetchTimeout: const Duration(seconds: 10),
minimumFetchInterval: const Duration(seconds: 1),
));
+3
View File
@@ -50,6 +50,7 @@ class RevenueCatPurchases with Logging {
log("Trial mode: $inTrial date: ${Cache().userLoggedIn!.trialDate}");
if (Cache().userLoggedIn!.admin == 1 || inTrial || Cache().userLoggedIn!.lifeLong == 1) {
Cache().hasPurchased = true;
log(" -- Purchased -- ");
}
}
@@ -94,6 +95,7 @@ class RevenueCatPurchases with Logging {
PurchaserInfo purchaserInfo = await Purchases.purchasePackage(selectedPackage);
if (purchaserInfo.entitlements.all["wt_subscription"] != null && purchaserInfo.entitlements.all["wt_subscription"]!.isActive) {
Cache().hasPurchased = true;
log(" -- Purchased -- ");
}
} else {
log("!!!! No Selected package to purchase");
@@ -107,6 +109,7 @@ class RevenueCatPurchases with Logging {
if (errorCode == PurchasesErrorCode.invalidReceiptError) {
log("iOS Sandbox invalid receipt");
Cache().hasPurchased = true;
log(" -- Purchased -- ");
return;
}
log(e.toString());
+17 -9
View File
@@ -6,9 +6,7 @@ import 'package:aitrainer_app/util/enums.dart';
import 'package:aitrainer_app/model/tracking.dart' as model;
import 'package:firebase_analytics/firebase_analytics.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
//import 'package:flurry_data/flurry_data.dart';
//import 'package:flutter_uxcam/flutter_uxcam.dart';
//import 'package:flutter_smartlook/flutter_smartlook.dart';
import 'package:posthog_flutter/posthog_flutter.dart';
import 'package:matomo_tracker/matomo_tracker.dart';
class Track with Logging {
@@ -22,12 +20,9 @@ class Track with Logging {
Track._internal();
void track(TrackingEvent event, {String eventValue = ""}) {
model.Tracking tracking = model.Tracking();
tracking.customerId = Cache().userLoggedIn == null ? 0 : Cache().userLoggedIn!.customerId!;
if (!isInDebugMode) {
//FlurryData.logEvent(event.enumToString());
//Smartlook.setGlobalEventProperty(event.toString(), eventValue, false);
//FlutterUxcam.logEventWithProperties(event.enumToString(), {"value": eventValue});
model.Tracking tracking = model.Tracking();
tracking.customerId = Cache().userLoggedIn == null ? 0 : Cache().userLoggedIn!.customerId!;
tracking.event = event.enumToString();
if (eventValue.isNotEmpty) {
tracking.eventValue = eventValue;
@@ -38,7 +33,20 @@ class Track with Logging {
FirebaseMessaging.instance.subscribeToTopic(event.enumToString());
analytics.logEvent(name: event.enumToString(), parameters: {"value": eventValue});
MatomoTracker.instance.trackEvent(eventName: event.enumToString(), eventCategory: "", action: eventValue, eventValue: tracking.customerId);
if (eventValue.isNotEmpty) {
MatomoTracker.instance.trackEvent(eventCategory: "wt", action: event.enumToString(), eventName: eventValue);
} else {
MatomoTracker.instance.trackEvent(eventCategory: "wt", action: event.enumToString());
}
Posthog().capture(
eventName: event.enumToString(),
properties: {
'action': eventValue,
'customer': tracking.customerId,
},
);
}
}
}
+8 -8
View File
@@ -73,7 +73,7 @@ class AccountPage extends StatelessWidget with Trans {
]),
style: TextButton.styleFrom(
backgroundColor: Colors.white38,
onSurface: Colors.grey,
disabledForegroundColor: Colors.grey,
),
onPressed: () => {
if (Cache().userLoggedIn != null)
@@ -94,7 +94,7 @@ class AccountPage extends StatelessWidget with Trans {
]),
style: TextButton.styleFrom(
backgroundColor: Colors.white38,
onSurface: Colors.grey,
disabledForegroundColor: Colors.grey,
),
onPressed: () => {
if (Cache().userLoggedIn != null)
@@ -116,7 +116,7 @@ class AccountPage extends StatelessWidget with Trans {
]),
style: TextButton.styleFrom(
backgroundColor: Colors.white38,
onSurface: Colors.grey,
disabledForegroundColor: Colors.grey,
),
onPressed: () => {
if (Cache().userLoggedIn != null)
@@ -134,7 +134,7 @@ class AccountPage extends StatelessWidget with Trans {
title: TextButton(
style: TextButton.styleFrom(
backgroundColor: Colors.white38,
onSurface: Colors.grey,
disabledForegroundColor: Colors.grey,
),
child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
Text(t(bodyType), style: TextStyle(color: Colors.blue)),
@@ -165,7 +165,7 @@ class AccountPage extends StatelessWidget with Trans {
title: TextButton(
style: TextButton.styleFrom(
backgroundColor: Colors.white38,
onSurface: Colors.grey,
disabledForegroundColor: Colors.grey,
),
child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
Text(t("Available Devices"), style: TextStyle(color: Colors.blue)),
@@ -189,7 +189,7 @@ class AccountPage extends StatelessWidget with Trans {
title: TextButton(
style: TextButton.styleFrom(
backgroundColor: Colors.white38,
onSurface: Colors.grey,
disabledForegroundColor: Colors.grey,
),
child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
Text(t("Trigger message"), style: TextStyle(color: Colors.purple)),
@@ -218,7 +218,7 @@ class AccountPage extends StatelessWidget with Trans {
title: TextButton(
style: TextButton.styleFrom(
backgroundColor: Colors.white38,
onSurface: Colors.grey,
disabledForegroundColor: Colors.grey,
),
child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
Text(t(text), style: TextStyle(color: buttonColor)),
@@ -253,7 +253,7 @@ class AccountPage extends StatelessWidget with Trans {
leading: Icon(Icons.people),
title: ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.white70,
backgroundColor: Colors.white70,
),
onPressed: () => accountBloc.add(AccountGetTrainees()),
child: Text("See my trainees"),
-2
View File
@@ -13,8 +13,6 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart';
import '../bloc/customer_change/customer_change_bloc.dart';
// ignore: must_be_immutable
class CustomerFitnessPage extends StatefulWidget {
late _CustomerFitnessPageState _state;
-2
View File
@@ -11,8 +11,6 @@ import 'package:google_fonts/google_fonts.dart';
import 'package:syncfusion_flutter_gauges/gauges.dart';
import '../bloc/customer_change/customer_change_bloc.dart';
// ignore: must_be_immutable
class CustomerHeightPage extends StatefulWidget {
late _CustomerHeightPageState _state;
-2
View File
@@ -11,8 +11,6 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart';
import '../bloc/customer_change/customer_change_bloc.dart';
// ignore: must_be_immutable
class CustomerSexPage extends StatefulWidget {
late _CustomerSexPageState _state;
-2
View File
@@ -11,8 +11,6 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart';
import '../bloc/customer_change/customer_change_bloc.dart';
// ignore: must_be_immutable
class CustomerWeightPage extends StatefulWidget {
late _CustomerWeightPageState _state;
+2 -2
View File
@@ -59,10 +59,10 @@ class _CustomerWelcomePageState extends State<CustomerWelcomePage> with Trans {
duration: Duration(seconds: 6),
),
SizedBox(
height: 110,
height: 40,
),
CircularPercentIndicator(
radius: 250.0,
radius: 200.0,
animation: true,
animationDuration: 4800,
lineWidth: 20.0,
+2 -2
View File
@@ -327,8 +327,8 @@ class _ExerciseControlPage extends State<ExerciseControlPage> with Trans {
TextButton(
style: TextButton.styleFrom(
padding: EdgeInsets.all(0),
primary: Colors.white,
onSurface: Colors.blueAccent,
foregroundColor: Colors.white,
disabledForegroundColor: Colors.blueAccent,
),
onPressed: () {
exerciseBloc.add(ExerciseControlSubmit(step: step));
+1 -1
View File
@@ -47,7 +47,7 @@ class _MyDevelopmentMuscleState extends State<MyDevelopmentMusclePage> with Comm
}
/// We require the initializers to run after the loading screen is rendered
SchedulerBinding.instance!.addPostFrameCallback((_) {
SchedulerBinding.instance.addPostFrameCallback((_) {
BlocProvider.of<DevelopmentByMuscleBloc>(context).add(DevelopmentByMuscleLoad());
});
}
+10 -5
View File
@@ -66,7 +66,10 @@ class _MyDevelopmentPage extends State<MyDevelopmentPage> with Trans {
text: t("My Training Logs"),
style: GoogleFonts.robotoMono(
textStyle: TextStyle(
fontSize: 14, color: Colors.white, fontWeight: FontWeight.bold, backgroundColor: Colors.black54.withOpacity(0.4))),
fontSize: 14,
color: Colors.white,
fontWeight: FontWeight.bold,
backgroundColor: Colors.black54.withOpacity(0.4))),
image: "asset/image/edzesnaplom400400.jpg",
left: 5,
onTap: () => Navigator.of(context).pushNamed('mydevelopmentLog', arguments: args),
@@ -186,7 +189,8 @@ class _MyDevelopmentPage extends State<MyDevelopmentPage> with Trans {
onTap: () => {Navigator.of(context).pushNamed('mydevelopmentMusclePage', arguments: args)},
isLocked: true,
))),
developmentWidget(imageWidth, t("Development of My Sizes"), "asset/image/sizes_q.jpg", TrackingEvent.my_size_development, args),
developmentWidget(
imageWidth, t("Development of My Sizes"), "asset/image/sizes_q.jpg", TrackingEvent.my_size_development, args),
hiddenWidget(customerRepository, exerciseRepository),
]),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
@@ -207,7 +211,8 @@ class _MyDevelopmentPage extends State<MyDevelopmentPage> with Trans {
textAlignment: Alignment.topLeft,
text: t(title),
style: GoogleFonts.robotoMono(
textStyle: TextStyle(fontSize: 14, color: Colors.white, fontWeight: FontWeight.bold, backgroundColor: Colors.black54.withOpacity(0.4))),
textStyle:
TextStyle(fontSize: 14, color: Colors.white, fontWeight: FontWeight.bold, backgroundColor: Colors.black54.withOpacity(0.4))),
image: imageUrl,
onTap: () => {
if (Cache().userLoggedIn != null)
@@ -240,8 +245,8 @@ class _MyDevelopmentPage extends State<MyDevelopmentPage> with Trans {
return TextButton(
style: TextButton.styleFrom(
padding: EdgeInsets.all(20),
primary: Colors.white,
onSurface: Colors.blueAccent,
backgroundColor: Colors.white,
disabledForegroundColor: Colors.blueAccent,
),
onPressed: () => {
if (Cache().getTrainee() != null)
+8 -7
View File
@@ -43,8 +43,8 @@ class SettingsPage extends StatelessWidget with Trans {
child: Form(
child: BlocConsumer<SettingsBloc, SettingsState>(listener: (context, state) {
if (state is SettingsError) {
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white))));
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white))));
} else if (state is SettingsReady) {
menuBloc.add(MenuRecreateTree());
Navigator.of(context).pushNamed("home");
@@ -193,7 +193,7 @@ class SettingsPage extends StatelessWidget with Trans {
]),
style: TextButton.styleFrom(
backgroundColor: Colors.white70,
onSurface: Colors.grey,
disabledForegroundColor: Colors.grey,
),
onPressed: () => {
Track().track(TrackingEvent.terms_of_use),
@@ -220,7 +220,7 @@ class SettingsPage extends StatelessWidget with Trans {
]),
style: TextButton.styleFrom(
backgroundColor: Colors.white70,
onSurface: Colors.grey,
disabledForegroundColor: Colors.grey,
),
onPressed: () => {
Track().track(TrackingEvent.data_privacy),
@@ -247,7 +247,7 @@ class SettingsPage extends StatelessWidget with Trans {
]),
style: TextButton.styleFrom(
backgroundColor: Colors.white70,
onSurface: Colors.grey,
disabledForegroundColor: Colors.grey,
),
onPressed: () => {
Navigator.of(context).pushNamed("faqPage"),
@@ -290,7 +290,7 @@ class SettingsPage extends StatelessWidget with Trans {
]),
style: TextButton.styleFrom(
backgroundColor: Colors.white70,
onSurface: Colors.grey,
disabledForegroundColor: Colors.grey,
),
onPressed: () => {
launchMailto(),
@@ -311,6 +311,7 @@ class SettingsPage extends StatelessWidget with Trans {
// Use either Dart's string interpolation
// or the toString() method.
print("Mailto: $mailtoLink");
await launch('$mailtoLink');
final Uri _url = Uri.parse("$mailtoLink");
await launchUrl(_url);
}
}
+2 -2
View File
@@ -165,8 +165,8 @@ class TestSetControl extends StatelessWidget with Trans {
TextButton(
style: TextButton.styleFrom(
padding: EdgeInsets.all(0),
primary: Colors.white,
onSurface: Colors.blueAccent,
foregroundColor: Colors.white,
disabledForegroundColor: Colors.blueAccent,
),
onPressed: () => {
bloc.add(TestSetControlSubmit()),
+9 -8
View File
@@ -316,8 +316,8 @@ class TrainingPlanActivatePage extends StatelessWidget with Trans {
getPlanDetails(plan, bloc, dayName),
ElevatedButton(
style: ElevatedButton.styleFrom(
onPrimary: Colors.white,
primary: restricted ? Colors.grey[600] : Colors.orange,
foregroundColor: Colors.white,
backgroundColor: restricted ? Colors.grey[600] : Colors.orange,
),
child: Text(t("Start")),
onPressed: () {
@@ -476,7 +476,8 @@ class TrainingPlanActivatePage extends StatelessWidget with Trans {
return DialogCommon(
title: t("Dropset"),
descriptions: t("A drop set is an advanced resistance training technique "),
description2: t(" in which you focus on completing a set until failure - or the inability to do another repetition."),
description2:
t(" in which you focus on completing a set until failure - or the inability to do another repetition."),
text: "OK",
onTap: () => {
Navigator.of(context).pop(),
@@ -490,7 +491,7 @@ class TrainingPlanActivatePage extends StatelessWidget with Trans {
headerGridLinesVisibility: GridLinesVisibility.both,
gridLinesVisibility: GridLinesVisibility.both,
columns: [
GridTextColumn(
GridColumn(
columnWidthMode: ColumnWidthMode.lastColumnFill,
maximumWidth: 130,
columnName: 'exerciseImage',
@@ -507,7 +508,7 @@ class TrainingPlanActivatePage extends StatelessWidget with Trans {
textAlign: TextAlign.start,
overflow: TextOverflow.ellipsis,
))),
GridTextColumn(
GridColumn(
maximumWidth: 0,
visible: false,
columnName: 'exerciseName',
@@ -520,7 +521,7 @@ class TrainingPlanActivatePage extends StatelessWidget with Trans {
textAlign: TextAlign.start,
overflow: TextOverflow.ellipsis,
))),
GridTextColumn(
GridColumn(
maximumWidth: 60,
columnName: 'Set',
label: Container(
@@ -532,7 +533,7 @@ class TrainingPlanActivatePage extends StatelessWidget with Trans {
style: GoogleFonts.inter(color: Colors.white, fontWeight: FontWeight.bold),
overflow: TextOverflow.ellipsis,
))),
GridTextColumn(
GridColumn(
maximumWidth: 100,
columnWidthMode: ColumnWidthMode.fill,
columnName: 'Repeats',
@@ -545,7 +546,7 @@ class TrainingPlanActivatePage extends StatelessWidget with Trans {
style: GoogleFonts.inter(color: Colors.white, fontWeight: FontWeight.bold),
overflow: TextOverflow.ellipsis,
))),
GridTextColumn(
GridColumn(
maximumWidth: 60,
columnName: 'Weight',
label: Container(
+12 -8
View File
@@ -297,7 +297,7 @@ class _ExerciseListState extends State<ExerciseList> with Trans {
@override
void initState() {
WidgetsBinding.instance!.addPostFrameCallback((_) {
WidgetsBinding.instance.addPostFrameCallback((_) {
animate();
});
super.initState();
@@ -306,7 +306,7 @@ class _ExerciseListState extends State<ExerciseList> with Trans {
@override
void didUpdateWidget(ExerciseList page) {
super.didUpdateWidget(page);
WidgetsBinding.instance!.addPostFrameCallback((_) {
WidgetsBinding.instance.addPostFrameCallback((_) {
animate();
});
}
@@ -333,8 +333,8 @@ class _ExerciseListState extends State<ExerciseList> with Trans {
String description2 = "";
if (next.exerciseTypeId != detail.exerciseTypeId) {
title = AppLocalizations.of(context)!.translate("Stop!");
description =
AppLocalizations.of(context)!.translate("Please continue with the next exercise in the queue:") + next.exerciseType!.nameTranslation;
description = AppLocalizations.of(context)!.translate("Please continue with the next exercise in the queue:") +
next.exerciseType!.nameTranslation;
} else {
final HashMap args = HashMap();
args['exerciseType'] = next.exerciseType;
@@ -388,7 +388,8 @@ class _ExerciseListState extends State<ExerciseList> with Trans {
bloc.getMyPlan()!.days[widget.dayName]!.forEach((element) {
if (prev == null || (prev != null && prev!.exerciseTypeId != element.exerciseTypeId)) {
tiles.add(GestureDetector(
onTap: () => bloc.getNext() != null ? executeExercise(bloc, bloc.getNext()!, context) : Navigator.of(context).pushNamed('home'),
onTap: () =>
bloc.getNext() != null ? executeExercise(bloc, bloc.getNext()!, context) : Navigator.of(context).pushNamed('home'),
child: ExerciseTile(
bloc: bloc,
detail: element,
@@ -543,7 +544,8 @@ class ExerciseTile extends StatelessWidget with Trans {
List<Widget> getExerciseTiles(CustomerTrainingPlanDetails detail) {
final List<Widget> list = [];
if (bloc.alternatives[detail.customerTrainingPlanDetailsId] != null && bloc.alternatives[detail.customerTrainingPlanDetailsId].length > 0) {
if (bloc.alternatives[detail.customerTrainingPlanDetailsId] != null &&
bloc.alternatives[detail.customerTrainingPlanDetailsId].length > 0) {
int index = 0;
for (CustomerTrainingPlanDetails alternative in bloc.alternatives[detail.customerTrainingPlanDetailsId]) {
final Widget widget = getTile(alternative, index);
@@ -563,7 +565,8 @@ class ExerciseTile extends StatelessWidget with Trans {
final int step = bloc.getStep(detail);
final int highlightStep = bloc.getHighlightStep(detail);
final bool hasLeftAlternative = detail.alternatives.length > 0 && index > 0;
final bool hasRightAlternative = detail.alternatives.length > 0 && index + 1 < bloc.alternatives[detail.customerTrainingPlanDetailsId].length;
final bool hasRightAlternative =
detail.alternatives.length > 0 && index + 1 < bloc.alternatives[detail.customerTrainingPlanDetailsId].length;
return Container(
child: Stack(alignment: Alignment.centerRight, children: [
@@ -598,7 +601,8 @@ class ExerciseTile extends StatelessWidget with Trans {
context: context,
builder: (BuildContext context) {
return DialogHTML(
title: detail.exerciseType!.nameTranslation, htmlData: '<p>' + detail.exerciseType!.descriptionTranslation + '</p>');
title: detail.exerciseType!.nameTranslation,
htmlData: '<p>' + detail.exerciseType!.descriptionTranslation + '</p>');
}),
icon: Icon(
Icons.info_outline,
@@ -38,7 +38,7 @@ class _BottomBarMultipleExercisesState extends State<BottomBarMultipleExercises>
@override
void initState() {
super.initState();
SchedulerBinding.instance!.addPostFrameCallback((_) {
SchedulerBinding.instance.addPostFrameCallback((_) {
_controller = ScrollController();
});
}
+8 -5
View File
@@ -209,12 +209,12 @@ class _ExerciseSaveState extends State<ExerciseSave> with Trans {
});
}
SchedulerBinding.instance!.addPostFrameCallback((_) {
SchedulerBinding.instance.addPostFrameCallback((_) {
subscription = stream.listen((event) {
//_controller1.text = ExerciseSaveStream().weight.toStringAsFixed(0);
_controller2.text = ExerciseSaveStream().repeats.toStringAsFixed(0);
});
print("ExerciseSave weight ${widget.weight}");
//print("ExerciseSave weight ${widget.weight}");
_controller1.text = widget.weight == null || widget.weight == -1
? "TEST"
: widget.weight! % widget.weight!.round() == 0
@@ -633,7 +633,8 @@ class _ExerciseSaveState extends State<ExerciseSave> with Trans {
padding: const EdgeInsets.all(2),
color: Colors.white70,
onPressed: () async {
stopWatchTimer.onExecute.add(StopWatchExecute.start);
//stopWatchTimer.onExecute.add(StopWatchExecute.start);
stopWatchTimer.onStartTimer();
Wakelock.enable(); // prevent sleep the phone
},
icon: Icon(CustomIcon.play_1),
@@ -647,7 +648,8 @@ class _ExerciseSaveState extends State<ExerciseSave> with Trans {
iconSize: 40,
color: Colors.white70,
onPressed: () async {
stopWatchTimer.onExecute.add(StopWatchExecute.stop);
//stopWatchTimer.onExecute.add(StopWatchExecute.stop);
stopWatchTimer.onStartTimer();
Wakelock.disable();
},
icon: Icon(CustomIcon.stop),
@@ -660,7 +662,8 @@ class _ExerciseSaveState extends State<ExerciseSave> with Trans {
iconSize: 40,
color: Colors.white70,
onPressed: () async {
stopWatchTimer.onExecute.add(StopWatchExecute.reset);
//stopWatchTimer.onExecute.add(StopWatchExecute.reset);
stopWatchTimer.onResetTimer();
},
icon: Icon(CustomIcon.creative_commons_zero),
),
+10 -4
View File
@@ -2,7 +2,6 @@ import 'package:aitrainer_app/bloc/session/session_bloc.dart';
import 'package:aitrainer_app/bloc/settings/settings_bloc.dart';
import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/service/logging.dart';
import 'package:aitrainer_app/util/app_language.dart';
import 'package:aitrainer_app/util/trans.dart';
import 'package:aitrainer_app/view/customer_goal_page.dart';
import 'package:aitrainer_app/view/login.dart';
@@ -12,6 +11,7 @@ import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:matomo_tracker/matomo_tracker.dart';
import 'package:upgrader/upgrader.dart';
import 'loading.dart';
@@ -25,15 +25,21 @@ class AitrainerHome extends StatefulWidget {
}
}
class _HomePageState extends State<AitrainerHome> with Logging, Trans {
class _HomePageState extends State<AitrainerHome> with Logging, Trans, TraceableClientMixin {
GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
@override
String get traceName => 'Home';
@override
String get traceTitle => this.widget.toString();
@override
void initState() {
super.initState();
/// We require the initializers to run after the loading screen is rendered
SchedulerBinding.instance!.addPostFrameCallback((_) {
SchedulerBinding.instance.addPostFrameCallback((_) {
runDelayedEvent();
});
@@ -70,7 +76,7 @@ class _HomePageState extends State<AitrainerHome> with Logging, Trans {
return Scaffold(
key: _scaffoldKey,
body: UpgradeAlert(
upgrader: Upgrader(appcastConfig: cfg, messages: MyLocalizedUpgraderMessages(context: context)),
upgrader: Upgrader(appcastConfig: cfg, messages: MyLocalizedUpgraderMessages(context: context)),
child: BlocConsumer<SessionBloc, SessionState>(listener: (context, state) {
if (state is SessionFailure) {
showDialog(
+4 -4
View File
@@ -174,8 +174,8 @@ class _InputDialogState<Event> extends State<InputDialog<Event>> with Trans {
children: <Widget>[
ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.black26,
onSurface: Colors.white,
backgroundColor: Colors.black26,
disabledBackgroundColor: Colors.white,
),
onPressed: () {
Navigator.of(context).pop();
@@ -187,8 +187,8 @@ class _InputDialogState<Event> extends State<InputDialog<Event>> with Trans {
),
ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.orange[600],
onSurface: Colors.white,
backgroundColor: Colors.orange[600],
disabledForegroundColor: Colors.white,
),
onPressed: () {
widget.onChanged(this.inputValue);
+10 -6
View File
@@ -5,7 +5,6 @@ import 'package:aitrainer_app/bloc/menu/menu_bloc.dart';
import 'package:aitrainer_app/repository/training_plan_repository.dart';
import 'package:aitrainer_app/util/enums.dart';
import 'package:aitrainer_app/util/track.dart';
import 'package:aitrainer_app/widgets/dialog_trial.dart';
import 'package:aitrainer_app/widgets/menu_image.dart';
import 'package:aitrainer_app/widgets/menu_search_bar.dart';
import 'package:aitrainer_app/util/app_language.dart';
@@ -55,7 +54,7 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
}
/// We require the initializers to run after the loading screen is rendered
SchedulerBinding.instance!.addPostFrameCallback((_) {
SchedulerBinding.instance.addPostFrameCallback((_) {
menuBloc.add(MenuCreate());
});
@@ -112,7 +111,9 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
return Stack(children: [
CustomScrollView(
controller: scrollController, scrollDirection: Axis.vertical, slivers: buildMenuColumn(widget.parent!, context, menuBloc, cWidth, cHeight)),
controller: scrollController,
scrollDirection: Axis.vertical,
slivers: buildMenuColumn(widget.parent!, context, menuBloc, cWidth, cHeight)),
]);
}
@@ -134,7 +135,8 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
padding: EdgeInsets.only(top: 15.0),
child: Center(
child: Stack(alignment: Alignment.bottomLeft, children: [
Text(AppLocalizations.of(context)!.translate("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) {
@@ -395,8 +397,10 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
dynamic getShape(WorkoutMenuTree workoutTree) {
bool base = workoutTree.base;
dynamic returnCode = (base == true)
? RoundedRectangleBorder(side: BorderSide(width: 6, color: Colors.orangeAccent), borderRadius: BorderRadius.all(Radius.circular(24.0)))
: RoundedRectangleBorder(side: BorderSide(width: 1, color: Colors.transparent), borderRadius: BorderRadius.all(Radius.circular(8.0)));
? RoundedRectangleBorder(
side: BorderSide(width: 6, color: Colors.orangeAccent), borderRadius: BorderRadius.all(Radius.circular(24.0)))
: RoundedRectangleBorder(
side: BorderSide(width: 1, color: Colors.transparent), borderRadius: BorderRadius.all(Radius.circular(8.0)));
return returnCode;
}
+3 -3
View File
@@ -178,7 +178,7 @@ class TutorialWidget with Trans, Logging {
children: [
ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.transparent,
backgroundColor: Colors.transparent,
),
onPressed: () => {bloc.add(TutorialNext(text: bloc.checks[0]))},
child: Text("« " + t(bloc.checks[0]),
@@ -186,7 +186,7 @@ class TutorialWidget with Trans, Logging {
),
ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.transparent,
backgroundColor: Colors.transparent,
),
onPressed: () => {bloc.add(TutorialNext(text: bloc.checks[1]))},
child: Text(t(bloc.checks[1]) + " »",
@@ -196,7 +196,7 @@ class TutorialWidget with Trans, Logging {
)
: ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.transparent,
backgroundColor: Colors.transparent,
),
onPressed: () => {
//tooltip!.rebuild(context),
+1 -1
View File
@@ -16,7 +16,7 @@ class _VictoryConfettiState extends State<VictoryConfetti> {
@override
void initState() {
_controllerBottomCenter = ConfettiController(duration: const Duration(seconds: 2));
SchedulerBinding.instance!.addPostFrameCallback((_) {
SchedulerBinding.instance.addPostFrameCallback((_) {
Future.delayed(Duration(milliseconds: 500)).then((value) => _controllerBottomCenter.play());
});
super.initState();