wt1.1.2f fix for 1.1.3

This commit is contained in:
Bossanyi Tibor 2020-10-28 14:05:31 +01:00
parent 27c1d26dfd
commit db95c9a6f7
26 changed files with 672 additions and 510 deletions

BIN
asset/image/predictions.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

File diff suppressed because one or more lines are too long

View File

@ -207,5 +207,6 @@
"3rd Control": "3. kontrollgyakorlat", "3rd Control": "3. kontrollgyakorlat",
"Summary of your test":"A teszt összefoglalása:", "Summary of your test":"A teszt összefoglalása:",
"Are you sure to delete this exercise?": "Biztos, hogy törlöd a gyakorlatot?" "Are you sure to delete this exercise?": "Biztos, hogy törlöd a gyakorlatot?",
"I forgot the password":"Elfelejtett jelszó"
} }

View File

@ -1,81 +0,0 @@
import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/customer.dart';
import 'package:aitrainer_app/model/workout_menu_tree.dart';
import 'package:aitrainer_app/repository/exercise_plan_repository.dart';
import 'package:aitrainer_app/repository/exercise_repository.dart';
import 'package:flutter_form_bloc/flutter_form_bloc.dart';
class ExerciseAddByPlanFormBloc extends FormBloc<String, String> {
final ExerciseRepository exerciseRepository;
final ExercisePlanRepository exercisePlanRepository;
final WorkoutMenuTree workoutTree;
final customerId;
Customer customer;
int step = 1;
int countSteps = 1;
final quantity1Field = TextFieldBloc(
);
final unitQuantity1Field = TextFieldBloc(
);
ExerciseAddByPlanFormBloc({this.exerciseRepository, this.exercisePlanRepository, this.customerId, this.workoutTree}) {
addFieldBlocs(fieldBlocs: [
quantity1Field,
unitQuantity1Field,
]);
quantity1Field.onValueChanges(onData: (previous, current) async* {
exerciseRepository.setQuantity(current.valueToDouble);
});
unitQuantity1Field.onValueChanges(onData: (previous, current) async* {
exerciseRepository.setUnitQuantity(unitQuantity1Field.valueToDouble);
});
exerciseRepository.exerciseType = workoutTree.exerciseType;
if ( Cache().userLoggedIn.customerId == customerId) {
customer = Cache().userLoggedIn;
} else if ( Cache().getTrainee().customerId == customerId) {
customer = Cache().getTrainee();
}
exercisePlanRepository.setActualPlanDetailByExerciseType(workoutTree.exerciseType);
exerciseRepository.customer = customer;
countSteps = exercisePlanRepository.getActualPlanDetail().serie;
unitQuantity1Field.updateInitialValue(exercisePlanRepository.getActualPlanDetail().weightEquation);
quantity1Field.updateInitialValue(exercisePlanRepository.getActualPlanDetail().repeats.toString());
}
@override
void onSubmitting() async {
try {
emitLoading(progress: 30);
step++;
exerciseRepository.setUnitQuantity(unitQuantity1Field.valueToDouble);
exerciseRepository.setQuantity(quantity1Field.valueToDouble);
exerciseRepository.exercise.exercisePlanDetailId =
exercisePlanRepository.getActualPlanDetail().exercisePlanDetailId;
exerciseRepository.exercise.unit = workoutTree.exerciseType.unit;
workoutTree.executed = true;
print("On Submitting Add Exercise By Plan " + exerciseRepository.exercise.toJson().toString());
await exerciseRepository.addExercise();
emitSuccess(canSubmitAgain: true);
} on Exception catch (ex) {
emitFailure(failureResponse: ex.toString());
}
}
//@override
Future<void> close() {
quantity1Field.close();
unitQuantity1Field.close();
return super.close();
}
}

View File

@ -0,0 +1,49 @@
import 'package:aitrainer_app/repository/user_repository.dart';
import 'package:aitrainer_app/util/common.dart';
import 'package:flutter_form_bloc/flutter_form_bloc.dart';
class ResetPasswordFormBloc extends FormBloc<String, String> with Common {
final UserRepository userRepository;
final emailField = TextFieldBloc(
validators: [
FieldBlocValidators.required,
],
);
ResetPasswordFormBloc({this.userRepository}) {
addFieldBlocs(fieldBlocs: [
emailField
]);
emailField.onValueChanges(onData: (previous, current) async* {
userRepository.setEmail(current.value);
});
}
@override
void onSubmitting() async {
try {
emitLoading(progress: 30);
if ( ! validateEmail(userRepository)) {
emailField.addFieldError(EMAIL_ERROR, isPermanent: true);
emitFailure(failureResponse: EMAIL_ERROR);
} else {
// Emit either Loaded or Error
await userRepository.resetPassword();
emitSuccess(canSubmitAgain: false);
}
} on Exception catch (ex) {
emitFailure(failureResponse: ex.toString());
}
}
Future<void> close() {
emailField.close();
return super.close();
}
}

View File

@ -305,12 +305,47 @@ class NumberPicker extends StatelessWidget {
? selectedStyle ? selectedStyle
: defaultStyle; : defaultStyle;
double top = defaultStyle != null && defaultStyle.fontSize != null
? listViewHeight / 2 - defaultStyle.fontSize / 2 - 15
: listViewHeight / 2 - 22;
double left = defaultStyle != null && defaultStyle.fontSize != null
? listViewWidth / 6 - defaultStyle.fontSize / 2 - 10
: listViewHeight / 2 - 27;
bool isExtra = index == 0 || index == listItemCount - 1; bool isExtra = index == 0 || index == listItemCount - 1;
return isExtra return isExtra
? Container() //empty first and last element ? Container() //empty first and last element
: Center( : Center(
child: Text( child: value != selectedIntValue ?
Container(
padding: EdgeInsets.only(top: 15, left: 10, right: 5, bottom: 10),
child: Stack(
children: [
Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: value < selectedIntValue ? Alignment.centerRight : Alignment.centerLeft,
end: value < selectedIntValue ? Alignment.centerLeft : Alignment.centerRight,
colors: [Colors.white12, Colors.black12]),
borderRadius: BorderRadius.circular(8.0),
),
),
Positioned(
top: top,
left: left,
child:
Text(
getDisplayedValue(value),
style: itemStyle,
),
),
],
)
) :
Text(
getDisplayedValue(value), getDisplayedValue(value),
style: itemStyle, style: itemStyle,
), ),

View File

@ -5,7 +5,6 @@ import 'package:aitrainer_app/util/common.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart'; import 'package:flutter/scheduler.dart';
import 'dart:math' as math;
class TreeView extends InheritedWidget { class TreeView extends InheritedWidget {
final List<Widget> children; final List<Widget> children;
@ -99,7 +98,6 @@ class TreeViewChildState extends State<TreeViewChild> with Common, SingleTicker
Color _color; Color _color;
double _opacity = 0; double _opacity = 0;
/* List<Widget> listWidgets; */
AnimationController _controller; AnimationController _controller;
Animation<double> sizeAnimation; Animation<double> sizeAnimation;
@ -107,16 +105,6 @@ class TreeViewChildState extends State<TreeViewChild> with Common, SingleTicker
void initState() { void initState() {
super.initState(); super.initState();
isExpanded = widget.startExpanded; isExpanded = widget.startExpanded;
_color = Colors.transparent;
_opacity = 0;
/* listWidgets = List.from(widget.children); */
/* _controller = AnimationController(
duration: const Duration(seconds: 1),
vsync: this,
);
sizeAnimation = Tween<double>(begin: 0.0, end: 1.0).animate(_controller);*/
} }
@override @override
@ -136,33 +124,7 @@ class TreeViewChildState extends State<TreeViewChild> with Common, SingleTicker
), ),
Flexible( Flexible(
child: Container( child: Container(
/*animation: _controller,
builder: (BuildContext context, Widget child) {
return Transform.scale(
scale: _controller.value,
child: child,
);
},*/
/* color: _color,
duration: Duration(seconds: 2),
curve: Curves.easeInOut,*/
//height: double.infinity,
/*child: isExpanded //animateChildren()
? Column(
mainAxisSize: MainAxisSize.min,
children: widget.children,
)
: Offstage(),*/
child: child:
/*AnimatedCrossFade(
firstChild: Column(
mainAxisSize: MainAxisSize.min,
children: widget.children,
),
secondChild: Offstage(),
duration: Duration(milliseconds:800),
crossFadeState: isExpanded ? CrossFadeState.showFirst : CrossFadeState.showSecond,
)*/
AnimatedSwitcher( AnimatedSwitcher(
duration: Duration(milliseconds:900), duration: Duration(milliseconds:900),
reverseDuration: Duration(milliseconds:500), reverseDuration: Duration(milliseconds:500),
@ -178,63 +140,11 @@ class TreeViewChildState extends State<TreeViewChild> with Common, SingleTicker
); );
} }
/*AnimatedList animateChildren() {
return AnimatedList(
shrinkWrap: true,
key: listKey,
initialItemCount: listWidgets.length,
itemBuilder: (context, index, animation) {
return slideIt(animation, listWidgets[index]);
},
);
}
Widget slideIt(Animation<double> animation, Widget element) {
return SizeTransition(
sizeFactor: animation,
axis: Axis.vertical,
child: element,
);
}*/
void toggleExpanded() { void toggleExpanded() {
setState(() { setState(() {
this.isExpanded = !this.isExpanded; this.isExpanded = !this.isExpanded;
_color = isExpanded ? Colors.black12 : Colors.transparent; _color = isExpanded ? Colors.black12 : Colors.transparent;
_opacity = isExpanded ? 1 : 0; _opacity = isExpanded ? 1 : 0;
/* if ( isExpanded == false ) {
_removeAllItems();
} else {
//_addAllItems();
listWidgets = List.from(widget.children);
}*/
}); });
} }
/* void _removeAllItems() {
final int itemCount = widget.children.length;
for (var i = 0; i < itemCount; i++) {
Widget itemToRemove = listWidgets[0];
listKey.currentState.removeItem(0,
(BuildContext context, Animation<double> animation) => slideIt(animation, itemToRemove),
duration: const Duration(milliseconds: 250),
);
listWidgets.removeAt(0);
}
}
void _addAllItems() {
final int itemCount = widget.children.length;
for (var i = 0; i < itemCount; i++) {
listKey.currentState.insertItem(0);
listWidgets.insert(0, widget.children[i]);
}
}*/
} }

