import 'dart:collection'; import 'dart:ui'; import 'package:aitrainer_app/bloc/tutorial/tutorial_bloc.dart'; import 'package:aitrainer_app/widgets/tutorial_widget.dart'; import 'package:intl/intl.dart'; import 'package:aitrainer_app/bloc/result/result_bloc.dart'; import 'package:aitrainer_app/util/app_language.dart'; import 'package:aitrainer_app/model/cache.dart'; import 'package:aitrainer_app/model/exercise.dart'; import 'package:aitrainer_app/model/exercise_ability.dart'; import 'package:aitrainer_app/model/exercise_type.dart'; import 'package:aitrainer_app/repository/exercise_repository.dart'; import 'package:aitrainer_app/repository/exercise_result_repository.dart'; import 'package:aitrainer_app/util/trans.dart'; import 'package:aitrainer_app/widgets/app_bar_min.dart'; import 'package:aitrainer_app/widgets/bottom_nav.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:aitrainer_app/model/result.dart'; import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart'; // ignore: must_be_immutable class EvaluationPage extends StatelessWidget with Trans { bool noRegistration = false; @override Widget build(BuildContext context) { dynamic arguments = ModalRoute.of(context)!.settings.arguments; ExerciseRepository exerciseRepository; if (arguments is LinkedHashMap) { exerciseRepository = arguments['exerciseRepository']; } else { exerciseRepository = ExerciseRepository(); } final TutorialBloc bloc = BlocProvider.of(context); noRegistration = bloc.actualCheck == "directTest"; ResultType resultType = ResultType.none; String imageUrl = ""; if (Cache().userLoggedIn == null) { imageUrl = 'asset/image/WT_Results_for_men.jpg'; } else if (Cache().userLoggedIn!.sex == "m") { resultType = ResultType.man; imageUrl = 'asset/image/WT_Results_for_men.jpg'; } else { resultType = ResultType.man; imageUrl = 'asset/image/WT_Results_for_female.jpg'; } if (arguments['past'] != null && arguments['past'] == true) { Exercise? exercise = arguments['exercise']; if (exercise != null) { ExerciseType exerciseType = exerciseRepository.getExerciseTypeById(exercise.exerciseTypeId!) as ExerciseType; exerciseRepository.exerciseType = exerciseType; exerciseRepository.exercise = exercise; String exerciseDate = DateFormat("yyyy-MM-dd", AppLanguage().appLocal.toString()).format(exercise.dateAdd!); exerciseRepository.getSameExercise(exercise.exerciseTypeId!, exerciseDate); } } if (exerciseRepository.exerciseType!.getAbility().equalsTo(ExerciseAbility.running)) { resultType = ResultType.running; imageUrl = 'asset/image/WT_Results_for_runners.jpg'; } final TutorialBloc tutorialBloc = BlocProvider.of(context); print("Evaluation page tutorial isActive? ${tutorialBloc.isActive} ${exerciseRepository.exercise!.quantity}"); if (tutorialBloc.isActive == false) { TutorialWidget().close(); } setContext(context); return Scaffold( appBar: AppBarMin( back: true, ), body: Container( height: double.infinity, width: double.infinity, alignment: Alignment.center, decoration: BoxDecoration( image: DecorationImage( image: AssetImage(imageUrl), fit: BoxFit.cover, alignment: Alignment.topCenter, ), ), child: BlocProvider( create: (context) => ResultBloc( resultRepository: ExerciseResultRepository(resultType: resultType), exerciseRepository: exerciseRepository, context: context), child: BlocConsumer(listener: (context, state) { if (state is ResultError) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(backgroundColor: Colors.orange, content: Text(state.error, style: TextStyle(color: Colors.white)))); } }, builder: (context, state) { final resultBloc = BlocProvider.of(context); return ModalProgressHUD( child: getEvaluationWidgets(resultBloc), inAsyncCall: state is ResultLoading, opacity: 0.5, color: Colors.black54, progressIndicator: CircularProgressIndicator(), ); }))), bottomNavigationBar: BottomNavigator(bottomNavIndex: 0)); } Widget getEvaluationWidgets(ResultBloc resultBloc) { String exerciseName = AppLanguage().appLocal == Locale("en") ? resultBloc.exerciseRepository.exerciseType!.name : resultBloc.exerciseRepository.exerciseType!.nameTranslation; String? volume, volumeEver, oneRepMax, oneRepMaxEver; if (resultBloc.exerciseRepository.actualExerciseList![0].unitQuantity != null) { oneRepMax = resultBloc.exerciseRepository.calculate1RM(resultBloc.exerciseRepository.actualExerciseList![0]).toStringAsFixed(1) + " " + t("kg"); volume = (resultBloc.exerciseRepository.actualExerciseList![0].quantity! * resultBloc.exerciseRepository.actualExerciseList![0].unitQuantity!) .toStringAsFixed(0) + " " + t("kg"); volumeEver = resultBloc.exerciseRepository.getBestVolume(resultBloc.exerciseRepository.actualExerciseList![0]).toStringAsFixed(0) + " " + t("kg"); oneRepMaxEver = resultBloc.exerciseRepository.getBest1RM(resultBloc.exerciseRepository.actualExerciseList![0]).toStringAsFixed(1) + " " + t("kg"); } return Container( padding: EdgeInsets.only(left: 10, right: 10), child: CustomScrollView(scrollDirection: Axis.vertical, slivers: [ SliverAppBar( pinned: true, backgroundColor: Colors.transparent, expandedHeight: 100.0, collapsedHeight: 100, toolbarHeight: 40, automaticallyImplyLeading: false, flexibleSpace: FlexibleSpaceBar( title: Text(exerciseName, textAlign: TextAlign.center, maxLines: 3, //softWrap: true, style: GoogleFonts.archivoBlack( fontSize: 28, color: Colors.orange[300], shadows: [ 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, ), ], )), ), ), //getResultSummary(resultBloc), SliverList( delegate: SliverChildListDelegate([ getEvaluationWidget(resultBloc), getSummary(resultBloc), Divider(), summaryRow("asset/image/pict_time_h.png", "Start of the Exercise", DateFormat('y-M-d HH:mm', AppLanguage().appLocal.toString()).format(resultBloc.exerciseRepository.start!)), Divider(), oneRepMax != null ? summaryRow("asset/image/pict_1rm.png", "Your One Rep Max", oneRepMax) : Offstage(), Divider(), resultBloc.exerciseRepository.actualExerciseList![0].unitQuantity != null ? summaryRow("asset/image/pict_weight_volumen_tonna.png", "Total Lift", volume!) : Offstage(), Divider(), resultBloc.exerciseRepository.actualExerciseList![0].unitQuantity != null ? summaryRow("asset/image/pict_history.png", "Total Lift Ever", volumeEver!) : Offstage(), Divider(), resultBloc.exerciseRepository.actualExerciseList![0].unitQuantity != null ? summaryRow("asset/image/pict_1rm.png", "Your One Rep Max Ever", oneRepMaxEver!) : Offstage(), ])), cta(resultBloc), getSuggestionTitle(resultBloc), getSuggestion(resultBloc), //emptySliver(), //getResultTitle(resultBloc), //getResults(resultBloc), ])); } Widget getEvaluationWidget(ResultBloc bloc) { List resultList = []; print("Act ${bloc.exerciseRepository.actualExerciseList}"); if (bloc.exerciseRepository.actualExerciseList == null || bloc.exerciseRepository.actualExerciseList!.isEmpty) { return Offstage(); } final int exerciseTypeId = bloc.exerciseRepository.actualExerciseList![0].exerciseTypeId!; final double quantity = bloc.exerciseRepository.actualExerciseList![0].quantity!; String eval = bloc.evaluationRepository.getEvaluationTextByExerciseType(exerciseTypeId, quantity); Color color = bloc.evaluationRepository.getEvaluationColor(eval); //if (!EvaluationText.fair.equalsStringTo(eval)) { resultList.add(RichText( text: TextSpan( style: GoogleFonts.inter( fontSize: 24, fontWeight: FontWeight.bold, color: Colors.white, ), children: [ TextSpan(text: t("Your result is") + ": "), TextSpan( text: t(eval), style: GoogleFonts.archivoBlack( fontWeight: FontWeight.bold, color: color, ), ), ]), )); resultList.add(Divider(color: Colors.transparent)); //} return Column(children: resultList); } Widget cta(ResultBloc resultBloc) { return SliverList( delegate: SliverChildListDelegate( ctaSales(resultBloc), ), ); } List ctaSales(ResultBloc resultBloc) { final List resultList = []; if (this.noRegistration) { resultList.add(Divider()); resultList.add(RichText( text: TextSpan( style: GoogleFonts.inter( fontSize: 16, fontWeight: FontWeight.normal, color: Colors.white, ), children: [ TextSpan( text: t('Reach all basic functions, suggestions and'), style: GoogleFonts.inter( color: Colors.white, ), ), TextSpan(text: " "), TextSpan( text: t('optimized training plans, customized to your fitness state and strength:'), style: GoogleFonts.inter( color: Colors.white, ), ), ]))); resultList.add( TextButton( onPressed: () => Navigator.of(context).pushNamed("registration"), child: Stack( alignment: Alignment.center, children: [ Image.asset('asset/icon/gomb_orange_a.png', width: 140, height: 60), Text( t("Register"), style: GoogleFonts.inter( fontSize: 20, fontWeight: FontWeight.bold, color: Colors.white, ), ), ], ), ), ); } else { if (!Cache().hasPurchased) { resultList.add(Divider()); resultList.add(Divider()); resultList.add(RichText( text: TextSpan( style: GoogleFonts.inter( fontSize: 20, fontWeight: FontWeight.normal, color: Colors.white, ), children: [ TextSpan( text: t('How can serve you this result?'), style: GoogleFonts.inter( color: Colors.white, ), ), ]), )); resultList.add(RichText( text: TextSpan( style: GoogleFonts.inter( fontSize: 20, fontWeight: FontWeight.normal, color: Colors.white, ), children: [ TextSpan( text: t('Get the Fastlane to your'), style: GoogleFonts.inter( fontWeight: FontWeight.bold, color: Colors.white, ), ), ]), )); resultList.add(RichText( text: TextSpan( style: GoogleFonts.inter( fontSize: 20, fontWeight: FontWeight.normal, color: Colors.white, ), children: [ TextSpan( text: t('Development'), style: GoogleFonts.inter( fontWeight: FontWeight.bold, color: Colors.yellow[300], ), ) ]))); resultList.add(TextButton( onPressed: () => {Navigator.of(context).pushNamed("salesPage")}, child: Stack( alignment: Alignment.center, children: [ Image.asset('asset/icon/gomb_orange_a.png', width: 140, height: 60), Text( t("Go"), style: GoogleFonts.inter( fontSize: 20, fontWeight: FontWeight.bold, color: Colors.white, ), ), ], ), )); } } return resultList; } Widget summaryRow(String imageUrl, String title, String data) { return Row( children: [ Image.asset( imageUrl, height: 40, ), SizedBox( width: 10, ), Flexible( fit: FlexFit.tight, flex: 1, child: Text(t(title), textAlign: TextAlign.start, maxLines: 2, softWrap: true, style: GoogleFonts.archivoBlack( fontSize: 18, color: Colors.orange[400], shadows: [ 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, ), ], ))), SizedBox( width: 10, ), Text(data, textAlign: TextAlign.center, maxLines: 2, softWrap: true, style: GoogleFonts.archivoBlack( fontSize: 20, color: Colors.white, shadows: [ 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, ), ], )) ], ); } Widget getSuggestionTitle(ResultBloc resultBloc) { if (resultBloc.exerciseRepository.exerciseType!.unitQuantityUnit != null) { return SliverList( delegate: SliverChildListDelegate( [ Divider(color: Colors.transparent), Divider(color: Colors.transparent), Text(t("Suggestions based on your test"), textAlign: TextAlign.center, maxLines: 2, softWrap: true, style: GoogleFonts.archivoBlack( fontSize: 20, color: Colors.yellow[300], shadows: [ 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, ), ], )), ], ), ); } else return emptySliver(); } Widget getResultTitle(ResultBloc resultBloc) { return SliverList( delegate: SliverChildListDelegate( [ Divider(color: Colors.transparent), Divider(color: Colors.transparent), Text(t("Health Data Summary"), textAlign: TextAlign.center, maxLines: 2, softWrap: true, style: GoogleFonts.archivoBlack( fontSize: 20, color: Colors.yellow[300], shadows: [ 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, ), ], )), Divider(), ], ), ); } Widget getSuggestion(ResultBloc resultBloc) { if (resultBloc.exerciseRepository.exerciseType!.unitQuantityUnit != null) { return SliverList( delegate: SliverChildListDelegate( [ getSuggestionWidget(resultBloc, "Hypertrophy", "asset/image/pict_hypertrophy.png", "3x10-12", 0.75, "2"), Divider(color: Colors.transparent), getSuggestionWidget(resultBloc, "Gain Strength", "asset/image/pict_weight_volumen_tonna.png", "3x4-8", 0.95, "3-5"), Divider(color: Colors.transparent), getSuggestionWidget(resultBloc, "Endurance", "asset/image/pict_reps_volumen_db.png", "4x25-35", 0.50, "3"), ], ), ); } else return emptySliver(); } Widget emptySliver({int count = 1}) { return SliverList( delegate: SliverChildListDelegate( [ Container(), Divider(color: Colors.transparent), ], ), ); } Widget getSuggestionWidget(ResultBloc resultBloc, String title, String picture, String repeats, double percent, String restTime) { double _opacity = 1; String unitQuantityUnit = resultBloc.exerciseRepository.exerciseType!.unitQuantityUnit == null ? "" : resultBloc.exerciseRepository.exerciseType!.unitQuantityUnit!; String weight = resultBloc.calculate1RM(percent: percent).toStringAsFixed(0); if (this.noRegistration) { repeats = "____"; weight = "_____"; restTime = "__"; } return Column( children: [ Text(t(title), textAlign: TextAlign.center, maxLines: 2, softWrap: true, style: GoogleFonts.archivoBlack( fontSize: 30, color: Colors.white, shadows: [ 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, ), ], )), Row(children: [ Image.asset( picture, height: 80, ), SizedBox( width: 10, ), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Text(repeats + " " + t("repeats"), textAlign: TextAlign.center, maxLines: 2, softWrap: true, style: GoogleFonts.archivoBlack( fontSize: 18, color: Colors.orange.withOpacity(_opacity), shadows: [ 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, ), ], )) ], ), Row( children: [ Text(t("Weight") + ": " + weight + " " + unitQuantityUnit, textAlign: TextAlign.center, maxLines: 2, softWrap: true, style: GoogleFonts.archivoBlack( fontSize: 18, color: Colors.orange, shadows: [ 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, ), ], )), ], ), Row( children: [ Text(t("Rest time") + ": " + restTime + " " + t("minutes"), textAlign: TextAlign.center, maxLines: 2, softWrap: true, style: GoogleFonts.archivoBlack( fontSize: 18, color: Colors.orange, shadows: [ 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, ), ], )), ], ), ], ) ]), ], ); } Widget getSummary(ResultBloc bloc) { int index = 0; List resultList = []; bloc.exerciseRepository.actualExerciseList!.forEach((actual) { //final String unit = t(bloc.exerciseRepository.exerciseType.unit); final String unit = bloc.exerciseRepository.exerciseType!.unitQuantityUnit != null ? bloc.exerciseRepository.exerciseType!.unitQuantityUnit! : bloc.exerciseRepository.exerciseType!.unit; String exerciseElement = ""; String exerciseRepeats = actual.quantity!.toStringAsFixed(0); if (bloc.exerciseRepository.exerciseType!.unit == "second") { exerciseRepeats = bloc.printTime(actual.quantity!); } final String exerciseUnitQuantity = actual.unitQuantity != null ? "x" + actual.unitQuantity!.toStringAsFixed(0) : ""; if (index == 0) { exerciseElement = t("Test") + ": "; } else if (index == 1) { exerciseElement = t("1st Control") + ": "; } else if (index == 2) { exerciseElement = t("2nd Control") + ": "; } else if (index == 3) { exerciseElement = t("3rd Control") + ": "; } index++; resultList.add(RichText( text: TextSpan( style: GoogleFonts.inter( fontSize: 20, color: Colors.white, ), children: [ TextSpan(text: exerciseElement), TextSpan( text: exerciseRepeats + exerciseUnitQuantity + " " + t(unit), style: GoogleFonts.archivoBlack( fontSize: 20, fontWeight: FontWeight.bold, color: Colors.yellow[300]!, ), ), ]), )); }); return Column(children: resultList); } Widget getResultSummary(ResultBloc resultBloc) { return SliverList( delegate: SliverChildListDelegate( [ Divider(color: Colors.transparent), getSummary(resultBloc), Divider(color: Colors.transparent), ], ), ); } Widget getResults(ResultBloc resultBloc) { return SliverGrid( delegate: SliverChildListDelegate( getResultData(resultBloc), ), gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 2, mainAxisSpacing: 5.0, crossAxisSpacing: 5.0, childAspectRatio: 1.1, ), ); } List getResultData(ResultBloc resultBloc) { List data = []; resultBloc.resultRepository.getResults().forEach((element) { data.add(getResultWidget(element)); }); return data; } Widget getResultWidget(ResultExt element) { bool? hasHardware = Cache().hasHardware; bool blur = (hasHardware != null && !hasHardware && element.isHardware()!); /* print("Blur: " + element.getDescription() + ": " + blur.toString() + " hasHardware:" + hasHardware.toString() + " isHw: " + element.isHardware().toString()); */ return Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ blur ? Stack(children: [ Image.asset( element.getImage(), height: 80, //color: Colors.white12, ), Image.asset( element.getImage(), height: 80, color: Colors.black.withOpacity(0.8), ), ]) : Image.asset( element.getImage(), height: 80, ), SizedBox( width: 10, ), Text( element.data.toStringAsFixed(0), style: GoogleFonts.archivoBlack(fontSize: 28, color: blur ? Colors.white12 : Colors.white), ), Text( t(element.getDescription()!), style: GoogleFonts.archivoBlack(fontSize: 14, color: blur ? Colors.white12 : Colors.white), textAlign: TextAlign.left, ), ], ); } }