Merge branch 'master' into othmane6

othmane6
Othmane BENJELLOUN 1 year ago
commit 7fa743edc6

@ -1,5 +1,5 @@
# SmartFit Web and Mobile! # SmartFit Web and Mobile!
TODO: Description TODO: Description + badge
## Getting Started ## Getting Started

@ -1,6 +1,6 @@
import 'package:smartfit_app_mobile/main.dart';
import 'package:smartfit_app_mobile/modele/activity_saver.dart'; import 'package:smartfit_app_mobile/modele/activity_saver.dart';
import 'package:smartfit_app_mobile/modele/helper.dart'; import 'package:smartfit_app_mobile/modele/helper.dart';
import 'package:smartfit_app_mobile/main.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:smartfit_app_mobile/modele/api/api_wrapper.dart'; import 'package:smartfit_app_mobile/modele/api/api_wrapper.dart';
@ -61,7 +61,7 @@ class _ListActivityWidget extends State<ListActivityWidget> {
.managerSelectedActivity .managerSelectedActivity
.removeSelectedActivity(activityObj.fileUuid); .removeSelectedActivity(activityObj.fileUuid);
} }
if (!Helper.isPlatformWeb()) { if (!Helper.isPlatformWeb() && localDB.getSaveLocally()) {
ActivitySaver actSaver = await ActivitySaver.create(); ActivitySaver actSaver = await ActivitySaver.create();
actSaver.deleteActivity(activityObj.fileUuid); actSaver.deleteActivity(activityObj.fileUuid);
localDB.removeActivity(activityObj.fileUuid); localDB.removeActivity(activityObj.fileUuid);

@ -267,7 +267,8 @@ class RequestApi implements IDataStrategy {
final response = await http.get(Uri.parse('$urlApi/user/info'), final response = await http.get(Uri.parse('$urlApi/user/info'),
headers: <String, String>{'Authorization': token}); headers: <String, String>{'Authorization': token});
if (response.statusCode == 200) { if (response.statusCode == 200) {
Map<String, dynamic> json = jsonDecode(response.body); Map<String,dynamic> json = jsonDecode(response.body);
return Tuple2(true, json); return Tuple2(true, json);
} }
if (response.statusCode == 400) { if (response.statusCode == 400) {
@ -285,7 +286,8 @@ class RequestApi implements IDataStrategy {
@override @override
Future<Tuple2> getModeleAI(String token, String category) async { Future<Tuple2> getModeleAI(String token, String category) async {
try { try {
final response = await http.post(Uri.parse('$urlApi/user/IA/$category')); final response = await http.get(Uri.parse('$urlApi/user/ai/$category'),
headers: <String, String>{'Authorization': token});
if (response.statusCode == 200) { if (response.statusCode == 200) {
Map<String, dynamic> json = jsonDecode(response.body); Map<String, dynamic> json = jsonDecode(response.body);

@ -2,7 +2,11 @@ class Convertisseur {
// Mettre que des trucs static // Mettre que des trucs static
static double secondeIntoMinute(double seconde) { static double secondeIntoMinute(double seconde) {
return seconde / 60; return (seconde / 60);
}
static double milisecondeIntoMinute(double miliseconde) {
return (miliseconde / 60000);
} }
static double msIntoKmh(double metreSeconde) { static double msIntoKmh(double metreSeconde) {

@ -100,25 +100,20 @@ class User extends ChangeNotifier {
Tuple2 result = await wrapper.getModeleAI(token, category, infoManager); Tuple2 result = await wrapper.getModeleAI(token, category, infoManager);
if (!result.item1) return Tuple2(false, ActivityInfo()); if (!result.item1) return Tuple2(false, ActivityInfo());
String model = result.item2["model"];
// Appel pour avoir le model Map<String, dynamic> jsonMap = json.decode(model);
//String jsonString =
// '{"coef": [270.63861280635473, 74.69699263779908, 1.9946527172333637, 0.03215810401413792, 0.3256805192289063], "intercept": [-335635.9890148213, -91874.0527070619, -2065.450392327813, -38.79838022998388, -291.590235396687]}';
Map<String, dynamic> jsonMap = json.decode(result.item2);
// Transformer la date // Transformer la date
int dateMilli = date.millisecondsSinceEpoch; int dateMilli = date.millisecondsSinceEpoch;
ActivityInfo activityInfo = ActivityInfo(); ActivityInfo activityInfo = ActivityInfo();
activityInfo.distance = activityInfo.bpmAvg =
jsonMap["coef"][0] * dateMilli + jsonMap["intercept"][0]; (jsonMap["coef"][0] * dateMilli + jsonMap["intercept"][0]).toInt();
activityInfo.timeOfActivity = activityInfo.timeOfActivity =
jsonMap["coef"][1] * dateMilli + jsonMap["intercept"][1]; jsonMap["coef"][1] * dateMilli + jsonMap["intercept"][1];
activityInfo.denivelePositif =
jsonMap["coef"][2] * dateMilli + jsonMap["intercept"][2];
activityInfo.vitesseAvg = activityInfo.vitesseAvg =
jsonMap["coef"][2] * dateMilli + jsonMap["intercept"][2];
activityInfo.distance =
jsonMap["coef"][3] * dateMilli + jsonMap["intercept"][3]; jsonMap["coef"][3] * dateMilli + jsonMap["intercept"][3];
activityInfo.bpmAvg =
jsonMap["coef"][4] * dateMilli + jsonMap["intercept"][4];
return Tuple2(true, activityInfo); return Tuple2(true, activityInfo);
} }

@ -20,9 +20,11 @@ class HomeViewUtil {
.getXWithTime(managerFile.fieldAltitude); .getXWithTime(managerFile.fieldAltitude);
List<FlSpot> bpmSecondes2 = List.from(bpmSecondes); List<FlSpot> bpmSecondes2 = List.from(bpmSecondes);
return DataHomeView(
return DataHomeView(normaliserPremierElement(bpmSecondes), normaliserPremierElement(normaliserDeuxiemeElement(bpmSecondes2)), normaliserPremierElement(bpmSecondes),
normaliserPremierElement(normaliserDeuxiemeElement(vitesseSecondes)), normaliserPremierElement(altitudeSeconde)); normaliserPremierElement(normaliserDeuxiemeElement(bpmSecondes2)),
normaliserPremierElement(normaliserDeuxiemeElement(vitesseSecondes)),
normaliserPremierElement(altitudeSeconde));
} }
List<FlSpot> normaliserDeuxiemeElement(List<FlSpot> liste) { List<FlSpot> normaliserDeuxiemeElement(List<FlSpot> liste) {
@ -41,21 +43,21 @@ class HomeViewUtil {
} }
return liste; return liste;
} }
List<FlSpot> normaliserPremierElement(List<FlSpot> liste) { List<FlSpot> normaliserPremierElement(List<FlSpot> liste) {
// Trouver le plus grand élément dans le premier élément de chaque FlSpot // Trouver le plus grand élément dans le premier élément de chaque FlSpot
double maxElement = 0.0; double maxElement = 0.0;
for (var spot in liste) { for (var spot in liste) {
if (spot.x > maxElement) { if (spot.x > maxElement) {
maxElement = spot.x; maxElement = spot.x;
}
} }
// Calculer le facteur de normalisation
double normalisationFactor = maxElement != 0.0 ? 100 / maxElement : 1.0;
// Mettre à jour tous les premiers éléments de la liste
for (int i = 0; i < liste.length; i++) {
liste[i] = FlSpot(liste[i].x * normalisationFactor, liste[i].y);
}
return liste;
} }
// Calculer le facteur de normalisation
double normalisationFactor = maxElement != 0.0 ? 100 / maxElement : 1.0;
// Mettre à jour tous les premiers éléments de la liste
for (int i = 0; i < liste.length; i++) {
liste[i] = FlSpot(liste[i].x * normalisationFactor, liste[i].y);
}
return liste;
}
} }

@ -5,7 +5,6 @@ import 'package:smartfit_app_mobile/modele/activity_saver.dart';
import 'package:smartfit_app_mobile/modele/helper.dart'; import 'package:smartfit_app_mobile/modele/helper.dart';
import 'dart:convert'; import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'dart:typed_data';
import 'package:csv/csv.dart'; import 'package:csv/csv.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -91,6 +90,9 @@ class ListActivityUtile {
String csvString = const ListToCsvConverter().convert(resultData.item2); String csvString = const ListToCsvConverter().convert(resultData.item2);
Uint8List byteCSV = Uint8List.fromList(utf8.encode(csvString)); Uint8List byteCSV = Uint8List.fromList(utf8.encode(csvString));
File x = await File("${await _managerFile.localPath}\\what")
.writeAsString(csvString);
Tuple2<bool, String> result = await api.uploadFileByte( Tuple2<bool, String> result = await api.uploadFileByte(
token, token,
byteCSV, byteCSV,

@ -29,6 +29,7 @@ class _MobileHomeView extends State<MobileHomeView> {
context.watch<User>().managerSelectedActivity; context.watch<User>().managerSelectedActivity;
data = HomeViewUtil().initData(context); data = HomeViewUtil().initData(context);
// -- BPM -- // // -- BPM -- //
data.maxBPM = data.maxBPM =
managerSelectedActivity.activitySelected.first.activityInfo.bpmMax; managerSelectedActivity.activitySelected.first.activityInfo.bpmMax;
@ -36,7 +37,6 @@ class _MobileHomeView extends State<MobileHomeView> {
managerSelectedActivity.activitySelected.first.activityInfo.bpmMin; managerSelectedActivity.activitySelected.first.activityInfo.bpmMin;
int avgBpm = int avgBpm =
managerSelectedActivity.activitySelected.first.activityInfo.bpmAvg; managerSelectedActivity.activitySelected.first.activityInfo.bpmAvg;
// -- Altitude -- // // -- Altitude -- //
double minAltitude = double minAltitude =
managerSelectedActivity.activitySelected.first.activityInfo.altitudeMin; managerSelectedActivity.activitySelected.first.activityInfo.altitudeMin;
@ -48,12 +48,12 @@ class _MobileHomeView extends State<MobileHomeView> {
double maxSpeed = managerSelectedActivity.getMaxSpeedAllActivitySelected(); double maxSpeed = managerSelectedActivity.getMaxSpeedAllActivitySelected();
double avgSpeed = managerSelectedActivity.getAvgSpeedAllActivitySelected(); double avgSpeed = managerSelectedActivity.getAvgSpeedAllActivitySelected();
double minSpeed = managerSelectedActivity.getMinSpeedAllActivitySelected(); double minSpeed = managerSelectedActivity.getMinSpeedAllActivitySelected();
data.maxSpeed = maxSpeed; data.maxSpeed = maxSpeed;
data.time = context data.time = context
.watch<User>() .watch<User>()
.managerSelectedActivity .managerSelectedActivity
.getTimeAllActivitySelected(); .getTimeAllActivitySelected();
return Scaffold( return Scaffold(
backgroundColor: TColor.white, backgroundColor: TColor.white,
body: SingleChildScrollView( body: SingleChildScrollView(

@ -5,6 +5,7 @@ import 'package:smartfit_app_mobile/common/colo_extension.dart';
import 'package:smartfit_app_mobile/common_widget/button/round_button.dart'; import 'package:smartfit_app_mobile/common_widget/button/round_button.dart';
import 'package:smartfit_app_mobile/common_widget/container/workout_row/workout_row.dart'; import 'package:smartfit_app_mobile/common_widget/container/workout_row/workout_row.dart';
import 'package:smartfit_app_mobile/modele/activity_info/activity_info.dart'; import 'package:smartfit_app_mobile/modele/activity_info/activity_info.dart';
import 'package:smartfit_app_mobile/modele/convertisseur.dart';
import 'package:smartfit_app_mobile/modele/manager_file.dart'; import 'package:smartfit_app_mobile/modele/manager_file.dart';
import 'package:smartfit_app_mobile/modele/user.dart'; import 'package:smartfit_app_mobile/modele/user.dart';
import 'package:smartfit_app_mobile/modele/utile/info_message.dart'; import 'package:smartfit_app_mobile/modele/utile/info_message.dart';
@ -45,14 +46,15 @@ class _PredictionState extends State<Prediction> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
var media = MediaQuery.of(context).size;
List<String> listCategory = [_managerFile.marche, _managerFile.velo]; List<String> listCategory = [_managerFile.marche, _managerFile.velo];
void prediction() async { void prediction() async {
InfoMessage tmp = InfoMessage(); InfoMessage tmp = InfoMessage();
setState(() {
lastWorkoutArr[0]["value"] = "null"; /*
}); if (selectedCategory != _managerFile.marche ||
selectedCategory != _managerFile.velo) return;*/
Tuple2<bool, ActivityInfo> resultat = Tuple2<bool, ActivityInfo> resultat =
await Provider.of<User>(context, listen: false) await Provider.of<User>(context, listen: false)
.predictActivity(DateTime.now(), selectedCategory, tmp); .predictActivity(DateTime.now(), selectedCategory, tmp);
@ -154,7 +156,6 @@ class _PredictionState extends State<Prediction> {
title: "Valider", title: "Valider",
onPressed: () async { onPressed: () async {
prediction(); prediction();
setState(() {});
}), }),
const SizedBox(height: 20), const SizedBox(height: 20),
ListView.builder( ListView.builder(
@ -163,7 +164,7 @@ class _PredictionState extends State<Prediction> {
shrinkWrap: true, shrinkWrap: true,
itemCount: lastWorkoutArr.length, itemCount: lastWorkoutArr.length,
itemBuilder: (context, index) { itemBuilder: (context, index) {
var wObj = lastWorkoutArr[index] as Map<String, dynamic> ?? {}; var wObj = lastWorkoutArr[index];
return InkWell( return InkWell(
child: WorkoutRow(wObj: wObj), child: WorkoutRow(wObj: wObj),
); );

@ -7,7 +7,11 @@ import 'package:smartfit_app_mobile/common_widget/container/profile/profile_comp
import 'package:smartfit_app_mobile/common_widget/container/profile/profile_entete.dart'; import 'package:smartfit_app_mobile/common_widget/container/profile/profile_entete.dart';
import 'package:smartfit_app_mobile/common_widget/container/profile/profile_info_user.dart'; import 'package:smartfit_app_mobile/common_widget/container/profile/profile_info_user.dart';
import 'package:smartfit_app_mobile/common_widget/container/profile/profile_other.dart'; import 'package:smartfit_app_mobile/common_widget/container/profile/profile_other.dart';
import 'package:smartfit_app_mobile/modele/api/api_wrapper.dart';
import 'package:smartfit_app_mobile/modele/user.dart'; import 'package:smartfit_app_mobile/modele/user.dart';
import 'package:smartfit_app_mobile/modele/utile/info_message.dart';
import 'package:smartfit_app_mobile/view/login/signup_view.dart';
import 'package:tuple/tuple.dart';
class ProfileViewAllPlatforme extends StatefulWidget { class ProfileViewAllPlatforme extends StatefulWidget {
final bool offlineSave; final bool offlineSave;
@ -26,7 +30,32 @@ class _ProfileViewAllPlatforme extends State<ProfileViewAllPlatforme> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
ApiWrapper wrapper = ApiWrapper();
String username = context.watch<User>().username; String username = context.watch<User>().username;
InfoMessage infoManager = InfoMessage();
void logOff() {
// Appel ici pour logOff
/*
if (!result.item1) {
// Affiché erreur
} else {
Navigator.push(context,
MaterialPageRoute(builder: (context) => const LoginView()));
}*/
}
void deleteUser() async {
// Ne marche pas !!
Tuple2 result = await wrapper.deleteUser(
Provider.of<User>(context, listen: false).token, infoManager);
if (!result.item1) {
// Affiché erreur
} else {
Navigator.push(context,
MaterialPageRoute(builder: (context) => const SignUpView()));
}
}
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
@ -59,8 +88,6 @@ class _ProfileViewAllPlatforme extends State<ProfileViewAllPlatforme> {
const SizedBox( const SizedBox(
height: 25, height: 25,
), ),
// TODO: Download/Delete (local) all users files on toggle ?
// TODO: Display size of download in Mo
Visibility( Visibility(
visible: isNative, visible: isNative,
child: const Column( child: const Column(
@ -72,7 +99,39 @@ class _ProfileViewAllPlatforme extends State<ProfileViewAllPlatforme> {
) )
], ],
)), )),
ProfileOther(widget.otherArr) ProfileOther(widget.otherArr),
const SizedBox(
height: 25,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextButton(
style: TextButton.styleFrom(
backgroundColor: TColor.primaryColor1,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8))),
onPressed: logOff,
child: const Text('Déconnexion',
style: TextStyle(color: Colors.black)),
),
const SizedBox(
width: 25,
),
TextButton(
style: TextButton.styleFrom(
backgroundColor: TColor.primaryColor1,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8))),
onPressed: deleteUser,
child: const Text('Supprimer son compte',
style: TextStyle(color: Colors.black)),
),
],
),
const SizedBox(
height: 25,
)
], ],
), ),
), ),

@ -5,17 +5,25 @@
// gestures. You can also use WidgetTester to find child widgets in the widget // gestures. You can also use WidgetTester to find child widgets in the widget
// tree, read text, and verify that the values of widget properties are correct. // tree, read text, and verify that the values of widget properties are correct.
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:smartfit_app_mobile/main.dart'; import 'package:smartfit_app_mobile/main.dart';
import 'package:smartfit_app_mobile/modele/activity.dart';
import 'package:smartfit_app_mobile/modele/activity_info/activity_info.dart';
import 'package:smartfit_app_mobile/modele/api/api_wrapper.dart';
import 'package:smartfit_app_mobile/modele/api/request_api.dart';
import 'package:smartfit_app_mobile/modele/user.dart';
import 'package:smartfit_app_mobile/modele/utile/signup_user.dart';
import 'package:tuple/tuple.dart';
void main() { void main() {
testWidgets('Counter increments smoke test', (WidgetTester tester) async { testWidgets('Test login', (WidgetTester tester) async {
// Build our app and trigger a frame. // Build our app and trigger a frame.
await tester.pumpWidget(const MyApp()); //await tester.pumpWidget(const MyApp());
// Verify that our counter starts at 0. //expect(find.text('Se connecter'), findsOneWidget);
/*
expect(find.text('0'), findsOneWidget); expect(find.text('0'), findsOneWidget);
expect(find.text('1'), findsNothing); expect(find.text('1'), findsNothing);
@ -25,6 +33,40 @@ void main() {
// Verify that our counter has incremented. // Verify that our counter has incremented.
expect(find.text('0'), findsNothing); expect(find.text('0'), findsNothing);
expect(find.text('1'), findsOneWidget); expect(find.text('1'), findsOneWidget);*/
});
// Ce n'est pas possible de faire des test http =>
//To test code that needs an HttpClient, provide your own HttpClient
//implementation to the code under test, so that your test can
//consistently provide a testable response to the code under test.
/*
test("Unit Test -- Create and delete User", () async {
final SignUp utilSignUp = SignUp();
final RequestApi requestApi = RequestApi();
Tuple2 result =
await utilSignUp.createUser("test@gmail.com", "test", "test");
expect(result.item1, true);
Tuple2 delete = await requestApi.deleteUser(result.item2);
expect(delete.item1, true);
});*/
test("User", () {
User user = User();
ActivityOfUser activityOfUser =
ActivityOfUser(ActivityInfo(), "CATEGORIE", "0000", "NAMEFILE");
expect(user.listActivity.length, 0);
user.addActivity(activityOfUser);
expect(user.listActivity.length, 1);
user.removeActivity(activityOfUser);
expect(user.listActivity.length, 0);
}); });
} }

Loading…
Cancel
Save