View File

@ -25,16 +25,18 @@ import 'package:aitrainer_app/view/mydevelopment_muscle_page.dart';
import 'package:aitrainer_app/view/mydevelopment_page.dart'; import 'package:aitrainer_app/view/mydevelopment_page.dart';
import 'package:aitrainer_app/view/myexcercise_plan_page.dart'; import 'package:aitrainer_app/view/myexcercise_plan_page.dart';
import 'package:aitrainer_app/view/registration.dart'; import 'package:aitrainer_app/view/registration.dart';
import 'package:aitrainer_app/view/reset_password.dart';
import 'package:aitrainer_app/view/settings.dart'; import 'package:aitrainer_app/view/settings.dart';
import 'package:aitrainer_app/widgets/home.dart'; import 'package:aitrainer_app/widgets/home.dart';
import 'package:firebase_analytics/firebase_analytics.dart'; //import 'package:firebase_analytics/firebase_analytics.dart';
import 'package:firebase_analytics/observer.dart'; //import 'package:firebase_analytics/observer.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:aitrainer_app/localization/app_localization.dart'; import 'package:aitrainer_app/localization/app_localization.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:sentry/sentry.dart'; import 'package:sentry/sentry.dart';
import 'bloc/account/account_bloc.dart'; import 'bloc/account/account_bloc.dart';
import 'bloc/body_development/body_development_bloc.dart'; import 'bloc/body_development/body_development_bloc.dart';
@ -157,7 +159,7 @@ class AitrainerApp extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
final FirebaseAnalytics analytics = FirebaseAnalytics(); //final FirebaseAnalytics analytics = FirebaseAnalytics();
return MaterialApp( return MaterialApp(
localizationsDelegates: [ localizationsDelegates: [
// ... app-specific localization delegate[s] here // ... app-specific localization delegate[s] here
@ -197,6 +199,7 @@ class AitrainerApp extends StatelessWidget {
'exerciseCustomPage': (context) => CustomExercisePage(), 'exerciseCustomPage': (context) => CustomExercisePage(),
'exerciseControlPage': (context) => ExerciseControlPage(), 'exerciseControlPage': (context) => ExerciseControlPage(),
'login': (context) => LoginPage(), 'login': (context) => LoginPage(),
'resetPassword': (context) => ResetPasswordPage(),
'registration': (context) => RegistrationPage(), 'registration': (context) => RegistrationPage(),
'gdpr': (context) => Gdpr(), 'gdpr': (context) => Gdpr(),
'menu_page': (context) => MenuPage(), 'menu_page': (context) => MenuPage(),
@ -218,13 +221,13 @@ class AitrainerApp extends StatelessWidget {
theme: ThemeData( theme: ThemeData(
brightness: Brightness.light, brightness: Brightness.light,
//primarySwatch: Colors.transparent, //primarySwatch: Colors.transparent,
fontFamily: 'Arial', //fontFamily: 'Arial',
textTheme: TextTheme( textTheme: TextTheme(
bodyText1: TextStyle(fontSize: 14.0), bodyText1: GoogleFonts.openSans(textStyle: TextStyle(fontSize: 14.0)),
) )
), ),
navigatorObservers: [ navigatorObservers: [
FirebaseAnalyticsObserver(analytics: analytics), //FirebaseAnalyticsObserver(analytics: analytics),
], ],
home: AitrainerHome(), home: AitrainerHome(),

View File

@ -40,6 +40,7 @@ class Cache {
// Keys to store and fetch data from SharedPreferences // Keys to store and fetch data from SharedPreferences
static final String authTokenKey = 'auth_token'; static final String authTokenKey = 'auth_token';
static final String customerIdKey = 'customer_id'; static final String customerIdKey = 'customer_id';
static final String firebaseUidKey = 'firebase_uid';
static final String lastStoreDateKey = 'last_date'; static final String lastStoreDateKey = 'last_date';
static final String isRegisteredKey = 'is_registered'; static final String isRegisteredKey = 'is_registered';
static final String isLoggedInKey = 'is_logged_in'; static final String isLoggedInKey = 'is_logged_in';
@ -52,6 +53,8 @@ class Cache {
String authToken = ""; String authToken = "";
Customer userLoggedIn; Customer userLoggedIn;
String firebaseUid;
bool firstLoad = true; bool firstLoad = true;
List<ExerciseType> _exerciseTypes; List<ExerciseType> _exerciseTypes;
@ -108,18 +111,24 @@ class Cache {
Future<SharedPreferences> prefs = SharedPreferences.getInstance(); Future<SharedPreferences> prefs = SharedPreferences.getInstance();
userLoggedIn = customer; userLoggedIn = customer;
setPreferences(prefs, SharePrefsChange.registration, customer.customerId); setPreferences(prefs, SharePrefsChange.registration, customer.customerId, Cache().firebaseUid);
} }
afterLogin(Customer customer) async { afterLogin(Customer customer) async {
Future<SharedPreferences> prefs = SharedPreferences.getInstance(); Future<SharedPreferences> prefs = SharedPreferences.getInstance();
userLoggedIn = customer; userLoggedIn = customer;
await setPreferences(prefs, SharePrefsChange.login, customer.customerId); await setPreferences(prefs, SharePrefsChange.login, customer.customerId, Cache().firebaseUid);
}
afterFirebaseLogin() async {
Future<SharedPreferences> prefs = SharedPreferences.getInstance();
await setPreferences(prefs, SharePrefsChange.login, userLoggedIn.customerId, Cache().firebaseUid);
} }
logout() async { logout() async {
userLoggedIn = null; userLoggedIn = null;
firebaseUid = null;
authToken = ""; authToken = "";
_trainee = null; _trainee = null;
_percentExercises = -1; _percentExercises = -1;
@ -129,12 +138,13 @@ class Cache {
_myExercisesPlanDetails = LinkedHashMap(); _myExercisesPlanDetails = LinkedHashMap();
print("Trainees is null? " + (_trainee == null).toString() ); print("Trainees is null? " + (_trainee == null).toString() );
Future<SharedPreferences> prefs = SharedPreferences.getInstance(); Future<SharedPreferences> prefs = SharedPreferences.getInstance();
await setPreferences(prefs, SharePrefsChange.logout, 0); await setPreferences(prefs, SharePrefsChange.logout, 0, "");
} }
setPreferences(Future<SharedPreferences> prefs, setPreferences(Future<SharedPreferences> prefs,
SharePrefsChange type, SharePrefsChange type,
int customerId) async { int customerId,
String firebaseUid) async {
SharedPreferences sharedPreferences; SharedPreferences sharedPreferences;
sharedPreferences = await prefs; sharedPreferences = await prefs;
@ -146,19 +156,22 @@ class Cache {
sharedPreferences.setInt(Cache.customerIdKey, customerId); sharedPreferences.setInt(Cache.customerIdKey, customerId);
sharedPreferences.setBool(Cache.isRegisteredKey, true); sharedPreferences.setBool(Cache.isRegisteredKey, true);
sharedPreferences.setBool(Cache.isLoggedInKey, true); sharedPreferences.setBool(Cache.isLoggedInKey, true);
sharedPreferences.setString(Cache.firebaseUidKey, firebaseUid);
await ExerciseTypeApi().getExerciseTypes(); await ExerciseTypeApi().getExerciseTypes();
await ExerciseTreeApi().getExerciseTree(); await ExerciseTreeApi().getExerciseTree();
exerciseRepository.getExercisesByCustomer(customerId); await exerciseRepository.getExercisesByCustomer(customerId);
} else if ( type == SharePrefsChange.login ) { } else if ( type == SharePrefsChange.login ) {
Cache().startPage = "home"; Cache().startPage = "home";
sharedPreferences.setInt(Cache.customerIdKey, customerId); sharedPreferences.setInt(Cache.customerIdKey, customerId);
sharedPreferences.setString(Cache.firebaseUidKey, firebaseUid);
sharedPreferences.setBool(Cache.isLoggedInKey, true); sharedPreferences.setBool(Cache.isLoggedInKey, true);
await ExerciseTypeApi().getExerciseTypes(); await ExerciseTypeApi().getExerciseTypes();
await ExerciseTreeApi().getExerciseTree(); await ExerciseTreeApi().getExerciseTree();
exerciseRepository.getExercisesByCustomer(customerId); await exerciseRepository.getExercisesByCustomer(customerId);
} else if ( type == SharePrefsChange.logout ) { } else if ( type == SharePrefsChange.logout ) {
sharedPreferences.setBool(Cache.isLoggedInKey, false); sharedPreferences.setBool(Cache.isLoggedInKey, false);
sharedPreferences.setInt(Cache.customerIdKey, 0); sharedPreferences.setInt(Cache.customerIdKey, 0);
sharedPreferences.setString(Cache.firebaseUidKey, null);
sharedPreferences.setString(authTokenKey, ""); sharedPreferences.setString(authTokenKey, "");
} }
} }

View File

@ -15,6 +15,7 @@ class Customer {
int admin; int admin;
int trainer; int trainer;
int dataPolicyAllowed; int dataPolicyAllowed;
String firebaseUid;
Customer({this.customerId, Customer({this.customerId,
@ -32,7 +33,8 @@ class Customer {
this.weight, this.weight,
this.admin, this.admin,
this.trainer, this.trainer,
this.dataPolicyAllowed this.dataPolicyAllowed,
this.firebaseUid,
}); });
Customer.fromJson(Map json) { Customer.fromJson(Map json) {
@ -50,6 +52,7 @@ class Customer {
this.weight = json['weight']; this.weight = json['weight'];
this.admin = json['admin']; this.admin = json['admin'];
this.trainer = json['trainer']; this.trainer = json['trainer'];
this.firebaseUid = json['firebaseUid'];
} }
Map<String, dynamic> toJson() => Map<String, dynamic> toJson() =>

View File

@ -2,6 +2,7 @@
String email; String email;
String password; String password;
int customerId; int customerId;
String firebaseUid;
User({this.customerId, this.email, this.password}); User({this.customerId, this.email, this.password});
@ -11,5 +12,6 @@
{ {
"username": email, "username": email,
"password": password, "password": password,
"firebaseUid": firebaseUid,
}; };
} }

View File

@ -87,11 +87,15 @@ class ExerciseRepository {
Future<List<Exercise>> getExercisesByCustomer( int customerId ) async { Future<List<Exercise>> getExercisesByCustomer( int customerId ) async {
final results = await ExerciseApi().getExercisesByCustomer(customerId); final results = await ExerciseApi().getExercisesByCustomer(customerId);
this.exerciseList = results; this.exerciseList = results;
if ( customerId == Cache().userLoggedIn.customerId) { if ( Cache().userLoggedIn != null ) {
if (customerId == Cache().userLoggedIn.customerId) {
Cache().setExercises(exerciseList); Cache().setExercises(exerciseList);
} else if ( Cache().getTrainee() != null && customerId == Cache().getTrainee().customerId ) { } else if (Cache().getTrainee() != null && customerId == Cache()
.getTrainee()
.customerId) {
Cache().setExercisesTrainee(exerciseList); Cache().setExercisesTrainee(exerciseList);
} }
}
return this.exerciseList; return this.exerciseList;
} }

View File

@ -1,5 +1,7 @@
import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/user.dart'; import 'package:aitrainer_app/model/user.dart';
import 'package:aitrainer_app/service/customer_service.dart'; import 'package:aitrainer_app/service/customer_service.dart';
import 'package:aitrainer_app/service/firebase_api.dart';
class UserRepository { class UserRepository {
User user; User user;
@ -22,11 +24,27 @@ class UserRepository {
Future<void> addUser() async { Future<void> addUser() async {
final User modelUser = this.user; final User modelUser = this.user;
String rc = await FirebaseApi().registerEmail(modelUser.email, modelUser.password);
if ( rc == FirebaseApi.SIGN_IN_OK ) {
modelUser.firebaseUid = Cache().firebaseUid;
await CustomerApi().addUser(modelUser); await CustomerApi().addUser(modelUser);
} }
}
Future<void> getUser() async { Future<void> getUser() async {
final User modelUser = this.user; final User modelUser = this.user;
await CustomerApi().getUser(modelUser); String rc = await FirebaseApi().signInEmail(modelUser.email, modelUser.password);
if ( rc == FirebaseApi.SIGN_IN_NOT_FOUND ) {
rc = await FirebaseApi().registerEmail(modelUser.email, modelUser.password);
}
if ( rc == FirebaseApi.SIGN_IN_OK ) {
await CustomerApi().getUserByEmail(modelUser.email);
Cache().afterFirebaseLogin();
}
}
Future<void> resetPassword() async {
final User modelUser = this.user;
await FirebaseApi().resetPassword(modelUser.email);
} }
} }

View File

@ -25,6 +25,14 @@ class CustomerApi {
body); body);
} }
Future<void> updateFirebaseUid(int customerId, String uid) async {
print(" ===== update Firebase uid : " + customerId.toString() + ": " +
uid);
await _client.post(
"customers/update_firebase_uid/" + customerId.toString(),
uid);
}
Future<void> addCustomer(Customer customer) async { Future<void> addCustomer(Customer customer) async {
String body = JsonEncoder().convert(customer.toJson()); String body = JsonEncoder().convert(customer.toJson());
print(" ===== add new customer: " + body); print(" ===== add new customer: " + body);
@ -35,7 +43,7 @@ class CustomerApi {
Future<void> addUser(User user) async { Future<void> addUser(User user) async {
String body = JsonEncoder().convert(user.toJson()); String body = JsonEncoder().convert(user.toJson());
print(" ===== register new user: " + body); print(" ===== add new user: " + body);
final String responseBody = await _client.post( final String responseBody = await _client.post(
"registration", "registration",
body); body);
@ -68,6 +76,23 @@ class CustomerApi {
} }
} }
Future<void> getUserByEmail(String email) async {
print(" ===== User getByEmail : " + email);
final String responseBody = await _client.get(
"customers/find_by_email/" + email,
"");
Customer customer;
try {
customer = Customer.fromJson(jsonDecode(responseBody));
if ( customer.firebaseUid == null ) {
await this.updateFirebaseUid(customer.customerId, Cache().firebaseUid);
}
Cache().userLoggedIn = customer;
} on FormatException {
throw new Exception(responseBody);
}
}
Future<void> getCustomer(int customerId) async { Future<void> getCustomer(int customerId) async {
String body = ""; String body = "";

View File

@ -0,0 +1,105 @@
import 'package:aitrainer_app/model/cache.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter_facebook_auth/flutter_facebook_auth.dart';
class FirebaseApi {
static FirebaseApi _instance;
static final FirebaseAuth auth = FirebaseAuth.instance;
static const String SIGN_IN_OK = "OK";
static const String SIGN_IN_NOT_FOUND = "user-not-found";
static const String SIGN_IN_WRONG_PWD = "wrong-password";
static const String REGISTER_WEAK_PWD = "weak-password";
static const String REGISTER_EMAIL_IN_USE = "email-already-in-use";
UserCredential userCredential;
factory FirebaseApi() => _instance ?? FirebaseApi._internal();
FirebaseApi._internal() {
_instance = this;
}
// Define an async function to initialize FlutterFire
Future<void> initializeFlutterFire() async {
try {
// Wait for Firebase to initialize and set `_initialized` state to true
await Firebase.initializeApp();
} catch (e) {
// Set `_error` state to true if Firebase initialization fails
print("Error initializing Firebase");
}
}
Future<String> signInEmail(String email, String password) async {
String rc = SIGN_IN_OK;
try {
userCredential = await FirebaseAuth.instance.signInWithEmailAndPassword(
email: email,
password: password
);
Cache().firebaseUid = userCredential.user.uid;
} on FirebaseAuthException catch (e) {
if (e.code == 'user-not-found') {
print('No user found for that email.');
rc = SIGN_IN_NOT_FOUND;
} else if (e.code == 'wrong-password') {
print('Wrong password provided for that user.');
rc = SIGN_IN_WRONG_PWD;
throw Exception("Customer does not exist or the password is wrong");
}
return e.code;
}
return rc;
}
Future<String> registerEmail(String email, String password) async {
String rc = SIGN_IN_OK;
try {
userCredential = await FirebaseAuth.instance.createUserWithEmailAndPassword(
email: email,
password: password
);
Cache().firebaseUid = userCredential.user.uid;
} on FirebaseAuthException catch (e) {
if (e.code == 'weak-password') {
print('The password provided is too weak.');
rc = REGISTER_WEAK_PWD;
throw Exception("Password too short");
} else if (e.code == 'email-already-in-use') {
print('The account already exists for that email.');
throw Exception("Customer exists");
rc = REGISTER_EMAIL_IN_USE;
}
} catch (e) {
print(e);
throw Exception(e.toString());
}
return rc;
}
Future<UserCredential> signInWithFacebook() async {
// Trigger the sign-in flow
final LoginResult result = await FacebookAuth.instance.login();
// Create a credential from the access token
final FacebookAuthCredential facebookAuthCredential =
FacebookAuthProvider.credential(result.accessToken.token);
// Once signed in, return the UserCredential
return await FirebaseAuth.instance.signInWithCredential(facebookAuthCredential);
}
Future<void> signOut() async {
await FirebaseAuth.instance.signOut();
}
Future<void> resetPassword(String email) async {
await FirebaseAuth.instance.sendPasswordResetEmail(email: email);
}
}

View File

@ -5,6 +5,7 @@ import 'package:aitrainer_app/service/api.dart';
import 'package:aitrainer_app/service/customer_service.dart'; import 'package:aitrainer_app/service/customer_service.dart';
import 'package:aitrainer_app/service/exercise_tree_service.dart'; import 'package:aitrainer_app/service/exercise_tree_service.dart';
import 'package:aitrainer_app/service/exercisetype_service.dart'; import 'package:aitrainer_app/service/exercisetype_service.dart';
import 'package:aitrainer_app/service/firebase_api.dart';
import 'package:devicelocale/devicelocale.dart'; import 'package:devicelocale/devicelocale.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
@ -31,7 +32,8 @@ class Session {
await AppLocalizations.delegate.load(AppLanguage().appLocal); await AppLocalizations.delegate.load(AppLanguage().appLocal);
print (" -- Session: fetch token.."); print (" -- Session: fetch token..");
await _fetchToken(_sharedPreferences); await _fetchToken(_sharedPreferences);
await _initializeFlutterFire(); print (" -- FireBase init..");
await FirebaseApi().initializeFlutterFire();
//initDeviceLocale(); //initDeviceLocale();
// Create the initialization Future outside of `build`: // Create the initialization Future outside of `build`:
@ -42,17 +44,6 @@ class Session {
} }
// Define an async function to initialize FlutterFire
void _initializeFlutterFire() async {
try {
// Wait for Firebase to initialize and set `_initialized` state to true
await Firebase.initializeApp();
} catch (e) {
// Set `_error` state to true if Firebase initialization fails
print("Error initializing Firebase");
}
}
Future<void> initDeviceLocale() async { Future<void> initDeviceLocale() async {
List languages; List languages;
String currentLocale; String currentLocale;
@ -90,10 +81,10 @@ class Session {
} else if (responseJson['token'] != null) { } else if (responseJson['token'] != null) {
prefs.setString(Cache.authTokenKey, responseJson['token']); prefs.setString(Cache.authTokenKey, responseJson['token']);
Cache().authToken = responseJson['token']; Cache().authToken = responseJson['token'];
Cache().firebaseUid = prefs.get(Cache.firebaseUidKey);
if (prefs.get(Cache.customerIdKey) == null) { if (prefs.get(Cache.customerIdKey) == null) {
print("************** Registration"); print("************** Registration");
// registration // registration
//Navigator.of(context).pushNamed('registration');
prefs.setBool(Cache.isRegisteredKey, true); prefs.setBool(Cache.isRegisteredKey, true);
Cache().startPage = "registration"; Cache().startPage = "registration";
} else { } else {
@ -107,7 +98,12 @@ class Session {
prefs.get(Cache.isLoggedInKey) == null || prefs.get(Cache.isLoggedInKey) == null ||
prefs.get(Cache.isLoggedInKey) == false) { prefs.get(Cache.isLoggedInKey) == false) {
print("************* Login"); print("************* Login");
//Navigator.of(context).pushNamed('login'); Cache().startPage = "login";
} else {
// only
if ( Cache().firebaseUid == null) {
print("************* firebaseUid is null, Login");
Cache().startPage = "login"; Cache().startPage = "login";
} else { } else {
// get API customer // get API customer
@ -115,6 +111,7 @@ class Session {
await CustomerApi().getCustomer(customerId); await CustomerApi().getCustomer(customerId);
Cache().startPage = "home"; Cache().startPage = "home";
} }
}
await ExerciseTypeApi().getExerciseTypes(); await ExerciseTypeApi().getExerciseTypes();
await ExerciseTreeApi().getExerciseTree(); await ExerciseTreeApi().getExerciseTree();

View File

@ -6,6 +6,7 @@ import 'package:aitrainer_app/localization/app_language.dart';
import 'package:aitrainer_app/model/workout_menu_tree.dart'; import 'package:aitrainer_app/model/workout_menu_tree.dart';
import 'package:aitrainer_app/repository/exercise_repository.dart'; import 'package:aitrainer_app/repository/exercise_repository.dart';
import 'package:aitrainer_app/util/trans.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/widgets/splash.dart';
import 'package:aitrainer_app/library/numberpicker.dart'; import 'package:aitrainer_app/library/numberpicker.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
@ -71,24 +72,7 @@ class _ExerciseExecuteAddPage extends State<ExerciseExecutePlanAddPage> with Tra
autovalidate: true, autovalidate: true,
child: Scaffold( child: Scaffold(
resizeToAvoidBottomInset: true, resizeToAvoidBottomInset: true,
appBar: AppBar( appBar: AppBarNav(depth: 1),
backgroundColor: Colors.black,
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(t("Save Exercise"), style: TextStyle(fontSize: 18),),
Image.asset(
'asset/image/WT_long_logo.png',
fit: BoxFit.cover,
height: 65.0,
),
],
),
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.white),
onPressed: () => Navigator.of(context).pop(),
),
),
body: Container( body: Container(
width: MediaQuery width: MediaQuery
.of(context) .of(context)
@ -115,6 +99,7 @@ class _ExerciseExecuteAddPage extends State<ExerciseExecutePlanAddPage> with Tra
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround, mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[ children: <Widget>[
Text(t("Save Exercise")),
Text(exerciseName, Text(exerciseName,
style: TextStyle(fontWeight: FontWeight.bold, style: TextStyle(fontWeight: FontWeight.bold,
fontSize: 18, fontSize: 18,

View File

@ -50,6 +50,8 @@ class _ExercisePlanDetailAddPage extends State<ExercisePlanDetailAddPage> with T
)); ));
} }
Widget getForm(ExercisePlanCustomAddBloc bloc, WorkoutMenuTree workoutMenuTree) { Widget getForm(ExercisePlanCustomAddBloc bloc, WorkoutMenuTree workoutMenuTree) {
String exerciseName = ""; String exerciseName = "";
if (bloc != null) { if (bloc != null) {
@ -94,20 +96,26 @@ class _ExercisePlanDetailAddPage extends State<ExercisePlanDetailAddPage> with T
fit: FlexFit.tight, fit: FlexFit.tight,
flex: 8, flex: 8,
child: child:
Text(t("Serie")), Text(
t("Serie"),
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
), ),
NumberPicker.horizontal( NumberPicker.horizontal(
highlightSelectedValue: true, highlightSelectedValue: true,
initialValue: bloc.serie.toInt(), initialValue: bloc.serie.toInt(),
minValue: 0, itemExtent: 85,
maxValue: 200, minValue: 1,
maxValue: 20,
//decoration: _decoration,
step: 1, step: 1,
onChanged: (value) => { onChanged: (value) => {
bloc.add(ExercisePlanCustomAddChangeSerie(quantity: value.toDouble())) bloc.add(ExercisePlanCustomAddChangeSerie(quantity: value.toDouble()))
}, },
listViewHeight: 80, listViewHeight: 80,
textStyle: TextStyle(fontSize: 24), textStyle: TextStyle(fontSize: 24),
textStyleHighlighted: TextStyle(fontSize: 40, color: Colors.orange, fontWeight: FontWeight.bold), textStyleHighlighted: TextStyle(fontSize: 36, color: Colors.orange, fontWeight: FontWeight.bold),
//decoration: _decoration, //decoration: _decoration,
), ),
@ -121,20 +129,22 @@ class _ExercisePlanDetailAddPage extends State<ExercisePlanDetailAddPage> with T
fit: FlexFit.tight, fit: FlexFit.tight,
flex: 8, flex: 8,
child: child:
Text(t("Weight") + " (" + bloc.exercisePlanRepository.getActualPlanDetail().exerciseType.unitQuantityUnit + ")"), Text(t("Repeats"),
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),),
), ),
NumberPicker.horizontal( NumberPicker.horizontal(
highlightSelectedValue: true, highlightSelectedValue: true,
initialValue: bloc.quantityUnit.toInt(), initialValue: bloc.quantity.toInt(),
itemExtent: 85,
minValue: 0, minValue: 0,
maxValue: 650, maxValue: 200,
step: 1, step: 1,
onChanged: (value) => { onChanged: (value) => {
bloc.add(ExercisePlanCustomAddChangeQuantityUnit(quantity: value.toDouble())) bloc.add(ExercisePlanCustomAddChangeQuantity(quantity: value.toDouble()))
}, },
listViewHeight: 80, listViewHeight: 80,
textStyle: TextStyle(fontSize: 24), textStyle: TextStyle(fontSize: 24),
textStyleHighlighted: TextStyle(fontSize: 40, color: Colors.orange, fontWeight: FontWeight.bold), textStyleHighlighted: TextStyle(fontSize: 36, color: Colors.orange, fontWeight: FontWeight.bold),
//decoration: _decoration, //decoration: _decoration,
), ),
]), ]),
@ -146,67 +156,35 @@ class _ExercisePlanDetailAddPage extends State<ExercisePlanDetailAddPage> with T
fit: FlexFit.tight, fit: FlexFit.tight,
flex: 8, flex: 8,
child: child:
Text(t("Repeats")), Text(t("Weight") + " (" + bloc.exercisePlanRepository.getActualPlanDetail().exerciseType.unitQuantityUnit + ")",
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),),
), ),
NumberPicker.horizontal( NumberPicker.horizontal(
highlightSelectedValue: true, highlightSelectedValue: true,
initialValue: bloc.quantity.toInt(), initialValue: bloc.quantityUnit.toInt(),
//decoration: _decoration,
itemExtent: 85,
minValue: 0, minValue: 0,
maxValue: 200, maxValue: 650,
step: 1, step: 1,
onChanged: (value) => { onChanged: (value) => {
bloc.add(ExercisePlanCustomAddChangeQuantity(quantity: value.toDouble())) bloc.add(ExercisePlanCustomAddChangeQuantityUnit(quantity: value.toDouble()))
}, },
listViewHeight: 80, listViewHeight: 80,
textStyle: TextStyle(fontSize: 24), textStyle: TextStyle(fontSize: 24),
textStyleHighlighted: TextStyle(fontSize: 40, color: Colors.orange, fontWeight: FontWeight.bold), textStyleHighlighted: TextStyle(fontSize: 36, color: Colors.orange, fontWeight: FontWeight.bold),
//decoration: _decoration, //decoration: _decoration,
), ),
]), ]),
Divider(), Divider(),
/*TextFieldBlocBuilder( Text(
textFieldBloc: bloc.serieField, bloc.serie.toStringAsFixed(0) + " x " + bloc.quantity.toStringAsFixed(0) + " x " + bloc.quantityUnit.toStringAsFixed(0) + " kg" ,
textAlign: TextAlign.center, style: TextStyle(fontSize: 28, fontWeight: FontWeight.normal),
style: TextStyle(fontSize: 30, color: Colors.lightBlue, fontWeight: FontWeight.bold),
inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r"[\d.]"))],
decoration: InputDecoration(
fillColor: Colors.white,
filled: false,
hintStyle: TextStyle(fontSize: 16, color: Colors.black54, fontWeight: FontWeight.w100),
hintText: AppLocalizations.of(context).translate("The number of the serie done with"),
labelStyle: TextStyle(fontSize: 16, color: Colors.lightBlue),
labelText: AppLocalizations.of(context).translate("Serie"),
), ),
),*/ Divider(),
/*TextFieldBlocBuilder(
textFieldBloc: bloc.quantityField,
textAlign: TextAlign.center,
style: TextStyle(fontSize: 30, color: Colors.lightBlue, fontWeight: FontWeight.bold),
inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r"[\d.]"))],
decoration: InputDecoration(
fillColor: Colors.white,
filled: false,
hintStyle: TextStyle(fontSize: 16, color: Colors.black54, fontWeight: FontWeight.w100),
hintText:
AppLocalizations.of(context).translate("The number of the repeats of one serie"),
labelStyle: TextStyle(fontSize: 16, color: Colors.lightBlue),
labelText: AppLocalizations.of(context).translate("Repeats"),
),
),*/
/*TextFieldBlocBuilder(
textFieldBloc: bloc.weightField,
textAlign: TextAlign.center,
style: TextStyle(fontSize: 30, color: Colors.lightBlue, fontWeight: FontWeight.bold),
inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r"[\d.]"))],
decoration: InputDecoration(
fillColor: Colors.white,
filled: false,
hintStyle: TextStyle(fontSize: 16, color: Colors.black54, fontWeight: FontWeight.w100),
hintText: AppLocalizations.of(context).translate("The weight"),
labelStyle: TextStyle(fontSize: 16, color: Colors.lightBlue),
labelText: AppLocalizations.of(context).translate("Weight"),
),
),*/
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceAround, mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [ children: [
@ -217,11 +195,6 @@ class _ExercisePlanDetailAddPage extends State<ExercisePlanDetailAddPage> with T
onPressed: () => { onPressed: () => {
bloc.add(ExercisePlanCustomAddRemove()), bloc.add(ExercisePlanCustomAddRemove()),
Navigator.of(context).pop(), Navigator.of(context).pop(),
/*print("Remove " + bloc.exercisePlanRepository.getActualPlanDetail().exerciseType.name),
bloc.exercisePlanRepository.getActualPlanDetail().change = ExercisePlanDetailChange.delete,
planBloc.add(ExercisePlanRemoveExercise(
exercisePlanDetail: bloc.exercisePlanRepository.getActualPlanDetail() )),
Navigator.of(context).pop(),*/
}, },
child: Text(t( child: Text(t(
"Delete")), //Text(AppLocalizations.of(context).translate("Delete"), style: TextStyle(fontSize: 16),) "Delete")), //Text(AppLocalizations.of(context).translate("Delete"), style: TextStyle(fontSize: 16),)
@ -233,8 +206,6 @@ class _ExercisePlanDetailAddPage extends State<ExercisePlanDetailAddPage> with T
onPressed: () => { onPressed: () => {
bloc.add(ExercisePlanCustomAddSubmit()), bloc.add(ExercisePlanCustomAddSubmit()),
Navigator.of(context).pop(), Navigator.of(context).pop(),
/* bloc.submit(),
Navigator.of(context).pop(),*/
}, },
child: Text( child: Text(
t("Save"), t("Save"),

View File

@ -2,12 +2,13 @@ import 'package:aitrainer_app/bloc/login_form_bloc.dart';
import 'package:aitrainer_app/bloc/account/account_bloc.dart'; import 'package:aitrainer_app/bloc/account/account_bloc.dart';
import 'package:aitrainer_app/localization/app_localization.dart'; import 'package:aitrainer_app/localization/app_localization.dart';
import 'package:aitrainer_app/repository/user_repository.dart'; import 'package:aitrainer_app/repository/user_repository.dart';
import 'package:aitrainer_app/service/firebase_api.dart';
import 'package:aitrainer_app/util/common.dart'; import 'package:aitrainer_app/util/common.dart';
import 'package:aitrainer_app/util/trans.dart';
import 'package:aitrainer_app/widgets/splash.dart'; import 'package:aitrainer_app/widgets/splash.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter_bloc/flutter_bloc.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:flutter_form_bloc/flutter_form_bloc.dart';
import '../library_keys.dart'; import '../library_keys.dart';
@ -26,13 +27,14 @@ class LoginWidget extends StatefulWidget {
State<StatefulWidget> createState() => _LoginWidget(); State<StatefulWidget> createState() => _LoginWidget();
} }
class _LoginWidget extends State<LoginWidget> with Common { class _LoginWidget extends State<LoginWidget> with Common, Trans {
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>(); final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
final _formKey = GlobalKey<FormState>(); final _formKey = GlobalKey<FormState>();
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final accountBloc = BlocProvider.of<AccountBloc>(context); final accountBloc = BlocProvider.of<AccountBloc>(context);
setContext(context);
return BlocProvider( return BlocProvider(
create: (context) => LoginFormBloc( create: (context) => LoginFormBloc(
userRepository: UserRepository(), userRepository: UserRepository(),
@ -72,7 +74,6 @@ class _LoginWidget extends State<LoginWidget> with Common {
} }
Widget buildLoginForm(LoginFormBloc formBloc, AccountBloc accountBloc) { Widget buildLoginForm(LoginFormBloc formBloc, AccountBloc accountBloc) {
final cWidth = mediaSizeWidth(context);
return Form( return Form(
key: _formKey, key: _formKey,
@ -81,17 +82,18 @@ class _LoginWidget extends State<LoginWidget> with Common {
child: child:
ListView(shrinkWrap: false, padding: EdgeInsets.only(top: 120.0), ListView(shrinkWrap: false, padding: EdgeInsets.only(top: 120.0),
children: <Widget>[ children: <Widget>[
FlatButton( /* FlatButton(
child: new Image.asset( child: new Image.asset(
'asset/image/login_fb.png', 'asset/image/login_fb.png',
width: cWidth * .85, width: cWidth * .85,
), ),
onPressed: () => { onPressed: () => {
_fbLogin(), //_fbLogin(),
FirebaseApi().signInWithFacebook(),
print("Login with FB"), print("Login with FB"),
}, },
), ),
Text(AppLocalizations.of(context).translate("OR")), Text(AppLocalizations.of(context).translate("OR")),*/
Divider(), Divider(),
Row( Row(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
@ -154,12 +156,17 @@ class _LoginWidget extends State<LoginWidget> with Common {
Navigator.of(context).pushNamed('registration'), Navigator.of(context).pushNamed('registration'),
), ),
Spacer(flex: 1), Spacer(flex: 1),
new InkWell(
child: new Text(
AppLocalizations.of(context).translate('I forgot the password')),
onTap: () => Navigator.of(context).pushNamed('resetPassword'),
),
Spacer(flex: 1),
new InkWell( new InkWell(
child: new Text( child: new Text(
AppLocalizations.of(context).translate('Privacy')), AppLocalizations.of(context).translate('Privacy')),
onTap: () => Navigator.of(context).pushNamed('gdpr'), onTap: () => Navigator.of(context).pushNamed('gdpr'),
), ),
Spacer(flex: 2),
]), ]),
])), ])),
); );
@ -172,30 +179,4 @@ class _LoginWidget extends State<LoginWidget> with Common {
content: Text(error, style: TextStyle(color: Colors.white)))); content: Text(error, style: TextStyle(color: Colors.white))));
} }
Future<Null> _fbLogin() async {
final FacebookLogin facebookSignIn = new FacebookLogin();
final FacebookLoginResult result = await facebookSignIn.logIn(['email']);
switch (result.status) {
case FacebookLoginStatus.loggedIn:
final FacebookAccessToken accessToken = result.accessToken;
showInSnackBar('''
Logged in!
Token: ${accessToken.token}
User id: ${accessToken.userId}
Expires: ${accessToken.expires}
Permissions: ${accessToken.permissions}
Declined permissions: ${accessToken.declinedPermissions}
''');
break;
case FacebookLoginStatus.cancelledByUser:
showInSnackBar('Login cancelled by the user.');
break;
case FacebookLoginStatus.error:
showInSnackBar('Something went wrong with the login process.\n'
'Here\'s the error Facebook gave us: ${result.errorMessage}');
break;
}
}
} }

View File

@ -3,6 +3,7 @@ import 'dart:collection';
import 'package:aitrainer_app/model/cache.dart'; import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/repository/customer_repository.dart'; import 'package:aitrainer_app/repository/customer_repository.dart';
import 'package:aitrainer_app/repository/exercise_repository.dart'; import 'package:aitrainer_app/repository/exercise_repository.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:aitrainer_app/util/trans.dart'; import 'package:aitrainer_app/util/trans.dart';
import 'package:aitrainer_app/widgets/app_bar.dart'; import 'package:aitrainer_app/widgets/app_bar.dart';
import 'package:aitrainer_app/widgets/bottom_nav.dart'; import 'package:aitrainer_app/widgets/bottom_nav.dart';
@ -22,6 +23,9 @@ class _MyDevelopmentPage extends State<MyDevelopmentPage> with Trans {
final CustomerRepository customerRepository = CustomerRepository(); final CustomerRepository customerRepository = CustomerRepository();
final LinkedHashMap args = LinkedHashMap(); final LinkedHashMap args = LinkedHashMap();
setContext(context); setContext(context);
double mediaWidth = MediaQuery.of(context).size.width;
double imageWidth = (mediaWidth - 45) / 2;
print("Media: " + mediaWidth.toString() + " imageWidth: " + imageWidth.toString());
return Scaffold( return Scaffold(
appBar: AppBarNav(depth: 0), appBar: AppBarNav(depth: 0),
@ -34,70 +38,77 @@ class _MyDevelopmentPage extends State<MyDevelopmentPage> with Trans {
alignment: Alignment.center, alignment: Alignment.center,
), ),
), ),
child: CustomScrollView( child: CustomScrollView(scrollDirection: Axis.vertical, slivers: [
scrollDirection: Axis.vertical,
slivers:
[
SliverGrid( SliverGrid(
delegate: SliverChildListDelegate( delegate: SliverChildListDelegate([
[
ImageButton( ImageButton(
width: imageWidth,
textAlignment: Alignment.topCenter, textAlignment: Alignment.topCenter,
text: t("My Exercise Logs"), text: t("My Exercise Logs"),
style: TextStyle(fontSize: 14, color: Colors.orange, fontWeight: FontWeight.bold, backgroundColor: Colors.black54.withOpacity(0.4)), style: GoogleFonts.robotoMono(
textStyle: TextStyle(
fontSize: 14,
color: Colors.orange,
fontWeight: FontWeight.bold,
backgroundColor: Colors.black54.withOpacity(0.4)
)
),
image: "asset/image/edzesnaplom400400.jpg", image: "asset/image/edzesnaplom400400.jpg",
top: 150,
left: 10, left: 10,
onTap:() => this.callBackExerciseLog(exerciseRepository, customerRepository), onTap: () => this.callBackExerciseLog(exerciseRepository, customerRepository),
isLocked: false, isLocked: false,
), ),
ImageButton( ImageButton(
width: imageWidth,
textAlignment: Alignment.topLeft, textAlignment: Alignment.topLeft,
text: t("My Whole Body Development"), text: t("My Whole Body Development"),
style: TextStyle(fontSize: 14, color: Colors.orange, fontWeight: FontWeight.bold, style: GoogleFonts.robotoMono(
textStyle: TextStyle(
fontSize: 14,
color: Colors.orange,
fontWeight: FontWeight.bold,
backgroundColor: Colors.black54.withOpacity(0.4)), backgroundColor: Colors.black54.withOpacity(0.4)),
),
image: "asset/image/testemfejl400x400.jpg", image: "asset/image/testemfejl400x400.jpg",
top: 150,
left: 10, left: 10,
onTap:() => { onTap: () => {
args['customerId'] = Cache().userLoggedIn.customerId, args['customerId'] = Cache().userLoggedIn.customerId,
Navigator.of(context).pushNamed('mydevelopmentBodyPage', Navigator.of(context).pushNamed('mydevelopmentBodyPage', arguments: args)
arguments: args)
}, },
isLocked: true, isLocked: true,
), ),
ImageButton( ImageButton(
width: imageWidth,
textAlignment: Alignment.topLeft, textAlignment: Alignment.topLeft,
text: t("Development Of Muscles"), text: t("Development Of Muscles"),
style: TextStyle(fontSize: 14, color: Colors.orange, fontWeight: FontWeight.bold, style: GoogleFonts.robotoMono(
backgroundColor: Colors.black54.withOpacity(0.4)), textStyle: TextStyle(
fontSize: 14,
color: Colors.orange,
fontWeight: FontWeight.bold,
backgroundColor: Colors.black54.withOpacity(0.4))),
image: "asset/image/izomcsop400400.jpg", image: "asset/image/izomcsop400400.jpg",
top: 120,
left: 10, left: 10,
onTap:() => { onTap: () => {Navigator.of(context).pushNamed('mydevelopmentMusclePage', arguments: args)},
Navigator.of(context).pushNamed('mydevelopmentMusclePage',
arguments: args)
},
isLocked: true, isLocked: true,
), ),
ImageButton( ImageButton(
width: imageWidth,
left: 10,
textAlignment: Alignment.topLeft, textAlignment: Alignment.topLeft,
text: t("Predictions"), text: t("Predictions"),
style: TextStyle(fontSize: 14, color: Colors.orange, fontWeight: FontWeight.bold, style: GoogleFonts.robotoMono(
backgroundColor: Colors.black54.withOpacity(0.4)), textStyle: TextStyle(
image: "asset/menu/2.2.1.1RM.png", fontSize: 14,
top: 150, color: Colors.orange,
onTap:() => { fontWeight: FontWeight.bold,
backgroundColor: Colors.black54.withOpacity(0.4))),
}, image: "asset/image/predictions.jpg",
onTap: () => {},
isLocked: true, isLocked: true,
), ),
hiddenWidget(customerRepository, exerciseRepository), hiddenWidget(customerRepository, exerciseRepository),
] ]),
),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2, crossAxisCount: 2,
mainAxisSpacing: 15.0, mainAxisSpacing: 15.0,
@ -105,9 +116,7 @@ class _MyDevelopmentPage extends State<MyDevelopmentPage> with Trans {
childAspectRatio: 1.0, childAspectRatio: 1.0,
), ),
) )
] ])),
)
),
bottomNavigationBar: BottomNavigator(bottomNavIndex: 1)); bottomNavigationBar: BottomNavigator(bottomNavIndex: 1));
} }
@ -119,17 +128,16 @@ class _MyDevelopmentPage extends State<MyDevelopmentPage> with Trans {
textColor: Colors.white, textColor: Colors.white,
color: Colors.black12, color: Colors.black12,
focusColor: Colors.blueAccent, focusColor: Colors.blueAccent,
onPressed: () => onPressed: () => {
{
args['exerciseRepository'] = exerciseRepository, args['exerciseRepository'] = exerciseRepository,
args['customerRepository'] = customerRepository, args['customerRepository'] = customerRepository,
args['customerId'] = Cache().getTrainee().customerId, args['customerId'] = Cache().getTrainee().customerId,
Navigator.of(context).pushNamed('exerciseLogPage', Navigator.of(context).pushNamed('exerciseLogPage', arguments: args)
arguments: args)
}, },
child: Text(t("My Trainee's Exercise Logs"), child: Text(
style: TextStyle(fontSize: 18),) t("My Trainee's Exercise Logs"),
); style: TextStyle(fontSize: 18),
));
} else { } else {
return Container(); return Container();
} }
@ -140,10 +148,6 @@ class _MyDevelopmentPage extends State<MyDevelopmentPage> with Trans {
args['exerciseRepository'] = exerciseRepository; args['exerciseRepository'] = exerciseRepository;
args['customerRepository'] = customerRepository; args['customerRepository'] = customerRepository;
args['customerId'] = Cache().userLoggedIn.customerId; args['customerId'] = Cache().userLoggedIn.customerId;
Navigator.of(context).pushNamed('exerciseLogPage', Navigator.of(context).pushNamed('exerciseLogPage', arguments: args);
arguments: args);
} }
} }

