WT1.1.3 logo change, error fixes

This commit is contained in:
bossanyit
2021-01-07 22:40:59 +01:00
parent 234a2f10e9
commit e6d0543021
119 changed files with 3580 additions and 1178 deletions
+3 -22
View File
@@ -2,6 +2,7 @@ import 'package:aitrainer_app/bloc/account/account_bloc.dart';
import 'package:aitrainer_app/localization/app_language.dart';
import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/customer.dart';
import 'package:aitrainer_app/util/common.dart';
import 'package:aitrainer_app/util/trans.dart';
import 'package:aitrainer_app/widgets/app_bar_min.dart';
import 'package:badges/badges.dart';
@@ -58,7 +59,7 @@ class AccountPage extends StatelessWidget with Trans {
ListView accountWidget(BuildContext context, String customerName, AccountBloc accountBloc) {
return ListView(padding: EdgeInsets.only(top: 35), children: <Widget>[
ListTile(
leading: badgedIcon(Colors.grey, Icons.perm_identity, "personalData"), //Icon(Icons.perm_identity),
leading: Common.badgedIcon(Colors.grey, Icons.perm_identity, "personalData"), //Icon(Icons.perm_identity),
subtitle: Text(t("Profile")),
title: FlatButton(
child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
@@ -84,7 +85,7 @@ class AccountPage extends StatelessWidget with Trans {
ListTile devices(BuildContext context, AccountBloc accountBloc) {
ListTile element = ListTile();
element = ListTile(
leading: badgedIcon(Colors.grey, Icons.device_hub, "customerDevice"),
leading: Common.badgedIcon(Colors.grey, Icons.device_hub, "customerDevice"),
title: FlatButton(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
@@ -226,24 +227,4 @@ class AccountPage extends StatelessWidget with Trans {
],
));
}
Widget badgedIcon(Color color, IconData icon, String badgeKey) {
bool show = Cache().getBadges()[badgeKey] != null;
int counter = Cache().getBadges()[badgeKey] != null ? Cache().getBadges()[badgeKey] : 0;
return Badge(
position: BadgePosition.topEnd(top: -10, end: -10),
animationDuration: Duration(milliseconds: 500),
animationType: BadgeAnimationType.slide,
badgeColor: Colors.red,
showBadge: show,
badgeContent: Text(
counter.toString(),
style: TextStyle(color: Colors.white),
),
child: Icon(
icon,
color: color,
),
);
}
}
+16 -12
View File
@@ -5,12 +5,12 @@ import 'package:aitrainer_app/localization/app_localization.dart';
import 'package:aitrainer_app/model/exercise_type.dart';
import 'package:aitrainer_app/repository/exercise_repository.dart';
import 'package:aitrainer_app/service/logging.dart';
import 'package:aitrainer_app/widgets/splash.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_form_bloc/flutter_form_bloc.dart';
import 'package:modal_progress_hud/modal_progress_hud.dart';
class CustomExercisePage extends StatefulWidget {
_CustomExerciseNewPageState createState() => _CustomExerciseNewPageState();
@@ -50,17 +50,15 @@ class _CustomExerciseNewPageState extends State<CustomExercisePage> with Logging
),
),
body: FormBlocListener<CustomExerciseFormBloc, String, String>(
onSubmitting: (context, state) {
/* onSubmitting: (context, state) {
LoadingDialog.show(context);
},
onSuccess: (context, state) {
LoadingDialog.hide(context);
},
onFailure: (context, state) {
LoadingDialog.hide(context);
Scaffold.of(context).showSnackBar(SnackBar(
backgroundColor: Colors.orange, content: Text(state.failureResponse, style: TextStyle(color: Colors.white))));
},
}, */
onSuccess: (context, state) {},
onFailure: (context, state) {
Scaffold.of(context).showSnackBar(SnackBar(
backgroundColor: Colors.orange, content: Text(state.failureResponse, style: TextStyle(color: Colors.white))));
},
child: ModalProgressHUD(
child: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
@@ -86,7 +84,13 @@ class _CustomExerciseNewPageState extends State<CustomExercisePage> with Logging
]),
),
gridCalculation(exerciseBloc)
]))));
])),
inAsyncCall: exerciseBloc.loading == true,
opacity: 0.5,
color: Colors.black54,
progressIndicator: CircularProgressIndicator(),
),
));
}));
}
+116 -78
View File
@@ -1,6 +1,10 @@
import 'package:aitrainer_app/bloc/customer_change/customer_change_bloc.dart';
import 'package:aitrainer_app/localization/app_localization.dart';
import 'package:aitrainer_app/repository/customer_repository.dart';
import 'package:aitrainer_app/util/trans.dart';
import 'package:aitrainer_app/widgets/app_bar_min.dart';
import 'package:aitrainer_app/widgets/dialog_html.dart';
import 'package:badges/badges.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
@@ -20,27 +24,16 @@ class BodyTypeItem {
static String mesomorph = "mesomorph";
}
class _CustomerBodyTypePageState extends State<CustomerBodyTypePage> {
class _CustomerBodyTypePageState extends State<CustomerBodyTypePage> with Trans {
String selected;
@override
Widget build(BuildContext context) {
final CustomerRepository customerRepository = ModalRoute.of(context).settings.arguments;
final double cWidth = MediaQuery.of(context).size.width * 0.75;
setContext(context);
return Scaffold(
appBar: AppBar(
title: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Image.asset(
'asset/image/WT_long_logo.png',
fit: BoxFit.cover,
height: 65.0,
),
],
),
backgroundColor: Colors.transparent,
),
appBar: AppBarMin(),
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
@@ -64,78 +57,123 @@ class _CustomerBodyTypePageState extends State<CustomerBodyTypePage> {
alignment: WrapAlignment.center,
children: [
Text(
AppLocalizations.of(context).translate("Your Body Type"),
t("Your Body Type"),
textAlign: TextAlign.center,
style: TextStyle(color: Colors.orange, fontSize: 42, fontFamily: 'Arial', fontWeight: FontWeight.w900),
)
]),
Divider(),
FlatButton(
child: Container(
width: cWidth,
child: Column(
children: [
Text(AppLocalizations.of(context).translate("Endomorph"),
textWidthBasis: TextWidthBasis.longestLine,
style: TextStyle(color: Colors.blue, fontSize: 32, fontFamily: 'Arial', fontWeight: FontWeight.w900)),
],
)),
padding: EdgeInsets.all(10.0),
shape: getShape(customerRepository, BodyTypeItem.endomorph),
onPressed: () => {
setState(() {
selected = BodyTypeItem.endomorph;
changeBloc.add(CustomerBodyTypeChange(bodyType: selected));
}),
}),
Divider(),
FlatButton(
child: Container(
width: cWidth,
child: Column(
children: [
InkWell(
child: Text(
AppLocalizations.of(context).translate("Ectomorph"),
style: TextStyle(color: Colors.blue, fontSize: 32, fontFamily: 'Arial', fontWeight: FontWeight.w900),
),
highlightColor: Colors.white,
),
],
),
Badge(
badgeColor: customerRepository.bodyType == BodyTypeItem.ectomorph ? Colors.orange[200] : Colors.blue[50],
badgeContent: GestureDetector(
onTap: () => {
showDialog(
context: context,
builder: (BuildContext context) {
return DialogHTML(
title: t("Ectomorph"),
htmlData: t("Ectomorph_desc"),
);
})
},
child: Icon(Icons.info_outline_rounded),
),
padding: EdgeInsets.all(10.0),
shape: getShape(customerRepository, BodyTypeItem.ectomorph),
onPressed: () => {
setState(() {
selected = BodyTypeItem.ectomorph;
changeBloc.add(CustomerBodyTypeChange(bodyType: selected));
}),
}),
Divider(),
FlatButton(
child: Container(
width: cWidth,
child: Column(
children: [
InkWell(
child: Text(
AppLocalizations.of(context).translate("Mesomorph"),
style: TextStyle(color: Colors.blue, fontSize: 32, fontFamily: 'Arial', fontWeight: FontWeight.w900),
),
highlightColor: Colors.white,
child: FlatButton(
child: Container(
width: cWidth,
child: Column(
children: [
InkWell(
child: Text(
t("Ectomorph"),
style: TextStyle(color: Colors.blue, fontSize: 32, fontFamily: 'Arial', fontWeight: FontWeight.w900),
),
highlightColor: Colors.white,
),
],
),
],
),
),
padding: EdgeInsets.all(10.0),
shape: getShape(customerRepository, BodyTypeItem.ectomorph),
onPressed: () => {
setState(() {
selected = BodyTypeItem.ectomorph;
changeBloc.add(CustomerBodyTypeChange(bodyType: selected));
}),
})),
Divider(),
Badge(
badgeColor: customerRepository.bodyType == BodyTypeItem.endomorph ? Colors.orange : Colors.blue[50],
badgeContent: GestureDetector(
onTap: () => {
showDialog(
context: context,
builder: (BuildContext context) {
return DialogHTML(
title: t("Endomorph"),
htmlData: t("Endomorph_desc"),
);
})
},
child: Icon(Icons.info_outline_rounded)),
child: FlatButton(
child: Container(
width: cWidth,
child: Column(
children: [
Text(t("Endomorph"),
textWidthBasis: TextWidthBasis.longestLine,
style:
TextStyle(color: Colors.blue, fontSize: 32, fontFamily: 'Arial', fontWeight: FontWeight.w900)),
],
)),
padding: EdgeInsets.all(10.0),
shape: getShape(customerRepository, BodyTypeItem.endomorph),
onPressed: () => {
setState(() {
selected = BodyTypeItem.endomorph;
changeBloc.add(CustomerBodyTypeChange(bodyType: selected));
}),
})),
Divider(),
Badge(
badgeColor: customerRepository.bodyType == BodyTypeItem.mesomorph ? Colors.orange[200] : Colors.blue[50],
badgeContent: GestureDetector(
onTap: () => {
showDialog(
context: context,
builder: (BuildContext context) {
return DialogHTML(
title: t("Mesomorph"),
htmlData: t("Mesomorph_desc"),
);
})
},
child: Icon(Icons.info_outline_rounded),
),
padding: EdgeInsets.all(10.0),
shape: getShape(customerRepository, BodyTypeItem.mesomorph),
onPressed: () => {
setState(() {
selected = BodyTypeItem.mesomorph;
changeBloc.add(CustomerBodyTypeChange(bodyType: selected));
}),
}),
child: FlatButton(
child: Container(
width: cWidth,
child: Column(
children: [
InkWell(
child: Text(
t("Mesomorph"),
style: TextStyle(color: Colors.blue, fontSize: 32, fontFamily: 'Arial', fontWeight: FontWeight.w900),
),
highlightColor: Colors.white,
),
],
),
),
padding: EdgeInsets.all(10.0),
shape: getShape(customerRepository, BodyTypeItem.mesomorph),
onPressed: () => {
setState(() {
selected = BodyTypeItem.mesomorph;
changeBloc.add(CustomerBodyTypeChange(bodyType: selected));
}),
})),
Divider(),
RaisedButton(
color: Colors.orange,
+17 -8
View File
@@ -7,6 +7,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:modal_progress_hud/modal_progress_hud.dart';
import 'package:toggle_switch/toggle_switch.dart';
@@ -23,7 +24,7 @@ class CustomerModifyPage extends StatelessWidget with Trans {
final accountBloc = BlocProvider.of<AccountBloc>(context);
return BlocProvider(
create: (context) => CustomerChangeBloc(customerRepository: accountBloc.customerRepository)..add(CustomerLoad()),
create: (context) => CustomerChangeBloc(customerRepository: accountBloc.customerRepository, context: context)..add(CustomerLoad()),
child: Builder(builder: (context) {
// ignore: close_sinks
final customerBloc = BlocProvider.of<CustomerChangeBloc>(context);
@@ -43,18 +44,26 @@ class CustomerModifyPage extends StatelessWidget with Trans {
),
child: BlocConsumer<CustomerChangeBloc, CustomerChangeState>(
listener: (context, state) {
if (state is CustomerChangeLoading) {
//LoadingDialog();
} else if (state is CustomerSaveError) {
//LoadingDialog.hide(context);
Scaffold.of(context).showSnackBar(
SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white))));
if (state is CustomerSaveError) {
String message = t(state.message);
if (message == null) {
message = "";
} else {
Scaffold.of(context).showSnackBar(
SnackBar(backgroundColor: Colors.orange, content: Text(message, style: TextStyle(color: Colors.white))));
}
} else if (state is CustomerSaveSuccess) {
Navigator.of(context).pushNamed("customerGoalPage", arguments: customerBloc.customerRepository);
}
},
builder: (context, state) {
return loadForm(customerBloc);
return ModalProgressHUD(
child: loadForm(customerBloc),
inAsyncCall: state is CustomerChangeLoading,
opacity: 0.5,
color: Colors.black54,
progressIndicator: CircularProgressIndicator(),
);
},
)));
}));
+23 -13
View File
@@ -58,9 +58,10 @@ class EvaluationPage extends StatelessWidget with Trans {
),
),
child: BlocProvider(
create: (context) =>
ResultBloc(resultRepository: ExerciseResultRepository(resultType: resultType), exerciseRepository: exerciseRepository)
..add(ResultLoad()),
create: (context) => ResultBloc(
resultRepository: ExerciseResultRepository(resultType: resultType),
exerciseRepository: exerciseRepository,
context: context), //..add(ResultLoad())
child: BlocConsumer<ResultBloc, ResultState>(listener: (context, state) {
if (state is ResultError) {
Scaffold.of(context).showSnackBar(
@@ -163,8 +164,8 @@ class EvaluationPage extends StatelessWidget with Trans {
getSuggestionTitle(resultBloc),
getSuggestion(resultBloc),
emptySliver(),
getResultTitle(resultBloc),
getResults(resultBloc),
//getResultTitle(resultBloc),
//getResults(resultBloc),
]));
}
@@ -239,9 +240,9 @@ class EvaluationPage extends StatelessWidget with Trans {
return SliverList(
delegate: SliverChildListDelegate(
[
getSuggestionWidget(resultBloc, "Hypertrophy", "asset/image/pict_hypertrophy.png", "3x10-12", 0.9, "2"),
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", "3x10-12", 0.75, "3-5"),
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"),
],
@@ -381,11 +382,20 @@ class EvaluationPage extends StatelessWidget with Trans {
Widget getSummary(ResultBloc bloc) {
int index = 0;
List<Text> resultList = List();
bloc.exerciseRepository.actualExerciseList.forEach((exercise) {
/* for (int i = 0; i < bloc.exerciseRepository.actualExerciseList.length; i++) {
print("Q " +
bloc.exerciseRepository.actualExerciseList[i].quantity.toString() +
" Qu: " +
bloc.exerciseRepository.actualExerciseList[i].unitQuantity.toString());
} */
bloc.exerciseRepository.actualExerciseList.forEach((actual) {
final String unit = t(bloc.exerciseRepository.exerciseType.unit);
String exerciseElement = "";
final String exerciseRepeats = exercise.quantity.toStringAsFixed(0);
final String exerciseUnitQuantity = exercise.unitQuantity != null ? "x" + exercise.unitQuantity.toStringAsFixed(0) : "";
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) {
@@ -477,7 +487,7 @@ class EvaluationPage extends StatelessWidget with Trans {
Image.asset(
element.getImage(),
height: 80,
color: Colors.black54,
color: Colors.black.withOpacity(0.8),
),
])
: Image.asset(
@@ -489,11 +499,11 @@ class EvaluationPage extends StatelessWidget with Trans {
),
Text(
element.data.toStringAsFixed(0),
style: GoogleFonts.archivoBlack(fontSize: 28, color: blur ? Colors.white30 : Colors.white),
style: GoogleFonts.archivoBlack(fontSize: 28, color: blur ? Colors.white12 : Colors.white),
),
Text(
t(element.getDescription()),
style: GoogleFonts.archivoBlack(fontSize: 14, color: blur ? Colors.white30 : Colors.white),
style: GoogleFonts.archivoBlack(fontSize: 14, color: blur ? Colors.white12 : Colors.white),
textAlign: TextAlign.left,
),
],
+124 -78
View File
@@ -1,25 +1,36 @@
import 'dart:collection';
import 'package:aitrainer_app/bloc/exercise_control/exercise_control_bloc.dart';
import 'package:aitrainer_app/library/custom_icon_icons.dart';
import 'package:aitrainer_app/localization/app_language.dart';
import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/repository/exercise_repository.dart';
import 'package:aitrainer_app/util/trans.dart';
import 'package:aitrainer_app/widgets/app_bar.dart';
import 'package:aitrainer_app/widgets/bottom_nav.dart';
import 'package:aitrainer_app/widgets/dialog_html.dart';
import 'package:aitrainer_app/widgets/number_picker.dart';
import 'package:aitrainer_app/widgets/splash.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_form_bloc/flutter_form_bloc.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:modal_progress_hud/modal_progress_hud.dart';
class ExerciseControlPage extends StatefulWidget {
_ExerciseControlPage createState() => _ExerciseControlPage();
}
class _ExerciseControlPage extends State<ExerciseControlPage> with Trans {
final ScrollController _controller = ScrollController();
double offset = 0;
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
LinkedHashMap arguments = ModalRoute.of(context).settings.arguments;
@@ -35,22 +46,24 @@ class _ExerciseControlPage extends State<ExerciseControlPage> with Trans {
if (state is ExerciseControlError) {
Scaffold.of(context).showSnackBar(
SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white))));
} else if (state is ExerciseControlLoading) {
return LoadingDialog();
}
}, builder: (context, state) {
final exerciseBloc = BlocProvider.of<ExerciseControlBloc>(context);
if (state is ExerciseControlLoading) {
return LoadingDialog();
} else if (state is ExerciseControlReady) {
return getControlForm(exerciseBloc);
} else {
return getControlForm(exerciseBloc);
if (state is ExerciseControlReady) {
_controller.animateTo(exerciseBloc.scrollOffset, duration: Duration(milliseconds: 300), curve: Curves.easeIn);
}
return ModalProgressHUD(
child: getControlForm(exerciseBloc),
inAsyncCall: state is ExerciseControlLoading,
opacity: 0.5,
color: Colors.black54,
progressIndicator: CircularProgressIndicator(),
);
}));
}
Form getControlForm(ExerciseControlBloc exerciseBloc) {
this.offset = exerciseBloc.scrollOffset;
String exerciseName = AppLanguage().appLocal == Locale("en")
? exerciseBloc.exerciseRepository.exerciseType.name
: exerciseBloc.exerciseRepository.exerciseType.nameTranslation;
@@ -75,9 +88,7 @@ class _ExerciseControlPage extends State<ExerciseControlPage> with Trans {
padding: const EdgeInsets.only(top: 10, left: 25, right: 25),
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
controller: ScrollController(
initialScrollOffset: exerciseBloc.scrollOffset,
),
controller: _controller,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.start,
@@ -86,7 +97,7 @@ class _ExerciseControlPage extends State<ExerciseControlPage> with Trans {
exerciseName,
style: GoogleFonts.archivoBlack(
fontWeight: FontWeight.bold,
fontSize: 20,
fontSize: 24,
color: Colors.white,
shadows: <Shadow>[
Shadow(
@@ -115,27 +126,9 @@ class _ExerciseControlPage extends State<ExerciseControlPage> with Trans {
Divider(
color: Colors.transparent,
),
/* FlatButton(
child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
Icon(
Icons.info,
color: Colors.yellow[50],
),
Flexible(
child: Text(t("Why do you need Exercise Control?"),
style: TextStyle(color: Colors.yellow[50], fontWeight: FontWeight.normal, fontSize: 14)),
),
Icon(
Icons.arrow_forward_ios,
color: Colors.yellow[50],
),
]),
textColor: Colors.blueAccent,
Divider(
color: Colors.transparent,
onPressed: () => {
//Navigator.of(context).pushNamed('exerciseTypeDescription', arguments: exerciseBloc.exerciseRepository),
},
), */
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
@@ -143,17 +136,92 @@ class _ExerciseControlPage extends State<ExerciseControlPage> with Trans {
style: GoogleFonts.inter(
color: Colors.yellow[300],
fontSize: 18,
shadows: <Shadow>[
Shadow(
offset: Offset(-2.0, -2.0),
blurRadius: 12.0,
color: Colors.black54,
),
Shadow(
offset: Offset(-3.0, 3.0),
blurRadius: 12.0,
color: Colors.black54,
),
],
)),
Text(
" " +
exerciseBloc.initialRM.toStringAsFixed(0) +
" " +
exerciseBloc.exerciseRepository.exerciseType.unitQuantityUnit,
style: GoogleFonts.inter(color: Colors.yellow[300], fontSize: 18, fontWeight: FontWeight.bold),
style: GoogleFonts.inter(
color: Colors.yellow[300],
fontSize: 18,
fontWeight: FontWeight.bold,
shadows: <Shadow>[
Shadow(
offset: Offset(-2.0, -2.0),
blurRadius: 6.0,
color: Colors.black54,
),
Shadow(
offset: Offset(-3.0, 3.0),
blurRadius: 6.0,
color: Colors.black54,
),
],
),
),
SizedBox(width: 10),
GestureDetector(
onTap: () => {
showDialog(
context: context,
builder: (BuildContext context) {
return DialogHTML(
title: t("OneRepMax"),
htmlData: t("OneRepMax_desc"),
);
})
},
child: Icon(CustomIcon.question, color: Colors.yellow[300]))
],
),
Divider(),
Row(mainAxisAlignment: MainAxisAlignment.start, children: [
Flexible(
child: Text(t("Why do you need Exercise Control?"),
style: GoogleFonts.inter(
color: Colors.yellow[300],
fontSize: 18,
shadows: <Shadow>[
Shadow(
offset: Offset(2.0, 2.0),
blurRadius: 6.0,
color: Colors.black54,
),
Shadow(
offset: Offset(-3.0, 3.0),
blurRadius: 12.0,
color: Colors.black54,
),
],
))),
SizedBox(width: 10),
GestureDetector(
onTap: () => {
showDialog(
context: context,
builder: (BuildContext context) {
return DialogHTML(
title: t("Control Exercise:"),
htmlData: t("controlexercise_desc"),
);
})
},
child: Icon(CustomIcon.question, color: Colors.yellow[300]))
]),
Divider(),
numberPickForm(exerciseBloc, 1),
Divider(),
numberPickForm(exerciseBloc, 2),
@@ -166,6 +234,24 @@ class _ExerciseControlPage extends State<ExerciseControlPage> with Trans {
);
}
List<Widget> getButton(int step, ExerciseControlBloc exerciseBloc) {
List<Widget> widgets = List();
if (step < exerciseBloc.step) {
widgets.add(Icon(
CustomIcon.check_circle,
color: Color(0xffb4f500),
size: 36,
));
} else {
widgets.add(Icon(
CustomIcon.question,
color: Colors.grey[700],
size: 36,
));
}
return widgets;
}
Widget numberPickForm(ExerciseControlBloc exerciseBloc, int step) {
String strTimes = step == 2 ? exerciseBloc.origQuantity.toStringAsFixed(0) : "max.";
String textInstruction = "";
@@ -211,7 +297,6 @@ class _ExerciseControlPage extends State<ExerciseControlPage> with Trans {
exerciseBloc.add(ExerciseControlSubmit(step: step)),
if (step == 3)
{
//confirmationDialog(exerciseBloc)
Navigator.of(context).pop(),
args['exerciseRepository'] = exerciseBloc.exerciseRepository,
Navigator.of(context).pushNamed('evaluationPage', arguments: args)
@@ -228,7 +313,10 @@ class _ExerciseControlPage extends State<ExerciseControlPage> with Trans {
),
],
)
: Container()),
: Stack(
alignment: Alignment.center,
children: getButton(step, exerciseBloc),
)),
],
),
];
@@ -238,46 +326,4 @@ class _ExerciseControlPage extends State<ExerciseControlPage> with Trans {
children: listWidgets,
);
}
void confirmationDialog(ExerciseControlBloc bloc) {
String unit = t(bloc.exerciseRepository.exerciseType.unit);
LinkedHashMap args = LinkedHashMap();
showCupertinoDialog(
useRootNavigator: true,
context: context,
//barrierDismissible: false,
builder: (_) => CupertinoAlertDialog(
title: Text(t("Summary of your test")),
content: Column(children: [
Text(
t("Test") + ": " + bloc.repeats[1].toStringAsFixed(0) + "x" + bloc.repeats[0].toStringAsFixed(0) + " " + unit,
style: (TextStyle(color: Colors.blue)),
),
Divider(),
Text(
t("1st Control") + ": " + bloc.repeats[2].toStringAsFixed(0) + "x" + bloc.unitQuantity.toStringAsFixed(0) + " " + unit,
style: (TextStyle(color: Colors.blue)),
),
Text(
t("2nd Control") + ": " + bloc.repeats[3].toStringAsFixed(0) + "x" + bloc.unitQuantity.toStringAsFixed(0) + " " + unit,
style: (TextStyle(color: Colors.blue)),
),
Text(
t("3rd Control") + ": " + bloc.repeats[4].toStringAsFixed(0) + "x" + bloc.unitQuantity.toStringAsFixed(0) + " " + unit,
style: (TextStyle(color: Colors.blue)),
),
]),
actions: [
FlatButton(
child: Text(t("OK")),
onPressed: () => {
Navigator.of(context).pop(),
args['exerciseRepository'] = bloc.exerciseRepository,
Navigator.of(context).pushNamed('evaluationPage', arguments: args)
},
)
],
));
}
}
+36 -8
View File
@@ -127,15 +127,43 @@ class _ExerciseExecutePage extends State<ExerciseExecutePage> with Trans {
exerciseTypes.add(explanation);
bloc.menuTreeRepository.sortedTree.forEach((name, list) {
if (bloc.selectedNumber == 0) {
exerciseTypes.add(Container(
margin: const EdgeInsets.only(left: 4.0),
child: TreeViewChild(
startExpanded: true,
parent: TreeviewParentWidget(text: name),
children: _getChildList(list, bloc),
)));
});
child: Center(
child: Text(
t("Please define your Exercise Plan"),
style: GoogleFonts.inter(color: Colors.white),
))));
exerciseTypes.add(Container(
child: Center(
child: Text(
t("Go to: 'Training Plan' - 'Edit My Custom Plan'"),
style: GoogleFonts.inter(color: Colors.white),
))));
exerciseTypes.add(Container(
child: Center(
child: InkWell(
onTap: () {
final LinkedHashMap args = LinkedHashMap();
args['customerId'] = Cache().userLoggedIn.customerId;
Navigator.of(context).pop();
Navigator.of(context).pushNamed('exercisePlanCustomPage', arguments: args);
},
child: Text(
t("Jump there »"),
style: GoogleFonts.inter(color: Colors.blue[200], decorationStyle: TextDecorationStyle.solid),
)))));
} else {
bloc.menuTreeRepository.sortedTree.forEach((name, list) {
exerciseTypes.add(Container(
margin: const EdgeInsets.only(left: 4.0),
child: TreeViewChild(
startExpanded: true,
parent: TreeviewParentWidget(text: name),
children: _getChildList(list, bloc),
)));
});
}
return exerciseTypes;
}
+9 -10
View File
@@ -7,12 +7,12 @@ import 'package:aitrainer_app/model/workout_menu_tree.dart';
import 'package:aitrainer_app/repository/exercise_repository.dart';
import 'package:aitrainer_app/util/trans.dart';
import 'package:aitrainer_app/widgets/app_bar.dart';
import 'package:aitrainer_app/widgets/splash.dart';
import 'package:aitrainer_app/library/numberpicker.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_form_bloc/flutter_form_bloc.dart';
import 'package:modal_progress_hud/modal_progress_hud.dart';
class ExerciseExecutePlanAddPage extends StatefulWidget {
_ExerciseExecuteAddPage createState() => _ExerciseExecuteAddPage();
@@ -40,19 +40,18 @@ class _ExerciseExecuteAddPage extends State<ExerciseExecutePlanAddPage> with Tra
if (state is ExerciseExecutePlanAddError) {
Scaffold.of(context).showSnackBar(
SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white))));
} else if (state is ExerciseExecutePlanAddLoading) {
return LoadingDialog();
}
}, builder: (context, state) {
// ignore: close_sinks
final exerciseBloc = BlocProvider.of<ExerciseExecutePlanAddBloc>(context);
if (state is ExerciseExecutePlanAddLoading) {
return LoadingDialog();
} else if (state is ExerciseExecutePlanAddReady) {
return getControlForm(exerciseBloc);
} else {
return getControlForm(exerciseBloc);
}
return ModalProgressHUD(
child: getControlForm(exerciseBloc),
inAsyncCall: state is ExerciseExecutePlanAddLoading,
opacity: 0.5,
color: Colors.black54,
progressIndicator: CircularProgressIndicator(),
);
}));
}
+9 -15
View File
@@ -4,7 +4,6 @@ import 'package:aitrainer_app/library/custom_icon_icons.dart';
import 'package:aitrainer_app/widgets/app_bar.dart';
import 'package:aitrainer_app/widgets/bottom_nav.dart';
import 'package:aitrainer_app/widgets/dialog_premium.dart';
import 'package:aitrainer_app/widgets/splash.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:intl/intl.dart';
@@ -18,6 +17,7 @@ import 'package:aitrainer_app/util/common.dart';
import 'package:aitrainer_app/util/trans.dart';
import 'package:flutter/material.dart';
import 'package:aitrainer_app/widgets/treeview_parent_widget.dart';
import 'package:modal_progress_hud/modal_progress_hud.dart';
class ExerciseLogPage extends StatefulWidget {
@override
@@ -28,31 +28,25 @@ class _ExerciseLogPage extends State<ExerciseLogPage> with Trans, Common {
@override
Widget build(BuildContext context) {
LinkedHashMap arguments = ModalRoute.of(context).settings.arguments;
//final ExerciseRepository exerciseRepository = arguments['exerciseRepository'];
final int customerId = arguments['customerId'];
setContext(context);
return BlocProvider(
create: (context) => ExerciseLogBloc(exerciseRepository: ExerciseRepository())..add(ExerciseLogLoad()),
child: BlocConsumer<ExerciseLogBloc, ExerciseLogState>(listener: (context, state) {
if (state is ExerciseLogLoading) {
return LoadingDialog();
} else if (state is ExerciseLogError) {
//LoadingDialog.hide(context);
if (state is ExerciseLogError) {
Scaffold.of(context).showSnackBar(
SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white))));
}
}, builder: (context, state) {
final exerciseBloc = BlocProvider.of<ExerciseLogBloc>(context);
if (state is ExerciseLogReady) {
//LoadingDialog.hide(context);
return getExerciseLog(customerId, exerciseBloc);
} else if (state is ExerciseLogLoading) {
return LoadingDialog();
} else {
//LoadingDialog.hide(context);
return getExerciseLog(customerId, exerciseBloc);
}
return ModalProgressHUD(
child: getExerciseLog(customerId, exerciseBloc),
inAsyncCall: state is ExerciseLogLoading,
opacity: 0.5,
color: Colors.black54,
progressIndicator: CircularProgressIndicator(),
);
}));
}
+7 -18
View File
@@ -23,6 +23,7 @@ import 'package:flutter_form_bloc/flutter_form_bloc.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:keyboard_actions/keyboard_actions.dart';
import 'package:stop_watch_timer/stop_watch_timer.dart';
import 'package:wakelock/wakelock.dart';
class ExerciseNewPage extends StatefulWidget {
_ExerciseNewPageState createState() => _ExerciseNewPageState();
@@ -94,9 +95,7 @@ class _ExerciseNewPageState extends State<ExerciseNewPage> with Trans, Logging {
child: BlocConsumer<ExerciseNewBloc, ExerciseNewState>(
listener: (context, state) {
if (state is ExerciseNewLoading) {
//LoadingDialog.show(context);
} else if (state is ExerciseNewError) {
//LoadingDialog.hide(context);
Scaffold.of(context).showSnackBar(
SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white))));
}
@@ -136,20 +135,7 @@ class _ExerciseNewPageState extends State<ExerciseNewPage> with Trans, Logging {
return SizeWidget(exerciseBloc: exerciseBloc);
}
bool isSecond = false;
String exerciseTask = "";
if (exerciseBloc.exerciseRepository.exerciseType.unit != "second") {
if (exerciseBloc.exerciseRepository.exerciseType.is1RM() && menuBloc.ability.toString() == ExerciseAbility.oneRepMax.toString()) {
exerciseTask = "Please take a relative bigger weight and repeat 12-20 times";
exerciseBloc.quantity = 12;
} else if (exerciseBloc.exerciseRepository.exerciseType.isEndurance() &&
menuBloc.ability.toString() == ExerciseAbility.endurance.toString()) {
exerciseTask = "Please take a medium weight and repeat 20-30 times";
exerciseBloc.quantity = 20;
}
} else {
isSecond = true;
}
final String exerciseTask = exerciseBloc.setExerciseTask();
return Form(
child: Scaffold(
@@ -205,7 +191,7 @@ class _ExerciseNewPageState extends State<ExerciseNewPage> with Trans, Logging {
Text(
exerciseDescription,
style: GoogleFonts.inter(fontSize: 12, color: Colors.yellow[300]),
maxLines: 8,
maxLines: 4,
overflow: TextOverflow.fade,
softWrap: true,
),
@@ -338,6 +324,7 @@ class _ExerciseNewPageState extends State<ExerciseNewPage> with Trans, Logging {
//shape: const StadiumBorder(),
onPressed: () async {
bloc.stopWatchTimer.onExecute.add(StopWatchExecute.start);
Wakelock.enable(); // prevent sleep the phone
},
icon: Icon(CustomIcon.play_1),
iconSize: 40,
@@ -352,6 +339,7 @@ class _ExerciseNewPageState extends State<ExerciseNewPage> with Trans, Logging {
//shape: const StadiumBorder(),
onPressed: () async {
bloc.stopWatchTimer.onExecute.add(StopWatchExecute.stop);
Wakelock.disable();
},
icon: Icon(CustomIcon.stop),
),
@@ -378,7 +366,7 @@ class _ExerciseNewPageState extends State<ExerciseNewPage> with Trans, Logging {
Divider(),
Text("Or type the time manually:", style: GoogleFonts.inter(color: Colors.white)),
TimePickerWidget(
onChange: (value) => {bloc.add(ExerciseNewQuantityChange(quantity: value))},
onChange: (value) => {print("timer"), bloc.add(ExerciseNewQuantityChange(quantity: value))},
)
]);
}
@@ -410,6 +398,7 @@ class _ExerciseNewPageState extends State<ExerciseNewPage> with Trans, Logging {
void confirmationDialog(ExerciseNewBloc bloc, MenuBloc menuBloc) {
LinkedHashMap args = LinkedHashMap();
print("quantity: " + bloc.quantity.toString());
if (bloc.exerciseRepository.exercise.quantity == null) {
return;
}
-26
View File
@@ -1,26 +0,0 @@
import 'package:aitrainer_app/localization/app_localization.dart';
import 'package:aitrainer_app/widgets/app_bar_min.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class Gdpr extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBarMin(
back: true,
),
body: Container(
padding: const EdgeInsets.only(left: 15, right: 15),
child: ListView(
children: <Widget>[
InkWell(
child: Text(
AppLocalizations.of(context).translate('gdpr_text'),
),
customBorder: Border.all(color: Colors.orange, width: 1),
),
],
)));
}
}
+91 -72
View File
@@ -1,67 +1,53 @@
import 'package:aitrainer_app/bloc/login_form_bloc.dart';
import 'package:aitrainer_app/bloc/account/account_bloc.dart';
import 'package:aitrainer_app/bloc/login/login_bloc.dart';
import 'package:aitrainer_app/localization/app_localization.dart';
import 'package:aitrainer_app/repository/user_repository.dart';
import 'package:aitrainer_app/util/common.dart';
import 'package:aitrainer_app/util/trans.dart';
import 'package:aitrainer_app/widgets/app_bar_min.dart';
import 'package:aitrainer_app/widgets/splash.dart';
import 'package:aitrainer_app/widgets/dialog_long.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_form_bloc/flutter_form_bloc.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:modal_progress_hud/modal_progress_hud.dart';
import '../library_keys.dart';
class LoginPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return LoginWidget();
}
}
class LoginWidget extends StatefulWidget {
LoginWidget();
@override
State<StatefulWidget> createState() => _LoginWidget();
}
class _LoginWidget extends State<LoginWidget> with Common, Trans {
// ignore: must_be_immutable
class LoginPage extends StatelessWidget with Trans {
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
@override
Widget build(BuildContext context) {
final accountBloc = BlocProvider.of<AccountBloc>(context);
setContext(context);
return BlocProvider(
create: (context) => LoginFormBloc(userRepository: UserRepository(), accountBloc: accountBloc),
child: Builder(builder: (context) {
final loginBloc = BlocProvider.of<LoginFormBloc>(context);
return Scaffold(
//key: _scaffoldKey,
appBar: AppBarMin(),
body: FormBlocListener<LoginFormBloc, String, String>(
onSubmitting: (context, state) {
LoadingDialog.show(context);
},
onSuccess: (context, state) {
LoadingDialog.hide(context);
Navigator.of(context).pushNamed('home');
},
onFailure: (context, state) {
LoadingDialog.hide(context);
Scaffold.of(context).showSnackBar(SnackBar(
backgroundColor: Colors.orange, content: Text(t(state.failureResponse), style: TextStyle(color: Colors.white))));
},
onLoaded: (context, state) {},
child: loadForm(loginBloc, accountBloc)),
);
}));
return Scaffold(
appBar: AppBarMin(),
body: BlocProvider(
create: (context) =>
LoginBloc(userRepository: UserRepository(), accountBloc: accountBloc, context: context, isRegistration: false),
child: BlocConsumer<LoginBloc, LoginState>(listener: (context, state) {
if (state is LoginError) {
Scaffold.of(context).showSnackBar(
SnackBar(backgroundColor: Colors.orange, content: Text(t(state.message), style: TextStyle(color: Colors.white))));
} else if (state is LoginSuccess) {
Navigator.of(context).pushNamed('home');
}
}, builder: (context, state) {
final loginBloc = BlocProvider.of<LoginBloc>(context);
return ModalProgressHUD(
child: loadForm(loginBloc, accountBloc),
inAsyncCall: state is LoginLoading,
opacity: 0.5,
color: Colors.black54,
progressIndicator: CircularProgressIndicator(),
);
})));
}
Widget loadForm(LoginFormBloc loginBloc, AccountBloc accountBloc) {
Widget loadForm(LoginBloc loginBloc, AccountBloc accountBloc) {
return SafeArea(
top: false,
bottom: false,
@@ -78,25 +64,20 @@ class _LoginWidget extends State<LoginWidget> with Common, Trans {
);
}
Widget buildLoginForm(LoginFormBloc formBloc, AccountBloc accountBloc) {
Widget buildLoginForm(LoginBloc loginBloc, AccountBloc accountBloc) {
return Form(
key: _scaffoldKey,
child: Container(
padding: const EdgeInsets.only(left: 15, right: 50),
child: ListView(shrinkWrap: false, padding: EdgeInsets.only(top: 150.0), children: <Widget>[
Divider(color: Colors.transparent),
/* FlatButton(
child: new Image.asset(
'asset/image/login_fb.png',
width: cWidth * .85,
),
onPressed: () => {
//_fbLogin(),
FirebaseApi().signInWithFacebook(),
print("Login with FB"),
},
),
Text(AppLocalizations.of(context).translate("OR")),*/
child: ListView(shrinkWrap: false, padding: EdgeInsets.only(top: 100.0), children: <Widget>[
FlatButton(
child: new Image.asset(
'asset/image/login_fb.png',
width: MediaQuery.of(context).size.width * .85,
),
onPressed: () => {loginBloc.add(LoginFB())},
),
Text(AppLocalizations.of(context).translate("OR")),
Divider(),
Row(
mainAxisAlignment: MainAxisAlignment.start,
@@ -107,28 +88,61 @@ class _LoginWidget extends State<LoginWidget> with Common, Trans {
),
],
),
Divider(),
TextFieldBlocBuilder(
Divider(
color: Colors.transparent,
),
TextFormField(
key: LibraryKeys.loginEmailField,
textFieldBloc: formBloc.emailField,
decoration: InputDecoration(
fillColor: Colors.white,
contentPadding: EdgeInsets.only(left: 15, top: 15, bottom: 15),
labelText: t('Email'),
fillColor: Colors.white24,
filled: true,
labelText: 'Email',
border: OutlineInputBorder(
gapPadding: 4.0,
borderRadius: BorderRadius.circular(12.0),
borderSide: BorderSide(color: Colors.green[50], width: 0.4),
),
),
initialValue: loginBloc.userRepository.user.email,
autovalidateMode: AutovalidateMode.onUserInteraction,
validator: (val) {
return t(loginBloc.emailValidation(val));
},
onChanged: (value) => loginBloc.add(LoginEmailChange(email: value)),
keyboardType: TextInputType.emailAddress,
style: new TextStyle(fontSize: 16, color: Colors.indigo),
),
Divider(
color: Colors.transparent,
),
TextFieldBlocBuilder(
TextFormField(
key: LibraryKeys.loginPasswordField,
textFieldBloc: formBloc.passwordField,
obscureText: true,
decoration: InputDecoration(
fillColor: Colors.white,
labelStyle: TextStyle(fontSize: 14),
contentPadding: EdgeInsets.only(left: 15, top: 15, bottom: 15),
suffixIcon: IconButton(
onPressed: () => {loginBloc.add(LoginPasswordChangeObscure())},
icon: Icon(Icons.remove_red_eye),
),
labelText: t('Password'),
fillColor: Colors.white24,
filled: true,
labelText: 'Password',
border: OutlineInputBorder(
gapPadding: 1.0,
borderRadius: BorderRadius.circular(12.0),
borderSide: BorderSide(color: Colors.green[50], width: 0.4),
),
),
suffixButton: SuffixButton.obscureText,
initialValue: loginBloc.userRepository.user.password,
autovalidateMode: AutovalidateMode.always,
validator: (val) {
return t(loginBloc.passwordValidation(val));
},
onChanged: (value) => loginBloc.add(LoginPasswordChange(password: value)),
keyboardType: TextInputType.visiblePassword,
style: new TextStyle(fontSize: 16, color: Colors.indigo),
),
Divider(
color: Colors.transparent,
@@ -147,7 +161,7 @@ class _LoginWidget extends State<LoginWidget> with Common, Trans {
],
),
//Image.asset('asset/icon/gomb_zold_b-1.png', width: 100, height: 100),
onPressed: () => {formBloc.add(SubmitFormBloc())}),
onPressed: () => {loginBloc.add(LoginSubmit())}),
]),
Divider(
color: Colors.transparent,
@@ -164,9 +178,14 @@ class _LoginWidget extends State<LoginWidget> with Common, Trans {
),
Spacer(flex: 2),
InkWell(
child: Text(AppLocalizations.of(context).translate('Privacy')),
onTap: () => Navigator.of(context).pushNamed('gdpr'),
),
child: Text(AppLocalizations.of(context).translate('Privacy')),
onTap: () => {
showDialog(
context: context,
builder: (BuildContext context) {
return DialogGDPR();
})
}),
]),
])),
);
+11 -7
View File
@@ -4,7 +4,7 @@ import 'package:aitrainer_app/library/radar_chart.dart';
import 'package:aitrainer_app/widgets/app_bar.dart';
import 'package:aitrainer_app/widgets/bottom_nav.dart';
import 'package:aitrainer_app/widgets/dialog_premium.dart';
import 'package:aitrainer_app/widgets/splash.dart';
import 'package:flurry/flurry.dart';
import 'package:flutter/scheduler.dart';
import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/util/common.dart';
@@ -12,6 +12,7 @@ import 'package:aitrainer_app/util/trans.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:aitrainer_app/bloc/body_development/body_development_bloc.dart';
import 'package:modal_progress_hud/modal_progress_hud.dart';
class MyDevelopmentBodyPage extends StatefulWidget {
@override
@@ -26,6 +27,7 @@ class _MyDevelopmentBodyPage extends State<MyDevelopmentBodyPage> with Trans, Co
@override
void initState() {
super.initState();
Flurry.logEvent("myDevelopmentBody");
if (!Cache().hasPurchased) {
Timer(
Duration(milliseconds: 2000),
@@ -74,16 +76,18 @@ class _MyDevelopmentBodyPage extends State<MyDevelopmentBodyPage> with Trans, Co
),
),
child: BlocConsumer<BodyDevelopmentBloc, BodyDevelopmentState>(
listener: (context, state) {
if (state is BodyDevelopmentLoading) {
LoadingDialog();
}
},
listener: (context, state) {},
builder: (context, state) {
if (state is BodyDevelopmentInitial) {
return Container();
} else {
return developmentWidget(customerId);
return ModalProgressHUD(
child: developmentWidget(customerId),
inAsyncCall: state is BodyDevelopmentLoading,
opacity: 0.5,
color: Colors.black54,
progressIndicator: CircularProgressIndicator(),
);
}
},
)),
+3 -1
View File
@@ -11,6 +11,7 @@ import 'package:aitrainer_app/bloc/development_by_muscle/development_by_muscle_b
import 'package:aitrainer_app/model/workout_menu_tree.dart';
import 'package:aitrainer_app/library/tree_view.dart';
import 'package:aitrainer_app/widgets/bottom_nav.dart';
import 'package:flurry/flurry.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
@@ -31,6 +32,7 @@ class _MyDevelopmentMuscleState extends State<MyDevelopmentMusclePage> with Comm
@override
void initState() {
super.initState();
Flurry.logEvent("myDevelopmentMuscle");
if (!Cache().hasPurchased) {
Timer(
Duration(milliseconds: 2000),
@@ -149,7 +151,7 @@ class _MyDevelopmentMuscleState extends State<MyDevelopmentMusclePage> with Comm
),
ChoiceChip(
avatar: Icon(Icons.accessibility_new),
label: Text(t('One Max Rep')),
label: Text(t('One Rep Max')),
labelStyle: TextStyle(fontSize: 9, color: Colors.black),
selectedColor: Colors.lightBlueAccent,
selected: bloc.diagramType == DiagramType.oneRepMax,
+2
View File
@@ -4,6 +4,7 @@ import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/repository/customer_repository.dart';
import 'package:aitrainer_app/repository/exercise_repository.dart';
import 'package:aitrainer_app/widgets/dialog_premium.dart';
import 'package:flurry/flurry.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:aitrainer_app/util/trans.dart';
import 'package:aitrainer_app/widgets/app_bar.dart';
@@ -100,6 +101,7 @@ class _MyDevelopmentPage extends State<MyDevelopmentPage> with Trans {
backgroundColor: Colors.black54.withOpacity(0.4))),
image: "asset/image/predictions.jpg",
onTap: () => {
Flurry.logEvent("Predictions"),
showDialog(
context: context,
builder: (BuildContext context) {
+23 -19
View File
@@ -7,6 +7,7 @@ import 'package:aitrainer_app/widgets/app_bar.dart';
import 'package:aitrainer_app/widgets/bottom_nav.dart';
import 'package:aitrainer_app/widgets/dialog_premium.dart';
import 'package:aitrainer_app/widgets/image_button.dart';
import 'package:flurry/flurry.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
@@ -40,25 +41,6 @@ class _MyExercisePlanPage extends State<MyExercisePlanPage> with Trans, Logging
child: CustomScrollView(scrollDirection: Axis.vertical, slivers: [
SliverGrid(
delegate: SliverChildListDelegate([
ImageButton(
width: imageWidth,
textAlignment: Alignment.topLeft,
text: t("Execute My Selected Training Plan"),
style: GoogleFonts.robotoMono(
textStyle: TextStyle(
fontSize: 14,
color: Colors.white,
fontWeight: FontWeight.bold,
backgroundColor: Colors.black54.withOpacity(0.4))),
image: "asset/image/exercise_plan_execute.jpg",
top: 130,
left: 5,
onTap: () => {
args['customerId'] = Cache().userLoggedIn.customerId,
Navigator.of(context).pushNamed('exerciseExecutePlanPage', arguments: args)
},
isLocked: false,
),
ImageButton(
width: imageWidth,
textAlignment: Alignment.topLeft,
@@ -78,6 +60,25 @@ class _MyExercisePlanPage extends State<MyExercisePlanPage> with Trans, Logging
},
isLocked: false,
),
ImageButton(
width: imageWidth,
textAlignment: Alignment.topLeft,
text: t("Execute My Selected Training Plan"),
style: GoogleFonts.robotoMono(
textStyle: TextStyle(
fontSize: 14,
color: Colors.white,
fontWeight: FontWeight.bold,
backgroundColor: Colors.black54.withOpacity(0.4))),
image: "asset/image/exercise_plan_execute.jpg",
top: 130,
left: 5,
onTap: () => {
args['customerId'] = Cache().userLoggedIn.customerId,
Navigator.of(context).pushNamed('exerciseExecutePlanPage', arguments: args)
},
isLocked: false,
),
ImageButton(
width: imageWidth,
textAlignment: Alignment.topLeft,
@@ -91,6 +92,7 @@ class _MyExercisePlanPage extends State<MyExercisePlanPage> with Trans, Logging
image: "asset/image/exercise_plan_suggested.jpg",
left: 2,
onTap: () => {
Flurry.logEvent("SuggestedTrainingPlan"),
showDialog(
context: context,
builder: (BuildContext context) {
@@ -119,6 +121,7 @@ class _MyExercisePlanPage extends State<MyExercisePlanPage> with Trans, Logging
image: "asset/image/exercise_plan_special.jpg",
left: 5,
onTap: () => {
Flurry.logEvent("SpecialTrainingPlan"),
showDialog(
context: context,
builder: (BuildContext context) {
@@ -147,6 +150,7 @@ class _MyExercisePlanPage extends State<MyExercisePlanPage> with Trans, Logging
image: "asset/image/exercise_plan_stars.jpg",
left: 5,
onTap: () => {
Flurry.logEvent("StarTrainingPlan"),
showDialog(
context: context,
builder: (BuildContext context) {
+192 -150
View File
@@ -1,175 +1,217 @@
import 'package:aitrainer_app/bloc/account/account_bloc.dart';
import 'package:aitrainer_app/bloc/registration_form_bloc.dart';
import 'package:aitrainer_app/bloc/login/login_bloc.dart';
import 'package:aitrainer_app/localization/app_localization.dart';
import 'package:aitrainer_app/util/common.dart';
import 'package:aitrainer_app/repository/customer_repository.dart';
import 'package:aitrainer_app/repository/user_repository.dart';
import 'package:aitrainer_app/util/trans.dart';
import 'package:aitrainer_app/widgets/app_bar_min.dart';
import 'package:aitrainer_app/widgets/splash.dart';
import 'package:aitrainer_app/widgets/dialog_long.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
//import 'package:flutter_facebook_login/flutter_facebook_login.dart';
import 'package:flutter_form_bloc/flutter_form_bloc.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:modal_progress_hud/modal_progress_hud.dart';
import 'package:toggle_switch/toggle_switch.dart';
import '../library_keys.dart';
class RegistrationPage extends StatelessWidget {
final UserRepository userRepository = UserRepository();
final CustomerRepository customerRepository = CustomerRepository();
@override
Widget build(BuildContext context) {
return RegistrationWidget(userRepository: userRepository, customerRepository: customerRepository);
}
}
class RegistrationWidget extends StatefulWidget {
final UserRepository userRepository;
final CustomerRepository customerRepository;
RegistrationWidget({this.userRepository, this.customerRepository});
@override
State<StatefulWidget> createState() => _RegistrationWidget();
}
class _RegistrationWidget extends State<RegistrationWidget> with Common, Trans {
// ignore: must_be_immutable
class RegistrationPage extends StatelessWidget with Trans {
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
@override
Widget build(BuildContext context) {
setContext(context);
// ignore: close_sinks
final accountBloc = BlocProvider.of<AccountBloc>(context);
return BlocProvider(
create: (context) => RegistrationFormBloc(userRepository: UserRepository(), accountBloc: accountBloc),
child: Builder(builder: (context) {
// ignore: close_sinks
final registrationBloc = BlocProvider.of<RegistrationFormBloc>(context);
return Scaffold(
key: _scaffoldKey,
appBar: AppBarMin(),
body: FormBlocListener<RegistrationFormBloc, String, String>(
onSubmitting: (context, state) {
LoadingDialog.show(context);
},
onSuccess: (context, state) {
LoadingDialog.hide(context);
setContext(context);
return Scaffold(
appBar: AppBarMin(),
body: BlocProvider(
create: (context) =>
LoginBloc(userRepository: UserRepository(), accountBloc: accountBloc, context: context, isRegistration: true),
child: BlocConsumer<LoginBloc, LoginState>(listener: (context, state) {
if (state is LoginError) {
String message = t(state.message);
if (message == null) {
message = "";
} else {
Scaffold.of(context).showSnackBar(
SnackBar(backgroundColor: Colors.orange, content: Text(message, style: TextStyle(color: Colors.white))));
}
} else if (state is LoginSuccess) {
Navigator.of(context).pushNamed('customerModifyPage');
},
onFailure: (context, state) {
LoadingDialog.hide(context);
Scaffold.of(context).showSnackBar(SnackBar(
backgroundColor: Colors.orange, content: Text(t(state.failureResponse), style: TextStyle(color: Colors.white))));
},
child: SafeArea(
bottom: false,
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_login.png'),
fit: BoxFit.cover,
//height: double.infinity,
//width: double.infinity,
alignment: Alignment.center,
),
),
child: Form(
child: Container(
padding: const EdgeInsets.only(left: 25, right: 50),
child: ListView(shrinkWrap: false, padding: EdgeInsets.only(top: 150.0),
//mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Divider(
color: Colors.transparent,
),
//Spacer(flex:4),
}
}, builder: (context, state) {
final loginBloc = BlocProvider.of<LoginBloc>(context);
/* FlatButton(
child: new Image.asset(
'asset/image/login_fb.png',
width: cWidth * .85,
),
onPressed: () => {
// _fbLogin(),
print("Login with FB"),
},
),
Text(AppLocalizations.of(context).translate("OR")),*/
Divider(),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
new InkWell(
child: new Text(AppLocalizations.of(context).translate('SignUp'),
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 24)),
),
],
),
Divider(),
TextFieldBlocBuilder(
key: LibraryKeys.loginEmailField,
textFieldBloc: registrationBloc.emailField,
decoration: InputDecoration(
fillColor: Colors.white,
filled: true,
labelText: 'Email',
),
),
Divider(
color: Colors.transparent,
),
TextFieldBlocBuilder(
key: LibraryKeys.loginPasswordField,
textFieldBloc: registrationBloc.passwordField,
decoration: InputDecoration(
fillColor: Colors.white,
filled: true,
labelText: 'Password',
),
suffixButton: SuffixButton.obscureText,
),
Divider(
color: Colors.transparent,
),
Row(mainAxisAlignment: MainAxisAlignment.end, children: <Widget>[
new FlatButton(
child: Stack(
alignment: Alignment.center,
children: [
Image.asset('asset/icon/gomb_zold_a.png', width: 140, height: 60),
Text(
t("OK"),
style: GoogleFonts.archivoBlack(fontSize: 20, color: Colors.white),
),
],
),
// Image.asset('asset/image/WT_OK.png', width: 100, height: 100),
onPressed: () => {registrationBloc.add(SubmitFormBloc())}),
]),
Row(mainAxisAlignment: MainAxisAlignment.spaceAround, children: <Widget>[
new InkWell(
child: new Text(AppLocalizations.of(context).translate('Login')),
onTap: () => Navigator.of(context).pushNamed('login'),
),
Spacer(flex: 1),
new InkWell(
child: new Text(AppLocalizations.of(context).translate('Privacy')),
onTap: () => Navigator.of(context).pushNamed('gdpr'),
),
Spacer(flex: 2),
]),
//Spacer(flex:2),
])),
),
return ModalProgressHUD(
child: loadForm(loginBloc, accountBloc),
inAsyncCall: state is LoginLoading,
opacity: 0.5,
color: Colors.black54,
progressIndicator: CircularProgressIndicator(),
);
})));
}
Widget loadForm(LoginBloc loginBloc, AccountBloc accountBloc) {
return SafeArea(
top: false,
bottom: false,
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_login.png'),
fit: BoxFit.cover,
alignment: Alignment.center,
),
),
child: buildLoginForm(loginBloc, accountBloc),
),
);
}
Widget buildLoginForm(LoginBloc loginBloc, AccountBloc accountBloc) {
return Form(
key: _scaffoldKey,
child: Container(
padding: const EdgeInsets.only(left: 15, right: 50),
child: ListView(shrinkWrap: false, padding: EdgeInsets.only(top: 150.0), children: <Widget>[
FlatButton(
child: Image.asset(
'asset/image/fb_registration.png',
width: MediaQuery.of(context).size.width * .85,
),
onPressed: () => {loginBloc.add(RegistrationFB())},
),
ListTile(title: Text(AppLocalizations.of(context).translate("OR"))),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
InkWell(
child:
Text(AppLocalizations.of(context).translate('SignUp'), style: TextStyle(fontWeight: FontWeight.bold, fontSize: 24)),
),
],
),
Divider(
color: Colors.transparent,
),
TextFormField(
key: LibraryKeys.loginEmailField,
decoration: InputDecoration(
contentPadding: EdgeInsets.only(left: 15, top: 15, bottom: 15),
labelText: t('Email'),
fillColor: Colors.white24,
filled: true,
border: OutlineInputBorder(
gapPadding: 4.0,
borderRadius: BorderRadius.circular(12.0),
borderSide: BorderSide(color: Colors.green[50], width: 0.4),
),
),
initialValue: loginBloc.userRepository.user.email,
autovalidateMode: AutovalidateMode.onUserInteraction,
validator: (val) {
return t(loginBloc.emailValidation(val));
},
onChanged: (value) => loginBloc.add(LoginEmailChange(email: value)),
keyboardType: TextInputType.emailAddress,
style: new TextStyle(fontSize: 16, color: Colors.indigo),
),
);
}));
Divider(
color: Colors.transparent,
),
TextFormField(
key: LibraryKeys.loginPasswordField,
obscureText: true,
decoration: InputDecoration(
labelStyle: TextStyle(fontSize: 14),
contentPadding: EdgeInsets.only(left: 15, top: 15, bottom: 15),
suffixIcon: IconButton(
onPressed: () => {loginBloc.add(LoginPasswordChangeObscure())},
icon: Icon(Icons.remove_red_eye),
),
labelText: t('Password'),
fillColor: Colors.white24,
filled: true,
border: OutlineInputBorder(
gapPadding: 1.0,
borderRadius: BorderRadius.circular(12.0),
borderSide: BorderSide(color: Colors.green[50], width: 0.4),
),
),
initialValue: loginBloc.userRepository.user.password,
autovalidateMode: AutovalidateMode.always,
validator: (val) {
return t(loginBloc.passwordValidation(val));
},
onChanged: (value) => loginBloc.add(LoginPasswordChange(password: value)),
keyboardType: TextInputType.visiblePassword,
style: new TextStyle(fontSize: 16, color: Colors.indigo),
),
Divider(
color: Colors.transparent,
),
getDataProtection(loginBloc),
Row(mainAxisAlignment: MainAxisAlignment.start, children: <Widget>[
FlatButton(
key: LibraryKeys.loginOKButton,
child: Stack(
alignment: Alignment.center,
children: [
Image.asset('asset/icon/gomb_zold_a.png', width: 140, height: 60),
Text(
t("OK"),
style: GoogleFonts.archivoBlack(fontSize: 20, color: Colors.white),
),
],
),
//Image.asset('asset/icon/gomb_zold_b-1.png', width: 100, height: 100),
onPressed: () => {loginBloc.add(RegistrationSubmit())}),
]),
Divider(
color: Colors.transparent,
),
Divider(
color: Colors.transparent,
),
Row(mainAxisAlignment: MainAxisAlignment.spaceAround, children: <Widget>[
InkWell(
child: Text(AppLocalizations.of(context).translate('Login')),
onTap: () => Navigator.of(context).pushNamed('login'),
),
Spacer(flex: 2),
InkWell(
child: Text(AppLocalizations.of(context).translate('Privacy')),
onTap: () => {
showDialog(
context: context,
builder: (BuildContext context) {
return DialogGDPR();
})
}),
]),
])),
);
}
Widget getDataProtection(LoginBloc loginBloc) {
return ListTile(
subtitle: Text(t("Please accept our data protection policy. For more information please click on 'Privacy'")),
title: ToggleSwitch(
minWidth: 100.0,
minHeight: 30.0,
fontSize: 14.0,
initialLabelIndex: loginBloc.dataPolicyAllowed ? 0 : 1,
activeBgColor: Colors.indigo,
activeFgColor: Colors.white,
inactiveBgColor: Colors.white30,
inactiveFgColor: Colors.black,
labels: [t('Yes'), t('No')],
onToggle: (index) {
loginBloc.add(DataProtectionClicked(marked: index == 0));
},
),
);
}
}
+10 -8
View File
@@ -3,12 +3,12 @@ import 'package:aitrainer_app/localization/app_localization.dart';
import 'package:aitrainer_app/repository/user_repository.dart';
import 'package:aitrainer_app/util/trans.dart';
import 'package:aitrainer_app/widgets/app_bar_min.dart';
import 'package:aitrainer_app/widgets/splash.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_form_bloc/flutter_form_bloc.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:modal_progress_hud/modal_progress_hud.dart';
import '../library_keys.dart';
@@ -30,15 +30,13 @@ class ResetPasswordPage extends StatelessWidget with Trans {
key: _scaffoldKey,
appBar: AppBarMin(),
body: FormBlocListener<ResetPasswordFormBloc, String, String>(
onSubmitting: (context, state) {
/* onSubmitting: (context, state) {
LoadingDialog.show(context);
},
}, */
onSuccess: (context, state) {
LoadingDialog.hide(context);
Navigator.of(context).pop();
},
onFailure: (context, state) {
LoadingDialog.hide(context);
showInSnackBar(state.failureResponse);
},
child: SafeArea(
@@ -48,12 +46,16 @@ class ResetPasswordPage extends StatelessWidget with Trans {
image: DecorationImage(
image: AssetImage('asset/image/WT_login.png'),
fit: BoxFit.cover,
//height: double.infinity,
//width: double.infinity,
alignment: Alignment.center,
),
),
child: buildResetPasswordForm(loginBloc),
child: ModalProgressHUD(
child: buildResetPasswordForm(loginBloc),
inAsyncCall: loginBloc.loading == true,
opacity: 0.5,
color: Colors.black54,
progressIndicator: CircularProgressIndicator(),
),
),
),
),
+8 -4
View File
@@ -2,10 +2,10 @@ import 'package:aitrainer_app/bloc/sales/sales_bloc.dart';
import 'package:aitrainer_app/util/trans.dart';
import 'package:aitrainer_app/widgets/app_bar_min.dart';
import 'package:aitrainer_app/widgets/sales_button.dart';
import 'package:aitrainer_app/widgets/splash.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';
// ignore: must_be_immutable
class SalesPage extends StatelessWidget with Trans {
@@ -18,12 +18,16 @@ class SalesPage extends StatelessWidget with Trans {
if (state is SalesError) {
Scaffold.of(context).showSnackBar(
SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white))));
} else if (state is SalesLoading) {
return LoadingDialog();
}
}, builder: (context, state) {
final salesBloc = BlocProvider.of<SalesBloc>(context);
return salesWidget(salesBloc);
return ModalProgressHUD(
child: salesWidget(salesBloc),
inAsyncCall: state is SalesLoading,
opacity: 0.5,
color: Colors.black54,
progressIndicator: CircularProgressIndicator(),
);
}));
}
+3 -2
View File
@@ -3,6 +3,7 @@ import 'package:aitrainer_app/bloc/settings/settings_bloc.dart';
import 'package:aitrainer_app/library/custom_icon_icons.dart';
import 'package:aitrainer_app/localization/app_language.dart';
import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/util/common.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';
@@ -72,7 +73,7 @@ class SettingsPage extends StatelessWidget with Trans {
settingsBloc.add(SettingsChangeLanguage(language: lang)),
})),
getServer(settingsBloc),
getDevice(settingsBloc),
//getDevice(settingsBloc),
]);
}
@@ -109,7 +110,7 @@ class SettingsPage extends StatelessWidget with Trans {
ListTile getDevice(SettingsBloc settingsBloc) {
return ListTile(
leading: Icon(CustomIcon.cog),
leading: Common.badgedIcon(Colors.grey, CustomIcon.cog, "hardware"),
subtitle: Text("Do you have Smart watch, or any device which collects the fit/health data?"),
title: ToggleSwitch(
minWidth: 120.0,