diff --git a/lib/common_widget/container/workout_row.dart b/lib/common_widget/container/workout_row.dart index ea2824b..d4d499a 100644 --- a/lib/common_widget/container/workout_row.dart +++ b/lib/common_widget/container/workout_row.dart @@ -81,7 +81,7 @@ class WorkoutRow extends StatelessWidget { ), ), Text( - "Dénivelé positif : ${wObj["denivelePositif"].toString()}", + "Dénivelé positif : ${wObj["DenivelePositif"].toString()}", style: TextStyle( color: TColor.black, fontSize: 12, diff --git a/lib/common_widget/graph/web/web_bpm_by_time.dart b/lib/common_widget/graph/web/web_bpm_by_time.dart index c9d202b..b529862 100644 --- a/lib/common_widget/graph/web/web_bpm_by_time.dart +++ b/lib/common_widget/graph/web/web_bpm_by_time.dart @@ -18,10 +18,22 @@ class WebBpmByTime extends StatefulWidget { class _WebBpmByTime extends State { @override Widget build(BuildContext context) { - final double maxY = - context.watch().managerSelectedActivity.getMaxBpm() + 2; - final double minY = - context.watch().managerSelectedActivity.getMinBpm() - 2; + final double maxY = context + .watch() + .managerSelectedActivity + .activitySelected + .first + .activityInfo + .bpmMax + + 2; + final double minY = context + .watch() + .managerSelectedActivity + .activitySelected + .first + .activityInfo + .bpmMin - + 2; final double maxX = widget.data.bpmSecondes[widget.data.bpmSecondes.length - 1].x; const double minX = 0.0; diff --git a/lib/common_widget/stats.dart b/lib/common_widget/stats.dart index 0d1e922..9d15654 100644 --- a/lib/common_widget/stats.dart +++ b/lib/common_widget/stats.dart @@ -1,4 +1,3 @@ - import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:smartfit_app_mobile/modele/user.dart'; @@ -15,7 +14,10 @@ class Stats extends StatelessWidget { .toString(); String heartrate = Provider.of(context, listen: false) .managerSelectedActivity - .getAvgBpm() + .activitySelected + .first + .activityInfo + .bpmAvg .toString(); String time = Provider.of(context, listen: false) .managerSelectedActivity diff --git a/lib/modele/activity.dart b/lib/modele/activity.dart index afdb3c3..131e018 100644 --- a/lib/modele/activity.dart +++ b/lib/modele/activity.dart @@ -1,12 +1,11 @@ +import 'package:smartfit_app_mobile/modele/activity_info/activity_info.dart'; + class ActivityOfUser { + final ActivityInfo _activityInfo; // A afficher final String _categorie; - final String _date; final String _fileUuid; final String _nameFile; - final double _timeActivity; - final double _denivelePositif; - final double _deniveleNegatif; // ------------ // late String _imageName; @@ -16,9 +15,7 @@ class ActivityOfUser { String get fileUuid => _fileUuid; String get nameFile => _nameFile; String get category => _categorie; - double get time => _timeActivity; - double get denivelePos => _denivelePositif; - double get deniveleNeg => _deniveleNegatif; + ActivityInfo get activityInfo => _activityInfo; Map get enteteCSV => _enteteCSV; // -- Getter/Setter -- Ancien // @@ -31,8 +28,8 @@ class ActivityOfUser { _contentActivity.removeAt(0); } - ActivityOfUser(this._categorie, this._date, this._fileUuid, this._nameFile, - this._timeActivity, this._denivelePositif, this._deniveleNegatif) { + ActivityOfUser( + this._activityInfo, this._categorie, this._fileUuid, this._nameFile) { // Mettre dans une fonction appart if (_categorie == "Walking") { _imageName = "assets/img/workout1.svg"; @@ -45,13 +42,14 @@ class ActivityOfUser { // -------------------------- FIN Localisation ---------------------- // Map toMap() { - return { + Map map = { 'categorie': _categorie, 'image': _imageName, - 'date': _date, - 'time': _timeActivity, - "denivelePositif": _denivelePositif, - "deniveleNegatif": _deniveleNegatif, + 'date': _activityInfo.startTime, + 'time': _activityInfo.timeOfActivity, }; + map.addAll(_activityInfo.toMap()); + + return map; } } diff --git a/lib/modele/activity_info/activity_info.dart b/lib/modele/activity_info/activity_info.dart index c487c87..3f759da 100644 --- a/lib/modele/activity_info/activity_info.dart +++ b/lib/modele/activity_info/activity_info.dart @@ -1,5 +1,9 @@ +import 'package:smartfit_app_mobile/modele/manager_file.dart'; + abstract class ActivityInfo { - // -- Time -- // + ManagerFile managerFile = ManagerFile(); + + // -- Time -- // Ne pas calculer (Ligne session) String startTime = "2000-01-01"; double timeOfActivity = 0.0; @@ -9,7 +13,54 @@ abstract class ActivityInfo { int bpmAvg = 0; // -- Fonction pour lire le csv et remplir la classe -- // - ActivityInfo getData(List> csv); + ActivityInfo getData(List> csv) { + // -- BPM -- // + int bpmSomme = 0; + int bpmNb = 0; + Map enteteCSV = getEntete(csv.first); + for (int i = 1; i < csv.length; i++) { + // -- BPM -- // + if (!isNull(enteteCSV["Value_${managerFile.fielBPM}"]!, csv[i])) { + int value = + int.parse(csv[i][enteteCSV["Value_${managerFile.fielBPM}"]!]); + bpmSomme += value; + bpmNb += 1; + if (value > bpmMax) { + bpmMax = value; + } + if (value < bpmMin) { + bpmMin = value; + } + } + } + + // -- BPM -- // + bpmAvg = bpmSomme ~/ bpmNb; + return this; + } + + Map getEntete(List content) { + Map enteteCSV = {}; + for (int i = 0; i < content.length; i++) { + enteteCSV.addAll({content[i]: i}); + } + return enteteCSV; + } + + bool isNull(int colonne, List ligne) { + return ligne[colonne] == "null"; + } String toJson(); + Map toMap(); + ActivityInfo.fromJson(Map? map) { + if (map == null) { + return; + } + startTime = map["startTime"]; + timeOfActivity = map["timeOfActivity"].toDouble(); + bpmAvg = map["bpmAvg"]; + bpmMax = map["bpmMax"]; + bpmMin = map["bpmMin"]; + } } diff --git a/lib/modele/activity_info/activity_info_generic.dart b/lib/modele/activity_info/activity_info_generic.dart index 54485bd..3b42b53 100644 --- a/lib/modele/activity_info/activity_info_generic.dart +++ b/lib/modele/activity_info/activity_info_generic.dart @@ -2,27 +2,16 @@ import 'dart:convert'; import 'package:smartfit_app_mobile/modele/activity_info/activity_info.dart'; -class ActivityInfoGeneric implements ActivityInfo { +class ActivityInfoGeneric extends ActivityInfo { + ActivityInfoGeneric.fromJson(super.map) : super.fromJson(); + ActivityInfoGeneric() : super.fromJson(null); + // ------- Ajout --------- // // ------- Activity Info -------- // - @override - late int bpmAvg; - - @override - late int bpmMax; - - @override - late int bpmMin; - - @override - late String startTime; - - @override - late double timeOfActivity; - @override ActivityInfo getData(List> csv) { + super.getData(csv); return this; } @@ -38,4 +27,9 @@ class ActivityInfoGeneric implements ActivityInfo { }; return jsonEncode(jsonMap); } + + @override + Map toMap() { + return {}; + } } diff --git a/lib/modele/activity_info/activity_info_walking.dart b/lib/modele/activity_info/activity_info_walking.dart index 65395ed..104ac30 100644 --- a/lib/modele/activity_info/activity_info_walking.dart +++ b/lib/modele/activity_info/activity_info_walking.dart @@ -2,32 +2,41 @@ import 'dart:convert'; import 'package:smartfit_app_mobile/modele/activity_info/activity_info.dart'; -class ActivityInfoWalking implements ActivityInfo { +class ActivityInfoWalking extends ActivityInfo { + ActivityInfoWalking.fromJson(map) : super.fromJson(map) { + deniveleNegatif = map["deniveleNegatif"].toDouble(); + denivelePositif = map["denivelePositif"].toDouble(); + } + ActivityInfoWalking() : super.fromJson(null); + // ------- Ajout --------- // // -- Denivelé -- // double denivelePositif = 0.0; double deniveleNegatif = 0.0; - // ------- Activity Info -------- // - @override - int bpmAvg = 0; - - @override - int bpmMax = 0; - - @override - int bpmMin = 0; - @override - String startTime = "2000-01-01"; + ActivityInfo getData(List> csv) { + super.getData(csv); - @override - double timeOfActivity = 0.0; + Map enteteCSV = getEntete(csv.first); + // -- Denivelé -- // + double lastDenivele = 0.0; - @override - ActivityInfo getData(List> csv) { - for (int i = 0; i < csv.length; i++) {} + // -- Lecture du corps -- // + for (int i = 1; i < csv.length; i++) { + // -- Denivele -- // + if (!isNull(enteteCSV["Value_${managerFile.fieldAltitude}"]!, csv[i])) { + double value = double.parse( + csv[i][enteteCSV["Value_${managerFile.fieldAltitude}"]!]); + if (value > lastDenivele) { + denivelePositif += value - lastDenivele; + } else { + deniveleNegatif += (value - lastDenivele) * -1; + } + lastDenivele = value; + } + } return this; } @@ -35,14 +44,25 @@ class ActivityInfoWalking implements ActivityInfo { // Méthode pour convertir les attributs en JSON String toJson() { Map jsonMap = { + // Unique 'denivelePositif': denivelePositif, 'deniveleNegatif': deniveleNegatif, + // All 'bpmAvg': bpmAvg, 'bpmMax': bpmMax, 'bpmMin': bpmMin, + // Ligne session 'startTime': startTime, 'timeOfActivity': timeOfActivity, }; return jsonEncode(jsonMap); } + + @override + Map toMap() { + return { + "DenivelePositif": denivelePositif, + "DeniveleNegatif": denivelePositif + }; + } } diff --git a/lib/modele/api/i_data_strategy.dart b/lib/modele/api/i_data_strategy.dart index 8e620a6..299e8eb 100644 --- a/lib/modele/api/i_data_strategy.dart +++ b/lib/modele/api/i_data_strategy.dart @@ -1,6 +1,7 @@ import 'dart:io'; import 'dart:typed_data'; +import 'package:smartfit_app_mobile/modele/activity_info/activity_info.dart'; import 'package:tuple/tuple.dart'; abstract class IDataStrategy { @@ -19,8 +20,13 @@ abstract class IDataStrategy { // Upload file on BDD Future> uploadFile(String token, File file); - Future> uploadFileByte(String token, - Uint8List contentFile, String nameFile, String category, String date); + Future> uploadFileByte( + String token, + Uint8List contentFile, + String nameFile, + String category, + String date, + ActivityInfo activityInfo); // Get one file by id Future getFile(String token, String fileUuid); diff --git a/lib/modele/api/request_api.dart b/lib/modele/api/request_api.dart index 7d54ff8..9a3330c 100644 --- a/lib/modele/api/request_api.dart +++ b/lib/modele/api/request_api.dart @@ -2,11 +2,12 @@ import 'dart:convert'; import 'dart:io'; import 'dart:typed_data'; +import 'package:smartfit_app_mobile/modele/activity_info/activity_info.dart'; import 'package:smartfit_app_mobile/modele/api/i_data_strategy.dart'; import 'package:http/http.dart' as http; import 'package:tuple/tuple.dart'; -class RequestApi extends IDataStrategy { +class RequestApi implements IDataStrategy { // Faire attention au URL String urlApi = "https://codefirst.iut.uca.fr/containers/SmartFit-smartfit_api"; @@ -32,8 +33,6 @@ class RequestApi extends IDataStrategy { if ((response.statusCode == 404)) { return const Tuple2(false, "404 - NOT FOUND"); } - print(response.statusCode); - print(response.body); return const Tuple2(false, "Fail"); } @@ -193,7 +192,8 @@ class RequestApi extends IDataStrategy { Uint8List contentFile, String nameFile, String category, - String date) async { + String date, + ActivityInfo activityInfo) async { final uri = Uri.parse('$urlApi/user/files'); Map headers = {'Authorization': token}; @@ -207,6 +207,7 @@ class RequestApi extends IDataStrategy { request.headers.addAll(headers); request.fields["SmartFit_Category"] = category; request.fields["SmartFit_Date"] = date; + request.fields["info"] = activityInfo.toJson(); final response = await request.send(); diff --git a/lib/modele/manager_file.dart b/lib/modele/manager_file.dart index 8dc171f..1361c3c 100644 --- a/lib/modele/manager_file.dart +++ b/lib/modele/manager_file.dart @@ -1,4 +1,5 @@ import 'dart:convert'; +import 'dart:io'; import 'dart:typed_data'; import 'package:csv/csv.dart'; import 'package:fit_tool/fit_tool.dart'; @@ -25,7 +26,7 @@ class ManagerFile { static const String _session = "session"; static const String _startTime = "start_time"; static const String _sport = "sport"; - static const String _timeActivity = "total_elapsed_time"; + //static const String _timeActivity = "total_elapsed_time"; // -- Getter field String get fieldTimeStamp => _fieldTimestamp; diff --git a/lib/modele/manager_selected_activity.dart b/lib/modele/manager_selected_activity.dart index 55e564d..b8fdec0 100644 --- a/lib/modele/manager_selected_activity.dart +++ b/lib/modele/manager_selected_activity.dart @@ -80,7 +80,7 @@ class ManagerSelectedActivity { } // ----------------- BPM ------------------ // - + /* // Retourne le BPM Max (Fichier CSV) int getMaxBpm() { int max = 0; @@ -98,8 +98,8 @@ class ManagerSelectedActivity { } return max; - } - + }*/ + /* // Retourne le BPM Min (Fichier CSV) int getMinBpm() { int min = 300; @@ -134,7 +134,7 @@ class ManagerSelectedActivity { } } return somme ~/ nb; - } + }*/ double getAvgAltitude() { double somme = 0; diff --git a/lib/modele/user.dart b/lib/modele/user.dart index 688015f..1a891a8 100644 --- a/lib/modele/user.dart +++ b/lib/modele/user.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; import 'package:smartfit_app_mobile/modele/activity.dart'; +import 'package:smartfit_app_mobile/modele/activity_info/activity_info_walking.dart'; import 'package:smartfit_app_mobile/modele/manager_selected_activity.dart'; class User extends ChangeNotifier { @@ -31,7 +31,7 @@ class User extends ChangeNotifier { double getTotalTimeAllActivity() { double totalTime = 0.0; for (ActivityOfUser activity in listActivity) { - totalTime += activity.time; + totalTime += activity.activityInfo.timeOfActivity; } return totalTime; } @@ -39,7 +39,12 @@ class User extends ChangeNotifier { double getTotalDenivelePositif() { double totalDevPos = 0.0; for (ActivityOfUser activity in listActivity) { - totalDevPos += activity.denivelePos; + try { + totalDevPos += + (activity.activityInfo as ActivityInfoWalking).denivelePositif; + } catch (e) { + //print(e); + } } return totalDevPos; } @@ -47,7 +52,12 @@ class User extends ChangeNotifier { double getTotalDeniveleNegatif() { double totalDevNeg = 0.0; for (ActivityOfUser activity in listActivity) { - totalDevNeg += activity.denivelePos; + try { + totalDevNeg += + (activity.activityInfo as ActivityInfoWalking).deniveleNegatif; + } catch (e) { + //print(e); + } } return totalDevNeg; } diff --git a/lib/modele/utile/list_activity/list_activity_utile.dart b/lib/modele/utile/list_activity/list_activity_utile.dart index ce7a38d..b5b7d0c 100644 --- a/lib/modele/utile/list_activity/list_activity_utile.dart +++ b/lib/modele/utile/list_activity/list_activity_utile.dart @@ -6,6 +6,7 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.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/activity_info/activity_info_walking.dart'; import 'package:smartfit_app_mobile/modele/api/i_data_strategy.dart'; import 'package:smartfit_app_mobile/modele/api/request_api.dart'; import 'package:smartfit_app_mobile/modele/manager_file.dart'; @@ -50,18 +51,13 @@ class ListActivityUtile { Provider.of(context, listen: false).listActivity.clear(); notZero = true; } + // -- connaitre le type de categorie pour changer le type d'info -- // + Provider.of(context, listen: false).addActivity(ActivityOfUser( + ActivityInfoWalking.fromJson(element["info"]), element["category"].toString(), - element["creation_date"].toString(), element["uuid"].toString(), - element["filename"].toString(), - /* - element["timeActivity"], - element["denivelePositif"], - element["deniveleNegatif"]*/ - 0.0, - 0.0, - 0.0)); + element["filename"].toString())); } /* if (notZero) { @@ -80,11 +76,16 @@ class ListActivityUtile { Uint8List byteCSV = Uint8List.fromList(utf8.encode(csvString)); // --- Save Local // --- Api - print("Start"); - print(resultData.item3.toJson()); + //ManagerFile x = ManagerFile(); + //await File("${await x.localPath}\\test.csv").writeAsString(csvString); Tuple2 result = await _strategy.uploadFileByte( - token, byteCSV, filename, resultData.item4, resultData.item3.startTime); + token, + byteCSV, + filename, + resultData.item4, + resultData.item3.startTime, + resultData.item3); if (result.item1 == false) { return Tuple2(false, result.item2); } diff --git a/lib/view/home/mobile/mobile_homeview.dart b/lib/view/home/mobile/mobile_homeview.dart index 3c7439c..8e74649 100644 --- a/lib/view/home/mobile/mobile_homeview.dart +++ b/lib/view/home/mobile/mobile_homeview.dart @@ -30,9 +30,12 @@ class _MobileHomeView extends State { data = HomeViewUtil().initData(context); // -- BPM -- // - data.maxBPM = managerSelectedActivity.getMaxBpm(); - data.minBPM = managerSelectedActivity.getMinBpm(); - int avgBpm = managerSelectedActivity.getAvgBpm(); + data.maxBPM = + managerSelectedActivity.activitySelected.first.activityInfo.bpmMax; + data.minBPM = + managerSelectedActivity.activitySelected.first.activityInfo.bpmMin; + int avgBpm = + managerSelectedActivity.activitySelected.first.activityInfo.bpmAvg; // -- Altitude -- // double minAltitude = managerSelectedActivity.getMinAltitude(); diff --git a/lib/view/home/stats_activities_view.dart b/lib/view/home/stats_activities_view.dart index d52934a..ab49b87 100644 --- a/lib/view/home/stats_activities_view.dart +++ b/lib/view/home/stats_activities_view.dart @@ -22,8 +22,27 @@ class _StatAtivities extends State { Widget build(BuildContext context) { var media = MediaQuery.of(context).size; data = HomeViewUtil().initData(context); - int maxBpm = context.watch().managerSelectedActivity.getMaxBpm(); - int avgBpm = context.watch().managerSelectedActivity.getAvgBpm(); + int maxBpm = context + .watch() + .managerSelectedActivity + .activitySelected + .first + .activityInfo + .bpmMax; + int minBpm = context + .watch() + .managerSelectedActivity + .activitySelected + .first + .activityInfo + .bpmMin; + int avgBpm = context + .watch() + .managerSelectedActivity + .activitySelected + .first + .activityInfo + .bpmAvg; double getTotalDistance = context.watch().managerSelectedActivity.getTotalDistance(); int totalSteps = @@ -54,8 +73,6 @@ class _StatAtivities extends State { double minTemperature = context.watch().managerSelectedActivity.getMinTemperature(); - int minBpm = context.watch().managerSelectedActivity.getMinBpm(); - return Scaffold( backgroundColor: TColor.white, body: SingleChildScrollView( diff --git a/lib/view/home/web/web_homeview.dart b/lib/view/home/web/web_homeview.dart index 74ccf41..44d337a 100644 --- a/lib/view/home/web/web_homeview.dart +++ b/lib/view/home/web/web_homeview.dart @@ -25,9 +25,27 @@ class _WebHomeView extends State { Widget build(BuildContext context) { var media = MediaQuery.of(context).size; // -- BPM -- // - int maxBpm = context.watch().managerSelectedActivity.getMaxBpm(); - int minBpm = context.watch().managerSelectedActivity.getMinBpm(); - int avgBpm = context.watch().managerSelectedActivity.getAvgBpm(); + int maxBpm = context + .watch() + .managerSelectedActivity + .activitySelected + .first + .activityInfo + .bpmMax; + int minBpm = context + .watch() + .managerSelectedActivity + .activitySelected + .first + .activityInfo + .bpmMin; + int avgBpm = context + .watch() + .managerSelectedActivity + .activitySelected + .first + .activityInfo + .bpmAvg; // -- Altitude -- // double minAltitude = context.watch().managerSelectedActivity.getMinAltitude();