305 lines
14 KiB
Dart
305 lines
14 KiB
Dart
import 'dart:async';
|
|
import 'dart:io';
|
|
import 'package:aitrainer_app/bloc/test_set_execute/test_set_execute_bloc.dart';
|
|
import 'package:aitrainer_app/bloc/training_plan/training_plan_bloc.dart';
|
|
import 'package:aitrainer_app/bloc/tutorial/tutorial_bloc.dart';
|
|
import 'package:aitrainer_app/repository/customer_repository.dart';
|
|
import 'package:aitrainer_app/repository/training_plan_repository.dart';
|
|
import 'package:aitrainer_app/repository/workout_tree_repository.dart';
|
|
import 'package:aitrainer_app/service/firebase_api.dart';
|
|
import 'package:aitrainer_app/util/session.dart';
|
|
import 'package:aitrainer_app/view/account.dart';
|
|
import 'package:aitrainer_app/view/customer_bodytype_animation.dart';
|
|
import 'package:aitrainer_app/view/customer_exercise_device.dart';
|
|
import 'package:aitrainer_app/view/customer_fitness_page.dart';
|
|
import 'package:aitrainer_app/view/customer_goal_page.dart';
|
|
import 'package:aitrainer_app/view/customer_height_page.dart';
|
|
import 'package:aitrainer_app/view/customer_modify_page.dart';
|
|
import 'package:aitrainer_app/view/customer_sex_page.dart';
|
|
import 'package:aitrainer_app/view/customer_weight_page.dart';
|
|
import 'package:aitrainer_app/view/customer_welcome_page.dart';
|
|
import 'package:aitrainer_app/view/evaluation_page.dart';
|
|
import 'package:aitrainer_app/view/exercise_control_page.dart';
|
|
import 'package:aitrainer_app/view/faq_page.dart';
|
|
import 'package:aitrainer_app/view/login.dart';
|
|
import 'package:aitrainer_app/view/exercise_new_page.dart';
|
|
import 'package:aitrainer_app/view/mydevelopment_log.dart';
|
|
import 'package:aitrainer_app/view/training_plan_custom.dart';
|
|
import 'package:aitrainer_app/view/training_plan_custom_add.dart';
|
|
import 'package:aitrainer_app/view/training_plan_execute.dart';
|
|
import 'package:aitrainer_app/view/training_plans_page.dart';
|
|
import 'package:aitrainer_app/view/mydevelopment_body_page.dart';
|
|
import 'package:aitrainer_app/view/mydevelopment_muscle_page.dart';
|
|
import 'package:aitrainer_app/view/mydevelopment_page.dart';
|
|
import 'package:aitrainer_app/view/mydevelopment_sizes_page.dart';
|
|
import 'package:aitrainer_app/view/registration.dart';
|
|
import 'package:aitrainer_app/view/reset_password.dart';
|
|
import 'package:aitrainer_app/view/sales_page.dart';
|
|
import 'package:aitrainer_app/view/settings.dart';
|
|
import 'package:aitrainer_app/view/test_set_control.dart';
|
|
import 'package:aitrainer_app/view/test_set_edit.dart';
|
|
import 'package:aitrainer_app/view/test_set_execute.dart';
|
|
import 'package:aitrainer_app/view/test_set_new.dart';
|
|
import 'package:aitrainer_app/view/training_plan_activate_page.dart';
|
|
import 'package:aitrainer_app/view/training_plan_exercise.dart';
|
|
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: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:google_fonts/google_fonts.dart';
|
|
import 'package:matomo_tracker/matomo_tracker.dart';
|
|
import 'package:sentry_flutter/sentry_flutter.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';
|
|
import 'bloc/development_by_muscle/development_by_muscle_bloc.dart';
|
|
import 'bloc/exercise_plan/exercise_plan_bloc.dart';
|
|
import 'bloc/menu/menu_bloc.dart';
|
|
import 'bloc/session/session_bloc.dart';
|
|
import 'bloc/settings/settings_bloc.dart';
|
|
import 'bloc/timer/timer_bloc.dart';
|
|
import 'model/cache.dart';
|
|
import 'view/training_evaluation_page.dart';
|
|
import 'package:syncfusion_localizations/syncfusion_localizations.dart';
|
|
|
|
const dsn = 'https://2309523cf2374c089fa1143d19209bc1@glitch.workouttest.org/2';
|
|
//const dsn = 'https://be8b4f90398a45e68b6798c32c4e6baf@app.glitchtip.com/1992';
|
|
|
|
/// Whether the VM is running in debug mode.
|
|
///
|
|
/// This is useful to decide whether a report should be sent to sentry. Usually
|
|
/// reports from dev mode are not very useful, as these happen on developers'
|
|
/// workspaces rather than on users' devices in production.
|
|
bool get isInDebugMode {
|
|
bool inDebugMode = false;
|
|
assert(inDebugMode = true);
|
|
return inDebugMode;
|
|
}
|
|
|
|
/// Reports [error] along with its [stackTrace] to Sentry.io.
|
|
Future<Null> _reportError(dynamic error, dynamic stackTrace) async {
|
|
print('Caught error: $error');
|
|
|
|
// Errors thrown in development mode are unlikely to be interesting. You can
|
|
// check if you are running in dev mode using an assertion and omit sending
|
|
// the report.
|
|
if (isInDebugMode) {
|
|
print(stackTrace);
|
|
print('In dev mode. Not sending report to Sentry.io.');
|
|
return;
|
|
}
|
|
|
|
print('Reporting to Sentry.io...');
|
|
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 {
|
|
// This captures errors reported by the Flutter framework.
|
|
FlutterError.onError = (FlutterErrorDetails details) async {
|
|
if (isInDebugMode) {
|
|
// In development mode simply print to console.
|
|
FlutterError.dumpErrorToConsole(details);
|
|
//} 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.
|
|
//
|
|
// Using a zone makes sure that as many errors as possible are captured,
|
|
// including those thrown from [Timer]s, microtasks, I/O, and those forwarded
|
|
// from the `FlutterError` handler.
|
|
//
|
|
// More about zones:
|
|
//
|
|
// - https://api.dartlang.org/stable/1.24.2/dart-async/Zone-class.html
|
|
// - https://www.dartlang.org/articles/libraries/zones
|
|
runZonedGuarded<Future<Null>>(() async {
|
|
final WorkoutTreeRepository menuTreeRepository = WorkoutTreeRepository();
|
|
WidgetsFlutterBinding.ensureInitialized();
|
|
|
|
await initThirdParty();
|
|
final FirebaseAnalytics analytics = FirebaseAnalytics.instance;
|
|
|
|
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);
|
|
});
|
|
}
|
|
|
|
class WorkoutTestApp extends StatelessWidget {
|
|
final FirebaseAnalytics analytics;
|
|
|
|
const WorkoutTestApp({required this.analytics});
|
|
|
|
static final facebookAppEvents = FacebookAppEvents();
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
|
|
Upgrader().installAppStoreListingURL(Platform.isAndroid
|
|
? "https://play.google.com/store/apps/details?id=com.aitrainer.aitrainer_app"
|
|
: "https://apps.apple.com/hu/app/workouttest/id1515271425");
|
|
//Upgrader().installAppStoreVersion("1.1.19");
|
|
// On iOS, the default behavior will be to use the App Store version of
|
|
// the app, so update the Bundle Identifier in example/ios/Runner with a
|
|
// valid identifier already in the App Store.
|
|
|
|
//facebookAppEvents.setAdvertiserTracking(enabled: true);
|
|
|
|
return MaterialApp(
|
|
localizationsDelegates: [
|
|
// ... app-specific localization delegate[s] here
|
|
AppLocalizations.delegate,
|
|
GlobalMaterialLocalizations.delegate,
|
|
GlobalCupertinoLocalizations.delegate,
|
|
SfGlobalLocalizations.delegate
|
|
],
|
|
supportedLocales: [
|
|
const Locale('en', "US"), // English
|
|
const Locale('hu', "HU"), // Hungarian
|
|
// ... other locales the app supports
|
|
],
|
|
localeResolutionCallback: (Locale? locale, Iterable<Locale> supportedLocales) {
|
|
//myLocale = deviceLocale ;
|
|
// here you make your app language similar to device language ,
|
|
// but you should check whether the localization is supported by your app
|
|
Locale realSupportedLocale = Locale('en', "US");
|
|
supportedLocales.forEach((supportedLocale) {
|
|
if (locale != null && supportedLocale.countryCode == locale.countryCode) {
|
|
realSupportedLocale = supportedLocale;
|
|
}
|
|
});
|
|
if (locale != null && realSupportedLocale.countryCode != locale.countryCode) {
|
|
//print ("Locale " + locale.countryCode + " not supported on this device :(");
|
|
}
|
|
return realSupportedLocale;
|
|
},
|
|
routes: {
|
|
'home': (context) => AitrainerHome(),
|
|
'customerModifyPage': (context) => CustomerModifyPage(),
|
|
'customerGoalPage': (context) => CustomerGoalPage(),
|
|
'customerFitnessPage': (context) => CustomerFitnessPage(),
|
|
'customerSexPage': (context) => CustomerSexPage(),
|
|
'customerWeightPage': (context) => CustomerWeightPage(),
|
|
'customerHeightPage': (context) => CustomerHeightPage(),
|
|
'customerBodyTypePage': (context) => CustomerBodyTypeAnimationPage(),
|
|
'customerWelcomePage': (context) => CustomerWelcomePage(),
|
|
'customerExerciseDevicePage': (context) => CustomerExerciseDevicePage(),
|
|
'exerciseNewPage': (context) => ExerciseNewPage(),
|
|
'exerciseControlPage': (context) => ExerciseControlPage(),
|
|
'login': (context) => LoginPage(),
|
|
'resetPassword': (context) => ResetPasswordPage(),
|
|
'registration': (context) => RegistrationPage(),
|
|
'account': (context) => AccountPage(),
|
|
'settings': (context) => SettingsPage(),
|
|
'myDevelopment': (context) => MyDevelopmentPage(),
|
|
'mydevelopmentLog': (context) => MyDevelopmentLog(),
|
|
'mydevelopmentMusclePage': (context) => MyDevelopmentMusclePage(),
|
|
'mydevelopmentBodyPage': (context) => MyDevelopmentBodyPage(),
|
|
'mydevelopmentSizesPage': (context) => SizesDevelopmentPage(),
|
|
'developmentDiagramPage': (context) => DevelopmentDiagram(),
|
|
'evaluationPage': (context) => EvaluationPage(),
|
|
'salesPage': (context) => SalesPage(),
|
|
'testSetEdit': (context) => TestSetEdit(),
|
|
'testSetExecute': (context) => TestSetExecute(),
|
|
'testSetNew': (context) => TestSetNew(),
|
|
'testSetControl': (context) => TestSetControl(),
|
|
'faqPage': (context) => FaqPage(),
|
|
'myTrainingPlans': (context) => MyTrainingPlans(),
|
|
'myTrainingPlanCustom': (context) => TrainingPlanCustomPage(),
|
|
'myTrainingPlanCustomAdd': (context) => TrainingPlanCustomAddPage(),
|
|
'myTrainingPlanActivate': (context) => TrainingPlanActivatePage(),
|
|
'myTrainingPlanExecute': (context) => TrainingPlanExecute(),
|
|
'myTrainingPlanExercise': (context) => TrainingPlanExercise(),
|
|
'myTrainingEvaluation': (context) => TrainingEvaluationPage(),
|
|
},
|
|
initialRoute: 'home',
|
|
title: 'WorkoutTest',
|
|
theme: ThemeData(
|
|
brightness: Brightness.light,
|
|
//primarySwatch: Colors.transparent,
|
|
//fontFamily: 'Arial',
|
|
textTheme: TextTheme(
|
|
bodyText1: GoogleFonts.inter(textStyle: TextStyle(fontSize: 14.0)),
|
|
)),
|
|
navigatorObservers: [
|
|
FirebaseAnalyticsObserver(analytics: analytics),
|
|
//PosthogObserver(),
|
|
],
|
|
home: AitrainerHome(),
|
|
);
|
|
}
|
|
}
|