View File

@ -7,6 +7,7 @@ import 'package:aitrainer_app/widgets/bottom_nav.dart';
import 'package:aitrainer_app/widgets/image_button.dart'; import 'package:aitrainer_app/widgets/image_button.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
class MyExercisePlanPage extends StatefulWidget { class MyExercisePlanPage extends StatefulWidget {
@override @override
@ -20,6 +21,10 @@ class _MyExercisePlanPage extends State<MyExercisePlanPage> with Trans {
final LinkedHashMap args = LinkedHashMap(); final LinkedHashMap args = LinkedHashMap();
setContext(context); setContext(context);
double mediaWidth = MediaQuery.of(context).size.width;
double imageWidth = (mediaWidth - 45) / 2;
print("Media: " + mediaWidth.toString() + " imageWidth: " + imageWidth.toString());
return Scaffold( return Scaffold(
appBar: AppBarNav(depth: 0), appBar: AppBarNav(depth: 0),
body: Container( body: Container(
@ -39,10 +44,12 @@ class _MyExercisePlanPage extends State<MyExercisePlanPage> with Trans {
delegate: SliverChildListDelegate( delegate: SliverChildListDelegate(
[ [
ImageButton( ImageButton(
width: imageWidth,
textAlignment: Alignment.topLeft, textAlignment: Alignment.topLeft,
text: t("Execute My Selected Training Plan"), text: t("Execute My Selected Training Plan"),
style: TextStyle(fontSize: 14, color: Colors.orange, fontWeight: FontWeight.bold, style: GoogleFonts.robotoMono(
backgroundColor: Colors.black54.withOpacity(0.4)), textStyle: TextStyle(fontSize: 14, color: Colors.orange, fontWeight: FontWeight.bold,
backgroundColor: Colors.black54.withOpacity(0.4))),
image: "asset/image/exercise_plan_execute.jpg", image: "asset/image/exercise_plan_execute.jpg",
top: 130, top: 130,
left: 10, left: 10,
@ -55,12 +62,13 @@ class _MyExercisePlanPage extends State<MyExercisePlanPage> with Trans {
), ),
ImageButton( ImageButton(
width: imageWidth,
textAlignment: Alignment.topLeft, textAlignment: Alignment.topLeft,
text: t("Edit My Custom Plan"), text: t("Edit My Custom Plan"),
style: TextStyle(fontSize: 14, color: Colors.orange, fontWeight: FontWeight.bold, style: GoogleFonts.robotoMono(
backgroundColor: Colors.black54.withOpacity(0.4)), textStyle: TextStyle(fontSize: 14, color: Colors.orange, fontWeight: FontWeight.bold,
backgroundColor: Colors.black54.withOpacity(0.4))),
image: "asset/image/exercise_plan_custom.jpg", image: "asset/image/exercise_plan_custom.jpg",
top: 150,
left: 10, left: 10,
onTap:() => { onTap:() => {
args['exerciseRepository'] = exerciseRepository, args['exerciseRepository'] = exerciseRepository,
@ -72,12 +80,13 @@ class _MyExercisePlanPage extends State<MyExercisePlanPage> with Trans {
), ),
ImageButton( ImageButton(
width: imageWidth,
textAlignment: Alignment.topLeft, textAlignment: Alignment.topLeft,
text: t("Suggested Training Plan"), text: t("Suggested Training Plan"),
style: TextStyle(fontSize: 14, color: Colors.orange, fontWeight: FontWeight.bold, style: GoogleFonts.robotoMono(
backgroundColor: Colors.black54.withOpacity(0.4)), textStyle: TextStyle(fontSize: 14, color: Colors.orange, fontWeight: FontWeight.bold,
backgroundColor: Colors.black54.withOpacity(0.4))),
image: "asset/image/exercise_plan_suggested.jpg", image: "asset/image/exercise_plan_suggested.jpg",
top: 130,
left: 10, left: 10,
onTap:() => { onTap:() => {
@ -86,12 +95,13 @@ class _MyExercisePlanPage extends State<MyExercisePlanPage> with Trans {
), ),
ImageButton( ImageButton(
width: imageWidth,
textAlignment: Alignment.topLeft, textAlignment: Alignment.topLeft,
text: t("My Special Plan"), text: t("My Special Plan"),
style: TextStyle(fontSize: 14, color: Colors.orange, fontWeight: FontWeight.bold, style: GoogleFonts.robotoMono(
backgroundColor: Colors.black54.withOpacity(0.4)), textStyle: TextStyle(fontSize: 14, color: Colors.orange, fontWeight: FontWeight.bold,
backgroundColor: Colors.black54.withOpacity(0.4))),
image: "asset/image/exercise_plan_special.jpg", image: "asset/image/exercise_plan_special.jpg",
top: 150,
left: 10, left: 10,
onTap:() => { onTap:() => {
@ -100,12 +110,13 @@ class _MyExercisePlanPage extends State<MyExercisePlanPage> with Trans {
), ),
ImageButton( ImageButton(
width: imageWidth,
textAlignment: Alignment.topLeft, textAlignment: Alignment.topLeft,
text: t("My Arnold's Plan"), text: t("My Arnold's Plan"),
style: TextStyle(fontSize: 14, color: Colors.orange, fontWeight: FontWeight.bold, style: GoogleFonts.robotoMono(
backgroundColor: Colors.black54.withOpacity(0.4)), textStyle: TextStyle(fontSize: 14, color: Colors.orange, fontWeight: FontWeight.bold,
backgroundColor: Colors.black54.withOpacity(0.4))),
image: "asset/image/exercise_plan_stars.jpg", image: "asset/image/exercise_plan_stars.jpg",
top: 120,
left: 10, left: 10,
onTap:() => { onTap:() => {

View File

@ -86,7 +86,7 @@ class _RegistrationWidget extends State<RegistrationWidget> with Common {
children: <Widget>[ children: <Widget>[
//Spacer(flex:4), //Spacer(flex:4),
FlatButton( /* FlatButton(
child: new Image.asset( child: new Image.asset(
'asset/image/login_fb.png', 'asset/image/login_fb.png',
width: cWidth * .85, width: cWidth * .85,
@ -96,7 +96,7 @@ class _RegistrationWidget extends State<RegistrationWidget> with Common {
print("Login with FB"), print("Login with FB"),
}, },
), ),
Text(AppLocalizations.of(context).translate("OR")), Text(AppLocalizations.of(context).translate("OR")),*/
Divider(), Divider(),
Row( Row(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
@ -187,30 +187,4 @@ class _RegistrationWidget extends State<RegistrationWidget> with Common {
error, error,
style: TextStyle(color: Colors.white)))); style: TextStyle(color: Colors.white))));
} }
/* Future<Null> _fbLogin() async {
final FacebookLogin facebookSignIn = new FacebookLogin();
final FacebookLoginResult result = await facebookSignIn.logIn(['email']);
switch (result.status) {
case FacebookLoginStatus.loggedIn:
final FacebookAccessToken accessToken = result.accessToken;
showInSnackBar('''
Logged in!
Token: ${accessToken.token}
User id: ${accessToken.userId}
Expires: ${accessToken.expires}
Permissions: ${accessToken.permissions}
Declined permissions: ${accessToken.declinedPermissions}
''');
break;
case FacebookLoginStatus.cancelledByUser:
showInSnackBar('Login cancelled by the user.');
break;
case FacebookLoginStatus.error:
showInSnackBar('Something went wrong with the login process.\n'
'Here\'s the error Facebook gave us: ${result.errorMessage}');
break;
}
} */
} }

View File

@ -0,0 +1,135 @@
import 'package:aitrainer_app/bloc/login_form_bloc.dart';
import 'package:aitrainer_app/bloc/account/account_bloc.dart';
import 'package:aitrainer_app/bloc/reset_password_bloc.dart';
import 'package:aitrainer_app/localization/app_localization.dart';
import 'package:aitrainer_app/repository/user_repository.dart';
import 'package:aitrainer_app/service/firebase_api.dart';
import 'package:aitrainer_app/util/common.dart';
import 'package:aitrainer_app/util/trans.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 '../library_keys.dart';
// ignore: must_be_immutable
class ResetPasswordPage extends StatelessWidget with Trans {
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
final _formKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
setContext(context);
return BlocProvider(
create: (context) => ResetPasswordFormBloc(
userRepository: UserRepository(),
),
child: Builder(builder: (context) {
final loginBloc = BlocProvider.of<ResetPasswordFormBloc>(context);
return Scaffold(
key: _scaffoldKey,
body: FormBlocListener<ResetPasswordFormBloc, String, String>(
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: 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: buildResetPasswordForm(loginBloc),
),
),
);
}));
}
Widget buildResetPasswordForm(ResetPasswordFormBloc formBloc) {
return Form(
key: _formKey,
child: Container(
padding: const EdgeInsets.only(left: 25, right: 100),
child:
ListView(shrinkWrap: false, padding: EdgeInsets.only(top: 120.0),
children: <Widget>[
Divider(),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
new InkWell(
child: new Text(
AppLocalizations.of(context).translate('I forgot the password'),
style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 24)),
),
],
),
Divider(),
TextFieldBlocBuilder(
key: LibraryKeys.loginEmailField,
textFieldBloc: formBloc.emailField,
decoration: InputDecoration(
fillColor: Colors.white,
filled: true,
labelText: 'Email',
),
),
Divider(
color: Colors.transparent,
),
Divider(
color: Colors.transparent,
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
new FlatButton(
key: LibraryKeys.loginOKButton,
child: Image.asset('asset/image/WT_OK.png',
width: 100, height: 100),
onPressed: () => {
formBloc.add(SubmitFormBloc())
}),
]),
Divider(
color: Colors.transparent,
),
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),
]),
])),
);
}
void showInSnackBar(String error) {
_scaffoldKey.currentState.showSnackBar(SnackBar(
backgroundColor: Colors.orange,
content: Text(error, style: TextStyle(color: Colors.white))));
}
}

View File

@ -5,12 +5,12 @@ import 'package:bloc/bloc.dart';
class ImageButton extends StatelessWidget { class ImageButton extends StatelessWidget {
final String text; final String text;
final TextStyle style; TextStyle style = TextStyle(fontSize: 14);
final String image; final String image;
final double top; final double top;
final double left; final double left;
final double height; final double height;
final double width; double width = 180;
final bool isShape; final bool isShape;
final Bloc bloc; final Bloc bloc;
final Alignment textAlignment; final Alignment textAlignment;
@ -30,10 +30,15 @@ class ImageButton extends StatelessWidget {
this.textAlignment, this.textAlignment,
this.onTap, this.onTap,
@required this.isLocked @required this.isLocked
}); }) {
width = width ?? 180;
style = style ?? TextStyle(fontSize: 14, fontFamily: "Roboto Mono");
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
double top = width - (style.fontSize - 5) * text.length < 0 ? width - 2 * style.fontSize - 10 : width - style.fontSize - 10;
print ("Top: " + top.toStringAsFixed(0) + " length: " + ((style.fontSize - 5) * text.length).toString());
return Stack( return Stack(
//alignment: textAlignment, //alignment: textAlignment,
fit: StackFit.passthrough, fit: StackFit.passthrough,
@ -63,11 +68,11 @@ class ImageButton extends StatelessWidget {
)] )]
), ),
Positioned( Positioned(
top: text.length > 20 ? 140 : 160, top: top,
left: left, left: left,
child: Container( child: Container(
height: 200, height: width - 2 * left,
width: 180, width: width - 2 * left,
child: InkWell( child: InkWell(
onTap: onTap ?? onTap, onTap: onTap ?? onTap,
child: Text( child: Text(

View File

@ -246,27 +246,6 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "7.3.2" version: "7.3.2"
firebase_analytics:
dependency: "direct main"
description:
name: firebase_analytics
url: "https://pub.dartlang.org"
source: hosted
version: "6.0.2"
firebase_analytics_platform_interface:
dependency: transitive
description:
name: firebase_analytics_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.3"
firebase_analytics_web:
dependency: transitive
description:
name: firebase_analytics_web
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.1"
firebase_auth: firebase_auth:
dependency: "direct main" dependency: "direct main"
description: description:
@ -340,13 +319,13 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
flutter_facebook_login: flutter_facebook_auth:
dependency: "direct main" dependency: "direct main"
description: description:
name: flutter_facebook_login name: flutter_facebook_auth
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.0.0" version: "0.3.3"
flutter_form_bloc: flutter_form_bloc:
dependency: "direct main" dependency: "direct main"
description: description:
@ -416,6 +395,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.2.0" version: "1.2.0"
google_fonts:
dependency: "direct main"
description:
name: google_fonts
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.1"
gradient_bottom_navigation_bar: gradient_bottom_navigation_bar:
dependency: "direct main" dependency: "direct main"
description: description:
@ -598,6 +584,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.1.4" version: "0.1.4"
path_provider:
dependency: transitive
description:
name: path_provider
url: "https://pub.dartlang.org"
source: hosted
version: "1.6.22"
path_provider_linux: path_provider_linux:
dependency: transitive dependency: transitive
description: description:
@ -605,6 +598,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.0.1+2" version: "0.0.1+2"
path_provider_macos:
dependency: transitive
description:
name: path_provider_macos
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.4+4"
path_provider_platform_interface: path_provider_platform_interface:
dependency: transitive dependency: transitive
description: description:
@ -632,7 +632,7 @@ packages:
name: percent_indicator name: percent_indicator
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.7+4" version: "2.1.8"
petitparser: petitparser:
dependency: transitive dependency: transitive
description: description:
@ -904,6 +904,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.1.1+2" version: "0.1.1+2"
toggle_switch:
dependency: "direct main"
description:
name: toggle_switch
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.8"
typed_data: typed_data:
dependency: transitive dependency: transitive
description: description:
@ -1004,4 +1011,4 @@ packages:
version: "2.2.1" version: "2.2.1"
sdks: sdks:
dart: ">=2.9.0-14.0.dev <3.0.0" dart: ">=2.9.0-14.0.dev <3.0.0"
flutter: ">=1.16.0 <2.0.0" flutter: ">=1.17.0 <2.0.0"

View File

@ -25,6 +25,7 @@ dependencies:
sdk: flutter sdk: flutter
cupertino_icons: ^1.0.0 cupertino_icons: ^1.0.0
google_fonts: ^1.1.1
devicelocale: ^0.3.3 devicelocale: ^0.3.3
sentry: ^3.0.1 sentry: ^3.0.1
flutter_bloc: ^6.0.6 flutter_bloc: ^6.0.6
@ -33,15 +34,16 @@ dependencies:
flutter_form_bloc: ^0.19.0 flutter_form_bloc: ^0.19.0
spider_chart: ^0.1.5 spider_chart: ^0.1.5
rainbow_color: ^0.1.1 rainbow_color: ^0.1.1
percent_indicator: ^2.1.7+4 percent_indicator: ^2.1.8
gradient_bottom_navigation_bar: ^1.0.0+4 gradient_bottom_navigation_bar: ^1.0.0+4
fl_chart: ^0.12.0 fl_chart: ^0.12.0
infinite_listview: ^1.0.1+1 infinite_listview: ^1.0.1+1
toggle_switch: ^0.1.8
firebase_core: 0.5.0+1 firebase_core: 0.5.0+1
firebase_analytics: ^6.0.2 #firebase_analytics: ^6.0.2
firebase_auth: ^0.18.1+2 firebase_auth: ^0.18.1+2
flutter_facebook_login: ^3.0.0 flutter_facebook_auth: ^0.3.3
mockito: ^4.1.1 mockito: ^4.1.1
@ -104,6 +106,7 @@ flutter:
- asset/image/exercise_plan_execute.jpg - asset/image/exercise_plan_execute.jpg
- asset/image/exercise_plan_custom.jpg - asset/image/exercise_plan_custom.jpg
- asset/image/exercise_plan_suggested.jpg - asset/image/exercise_plan_suggested.jpg
- asset/image/predictions.jpg
- asset/menu/1.cardio.png - asset/menu/1.cardio.png
- asset/menu/1.1.aerob.png - asset/menu/1.1.aerob.png
- asset/menu/1.2.anaerob.png - asset/menu/1.2.anaerob.png