WT1.1.6+3 bodyType animation, bug fixes

This commit is contained in:
bossanyit
2021-02-20 16:48:01 +01:00
parent 3c5360f224
commit cf348cebb0
293 changed files with 2966 additions and 1673 deletions
+92 -32
View File
@@ -1,8 +1,13 @@
import 'dart:collection';
import 'package:aitrainer_app/bloc/account/account_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/model/customer.dart';
import 'package:aitrainer_app/repository/customer_repository.dart';
import 'package:aitrainer_app/util/common.dart';
import 'package:aitrainer_app/util/enums.dart';
import 'package:aitrainer_app/util/trans.dart';
import 'package:aitrainer_app/widgets/app_bar_min.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
@@ -24,7 +29,7 @@ class AccountPage extends StatelessWidget with Trans {
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_light_background.png'),
image: AssetImage('asset/image/WT_light_background.jpg'),
fit: BoxFit.cover,
alignment: Alignment.center,
),
@@ -35,41 +40,27 @@ class AccountPage extends StatelessWidget with Trans {
SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white))));
} else if (state is AccountLoading) {}
}, builder: (context, state) {
if (state is AccountInitial) {
String customerName = accountBloc.customerRepository.firstName + " " + accountBloc.customerRepository.name;
if (customerName.length < 3) {
customerName = t("Personal data");
}
return accountWidget(context, customerName, accountBloc);
} else if (state is AccountLoggedIn) {
String customerName = accountBloc.customerRepository.firstName + " " + accountBloc.customerRepository.name;
if (customerName.length < 3) {
customerName = t("Personal data");
}
return accountWidget(context, customerName, accountBloc);
} else if (state is AccountLoggedOut) {
String customerName = "";
if (customerName.length < 3) {
customerName = t("Personal data");
}
return accountWidget(context, customerName, accountBloc);
} else if (state is AccountReady) {
String customerName = accountBloc.customerRepository.firstName + " " + accountBloc.customerRepository.name;
if (customerName.length < 3) {
customerName = t("Personal data");
}
return accountWidget(context, customerName, accountBloc);
} else {
return accountWidget(context, t("Personal data"), accountBloc);
}
return accountWidget(context, accountBloc);
}),
),
bottomNavigationBar: BottomNavigator(bottomNavIndex: 3));
}
ListView accountWidget(BuildContext context, String customerName, AccountBloc accountBloc) {
ListView accountWidget(BuildContext context, AccountBloc accountBloc) {
String customerName = "";
String goal = t("Set your goal");
String fitnessLevel = t("Set your fitness level");
String bodyType = "";
if (accountBloc.customerRepository.customer != null) {
customerName = accountBloc.customerRepository.firstName + " " + accountBloc.customerRepository.name;
customerName = customerName.length < 3 ? t("Personal data") : customerName;
goal = accountBloc.customerRepository.customer.goal != null ? t(accountBloc.customerRepository.customer.goal) : goal;
fitnessLevel = accountBloc.customerRepository.customer.fitnessLevel != null
? t(capitalize(accountBloc.customerRepository.customer.fitnessLevel))
: fitnessLevel;
bodyType = accountBloc.getAccurateBodyType();
}
final HashMap<String, dynamic> args = HashMap();
return ListView(padding: EdgeInsets.only(top: 35), children: <Widget>[
ListTile(
leading: Common.badgedIcon(Colors.grey, Icons.perm_identity, "personalData"), //Icon(Icons.perm_identity),
@@ -84,7 +75,68 @@ class AccountPage extends StatelessWidget with Trans {
onPressed: () => {
if (accountBloc.customerRepository.customer != null && Cache().userLoggedIn != null)
{
Navigator.of(context).pushNamed('customerModifyPage'),
args['personal_data'] = true,
Navigator.of(context).pushNamed('customerModifyPage', arguments: args),
}
},
),
),
ListTile(
leading: Common.badgedIcon(Colors.grey, Icons.arrow_forward_sharp, "Goal"), //Icon(Icons.arrow_forward_sharp),
subtitle: Text(t("Goal")),
title: FlatButton(
child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
Text(goal, style: TextStyle(color: Colors.blue)),
Icon(Icons.arrow_forward_ios),
]),
textColor: Colors.grey,
color: Colors.white,
onPressed: () => {
if (accountBloc.customerRepository.customer != null && Cache().userLoggedIn != null)
{
args['personal_data'] = true,
args['bloc'] = accountBloc.customerRepository,
Navigator.of(context).pushNamed('customerGoalPage', arguments: args),
}
},
),
),
ListTile(
leading: Common.badgedIcon(Colors.grey, Icons.perm_contact_cal, "FitnessLevel"), //Icon(Icons.perm_contact_cal),
subtitle: Text(t("Activity")),
title: FlatButton(
child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
Text(fitnessLevel, style: TextStyle(color: Colors.blue)),
Icon(Icons.arrow_forward_ios),
]),
textColor: Colors.grey,
color: Colors.white,
onPressed: () => {
if (accountBloc.customerRepository.customer != null && Cache().userLoggedIn != null)
{
args['personal_data'] = true,
args['bloc'] = accountBloc.customerRepository,
Navigator.of(context).pushNamed('customerFitnessPage', arguments: args),
}
},
),
),
ListTile(
leading: Common.badgedIcon(Colors.grey, CustomIcon.people_arrows, "bodyType"), //Icon(CustomIcon.people_arrows),
subtitle: Text(t("Body Type")),
title: FlatButton(
child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
Text(t(bodyType), style: TextStyle(color: Colors.blue)),
Icon(Icons.arrow_forward_ios),
]),
textColor: Colors.grey,
color: Colors.white,
onPressed: () => {
if (accountBloc.customerRepository.customer != null && Cache().userLoggedIn != null)
{
args['personal_data'] = true,
args['bloc'] = accountBloc.customerRepository,
Navigator.of(context).pushNamed('customerBodyTypePage', arguments: args),
}
},
),
@@ -99,6 +151,7 @@ class AccountPage extends StatelessWidget with Trans {
ListTile element = ListTile();
element = ListTile(
leading: Common.badgedIcon(Colors.grey, Icons.device_hub, "customerDevice"),
subtitle: Text(t("These equipments and devices are available")),
title: FlatButton(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
@@ -240,4 +293,11 @@ class AccountPage extends StatelessWidget with Trans {
],
));
}
String capitalize(String s) {
if (s == null || s.isEmpty) {
return " ";
}
return s[0].toUpperCase() + s.substring(1);
}
}
+1 -1
View File
@@ -64,7 +64,7 @@ class _CustomExerciseNewPageState extends State<CustomExercisePage> with Logging
height: MediaQuery.of(context).size.height,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_light_background.png'),
image: AssetImage('asset/image/WT_light_background.jpg'),
fit: BoxFit.fill,
alignment: Alignment.center,
),
+675
View File
@@ -0,0 +1,675 @@
import 'dart:collection';
import 'dart:ui';
import 'package:aitrainer_app/bloc/body_type/bodytype_bloc.dart';
import 'package:aitrainer_app/localization/app_localization.dart';
import 'package:aitrainer_app/repository/customer_repository.dart';
import 'package:aitrainer_app/util/enums.dart';
import 'package:aitrainer_app/util/trans.dart';
import 'package:aitrainer_app/widgets/app_bar.dart';
import 'package:aitrainer_app/widgets/dialog_html.dart';
import 'package:flutter/material.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:liquid_progress_indicator/liquid_progress_indicator.dart';
import 'package:modal_progress_hud/modal_progress_hud.dart';
import 'package:rainbow_color/rainbow_color.dart';
class CustomerBodyTypeAnimationPage extends StatefulWidget {
@override
_CustomerBodyTypeAnimationPageState createState() => _CustomerBodyTypeAnimationPageState();
}
class _CustomerBodyTypeAnimationPageState extends State<CustomerBodyTypeAnimationPage> with Trans {
bool fulldata;
@override
Widget build(BuildContext context) {
CustomerRepository customerRepository;
dynamic args = ModalRoute.of(context).settings.arguments;
if (args is HashMap && args['personal_data'] != null) {
fulldata = args['personal_data'];
customerRepository = args['bloc'];
} else {
customerRepository = ModalRoute.of(context).settings.arguments;
}
setContext(context);
return Scaffold(
appBar: AppBarNav(depth: 0),
body: Container(
height: double.infinity,
width: double.infinity,
alignment: Alignment.center,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_black_G_background.jpg'),
fit: BoxFit.cover,
alignment: Alignment.topCenter,
),
),
child: BlocProvider(
create: (context) => BodytypeBloc(repository: customerRepository),
child: BlocConsumer<BodytypeBloc, BodytypeState>(listener: (context, state) {
if (state is BodytypeError) {
Scaffold.of(context).showSnackBar(
SnackBar(backgroundColor: Colors.orange, content: Text(state.error, style: TextStyle(color: Colors.white))));
}
}, builder: (context, state) {
final bloc = BlocProvider.of<BodytypeBloc>(context);
return ModalProgressHUD(
child: getBodyTypeAnimation(bloc),
inAsyncCall: state is BodytypeLoading,
opacity: 0.5,
color: Colors.black54,
progressIndicator: CircularProgressIndicator(),
);
}))),
);
}
Widget getBodyTypeAnimation(BodytypeBloc bloc) {
return Column(
children: [
Text(t("Body Type Analyser"),
textAlign: TextAlign.center,
style: GoogleFonts.archivoBlack(
fontSize: 24,
color: Colors.yellow[300],
shadows: <Shadow>[
Shadow(
offset: Offset(5.0, 5.0),
blurRadius: 12.0,
color: Colors.black54,
),
Shadow(
offset: Offset(-3.0, 3.0),
blurRadius: 12.0,
color: Colors.black54,
),
],
)),
SizedBox(
height: 30,
),
_AnimatedLiquidCustomProgressIndicator(
percentFrom: ((bloc.step - 1) / 22 * 100).toInt(),
percentTo: (bloc.step / 22 * 100).toInt(),
),
Divider(
color: Colors.transparent,
),
Text(t("How likely is it true about you?"),
textAlign: TextAlign.center,
style: GoogleFonts.archivoBlack(
fontSize: 16,
color: Colors.yellow[300],
shadows: <Shadow>[
Shadow(
offset: Offset(5.0, 5.0),
blurRadius: 12.0,
color: Colors.black54,
),
Shadow(
offset: Offset(-3.0, 3.0),
blurRadius: 12.0,
color: Colors.black54,
),
],
)),
SizedBox(
height: 30,
),
Divider(
color: Colors.white54,
),
Question(
bloc: bloc,
text: bloc.getQuestion(),
),
Divider(color: Colors.transparent),
drawCircles(bloc),
Divider(
color: Colors.transparent,
),
getLegend("Very unlikely", "Maybe", "Very likely"),
Divider(color: Colors.transparent),
InkWell(
onTap: () => bloc.add(BodytypeBack()),
child: Text(t("« Back"),
textAlign: TextAlign.center,
style: GoogleFonts.inter(
fontSize: 16,
color: Colors.blue[300],
shadows: <Shadow>[
Shadow(
offset: Offset(5.0, 5.0),
blurRadius: 12.0,
color: Colors.black54,
),
Shadow(
offset: Offset(-3.0, 3.0),
blurRadius: 12.0,
color: Colors.black54,
),
],
))),
Divider(
color: Colors.white54,
),
SizedBox(
height: 20,
),
bloc.showResults()
? Text(t("Your Bodytype result"),
textAlign: TextAlign.center,
style: GoogleFonts.archivoBlack(
fontSize: 20,
color: Colors.yellow[300],
shadows: <Shadow>[
Shadow(
offset: Offset(5.0, 5.0),
blurRadius: 12.0,
color: Colors.black54,
),
Shadow(
offset: Offset(-3.0, 3.0),
blurRadius: 12.0,
color: Colors.black54,
),
],
))
: Offstage(),
SizedBox(
height: 30,
),
bloc.showResults() ? BodyTypeResult(bloc: bloc) : Offstage(),
Divider(
color: Colors.transparent,
),
bloc.showResults()
? getLegend(PropertyEnum.Ectomorph.toStr(), PropertyEnum.Mesomorph.toStr(), PropertyEnum.Endomorph.toStr(), info: true)
: Offstage(),
],
);
}
Widget getLegend(String text1, String text2, String text3, {bool info = false}) {
return Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
Text(t(text1),
textAlign: TextAlign.center,
style: GoogleFonts.archivoBlack(
fontSize: 14,
color: Colors.green[300],
shadows: <Shadow>[
Shadow(
offset: Offset(2.0, 2.0),
blurRadius: 14.0,
color: Colors.black54,
),
Shadow(
offset: Offset(-3.0, 3.0),
blurRadius: 12.0,
color: Colors.black54,
),
],
)),
info
? GestureDetector(
onTap: () => showDialog(
context: context,
builder: (BuildContext context) {
return DialogHTML(
title: t(text1),
htmlData: t(text1 + "_desc"),
);
}),
child: Icon(
Icons.info_outline_rounded,
color: Colors.yellow[100],
))
: Offstage(),
SizedBox(
width: 5,
),
Text(t(text2),
textAlign: TextAlign.center,
style: GoogleFonts.archivoBlack(
fontSize: 14,
color: Colors.green[300],
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,
),
],
)),
info
? GestureDetector(
onTap: () => showDialog(
context: context,
builder: (BuildContext context) {
return DialogHTML(
title: t(text2),
htmlData: t(text2 + "_desc"),
);
}),
child: Icon(
Icons.info_outline_rounded,
color: Colors.yellow[100],
))
: Offstage(),
SizedBox(
width: 5,
),
Text(t(text3),
textAlign: TextAlign.center,
style: GoogleFonts.archivoBlack(
fontSize: 14,
color: Colors.green[300],
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,
),
],
)),
info
? GestureDetector(
onTap: () => showDialog(
context: context,
builder: (BuildContext context) {
return DialogHTML(
title: t(text3),
htmlData: t(text3 + "_desc"),
);
}),
child: Icon(
Icons.info_outline_rounded,
color: Colors.yellow[100],
))
: Offstage(),
]);
}
Widget drawCircles(BodytypeBloc bloc) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
CircleButton(value: 1, bloc: bloc, onTap: () => bloc.add(BodytypeClick(value: 1))),
CircleButton(value: 2, bloc: bloc, onTap: () => bloc.add(BodytypeClick(value: 2))),
CircleButton(value: 3, bloc: bloc, onTap: () => bloc.add(BodytypeClick(value: 3))),
CircleButton(value: 4, bloc: bloc, onTap: () => bloc.add(BodytypeClick(value: 4))),
CircleButton(value: 5, bloc: bloc, onTap: () => bloc.add(BodytypeClick(value: 5))),
],
);
}
}
class BodyTypeResult extends StatefulWidget {
final BodytypeBloc bloc;
const BodyTypeResult({this.bloc});
@override
_BodyTypeResultState createState() => _BodyTypeResultState();
}
class _BodyTypeResultState extends State<BodyTypeResult> with TickerProviderStateMixin {
Animation<Color> colorAnim;
AnimationController colorController;
@override
void initState() {
buildAnimation();
super.initState();
}
void buildAnimation() {
colorController = AnimationController(duration: Duration(seconds: 2), vsync: this);
colorAnim = RainbowColorTween([
Colors.green[800],
Colors.green[700],
Colors.green[600],
Colors.green[500],
Colors.green[400],
Colors.green[300],
Colors.green[200],
Colors.green[100],
Color(0xffb4f500),
]).animate(colorController)
..addListener(() {
setState(() {});
});
colorController.forward();
}
@override
void didUpdateWidget(BodyTypeResult oldWidget) {
buildAnimation();
super.didUpdateWidget(oldWidget);
}
@override
void dispose() {
colorController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.only(left: 15, right: 15),
width: MediaQuery.of(context).size.width - 20,
height: 5,
child: CustomPaint(
painter: CurvePainter(value: widget.bloc.getBodyTypeValue(), color: colorAnim.value),
));
}
}
class CurvePainter extends CustomPainter {
final linePainter = Paint();
final circlePainter = Paint();
final Color color;
final int value;
CurvePainter({this.value, this.color});
@override
void paint(Canvas canvas, Size size) {
var paint = linePainter;
paint.color = Colors.green[800];
paint.strokeWidth = 5;
paint.style = PaintingStyle.fill;
canvas.drawLine(
Offset(0, size.height / 2),
Offset(size.width, size.height / 2),
paint,
);
paint.strokeWidth = 12;
canvas.drawCircle(Offset(size.width / 2, size.height / 2), 6, paint);
canvas.drawCircle(Offset(0, size.height / 2), 6, paint);
canvas.drawCircle(Offset(size.width, size.height / 2), 6, paint);
var paint2 = circlePainter;
paint2.color = this.color; //Color(0xffb4f500);
paint2.strokeWidth = 30;
canvas.drawCircle(Offset(size.width * (value / 100), size.height / 2), 15, paint2);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return false;
}
}
class Question extends StatefulWidget {
final String text;
final BodytypeBloc bloc;
const Question({this.text, this.bloc});
@override
_QuestionState createState() => _QuestionState();
}
class _QuestionState extends State<Question> with TickerProviderStateMixin {
AnimationController _controller;
Animation<double> _animation;
@override
void initState() {
super.initState();
buildAnimation();
}
@override
void didUpdateWidget(Question oldWidget) {
if (oldWidget.text != widget.text) {
buildAnimation();
}
super.didUpdateWidget(oldWidget);
}
void buildAnimation() {
_controller = AnimationController(duration: const Duration(milliseconds: 1000), vsync: this);
_animation = CurvedAnimation(parent: _controller, curve: Curves.slowMiddle);
_controller.forward();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.only(left: 10, right: 10),
child: FadeTransition(
key: ValueKey(widget.text),
opacity: _animation,
child: Text(AppLocalizations.of(context).translate(widget.bloc.getQuestion()),
textAlign: TextAlign.center,
maxLines: 3,
style: GoogleFonts.archivoBlack(
fontSize: 18,
color: Color(0xffb4f500),
shadows: <Shadow>[
Shadow(
offset: Offset(5.0, 5.0),
blurRadius: 12.0,
color: Colors.black54,
),
Shadow(
offset: Offset(-3.0, 3.0),
blurRadius: 12.0,
color: Colors.black54,
),
],
))));
}
}
class CircleButton extends StatefulWidget {
final GestureTapCallback onTap;
final BodytypeBloc bloc;
final int value;
CircleButton({Key key, this.onTap, this.bloc, this.value}) : super(key: key);
@override
_CircleButtonState createState() => _CircleButtonState();
}
class _CircleButtonState extends State<CircleButton> with TickerProviderStateMixin {
Animation<Color> colorAnim;
AnimationController colorController;
@override
void initState() {
buildAnimation();
super.initState();
}
@override
void dispose() {
colorController.dispose();
super.dispose();
}
@override
void didUpdateWidget(CircleButton oldWidget) {
if (widget.bloc.getPrevValue() == widget.value) {
buildAnimation();
}
super.didUpdateWidget(oldWidget);
}
void buildAnimation() {
colorController = AnimationController(duration: Duration(seconds: 2), vsync: this);
colorAnim = RainbowColorTween([
Color(0xffb4f500),
Color(0xffb4f500),
Color(0xffb4f500),
Color(0xffb4f500),
Color(0xffb4f500),
Color(0xffb4f500),
Colors.green[100],
Colors.green[200],
Colors.green[300],
Colors.green[400],
Colors.green[500],
Colors.green[600],
Colors.green[700],
Colors.green[800],
]).animate(colorController)
..addListener(() {
setState(() {});
});
colorController.forward();
}
@override
Widget build(BuildContext context) {
final double size = 50.0;
return InkResponse(
onTap: () => {
widget.bloc.add(BodytypeClick(value: widget.value)),
},
child: Container(
key: UniqueKey(),
width: size,
height: size,
decoration: BoxDecoration(
color: widget.value == widget.bloc.getPrevValue() ? colorAnim.value : Colors.green[800],
shape: BoxShape.circle,
)));
}
}
class _AnimatedLiquidCustomProgressIndicator extends StatefulWidget {
final int percentTo;
final int percentFrom;
const _AnimatedLiquidCustomProgressIndicator({this.percentTo, this.percentFrom});
@override
State<StatefulWidget> createState() => _AnimatedLiquidCustomProgressIndicatorState();
}
class _AnimatedLiquidCustomProgressIndicatorState extends State<_AnimatedLiquidCustomProgressIndicator> with TickerProviderStateMixin {
AnimationController _animationController;
bool switching = false;
@override
void didChangeDependencies() {
buildAnimation();
super.didChangeDependencies();
}
@override
void didUpdateWidget(_AnimatedLiquidCustomProgressIndicator oldWidget) {
if (oldWidget.percentFrom != widget.percentFrom) {
buildAnimation();
}
super.didUpdateWidget(oldWidget);
}
void buildAnimation() {
_animationController = AnimationController(
lowerBound: (widget.percentFrom / 100).toDouble(),
upperBound: (widget.percentTo / 100).toDouble(),
vsync: this,
duration: Duration(seconds: 3),
)..addListener(() {
setState(() {});
});
_animationController.forward();
}
@override
void initState() {
buildAnimation();
super.initState();
}
@override
void dispose() {
_animationController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final percentage = _animationController.value * 100;
return Center(
key: ValueKey(widget.percentFrom),
child: LiquidCustomProgressIndicator(
value: _animationController.value,
direction: Axis.vertical,
backgroundColor: Colors.white,
valueColor: AlwaysStoppedAnimation(Colors.blue[200]),
shapePath: _buildHeartPath(),
center: Text(
"${percentage.toStringAsFixed(0)}%",
style: TextStyle(
color: Colors.blue[800],
fontSize: 20.0,
fontWeight: FontWeight.bold,
),
),
),
);
}
Path _buildHeartPath() {
return Path()
..moveTo(55, 15)
..cubicTo(55, 12, 50, 0, 30, 0)
..cubicTo(0, 0, 0, 37.5, 0, 37.5)
..cubicTo(0, 55, 20, 77, 55, 95)
..cubicTo(90, 77, 110, 55, 110, 37.5)
..cubicTo(110, 37.5, 110, 0, 80, 0)
..cubicTo(65, 0, 55, 12, 55, 15)
..close();
}
Path _buildManPath() {
return Path()
..moveTo(55, 15)
..cubicTo(75, 20, 75, 32, 68, 38)
..lineTo(68, 43)
..lineTo(116, 43)
..lineTo(116, 55)
..lineTo(75, 55)
..conicTo(68, 80, 80, 120, 20)
..lineTo(68, 120)
..lineTo(55, 90)
..lineTo(42, 120)
..lineTo(20, 120)
..conicTo(42, 80, 40, 55, 40)
..lineTo(0, 55)
..lineTo(0, 43)
..lineTo(48, 43)
..lineTo(48, 38)
..cubicTo(25, 20, 25, 32, 55, 15)
..close();
}
}
+20 -6
View File
@@ -1,8 +1,10 @@
import 'dart:collection';
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/app_bar_progress.dart';
import 'package:aitrainer_app/widgets/dialog_html.dart';
import 'package:badges/badges.dart';
import 'package:flutter/material.dart';
@@ -26,18 +28,30 @@ class BodyTypeItem {
class _CustomerBodyTypePageState extends State<CustomerBodyTypePage> with Trans {
String selected;
bool fulldata = false;
@override
Widget build(BuildContext context) {
final CustomerRepository customerRepository = ModalRoute.of(context).settings.arguments;
CustomerRepository customerRepository;
dynamic args = ModalRoute.of(context).settings.arguments;
if (args is HashMap && args['personal_data'] != null) {
fulldata = args['personal_data'];
customerRepository = args['bloc'];
} else {
customerRepository = ModalRoute.of(context).settings.arguments;
}
final double cWidth = MediaQuery.of(context).size.width * 0.75;
setContext(context);
return Scaffold(
appBar: AppBarMin(),
appBar: fulldata
? AppBarMin(
back: true,
)
: AppBarProgress(min: 76, max: 100),
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_light_background.png'),
image: AssetImage('asset/image/WT_light_background.jpg'),
fit: BoxFit.cover,
alignment: Alignment.center,
),
@@ -178,11 +192,11 @@ class _CustomerBodyTypePageState extends State<CustomerBodyTypePage> with Trans
RaisedButton(
color: Colors.orange,
textColor: Colors.white,
child: InkWell(child: Text(AppLocalizations.of(context).translate("Next"))),
child: Text(fulldata ? t("Save") : t("Next")),
onPressed: () => {
changeBloc.add(CustomerSave()),
Navigator.of(context).pop(),
Navigator.of(context).pushNamed("customerWelcomePage", arguments: customerRepository)
if (fulldata == false) {Navigator.of(context).pushNamed("customerWelcomePage", arguments: customerRepository)}
},
)
],
+3 -3
View File
@@ -27,7 +27,7 @@ class CustomerExerciseDevicePage extends StatelessWidget with Trans {
padding: EdgeInsets.all(10),
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_black_background.png'),
image: AssetImage('asset/image/WT_black_background.jpg'),
fit: BoxFit.cover,
alignment: Alignment.center,
),
@@ -189,7 +189,7 @@ class CustomerExerciseDevicePage extends StatelessWidget with Trans {
devices.sort((a, b) => a.sort.compareTo(b.sort));
devices.forEach((element) {
if (element.place == false) {
final String url = "asset/image/" + element.imageUrl.substring(7);
final String url = "asset/equipment/" + element.imageUrl.substring(7);
ImageButton button = ImageButton(
width: cWidth / 2 - 10,
height: cWidth / 2 - 10,
@@ -219,7 +219,7 @@ class CustomerExerciseDevicePage extends StatelessWidget with Trans {
devices.sort((a, b) => a.sort.compareTo(b.sort));
devices.forEach((element) {
if (element.place) {
final String url = "asset/image/" + element.imageUrl.substring(7);
final String url = "asset/equipment/" + element.imageUrl.substring(7);
ImageButton button = ImageButton(
width: cWidth - 60,
height: cWidth / 2 - 40,
+32 -33
View File
@@ -1,7 +1,12 @@
import 'dart:collection';
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/model/fitness_state.dart';
import 'package:aitrainer_app/util/trans.dart';
import 'package:aitrainer_app/widgets/app_bar_min.dart';
import 'package:aitrainer_app/widgets/app_bar_progress.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
@@ -17,51 +22,45 @@ class CustomerFitnessPage extends StatefulWidget {
}
}
/* class FitnessItem {
static String beginner = "beginner";
static String intermediate = "intermediate";
static String advanced = "advanced";
static String professional = "professional";
}
*/
//TODO
// dropbox for professional sport
class _CustomerFitnessPageState extends State<CustomerFitnessPage> {
class _CustomerFitnessPageState extends State<CustomerFitnessPage> with Trans {
String selected;
bool fulldata = false;
@override
Widget build(BuildContext context) {
setContext(context);
final double cWidth = MediaQuery.of(context).size.width * 0.75;
final CustomerRepository customerRepository = ModalRoute.of(context).settings.arguments;
CustomerRepository customerRepository;
dynamic args = ModalRoute.of(context).settings.arguments;
if (args is HashMap && args['personal_data'] != null) {
fulldata = args['personal_data'];
customerRepository = args['bloc'];
} else {
customerRepository = ModalRoute.of(context).settings.arguments;
}
selected = customerRepository.customer.fitnessLevel;
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: fulldata
? AppBarMin(
back: true,
)
: AppBarProgress(max: 75, min: 51),
body: BlocProvider(
create: (context) => CustomerChangeBloc(customerRepository: customerRepository),
child: Builder(builder: (context) {
// ignore: close_sinks
CustomerChangeBloc changeBloc = BlocProvider.of<CustomerChangeBloc>(context);
return SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Container(
padding: EdgeInsets.only(bottom: 200),
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_light_background.png'),
image: AssetImage('asset/image/WT_light_background.jpg'),
fit: BoxFit.cover,
alignment: Alignment.center,
),
@@ -75,7 +74,7 @@ class _CustomerFitnessPageState extends State<CustomerFitnessPage> {
alignment: WrapAlignment.center,
children: [
Text(
AppLocalizations.of(context).translate("Your Fitness State"),
t("Your Fitness State"),
textAlign: TextAlign.center,
style: TextStyle(color: Colors.orange, fontSize: 42, fontFamily: 'Arial', fontWeight: FontWeight.w900),
)
@@ -86,11 +85,11 @@ class _CustomerFitnessPageState extends State<CustomerFitnessPage> {
width: cWidth,
child: Column(
children: [
Text(AppLocalizations.of(context).translate("Beginner"),
Text(t("Beginner"),
textWidthBasis: TextWidthBasis.longestLine,
style: TextStyle(color: Colors.blue, fontSize: 32, fontFamily: 'Arial', fontWeight: FontWeight.w900)),
Text(
AppLocalizations.of(context).translate("I am beginner"),
t("I am beginner"),
style: TextStyle(color: Colors.black, fontSize: 20, fontFamily: 'Arial', fontWeight: FontWeight.w100),
),
],
@@ -111,14 +110,14 @@ class _CustomerFitnessPageState extends State<CustomerFitnessPage> {
children: [
InkWell(
child: Text(
AppLocalizations.of(context).translate("Intermediate"),
t("Intermediate"),
style: TextStyle(color: Colors.blue, fontSize: 32, fontFamily: 'Arial', fontWeight: FontWeight.w900),
),
highlightColor: Colors.white,
),
InkWell(
child: Text(
AppLocalizations.of(context).translate("I am intermediate"),
t("I am intermediate"),
style: TextStyle(color: Colors.black, fontSize: 20, fontFamily: 'Arial', fontWeight: FontWeight.w100),
),
highlightColor: Colors.white,
@@ -143,14 +142,14 @@ class _CustomerFitnessPageState extends State<CustomerFitnessPage> {
children: [
InkWell(
child: Text(
AppLocalizations.of(context).translate("Advanced"),
t("Advanced"),
style: TextStyle(color: Colors.blue, fontSize: 32, fontFamily: 'Arial', fontWeight: FontWeight.w900),
),
highlightColor: Colors.white,
),
InkWell(
child: Text(
AppLocalizations.of(context).translate("I am advanced"),
t("I am advanced"),
style: TextStyle(color: Colors.black, fontSize: 20, fontFamily: 'Arial', fontWeight: FontWeight.w100),
),
highlightColor: Colors.white,
@@ -203,11 +202,11 @@ class _CustomerFitnessPageState extends State<CustomerFitnessPage> {
RaisedButton(
color: Colors.orange,
textColor: Colors.white,
child: InkWell(child: Text(AppLocalizations.of(context).translate("Next"))),
child: Text(fulldata ? t("Save") : t("Next")),
onPressed: () => {
changeBloc.add(CustomerSave()),
Navigator.of(context).pop(),
Navigator.of(context).pushNamed("customerBodyTypePage", arguments: customerRepository)
if (!fulldata) {Navigator.of(context).pushNamed("customerBodyTypePage", arguments: customerRepository)}
},
)
],
+27 -20
View File
@@ -1,6 +1,11 @@
import 'dart:collection';
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/app_bar_progress.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_form_bloc/flutter_form_bloc.dart';
@@ -16,31 +21,33 @@ class CustomerGoalPage extends StatefulWidget {
State<StatefulWidget> createState() => _CustomerGoalPage();
}
class _CustomerGoalPage extends State<CustomerGoalPage> {
class _CustomerGoalPage extends State<CustomerGoalPage> with Trans {
String selected;
bool fulldata = false;
@override
Widget build(BuildContext context) {
final CustomerRepository customerRepository = ModalRoute.of(context).settings.arguments;
setContext(context);
CustomerRepository customerRepository;
dynamic args = ModalRoute.of(context).settings.arguments;
if (args is HashMap && args['personal_data'] != null) {
fulldata = args['personal_data'];
customerRepository = args['bloc'];
} else {
customerRepository = ModalRoute.of(context).settings.arguments;
}
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: fulldata
? AppBarMin(
back: true,
)
: AppBarProgress(max: 50, min: 26),
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_light_background.png'),
image: AssetImage('asset/image/WT_light_background.jpg'),
fit: BoxFit.cover,
alignment: Alignment.center,
),
@@ -67,7 +74,7 @@ class _CustomerGoalPage extends State<CustomerGoalPage> {
Stack(alignment: Alignment.bottomLeft, overflow: Overflow.visible, children: [
FlatButton(
child: Image.asset(
"asset/image/Gain_muscle.png",
"asset/image/Gain_muscle.jpg",
height: 180,
),
padding: EdgeInsets.all(0.0),
@@ -90,7 +97,7 @@ class _CustomerGoalPage extends State<CustomerGoalPage> {
Stack(alignment: Alignment.bottomLeft, overflow: Overflow.visible, children: [
FlatButton(
child: Image.asset(
"asset/image/WT_weight_loss.png",
"asset/image/WT_weight_loss.jpg",
height: 180,
),
padding: EdgeInsets.all(0.0),
@@ -113,12 +120,12 @@ class _CustomerGoalPage extends State<CustomerGoalPage> {
RaisedButton(
color: Colors.orange,
textColor: Colors.white,
child: InkWell(child: Text(AppLocalizations.of(context).translate("Next"))),
child: Text(fulldata ? t("Save") : t("Next")),
onPressed: () => {
//changingViewModel.saveCustomer(),
changeBloc.add(CustomerSave()),
Navigator.of(context).pop(),
Navigator.of(context).pushNamed("customerFitnessPage", arguments: changeBloc.customerRepository)
if (!fulldata) {Navigator.of(context).pushNamed("customerFitnessPage", arguments: changeBloc.customerRepository)}
},
)
],
+46 -58
View File
@@ -1,10 +1,13 @@
import 'dart:collection';
import 'package:aitrainer_app/bloc/account/account_bloc.dart';
import 'package:aitrainer_app/bloc/customer_change/customer_change_bloc.dart';
import 'package:aitrainer_app/library/numberpicker.dart';
import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/util/enums.dart';
import 'package:aitrainer_app/util/trans.dart';
import 'package:aitrainer_app/widgets/app_bar_min.dart';
import 'package:aitrainer_app/widgets/app_bar_progress.dart';
import 'package:aitrainer_app/widgets/number_picker.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/widgets.dart';
@@ -19,9 +22,15 @@ import '../library_keys.dart';
// ignore: must_be_immutable
class CustomerModifyPage extends StatelessWidget with Trans {
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
bool fulldata = false;
@override
Widget build(BuildContext context) {
dynamic arguments = ModalRoute.of(context).settings.arguments;
if (arguments is HashMap && arguments['personal_data'] != null) {
fulldata = arguments['personal_data'];
}
setContext(context);
// ignore: close_sinks
final accountBloc = BlocProvider.of<AccountBloc>(context);
@@ -34,13 +43,15 @@ class CustomerModifyPage extends StatelessWidget with Trans {
return Scaffold(
resizeToAvoidBottomInset: true,
appBar: AppBarMin(
back: true,
),
appBar: fulldata
? AppBarMin(
back: true,
)
: AppBarProgress(max: 25, min: 0),
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_light_background.png'),
image: AssetImage('asset/image/WT_light_background.jpg'),
fit: BoxFit.fill,
alignment: Alignment.center,
),
@@ -56,7 +67,11 @@ class CustomerModifyPage extends StatelessWidget with Trans {
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);
if (fulldata) {
Navigator.of(context).pop();
} else {
Navigator.of(context).pushNamed("customerGoalPage", arguments: customerBloc.customerRepository);
}
}
},
builder: (context, state) {
@@ -83,14 +98,11 @@ class CustomerModifyPage extends StatelessWidget with Trans {
alignment: Alignment.center,
child: Column(
children: [
Text(t("Please provide us some personal data"),
style: GoogleFonts.inter(color: Colors.indigo, fontSize: 16), textAlign: TextAlign.center),
Text(t("To lift your experience using the app"),
style: GoogleFonts.inter(color: Colors.orange[700], fontSize: 16), textAlign: TextAlign.center),
Text(t("Edit Profile"), style: GoogleFonts.inter(color: Colors.indigo, fontSize: 16), textAlign: TextAlign.center),
Divider(
color: Colors.transparent,
),
Cache().getLoginType() == LoginType.email
Cache().getLoginType() == LoginType.email || fulldata
? TextFormField(
key: LibraryKeys.loginEmailField,
decoration: InputDecoration(
@@ -148,7 +160,7 @@ class CustomerModifyPage extends StatelessWidget with Trans {
Divider(
color: Colors.transparent,
),
Cache().getLoginType() != LoginType.apple
Cache().getLoginType() != LoginType.apple || fulldata
? TextFormField(
decoration: InputDecoration(
contentPadding: EdgeInsets.only(left: 15, top: 15, bottom: 15),
@@ -173,7 +185,7 @@ class CustomerModifyPage extends StatelessWidget with Trans {
Divider(
color: Colors.transparent,
),
Cache().getLoginType() != LoginType.apple
Cache().getLoginType() != LoginType.apple || fulldata
? TextFormField(
decoration: InputDecoration(
contentPadding: EdgeInsets.only(left: 15, top: 15, bottom: 15),
@@ -203,75 +215,51 @@ class CustomerModifyPage extends StatelessWidget with Trans {
children: [
Expanded(
flex: 4,
child: Text(t("Birth Year"), style: TextStyle(fontWeight: FontWeight.normal, fontSize: 14)),
child: Text(t("Birth Year"), style: TextStyle(fontWeight: FontWeight.normal, fontSize: 18)),
),
Flexible(
fit: FlexFit.tight,
flex: 8,
child: NumberPicker.horizontal(
highlightSelectedValue: true,
initialValue: customerBloc.year,
NumberPickerWidget(
minValue: 1930,
maxValue: 2100,
step: 1,
textStyle: TextStyle(fontWeight: FontWeight.bold),
textStyleHighlighted: TextStyle(fontSize: 16, color: Colors.indigo, fontWeight: FontWeight.bold),
onChanged: (value) => {customerBloc.add(CustomerBirthYearChange(year: value))},
listViewHeight: 60,
//decoration: _decoration,
),
),
initalValue: customerBloc.year.toInt(),
unit: " ",
color: Colors.indigo,
onChange: (value) => {customerBloc.add(CustomerBirthYearChange(year: value.toInt()))}),
SizedBox(width: 80),
],
),
Divider(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Expanded(
flex: 4,
child: Text(t("Weight"), style: TextStyle(fontWeight: FontWeight.normal, fontSize: 14)),
child: Text(t("Weight"), style: TextStyle(fontWeight: FontWeight.normal, fontSize: 18)),
),
Flexible(
fit: FlexFit.tight,
flex: 8,
child: NumberPicker.horizontal(
highlightSelectedValue: true,
initialValue: customerBloc.weight.toInt(),
NumberPickerWidget(
minValue: 0,
maxValue: 200,
step: 1,
textStyle: TextStyle(fontWeight: FontWeight.bold),
textStyleHighlighted: TextStyle(fontSize: 18, color: Colors.indigo, fontWeight: FontWeight.bold),
onChanged: (value) => {customerBloc.add(CustomerWeightChange(weight: value))},
listViewHeight: 60,
),
),
initalValue: customerBloc.weight.toInt(),
unit: " ",
color: Colors.indigo,
onChange: (value) => {customerBloc.add(CustomerWeightChange(weight: value.toInt()))}),
SizedBox(width: 80),
],
),
Divider(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Expanded(
flex: 4,
child: Text(t("Height"), style: TextStyle(fontWeight: FontWeight.normal, fontSize: 14)),
child: Text(t("Height"), style: TextStyle(fontWeight: FontWeight.normal, fontSize: 18)),
),
Flexible(
fit: FlexFit.tight,
flex: 8,
child: NumberPicker.horizontal(
highlightSelectedValue: true,
initialValue: customerBloc.height.toInt(),
NumberPickerWidget(
minValue: 0,
maxValue: 230,
step: 1,
textStyle: TextStyle(fontWeight: FontWeight.bold),
textStyleHighlighted: TextStyle(fontSize: 18, color: Colors.indigo, fontWeight: FontWeight.bold),
onChanged: (value) => {customerBloc.add(CustomerHeightChange(height: value))},
listViewHeight: 60,
),
),
initalValue: customerBloc.height.toInt(),
unit: " ",
color: Colors.indigo[300],
onChange: (value) => {customerBloc.add(CustomerHeightChange(height: value.toInt()))}),
SizedBox(width: 80),
],
),
@@ -298,7 +286,7 @@ class CustomerModifyPage extends StatelessWidget with Trans {
children: [
Image.asset('asset/icon/gomb_orange_a.png', width: 140, height: 60),
Text(
t("Next"),
fulldata ? t("Save") : t("Next"),
style: TextStyle(fontSize: 16, color: Colors.white),
),
],
+1 -1
View File
@@ -35,7 +35,7 @@ class _CustomerWelcomePageState extends State<CustomerWelcomePage> {
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_welcome.png'),
image: AssetImage('asset/image/WT_welcome.jpg'),
fit: BoxFit.fill,
alignment: Alignment.center,
),
+8 -13
View File
@@ -35,10 +35,10 @@ class EvaluationPage extends StatelessWidget with Trans {
String imageUrl = "";
if (Cache().userLoggedIn.sex == "m") {
resultType = ResultType.man;
imageUrl = 'asset/image/WT_Results_for_men.png';
imageUrl = 'asset/image/WT_Results_for_men.jpg';
} else {
resultType = ResultType.man;
imageUrl = 'asset/image/WT_Results_for_female.png';
imageUrl = 'asset/image/WT_Results_for_female.jpg';
}
if (arguments['past'] != null && arguments['past'] == true) {
@@ -53,7 +53,7 @@ class EvaluationPage extends StatelessWidget with Trans {
}
if (exerciseRepository.exerciseType.getAbility().equalsTo(ExerciseAbility.running)) {
resultType = ResultType.running;
imageUrl = 'asset/image/WT_Results_for_runners.png';
imageUrl = 'asset/image/WT_Results_for_runners.jpg';
}
setContext(context);
@@ -81,11 +81,6 @@ class EvaluationPage extends StatelessWidget with Trans {
if (state is ResultError) {
Scaffold.of(context).showSnackBar(
SnackBar(backgroundColor: Colors.orange, content: Text(state.error, style: TextStyle(color: Colors.white))));
} else if (state is ResultLoading) {
Scaffold.of(context).showSnackBar(SnackBar(
duration: Duration(milliseconds: 100),
backgroundColor: Colors.transparent,
content: Container(child: Center(child: CircularProgressIndicator()))));
}
}, builder: (context, state) {
final resultBloc = BlocProvider.of<ResultBloc>(context);
@@ -110,9 +105,9 @@ class EvaluationPage extends StatelessWidget with Trans {
SliverAppBar(
pinned: true,
backgroundColor: Colors.transparent,
expandedHeight: 120.0,
collapsedHeight: 80,
toolbarHeight: 30,
expandedHeight: 100.0,
collapsedHeight: 100,
toolbarHeight: 40,
automaticallyImplyLeading: false,
flexibleSpace: FlexibleSpaceBar(
title: Text(exerciseName,
@@ -120,8 +115,8 @@ class EvaluationPage extends StatelessWidget with Trans {
maxLines: 3,
//softWrap: true,
style: GoogleFonts.archivoBlack(
fontSize: 24,
color: Colors.white,
fontSize: 20,
color: Colors.yellow[300],
shadows: <Shadow>[
Shadow(
offset: Offset(5.0, 5.0),
+145 -45
View File
@@ -78,8 +78,8 @@ class _ExerciseControlPage extends State<ExerciseControlPage> with Trans {
decoration: BoxDecoration(
image: DecorationImage(
image: Cache().userLoggedIn.sex == "m"
? AssetImage("asset/image/WT_Results_for_men.png")
: AssetImage("asset/image/WT_Results_for_female.png"),
? AssetImage("asset/image/WT_Results_for_men.jpg")
: AssetImage("asset/image/WT_Results_for_female.jpg"),
fit: BoxFit.cover,
alignment: Alignment.topCenter,
),
@@ -229,7 +229,7 @@ class _ExerciseControlPage extends State<ExerciseControlPage> with Trans {
numberPickForm(exerciseBloc, 3),
]),
))),
bottomNavigationBar: BottomNavigator(bottomNavIndex: 1),
//bottomNavigationBar: BottomNavigator(bottomNavIndex: 1),
),
);
}
@@ -253,19 +253,7 @@ class _ExerciseControlPage extends State<ExerciseControlPage> with Trans {
}
Widget numberPickForm(ExerciseControlBloc exerciseBloc, int step) {
String strTimes = step == 2 ? exerciseBloc.origQuantity.toStringAsFixed(0) : "max.";
String textInstruction = "";
textInstruction = t("Please repeat with ") +
exerciseBloc.unitQuantity.toStringAsFixed(0) +
" " +
exerciseBloc.exerciseRepository.exerciseType.unitQuantityUnit +
t("hu_with") +
" " +
strTimes +
" " +
t(
"times!",
);
final String strTimes = step == 2 ? exerciseBloc.origQuantity.toStringAsFixed(0) : "max.";
String title = (step + 1).toString() + "/4 " + t("Control Exercise:");
LinkedHashMap args = LinkedHashMap();
@@ -275,44 +263,55 @@ class _ExerciseControlPage extends State<ExerciseControlPage> with Trans {
title,
style: GoogleFonts.inter(color: Colors.yellow[300], fontSize: 18, fontWeight: FontWeight.bold),
),
RichText(
text: TextSpan(
style: GoogleFonts.inter(
fontSize: 16,
fontWeight: FontWeight.normal,
color: Colors.yellow[300],
),
children: [
TextSpan(text: t("Please repeat with ")),
TextSpan(
text: exerciseBloc.unitQuantity.toStringAsFixed(0) + " " + exerciseBloc.exerciseRepository.exerciseType.unitQuantityUnit,
GestureDetector(
onTap: () => showDialog(
context: context,
builder: (BuildContext context) {
return UnitQuantityControl(
exerciseBloc: exerciseBloc,
step: step,
);
}),
child: RichText(
text: TextSpan(
style: GoogleFonts.inter(
fontSize: 16,
fontWeight: FontWeight.bold,
color: Colors.yellow[400],
fontWeight: FontWeight.normal,
color: Colors.yellow[300],
),
),
TextSpan(
text: t("hu_with") +
" " +
strTimes +
" " +
t(
"times!",
))
]),
),
/* Text(
textInstruction,
style: GoogleFonts.inter(color: Colors.yellow[300], fontSize: 16),
), */
children: [
TextSpan(text: t("Please repeat with ")),
TextSpan(
text:
exerciseBloc.unitQuantity.toStringAsFixed(0) + " " + exerciseBloc.exerciseRepository.exerciseType.unitQuantityUnit,
style: GoogleFonts.inter(
decoration: TextDecoration.underline,
fontSize: 16,
fontWeight: FontWeight.bold,
color: Colors.yellow[100],
),
),
TextSpan(text: t("hu_with") + " "),
TextSpan(
text: strTimes + " ",
style: GoogleFonts.inter(
fontSize: 16,
fontWeight: FontWeight.bold,
color: Colors.yellow[100],
)),
TextSpan(
text: t(
"times!",
)),
]),
)),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
NumberPickerWidget(
minValue: 0,
maxValue: 200,
initalValue: exerciseBloc.quantity.toInt(),
initalValue: exerciseBloc.quantity.round(),
unit: t("reps"),
color: Colors.yellow[50],
onChange: (value) => {exerciseBloc.add(ExerciseControlQuantityChange(quantity: value.toDouble(), step: step))}),
@@ -354,3 +353,104 @@ class _ExerciseControlPage extends State<ExerciseControlPage> with Trans {
);
}
}
class UnitQuantityControl extends StatefulWidget {
final ExerciseControlBloc exerciseBloc;
final int step;
const UnitQuantityControl({this.exerciseBloc, this.step});
@override
_UnitQuantityControlState createState() => _UnitQuantityControlState();
}
class _UnitQuantityControlState extends State<UnitQuantityControl> with Trans {
double changedValue;
@override
Widget build(BuildContext context) {
changedValue = widget.exerciseBloc.unitQuantity;
setContext(context);
return Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(31),
),
elevation: 0,
backgroundColor: Colors.transparent,
child: contentBox(context),
);
}
contentBox(context) {
return Stack(alignment: AlignmentDirectional.topStart, children: <Widget>[
Container(
padding: EdgeInsets.only(left: 20, top: 24, right: 20, bottom: 30),
margin: EdgeInsets.only(top: 30),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(24),
boxShadow: [BoxShadow(color: Colors.black, offset: Offset(0, 10), blurRadius: 10)],
image: DecorationImage(
image: AssetImage('asset/image/WT_results_background.jpg'),
fit: BoxFit.cover,
alignment: Alignment.center,
),
),
child: Column(mainAxisSize: MainAxisSize.min, children: [
Text(
t("Change the weight to"),
textAlign: TextAlign.center,
style: GoogleFonts.archivoBlack(
fontSize: 24,
color: Colors.yellow[100],
shadows: <Shadow>[
Shadow(
offset: Offset(5.0, 5.0),
blurRadius: 12.0,
color: Colors.black54,
),
Shadow(
offset: Offset(-3.0, 3.0),
blurRadius: 12.0,
color: Colors.black54,
),
],
),
),
SizedBox(
height: 20,
),
NumberPickerWidget(
minValue: (widget.exerciseBloc.unitQuantity - 10).round(),
maxValue: (widget.exerciseBloc.unitQuantity + 10).round(),
initalValue: widget.exerciseBloc.unitQuantity.round(),
unit: t("kg"),
color: Colors.yellow[50],
onChange: (value) => {changedValue = value}),
Align(
alignment: Alignment.center,
child: GestureDetector(
onTap: () => {
widget.exerciseBloc.add(ExerciseControlUnitQuantityChange(quantity: changedValue.toDouble(), step: widget.step)),
Navigator.of(context).pop(),
},
child: Stack(
alignment: Alignment.center,
children: [
Image.asset('asset/icon/gomb_orange_c.png', width: 100, height: 45),
Text(
t("OK"),
style: TextStyle(fontSize: 16, color: Colors.white),
),
],
))),
])),
GestureDetector(
onTap: () => Navigator.of(context).pop(),
child: CircleAvatar(
backgroundColor: Colors.transparent,
radius: 28,
child: Text(
"X",
style: GoogleFonts.archivoBlack(fontSize: 32, color: Colors.white54),
),
)),
]);
}
}
+2 -2
View File
@@ -49,8 +49,8 @@ class _ExerciseExecutePage extends State<ExerciseExecutePage> with Trans {
decoration: BoxDecoration(
image: DecorationImage(
image: customerId == Cache().userLoggedIn.customerId
? AssetImage('asset/image/WT_black_background.png')
: AssetImage('asset/image/WT_light_background.png'),
? AssetImage('asset/image/WT_black_background.jpg')
: AssetImage('asset/image/WT_light_background.jpg'),
fit: BoxFit.cover,
alignment: Alignment.center,
),
+134 -53
View File
@@ -2,16 +2,18 @@ import 'dart:collection';
import 'package:aitrainer_app/bloc/exercise_execute_plan/exercise_execute_plan_bloc.dart';
import 'package:aitrainer_app/bloc/exercise_execute_plan_add/exercise_execute_plan_add_bloc.dart';
import 'package:aitrainer_app/library/custom_icon_icons.dart';
import 'package:aitrainer_app/localization/app_language.dart';
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/library/numberpicker.dart';
import 'package:aitrainer_app/widgets/number_picker.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 ExerciseExecutePlanAddPage extends StatefulWidget {
@@ -19,6 +21,15 @@ class ExerciseExecutePlanAddPage extends StatefulWidget {
}
class _ExerciseExecuteAddPage extends State<ExerciseExecutePlanAddPage> 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;
@@ -44,7 +55,9 @@ class _ExerciseExecuteAddPage extends State<ExerciseExecutePlanAddPage> with Tra
}, builder: (context, state) {
// ignore: close_sinks
final exerciseBloc = BlocProvider.of<ExerciseExecutePlanAddBloc>(context);
if (state is ExerciseExecutePlanAddReady) {
_controller.animateTo(exerciseBloc.scrollOffset, duration: Duration(milliseconds: 300), curve: Curves.easeIn);
}
return ModalProgressHUD(
child: getControlForm(exerciseBloc),
inAsyncCall: state is ExerciseExecutePlanAddLoading,
@@ -69,7 +82,7 @@ class _ExerciseExecuteAddPage extends State<ExerciseExecutePlanAddPage> with Tra
height: MediaQuery.of(context).size.height,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_light_background.png'),
image: AssetImage('asset/image/WT_black_background.jpg'),
fit: BoxFit.fill,
alignment: Alignment.center,
),
@@ -79,16 +92,33 @@ class _ExerciseExecuteAddPage extends State<ExerciseExecutePlanAddPage> with Tra
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
physics: BouncingScrollPhysics(),
controller: ScrollController(
initialScrollOffset: exerciseBloc.scrollOffset,
),
controller: _controller,
child: Column(mainAxisAlignment: MainAxisAlignment.spaceAround, children: <Widget>[
Text(t("Save Exercise")),
Text(
t("Save Exercise"),
style: GoogleFonts.inter(fontSize: 16, color: Colors.orange[50]),
),
Text(
exerciseName,
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18, color: Colors.deepOrange),
style: GoogleFonts.archivoBlack(
fontSize: 24,
color: Colors.orange[700],
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,
),
],
),
textAlign: TextAlign.center,
overflow: TextOverflow.fade,
maxLines: 1,
maxLines: 3,
softWrap: true,
),
Divider(
@@ -115,52 +145,85 @@ class _ExerciseExecuteAddPage extends State<ExerciseExecutePlanAddPage> with Tra
Divider(
color: Colors.transparent,
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.baseline,
children: [
Text(
t("Execute the") + " ",
style: TextStyle(fontWeight: FontWeight.bold),
),
Text(
(i + 1).toString() + ". ",
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
),
Text(
t("set!"),
style: TextStyle(fontWeight: FontWeight.bold),
),
],
RichText(
text: TextSpan(
style: GoogleFonts.inter(
fontSize: 16,
fontWeight: FontWeight.normal,
color: Colors.yellow[300],
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,
),
],
),
children: [
TextSpan(text: t("Execute the") + " "),
TextSpan(
text: (i + 1).toString() + ". ",
style: GoogleFonts.inter(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Colors.yellow[600],
),
),
TextSpan(text: t("set!"))
]),
),
Divider(
color: Colors.transparent,
),
Text(t("Please repeat with") +
" " +
exerciseBloc.unitQuantity.toStringAsFixed(0) +
" " +
exerciseBloc.exerciseRepository.exerciseType.unitQuantityUnit +
" " +
exerciseBloc.exercisePlanRepository.getActualPlanDetail().repeats.toString() +
" " +
t("times!")),
Row(children: [
NumberPicker.horizontal(
highlightSelectedValue: (i + 1) == exerciseBloc.step,
initialValue: exerciseBloc.unitQuantity.toInt(),
minValue: 0,
maxValue: 650,
step: 1,
textStyle: TextStyle(fontWeight: FontWeight.bold),
textStyleHighlighted: TextStyle(fontSize: 24, color: Colors.indigo, fontWeight: FontWeight.bold),
onChanged: (value) => {exerciseBloc.add(ExerciseExecutePlanAddChangeUnitQuantity(quantity: value.toDouble()))},
listViewHeight: 80,
//decoration: _decoration,
),
Text(exerciseBloc.exerciseRepository.exerciseType.unitQuantityUnit),
Row(mainAxisAlignment: MainAxisAlignment.start, children: [
exerciseBloc.exerciseRepository.exerciseType.unitQuantityUnit == null
? Offstage()
: NumberPickerWidget(
minValue: 0,
maxValue: 1000,
fontSize: 16,
initalValue: exerciseBloc.unitQuantity.toInt(),
unit: t(exerciseBloc.exerciseRepository.exerciseType.unitQuantityUnit),
color: Colors.yellow[50],
onChange: (value) => {exerciseBloc.add(ExerciseExecutePlanAddChangeUnitQuantity(quantity: value.toDouble()))}),
NumberPickerWidget(
minValue: 0,
maxValue: 200,
fontSize: 16,
initalValue: exerciseBloc.quantity.toInt(),
unit: t(exerciseBloc.exerciseRepository.exerciseType.unit), //t("repeat"),
color: Colors.yellow[50],
onChange: (value) => {exerciseBloc.add(ExerciseExecutePlanAddChangeQuantity(quantity: value.toDouble()))}),
]),
Row(children: [
FlatButton(
padding: EdgeInsets.all(0),
textColor: Colors.white,
focusColor: Colors.blueAccent,
onPressed: () => {
if (exerciseBloc.step == i + 1) {exerciseBloc.add(ExerciseExecutePlanAddSubmit())},
if (i + 1 == exerciseBloc.countSteps) {Navigator.of(context).pop()}
},
child: exerciseBloc.step == i + 1
? Stack(
alignment: Alignment.center,
children: [
Image.asset('asset/icon/gomb_orange_c.png', width: 140, height: 60),
Text(
t("Save"),
style: TextStyle(fontSize: 16, color: Colors.white),
),
],
)
: Stack(
alignment: Alignment.center,
children: getButton(i + 1, exerciseBloc),
)),
/* Row(children: [
NumberPicker.horizontal(
highlightSelectedValue: (i + 1) == exerciseBloc.step,
initialValue: exerciseBloc.quantity.toInt(),
@@ -174,8 +237,8 @@ class _ExerciseExecuteAddPage extends State<ExerciseExecutePlanAddPage> with Tra
//decoration: _decoration,
),
Text(t("repeat")),
]),
RaisedButton(
]), */
/* RaisedButton(
padding: EdgeInsets.all(0),
textColor: Colors.white,
color: exerciseBloc.step == i + 1 ? Colors.blue : Colors.black26,
@@ -187,7 +250,7 @@ class _ExerciseExecuteAddPage extends State<ExerciseExecutePlanAddPage> with Tra
child: Text(
t("Save"),
style: TextStyle(fontSize: 12),
)),
)), */
Divider(),
],
);
@@ -195,4 +258,22 @@ class _ExerciseExecuteAddPage extends State<ExerciseExecutePlanAddPage> with Tra
}
return listColumns;
}
List<Widget> getButton(int step, ExerciseExecutePlanAddBloc 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;
}
}
+2 -2
View File
@@ -58,8 +58,8 @@ class _ExerciseLogPage extends State<ExerciseLogPage> with Trans, Common {
decoration: BoxDecoration(
image: DecorationImage(
image: customerId == Cache().userLoggedIn.customerId
? AssetImage('asset/image/WT_black_background.png')
: AssetImage('asset/image/WT_light_background.png'),
? AssetImage('asset/image/WT_black_background.jpg')
: AssetImage('asset/image/WT_light_background.jpg'),
fit: BoxFit.cover,
alignment: Alignment.center,
),
+43 -15
View File
@@ -16,6 +16,7 @@ import 'package:aitrainer_app/widgets/bmi_widget.dart';
import 'package:aitrainer_app/widgets/bmr_widget.dart';
import 'package:aitrainer_app/widgets/size_widget.dart';
import 'package:aitrainer_app/widgets/time_picker.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
@@ -33,6 +34,29 @@ class ExerciseNewPage extends StatefulWidget {
class _ExerciseNewPageState extends State<ExerciseNewPage> with Trans, Logging {
final FocusNode _nodeText1 = FocusNode();
final FocusNode _nodeText2 = FocusNode();
final _controller1 = TextEditingController();
final _controller2 = TextEditingController();
initState() {
super.initState();
_controller1.text = "30";
_nodeText1.addListener(() {
if (_nodeText1.hasFocus) {
_controller1.selection = TextSelection(baseOffset: 0, extentOffset: _controller1.text.length);
}
});
SchedulerBinding.instance.addPostFrameCallback((_) {
// ignore: close_sinks
final menuBloc = BlocProvider.of<MenuBloc>(context);
_controller2.text = menuBloc.ability.toString() == ExerciseAbility.oneRepMax.toString() ? "12" : "20";
_nodeText2.addListener(() {
if (_nodeText2.hasFocus) {
_controller2.selection = TextSelection(baseOffset: 0, extentOffset: _controller2.text.length);
}
});
});
}
KeyboardActionsConfig _buildConfig(BuildContext context) {
return KeyboardActionsConfig(
@@ -150,7 +174,7 @@ class _ExerciseNewPageState extends State<ExerciseNewPage> with Trans, Logging {
height: MediaQuery.of(context).size.height,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_black_background.png'),
image: AssetImage('asset/image/WT_black_background.jpg'),
fit: BoxFit.fill,
alignment: Alignment.center,
),
@@ -234,18 +258,20 @@ class _ExerciseNewPageState extends State<ExerciseNewPage> with Trans, Logging {
Divider(
color: Colors.transparent,
),
Text(
t("Step" + ": " + "1/4"),
style: GoogleFonts.inter(
fontSize: 22,
color: Colors.white,
fontWeight: FontWeight.bold,
),
maxLines: 3,
textAlign: TextAlign.center,
overflow: TextOverflow.fade,
softWrap: true,
),
exerciseBloc.exerciseRepository.exerciseType.unitQuantity == "1"
? Text(
t("Step") + ": " + "1/4",
style: GoogleFonts.inter(
fontSize: 22,
color: Colors.white,
fontWeight: FontWeight.bold,
),
maxLines: 3,
textAlign: TextAlign.center,
overflow: TextOverflow.fade,
softWrap: true,
)
: Offstage(),
Divider(
color: Colors.transparent,
),
@@ -278,6 +304,7 @@ class _ExerciseNewPageState extends State<ExerciseNewPage> with Trans, Logging {
row = Column(mainAxisAlignment: MainAxisAlignment.spaceAround, children: [
TextFormField(
focusNode: _nodeText1,
controller: _controller1,
decoration: InputDecoration(
contentPadding: EdgeInsets.only(left: 25, top: 5, bottom: 5),
labelText: t(bloc.exerciseRepository.exerciseType.unitQuantityUnit),
@@ -290,7 +317,7 @@ class _ExerciseNewPageState extends State<ExerciseNewPage> with Trans, Logging {
borderSide: BorderSide(color: Colors.white12, width: 0.4),
),
),
initialValue: "30",
//initialValue: "30",
keyboardType: TextInputType.numberWithOptions(decimal: true),
textInputAction: TextInputAction.done,
style: GoogleFonts.archivoBlack(fontSize: 80, color: Colors.yellow[300]),
@@ -388,6 +415,7 @@ class _ExerciseNewPageState extends State<ExerciseNewPage> with Trans, Logging {
Column row = Column(mainAxisAlignment: MainAxisAlignment.spaceAround, children: [
TextFormField(
focusNode: _nodeText2,
controller: _controller2,
decoration: InputDecoration(
contentPadding: EdgeInsets.only(left: 25, top: 5, bottom: 5),
labelText: t(bloc.exerciseRepository.exerciseType.unit),
@@ -400,7 +428,7 @@ class _ExerciseNewPageState extends State<ExerciseNewPage> with Trans, Logging {
borderSide: BorderSide(color: Colors.black26, width: 0.4),
),
),
initialValue: bloc.quantity.toStringAsFixed(0),
//initialValue: bloc.quantity.toStringAsFixed(0),
keyboardType: TextInputType.number,
textInputAction: TextInputAction.next,
style: GoogleFonts.archivoBlack(fontSize: 80, color: Colors.orange[200]),
@@ -15,6 +15,7 @@ import 'package:google_fonts/google_fonts.dart';
import 'package:keyboard_actions/keyboard_actions.dart';
import 'package:keyboard_actions/keyboard_actions_config.dart';
import 'package:keyboard_actions/keyboard_actions_item.dart';
import 'package:modal_progress_hud/modal_progress_hud.dart';
class ExercisePlanDetailAddPage extends StatefulWidget {
@override
@@ -104,21 +105,21 @@ class _ExercisePlanDetailAddPage extends State<ExercisePlanDetailAddPage> with T
..add(ExercisePlanCustomAddLoad()),
child: BlocConsumer<ExercisePlanCustomAddBloc, ExercisePlanCustomAddState>(
listener: (context, state) {
if (state is ExercisePlanCustomAddLoading) {
//LoadingDialog.show(context);
} else if (state is ExercisePlanCustomAddError) {
//LoadingDialog.hide(context);
if (state is ExercisePlanCustomAddError) {
Scaffold.of(context).showSnackBar(
SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white))));
}
},
builder: (context, state) {
if (state is ExercisePlanCustomAddReady) {
//LoadingDialog.hide(context);
}
// ignore: close_sinks
final bloc = BlocProvider.of<ExercisePlanCustomAddBloc>(context);
return getForm(bloc, workoutMenuTree);
return ModalProgressHUD(
child: getForm(bloc, workoutMenuTree),
inAsyncCall: state is ExercisePlanCustomAddLoading,
opacity: 0.5,
color: Colors.black54,
progressIndicator: CircularProgressIndicator(),
);
},
));
}
@@ -130,6 +131,12 @@ class _ExercisePlanDetailAddPage extends State<ExercisePlanDetailAddPage> with T
? bloc.exercisePlanRepository.getActualPlanDetail().exerciseType.name
: bloc.exercisePlanRepository.getActualPlanDetail().exerciseType.nameTranslation;
}
final bool weightVisible = bloc.exercisePlanRepository.getActualPlanDetail().exerciseType.unitQuantityUnit != null;
String summary = bloc.serie.toStringAsFixed(0) + " x " + bloc.quantity.toStringAsFixed(0);
if (bloc.quantityUnit > 0) {
summary += " x " + bloc.quantityUnit.toStringAsFixed(0) + " kg";
}
final String unit = bloc.exercisePlanRepository.getActualPlanDetail().exerciseType.unit;
return Form(
child: Scaffold(
resizeToAvoidBottomInset: true,
@@ -139,7 +146,7 @@ class _ExercisePlanDetailAddPage extends State<ExercisePlanDetailAddPage> with T
height: MediaQuery.of(context).size.height,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_black_background.png'),
image: AssetImage('asset/image/WT_black_background.jpg'),
fit: BoxFit.fill,
alignment: Alignment.center,
),
@@ -195,7 +202,7 @@ class _ExercisePlanDetailAddPage extends State<ExercisePlanDetailAddPage> with T
TextFormField(
decoration: InputDecoration(
contentPadding: EdgeInsets.only(left: 25, top: 5, bottom: 5),
labelText: t('Repeats'),
labelText: t(unit),
fillColor: Colors.white24,
labelStyle: GoogleFonts.inter(fontSize: 20, color: Colors.yellow[50]),
filled: true,
@@ -210,37 +217,33 @@ class _ExercisePlanDetailAddPage extends State<ExercisePlanDetailAddPage> with T
keyboardType: TextInputType.number,
style: GoogleFonts.archivoBlack(fontSize: 60, color: Colors.yellow[200]),
onChanged: (value) => {bloc.add(ExercisePlanCustomAddChangeQuantity(quantity: double.parse(value)))}),
//]),
Divider(),
TextFormField(
decoration: InputDecoration(
contentPadding: EdgeInsets.only(left: 25, top: 5, bottom: 5),
labelText: t('Weight'),
fillColor: Colors.white24,
labelStyle: GoogleFonts.inter(fontSize: 20, color: Colors.yellow[50]),
filled: true,
border: OutlineInputBorder(
gapPadding: 2.0,
borderRadius: BorderRadius.circular(12.0),
borderSide: BorderSide(color: Colors.green[50], width: 0.4),
),
),
focusNode: _nodeText3,
initialValue: bloc.quantityUnit.toStringAsFixed(0),
keyboardType: TextInputType.numberWithOptions(decimal: true),
style: GoogleFonts.archivoBlack(fontSize: 60, color: Colors.yellow[200]),
onChanged: (value) => {bloc.add(ExercisePlanCustomAddChangeQuantityUnit(quantity: double.parse(value)))}),
//]),
weightVisible
? TextFormField(
decoration: InputDecoration(
contentPadding: EdgeInsets.only(left: 25, top: 5, bottom: 5),
labelText: t('Weight'),
fillColor: Colors.white24,
labelStyle: GoogleFonts.inter(fontSize: 20, color: Colors.yellow[50]),
filled: true,
border: OutlineInputBorder(
gapPadding: 2.0,
borderRadius: BorderRadius.circular(12.0),
borderSide: BorderSide(color: Colors.green[50], width: 0.4),
),
),
focusNode: _nodeText3,
initialValue: bloc.quantityUnit.toStringAsFixed(0),
keyboardType: TextInputType.numberWithOptions(decimal: true),
style: GoogleFonts.archivoBlack(fontSize: 60, color: Colors.yellow[200]),
onChanged: (value) => {bloc.add(ExercisePlanCustomAddChangeQuantityUnit(quantity: double.parse(value)))})
: Offstage(),
Divider(),
Text(
bloc.serie.toStringAsFixed(0) +
" x " +
bloc.quantity.toStringAsFixed(0) +
" x " +
bloc.quantityUnit.toStringAsFixed(0) +
" kg",
summary,
style: TextStyle(fontSize: 24, fontWeight: FontWeight.normal, color: Colors.yellow[50]),
),
Divider(),
+13 -22
View File
@@ -14,6 +14,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:modal_progress_hud/modal_progress_hud.dart';
class ExercisePlanCustomPage extends StatefulWidget {
@override
@@ -51,8 +52,8 @@ class _ExercisePlanCustomPage extends State<ExercisePlanCustomPage> with Trans {
decoration: BoxDecoration(
image: DecorationImage(
image: customerId == Cache().userLoggedIn.customerId
? AssetImage('asset/image/WT_black_background.png')
: AssetImage('asset/image/WT_light_background.png'),
? AssetImage('asset/image/WT_black_background.jpg')
: AssetImage('asset/image/WT_light_background.jpg'),
fit: BoxFit.cover,
alignment: Alignment.center,
),
@@ -65,17 +66,15 @@ class _ExercisePlanCustomPage extends State<ExercisePlanCustomPage> with Trans {
),
backgroundColor: Colors.orange,
));
} else if (state is ExercisePlanLoading) {
//LoadingDialog.show(context);
}
},
// ignore: missing_return
builder: (context, state) {
if (state is ExercisePlanReady) {
//LoadingDialog.hide(context);
return exerciseWidget(bloc);
}
return Container();
}, builder: (context, state) {
return ModalProgressHUD(
child: exerciseWidget(bloc),
inAsyncCall: state is ExercisePlanLoading,
opacity: 0.5,
color: Colors.black54,
progressIndicator: CircularProgressIndicator(),
);
})),
bottomNavigationBar: BottomNavigator(bottomNavIndex: 2),
);
@@ -138,6 +137,7 @@ class _ExercisePlanCustomPage extends State<ExercisePlanCustomPage> with Trans {
List<Widget> _getChildList(List<WorkoutMenuTree> listWorkoutTree, ExercisePlanBloc bloc) {
List<Widget> list = List();
listWorkoutTree.forEach((element) {
final String unitQuantityUnit = element.exerciseType.unitQuantityUnit != null ? element.exerciseType.unitQuantityUnit : "";
list.add(TreeViewChild(
startExpanded: false,
parent: Card(
@@ -180,20 +180,11 @@ class _ExercisePlanCustomPage extends State<ExercisePlanCustomPage> with Trans {
bloc.exercisePlanRepository.exercisePlanDetails[element.exerciseTypeId].repeats.toString() +
" x " +
bloc.exercisePlanRepository.exercisePlanDetails[element.exerciseTypeId].weightEquation +
" " +
element.exerciseType.unitQuantityUnit,
unitQuantityUnit,
style: TextStyle(fontSize: 9, color: Colors.green),
),
onTap: () => clickAddDetail(bloc, element),
),
/* IconButton(
padding: EdgeInsets.all(0),
icon: Icon(
Icons.info,
color: Colors.black12,
),
onPressed: () {},
), */
]),
)),
children: []));
+27 -30
View File
@@ -7,46 +7,43 @@ import 'package:flutter/material.dart';
class ExerciseTypeDescription extends StatelessWidget {
@override
Widget build(BuildContext context) {
final ExerciseRepository exerciseRepository =
ModalRoute.of(context).settings.arguments;
final ExerciseRepository exerciseRepository = ModalRoute.of(context).settings.arguments;
String exerciseDescription = AppLanguage().appLocal == Locale("en")
? exerciseRepository.exerciseType.description
: exerciseRepository.exerciseType.descriptionTranslation;
String exerciseName = AppLanguage().appLocal == Locale("en") ?
exerciseRepository.exerciseType.name :
exerciseRepository.exerciseType.nameTranslation;
String exerciseName =
AppLanguage().appLocal == Locale("en") ? exerciseRepository.exerciseType.name : exerciseRepository.exerciseType.nameTranslation;
return Scaffold(
appBar: AppBarMin(back: true,),
appBar: AppBarMin(
back: true,
),
body: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_light_background.png'),
fit: BoxFit.fill,
alignment: Alignment.center,
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_light_background.jpg'),
fit: BoxFit.fill,
alignment: Alignment.center,
),
),
),
padding: EdgeInsets.only(left: 20, top: 20, right: 15),
child: ListView(
children: [
Text(exerciseName,
style: TextStyle(color: Colors.blueGrey,
fontSize: 20, fontWeight: FontWeight.bold),
padding: EdgeInsets.only(left: 20, top: 20, right: 15),
child: ListView(children: [
Text(
exerciseName,
style: TextStyle(color: Colors.blueGrey, fontSize: 20, fontWeight: FontWeight.bold),
),
Divider(
color: Colors.transparent,
),
Divider(color: Colors.transparent,),
InkWell(
child: Text(exerciseDescription,
style: TextStyle(color: Colors.blueGrey,
fontSize: 18, fontWeight: FontWeight.normal),),
child: Text(
exerciseDescription,
style: TextStyle(color: Colors.blueGrey, fontSize: 18, fontWeight: FontWeight.normal),
),
),
]
)
)
);
])));
}
}
+1 -1
View File
@@ -56,7 +56,7 @@ class LoginPage extends StatelessWidget with Trans {
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_login.png'),
image: AssetImage('asset/image/WT_login.jpg'),
fit: BoxFit.cover,
alignment: Alignment.center,
),
+1 -1
View File
@@ -36,7 +36,7 @@ class _MenuPage extends State<MenuPage> {
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_menu_dark.png'),
image: AssetImage('asset/image/WT_menu_dark.jpg'),
fit: BoxFit.fill,
alignment: Alignment.center,
),
+2 -4
View File
@@ -4,7 +4,6 @@ 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:flurry/flurry.dart';
import 'package:flutter/scheduler.dart';
import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/util/common.dart';
@@ -27,7 +26,6 @@ class _MyDevelopmentBodyPage extends State<MyDevelopmentBodyPage> with Trans, Co
@override
void initState() {
super.initState();
Flurry.logEvent("myDevelopmentBody");
if (!Cache().hasPurchased || true) {
Timer(
Duration(milliseconds: 2000),
@@ -69,8 +67,8 @@ class _MyDevelopmentBodyPage extends State<MyDevelopmentBodyPage> with Trans, Co
decoration: BoxDecoration(
image: DecorationImage(
image: customerId == Cache().userLoggedIn.customerId
? AssetImage('asset/image/WT_light_background.png')
: AssetImage('asset/image/WT_menu_dark.png'),
? AssetImage('asset/image/WT_light_background.jpg')
: AssetImage('asset/image/WT_menu_dark.jpg'),
fit: BoxFit.cover,
alignment: Alignment.center,
),
+1 -3
View File
@@ -11,7 +11,6 @@ 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';
@@ -32,7 +31,6 @@ class _MyDevelopmentMuscleState extends State<MyDevelopmentMusclePage> with Comm
@override
void initState() {
super.initState();
Flurry.logEvent("myDevelopmentMuscle");
if (!Cache().hasPurchased) {
Timer(
Duration(milliseconds: 2000),
@@ -71,7 +69,7 @@ class _MyDevelopmentMuscleState extends State<MyDevelopmentMusclePage> with Comm
padding: EdgeInsets.all(20),
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_menu_dark.png'),
image: AssetImage('asset/image/WT_menu_dark.jpg'),
fit: BoxFit.cover,
alignment: Alignment.center,
),
+23 -14
View File
@@ -3,8 +3,9 @@ import 'dart:collection';
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/util/enums.dart';
import 'package:aitrainer_app/util/track.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';
@@ -34,7 +35,7 @@ class _MyDevelopmentPage extends State<MyDevelopmentPage> with Trans {
padding: EdgeInsets.all(10),
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_menu_dark.png'),
image: AssetImage('asset/image/WT_menu_dark.jpg'),
fit: BoxFit.cover,
alignment: Alignment.center,
),
@@ -68,8 +69,11 @@ class _MyDevelopmentPage extends State<MyDevelopmentPage> with Trans {
image: "asset/image/testemfejl400x400.jpg",
left: 5,
onTap: () => {
args['customerId'] = Cache().userLoggedIn.customerId,
Navigator.of(context).pushNamed('mydevelopmentBodyPage', arguments: args)
if (Cache().userLoggedIn != null)
{
args['customerId'] = Cache().userLoggedIn.customerId,
Navigator.of(context).pushNamed('mydevelopmentBodyPage', arguments: args)
}
},
isLocked: true,
),
@@ -101,7 +105,7 @@ class _MyDevelopmentPage extends State<MyDevelopmentPage> with Trans {
backgroundColor: Colors.black54.withOpacity(0.4))),
image: "asset/image/predictions.jpg",
onTap: () => {
Flurry.logEvent("Predictions"),
Track().track(TrackingEvent.prediction),
showDialog(
context: context,
builder: (BuildContext context) {
@@ -138,10 +142,13 @@ class _MyDevelopmentPage extends State<MyDevelopmentPage> with Trans {
color: Colors.black12,
focusColor: Colors.blueAccent,
onPressed: () => {
args['exerciseRepository'] = exerciseRepository,
args['customerRepository'] = customerRepository,
args['customerId'] = Cache().getTrainee().customerId,
Navigator.of(context).pushNamed('exerciseLogPage', arguments: args)
if (Cache().getTrainee() != null)
{
args['exerciseRepository'] = exerciseRepository,
args['customerRepository'] = customerRepository,
args['customerId'] = Cache().getTrainee().customerId,
Navigator.of(context).pushNamed('exerciseLogPage', arguments: args)
},
},
child: Text(
t("My Trainee's Exercise Logs"),
@@ -153,10 +160,12 @@ class _MyDevelopmentPage extends State<MyDevelopmentPage> with Trans {
}
void callBackExerciseLog(ExerciseRepository exerciseRepository, CustomerRepository customerRepository) {
final LinkedHashMap args = LinkedHashMap();
args['exerciseRepository'] = exerciseRepository;
args['customerRepository'] = customerRepository;
args['customerId'] = Cache().userLoggedIn.customerId;
Navigator.of(context).pushNamed('exerciseLogPage', arguments: args);
if (Cache().userLoggedIn != null) {
final LinkedHashMap args = LinkedHashMap();
args['exerciseRepository'] = exerciseRepository;
args['customerRepository'] = customerRepository;
args['customerId'] = Cache().userLoggedIn.customerId;
Navigator.of(context).pushNamed('exerciseLogPage', arguments: args);
}
}
}
+28 -15
View File
@@ -2,12 +2,13 @@ import 'dart:collection';
import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/repository/exercise_repository.dart';
import 'package:aitrainer_app/service/logging.dart';
import 'package:aitrainer_app/util/enums.dart';
import 'package:aitrainer_app/util/track.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_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';
@@ -33,7 +34,7 @@ class _MyExercisePlanPage extends State<MyExercisePlanPage> with Trans, Logging
padding: EdgeInsets.all(10),
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_menu_dark.png'),
image: AssetImage('asset/image/WT_menu_dark.jpg'),
fit: BoxFit.cover,
alignment: Alignment.center,
),
@@ -54,9 +55,12 @@ class _MyExercisePlanPage extends State<MyExercisePlanPage> with Trans, Logging
image: "asset/image/exercise_plan_custom.jpg",
left: 5,
onTap: () => {
args['exerciseRepository'] = exerciseRepository,
args['customerId'] = Cache().userLoggedIn.customerId,
Navigator.of(context).pushNamed('exercisePlanCustomPage', arguments: args)
if (Cache().userLoggedIn != null)
{
args['exerciseRepository'] = exerciseRepository,
args['customerId'] = Cache().userLoggedIn.customerId,
Navigator.of(context).pushNamed('exercisePlanCustomPage', arguments: args)
}
},
isLocked: false,
),
@@ -74,8 +78,11 @@ class _MyExercisePlanPage extends State<MyExercisePlanPage> with Trans, Logging
top: 130,
left: 5,
onTap: () => {
args['customerId'] = Cache().userLoggedIn.customerId,
Navigator.of(context).pushNamed('exerciseExecutePlanPage', arguments: args)
if (Cache().userLoggedIn != null)
{
args['customerId'] = Cache().userLoggedIn.customerId,
Navigator.of(context).pushNamed('exerciseExecutePlanPage', arguments: args)
}
},
isLocked: false,
),
@@ -92,7 +99,7 @@ class _MyExercisePlanPage extends State<MyExercisePlanPage> with Trans, Logging
image: "asset/image/exercise_plan_suggested.jpg",
left: 2,
onTap: () => {
Flurry.logEvent("SuggestedTrainingPlan"),
Track().track(TrackingEvent.my_suggested_plan),
showDialog(
context: context,
builder: (BuildContext context) {
@@ -121,7 +128,7 @@ class _MyExercisePlanPage extends State<MyExercisePlanPage> with Trans, Logging
image: "asset/image/exercise_plan_stars.jpg",
left: 5,
onTap: () => {
Flurry.logEvent("SpecialTraining Programs"),
Track().track(TrackingEvent.my_special_plan),
showDialog(
context: context,
builder: (BuildContext context) {
@@ -150,7 +157,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) {
@@ -189,9 +196,12 @@ class _MyExercisePlanPage extends State<MyExercisePlanPage> with Trans, Logging
color: Colors.black12,
focusColor: Colors.blueAccent,
onPressed: () => {
args['exerciseRepository'] = exerciseRepository,
args['customerId'] = Cache().getTrainee().customerId,
Navigator.of(context).pushNamed('exercisePlanCustomPage', arguments: args)
if (Cache().getTrainee() != null)
{
args['exerciseRepository'] = exerciseRepository,
args['customerId'] = Cache().getTrainee().customerId,
Navigator.of(context).pushNamed('exercisePlanCustomPage', arguments: args)
}
},
child: Text(
t("My Trainee's Plan"),
@@ -212,8 +222,11 @@ class _MyExercisePlanPage extends State<MyExercisePlanPage> with Trans, Logging
color: Colors.black12,
focusColor: Colors.blueAccent,
onPressed: () => {
args['customerId'] = Cache().getTrainee().customerId,
Navigator.of(context).pushNamed('exerciseExecutePlanPage', arguments: args)
if (Cache().getTrainee() != null)
{
args['customerId'] = Cache().getTrainee().customerId,
Navigator.of(context).pushNamed('exerciseExecutePlanPage', arguments: args)
}
},
child: Text(
t("Execute My Trainee's Training Plan"),
+17 -12
View File
@@ -6,6 +6,7 @@ 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/dialog_common.dart';
import 'package:aitrainer_app/widgets/dialog_long.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
@@ -39,7 +40,21 @@ class RegistrationPage extends StatelessWidget with Trans {
SnackBar(backgroundColor: Colors.orange, content: Text(message, style: TextStyle(color: Colors.white))));
}
} else if (state is LoginSuccess) {
Navigator.of(context).pushNamed('customerModifyPage');
//Navigator.of(context).pushNamed('customerModifyPage');
showDialog(
context: context,
builder: (BuildContext context) {
return DialogCommon(
title: t("Successful Registration"),
descriptions: t("Now we would like to know you better to lift the experience of the app."),
description2: t("Please go through the pages, it will take couple of minutes!"),
text: "OK",
onTap: () => {Navigator.of(context).pushNamed('customerModifyPage')},
onCancel: () => {
Navigator.of(context).pushNamed("home"),
},
);
});
}
}, builder: (context, state) {
final loginBloc = BlocProvider.of<LoginBloc>(context);
@@ -61,7 +76,7 @@ class RegistrationPage extends StatelessWidget with Trans {
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_login.png'),
image: AssetImage('asset/image/WT_login.jpg'),
fit: BoxFit.cover,
alignment: Alignment.center,
),
@@ -109,16 +124,6 @@ class RegistrationPage extends StatelessWidget with Trans {
],
),
ListTile(title: Text(t("OR"), style: GoogleFonts.inter())),
/* Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
InkWell(
child: Text(AppLocalizations.of(context).translate('SignUp with Email'),
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 24)),
),
],
), */
TextFormField(
key: LibraryKeys.loginEmailField,
decoration: InputDecoration(
+1 -1
View File
@@ -44,7 +44,7 @@ class ResetPasswordPage extends StatelessWidget with Trans {
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_login.png'),
image: AssetImage('asset/image/WT_login.jpg'),
fit: BoxFit.cover,
alignment: Alignment.center,
),
+1 -1
View File
@@ -60,7 +60,7 @@ class SalesPage extends StatelessWidget with Trans, Logging {
return Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_black_background.png'),
image: AssetImage('asset/image/WT_black_background.jpg'),
fit: BoxFit.cover,
alignment: Alignment.center,
),
+2 -2
View File
@@ -29,7 +29,7 @@ class SettingsPage extends StatelessWidget with Trans {
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_light_background.png'),
image: AssetImage('asset/image/WT_light_background.jpg'),
fit: BoxFit.cover,
alignment: Alignment.center,
),
@@ -78,7 +78,7 @@ class SettingsPage extends StatelessWidget with Trans {
}
ListTile getServer(SettingsBloc settingsBloc) {
if (Cache().userLoggedIn.admin != 1) {
if (Cache().userLoggedIn == null || Cache().userLoggedIn.admin != 1) {
return ListTile(
title: Container(),
);