Merge branch 'Enzo'
continuous-integration/drone/push Build is failing Details

profile
Enzo 1 year ago
commit 1e575807db

@ -60,7 +60,14 @@ class WorkoutRow extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
wObj["nomActivite"].toString(),
wObj["categorie"].toString(),
style: TextStyle(
color: TColor.black,
fontSize: 12,
),
),
Text(
wObj["date"].toString(),
style: TextStyle(
color: TColor.black,
fontSize: 12,

@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:smartfit_app_mobile/modele/user.dart';
import 'package:smartfit_app_mobile/common/colo_extension.dart';
import 'package:smartfit_app_mobile/view/main_tab/main_tab_view.dart';
import 'package:smartfit_app_mobile/view/login/signup_view.dart';
void main() {
runApp(ChangeNotifierProvider(
@ -36,7 +36,7 @@ class MyApp extends StatelessWidget {
primaryColor: TColor.primaryColor1,
fontFamily: "Poppins"),
//home: const StartedView(),
home: const MainTabView(),
home: const SignUpView(),
);
}
}

@ -3,20 +3,42 @@ import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:smartfit_app_mobile/common_widget/graph/graph.dart';
class ActivityOfUser {
late String _nomActivite;
// A afficher
late String _categorie;
late String _date;
late String _fileUuid;
late String _nameFile;
// ------------ //
late String _imageName;
late List<dynamic> _contentActivity;
late int _dataSession;
// -- Getter/Setter -- //
List<dynamic> get contentActivity => _contentActivity;
ActivityOfUser(String nom, List<dynamic> listeDynamic) {
_nomActivite = nom;
_imageName = "assets/img/workout1.svg";
_contentActivity = listeDynamic;
set contentActivity(List<dynamic> content) {
_contentActivity = content;
_dataSession = getDataSession();
}
String get fileUuid => _fileUuid;
String get nameFile => _nameFile;
ActivityOfUser(
String date, String categorie, String fileUuid, String nameFile) {
_categorie = categorie;
_date = date;
_fileUuid = fileUuid;
_nameFile = nameFile;
// Mettre dans une fonction appart
if (categorie == "Walking") {
_imageName = "assets/img/workout1.svg";
} else {
// Mettre des conditions pour d'autre type d'activité
_imageName = "assets/img/workout1.svg";
}
}
// ----- Retourne l'indice de la ligne qui contient les données de la session -- //
int getDataSession() {
for (int i = _contentActivity.length - 1; i != 0; i--) {
@ -287,9 +309,6 @@ class ActivityOfUser {
// -------------------------- FIN Localisation ---------------------- //
Map<String, dynamic> toMap() {
return {
'nomActivite': _nomActivite,
'image': _imageName,
};
return {'categorie': _categorie, 'image': _imageName, 'date': _date};
}
}

@ -1,4 +1,5 @@
import 'dart:io';
import 'dart:typed_data';
import 'package:tuple/tuple.dart';
@ -18,6 +19,8 @@ abstract class IDataStrategy {
// Upload file on BDD
Future<Tuple2<bool, String>> uploadFile(String token, File file);
Future<Tuple2<bool, String>> uploadFileByte(String token,
Uint8List contentFile, String nameFile, String category, String date);
// Get one file by id
Future<Tuple2> getFile(String token, String fileUuid);

@ -1,5 +1,6 @@
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
import 'package:smartfit_app_mobile/modele/api/i_data_strategy.dart';
import 'package:http/http.dart' as http;
@ -73,7 +74,8 @@ class RequestApi extends IDataStrategy {
headers: <String, String>{'Authorization': token});
if (response.statusCode == 200) {
return Tuple2(true, response.body);
return Tuple2(true,
(json.decode(response.body) as List).cast<Map<String, dynamic>>());
}
if (response.statusCode == 401) {
return const Tuple2(false, "401 - UNAUTHORIZED");
@ -120,37 +122,6 @@ class RequestApi extends IDataStrategy {
return const Tuple2(false, "Fail");
}
/*
@override
Future<bool> updateEmail(String token, String email) async {
final response = await http.put(Uri.parse('$urlApi/$token/email'),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
body: jsonEncode(<String, String>{'email': email}));
if (response.statusCode == 200) {
return true;
} else {
return false;
}
}
@override
Future<bool> updateUsername(String token, String username) async {
final response = await http.put(Uri.parse('$urlApi/$token/username'),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
body: jsonEncode(<String, String>{'username': username}));
if (response.statusCode == 200) {
return true;
} else {
return false;
}
}*/
@override
Future<Tuple2> modifAttribut(
String token, String nameAttribut, String newValue) async {
@ -212,6 +183,44 @@ class RequestApi extends IDataStrategy {
return const Tuple2(false, "Fail ");
}
@override
Future<Tuple2<bool, String>> uploadFileByte(
String token,
Uint8List contentFile,
String nameFile,
String category,
String date) async {
final uri = Uri.parse('$urlApi/user/files');
Map<String, String> headers = {'Authorization': token};
var request = http.MultipartRequest('POST', uri);
final httpImage = http.MultipartFile.fromBytes(
'file',
contentFile,
filename: nameFile,
);
request.files.add(httpImage);
request.headers.addAll(headers);
request.fields["SmartFit_Category"] = category;
request.fields["SmartFit_Date"] = date;
final response = await request.send();
if (response.statusCode == 200) {
return const Tuple2(true, "Successful");
}
if (response.statusCode == 400) {
return const Tuple2(false, "400 - BAD REQUEST");
}
if (response.statusCode == 401) {
return const Tuple2(false, "401 - UNAUTHORIZED");
}
if (response.statusCode == 409) {
return const Tuple2(false, "409 - CONFLICT");
}
return const Tuple2(false, "Fail ");
}
@override
Future<Tuple2> getInfoUser(String token) async {
final response = await http.get(Uri.parse('$urlApi/user/info'),

@ -27,10 +27,18 @@ class ManagerFile {
return fitFile.toRows();
}
List<dynamic> readFitFileWeb(Uint8List bytes) {
Future<List<dynamic>> readFitFileWhithFile(File file) async {
final bytes = await file.readAsBytes();
final fitFile = FitFile.fromBytes(bytes);
return fitFile.toRows();
}
List<dynamic> readFitFileWeb(Uint8List bytes) {
final fitFile = FitFile.fromBytes(bytes);
return fitFile.toRows();
}
// ------------- Get The path of application --- //
Future<String> get localPath async {
final directory = await getApplicationDocumentsDirectory();

@ -0,0 +1,6 @@
class AttributUser {
final String _email = "email";
final String _username = "username";
String get email => _email;
String get username => _username;
}

@ -0,0 +1,3 @@
class AttributFileFit {
// Ajouter une variable privé qui contient le champs + un getter
}

@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:smartfit_app_mobile/modele/activity.dart';
import 'package:smartfit_app_mobile/modele/utile/list_activity.dart/list_activity_utile.dart';
class User extends ChangeNotifier {
String username = "VOID";
@ -22,4 +23,16 @@ class User extends ChangeNotifier {
listActivity.insert(index, activity);
notifyListeners();
}
void insertActivityTopMobile(ActivityOfUser activity, BuildContext context) {
listActivity.insert(0, activity);
ListActivityUtile().getContentOnTheFirstFileMobile(context);
notifyListeners();
}
void insertActivityTopWeb(ActivityOfUser activity, BuildContext context) {
listActivity.insert(0, activity);
ListActivityUtile().getContentOnTheFirstFileWeb(context);
notifyListeners();
}
}

@ -0,0 +1,44 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:provider/provider.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';
import 'package:smartfit_app_mobile/modele/user.dart';
import 'package:tuple/tuple.dart';
class ListActivityUtile {
final IDataStrategy _strategy = RequestApi();
final ManagerFile _managerFile = ManagerFile();
Future<void> getContentOnTheFirstFileMobile(BuildContext context) async {
Tuple2 result = await _strategy.getFile(
Provider.of<User>(context, listen: false).token,
Provider.of<User>(context, listen: false).listActivity[0].fileUuid);
if (result.item1 == false) {
//Erreur
//print(result);
return;
}
File file = File(
"${await _managerFile.localPath}/${Provider.of<User>(context, listen: false).listActivity[0].nameFile}");
await file.create();
await file.writeAsBytes(result.item2);
Provider.of<User>(context, listen: false).listActivity[0].contentActivity =
await _managerFile.readFitFileWhithFile(file);
}
Future<void> getContentOnTheFirstFileWeb(BuildContext context) async {
User user = Provider.of<User>(context, listen: false);
Tuple2 result =
await _strategy.getFile(user.token, user.listActivity[0].fileUuid);
if (result.item1 == false) {
//Erreur
//print(result);
return;
}
Provider.of<User>(context, listen: false).listActivity[0].contentActivity =
await _managerFile.readFitFileWeb(result.item2);
}
}

@ -26,12 +26,9 @@ class Login {
return Tuple2(true, result.item2);
}
void fillUser(BuildContext context, Map<String, dynamic> map, String token) {
print(map);
void fillUser(BuildContext context, Map<dynamic, dynamic> map, String token) {
context.read<User>().email = map["email"];
context.read<User>().username = map["username"];
context.read<User>().token = token;
context.read<User>().listActivity = List.empty(growable: true);
}
}

@ -0,0 +1,10 @@
import 'package:smartfit_app_mobile/modele/api/i_data_strategy.dart';
import 'package:smartfit_app_mobile/modele/api/request_api.dart';
class ProfileUtil {
final IDataStrategy _dataStrategy = RequestApi();
void modifyDataUser(String token, String attribut, String newUsername) {
_dataStrategy.modifAttribut(token, attribut, newUsername);
}
}

@ -1,3 +1,5 @@
import 'dart:io';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
@ -5,9 +7,10 @@ import 'package:smartfit_app_mobile/common/colo_extension.dart';
import 'package:smartfit_app_mobile/modele/activity.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';
import 'package:smartfit_app_mobile/modele/user.dart';
import 'package:smartfit_app_mobile/common_widget/container/workout_row.dart';
import 'package:smartfit_app_mobile/modele/utile/list_activity.dart/list_activity_utile.dart';
import 'package:tuple/tuple.dart';
class MobileListActivity extends StatefulWidget {
const MobileListActivity({Key? key}) : super(key: key);
@ -18,37 +21,68 @@ class MobileListActivity extends StatefulWidget {
class _MobileListActivity extends State<MobileListActivity> {
FilePickerResult? result;
IDataStrategy strategy = RequestApi();
final IDataStrategy strategy = RequestApi();
final ListActivityUtile _utile = ListActivityUtile();
int firstActivityIndex = 0;
/*
Future<void> readFile(String nom) async {
ManagerFile x = ManagerFile();
PlatformFile t = result!.files.single;
String? y = t.path;
if (t.path == null) {
print("t");
} else {
List<dynamic> result = await x.readFitFile(y!);
print("test11");
print(result);
print("test22");
print(ActivityOfUser(nom, result).getHeartRateWithTime());
print("test33");
List<dynamic> result = await _managerFile.readFitFile(y!);
// Upload the file and Syncronise (getFiles())
strategy.uploadFile(context.watch<User>().token, File(y));
Provider.of<User>(context, listen: false)
.addActivity(ActivityOfUser(nom, result));
//print(x.getDistanceWithTime(ActivityOfUser(result)));
//print(x.getDistance(ActivityOfUser(result)));
//print(x.getAltitudeWithTime(ActivityOfUser(result)));
//print(x.getSpeedWithTime(ActivityOfUser(result)));
.addActivity(ActivityOfUser("Random date", "$nom categorie !"));
Provider.of<User>(context, listen: false)
.listActivity
.last
.contentActivity = result;
}
}*/
void addFile(String path) async {
Tuple2<bool, String> result = await strategy.uploadFile(
Provider.of<User>(context, listen: false).token, File(path));
if (result.item1 == false) {
// Afficher msg d'erreur
print("Upload - ${result.item2}");
return;
}
getFiles();
}
List lastWorkoutArr = [];
void getFiles() async {
Tuple2 result = await strategy
.getFiles(Provider.of<User>(context, listen: false).token);
if (result.item1 == false) {
print("GetFiles - ${result.item2}");
// Afficher une message d'erreur
return;
}
Provider.of<User>(context, listen: false).listActivity.clear();
for (Map<String, dynamic> element in result.item2) {
Provider.of<User>(context, listen: false).addActivity(ActivityOfUser(
element["creation_date"].toString(),
element["category"].toString(),
element["uuid"].toString(),
element["filename"].toString()));
}
await _utile.getContentOnTheFirstFileMobile(context);
return;
}
@override
Widget build(BuildContext context) {
var media = MediaQuery.of(context).size;
int firstActivityIndex = 0;
print("tttt");
return Scaffold(
backgroundColor: TColor.white,
body: SingleChildScrollView(
@ -69,16 +103,23 @@ class _MobileListActivity extends State<MobileListActivity> {
fontSize: 16,
fontWeight: FontWeight.w700),
),
TextButton(
onPressed: getFiles,
child: Text("Get activity",
style: TextStyle(
color: TColor.gray,
fontSize: 14,
fontWeight: FontWeight.w700))),
TextButton(
onPressed: () async {
result = await FilePicker.platform.pickFiles();
if (result == null) {
print("No file selected");
FilePickerResult? result =
await FilePicker.platform.pickFiles();
if (result != null) {
addFile(result.files.single.path!);
} else {
for (var element in result!.files) {
readFile(element.name);
print(element.name);
}
print("Picker");
// msg d'erreur
// User canceled the picker
}
},
child: Text(
@ -95,7 +136,7 @@ class _MobileListActivity extends State<MobileListActivity> {
? Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 20),
const SizedBox(height: 20),
Text(
"Vous n'avez pas d'activités pour le moment, veuillez en ajouter.",
style: TextStyle(
@ -118,7 +159,7 @@ class _MobileListActivity extends State<MobileListActivity> {
itemBuilder: (context, index) {
var activityObj =
Provider.of<User>(context, listen: true)
.listActivity[index] as ActivityOfUser;
.listActivity[index];
var activityMap = activityObj.toMap();
bool isFirstActivity = false;
@ -145,7 +186,8 @@ class _MobileListActivity extends State<MobileListActivity> {
Provider.of<User>(context, listen: false)
.removeActivity(activityObj);
Provider.of<User>(context, listen: false)
.insertActivity(0, activityObj);
.insertActivityTopMobile(
activityObj, context);
},
isFirstActivity: isFirstActivity,
),

@ -1,6 +1,9 @@
import 'dart:html';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:smartfit_app_mobile/modele/manager_file.dart';
import 'package:smartfit_app_mobile/modele/utile/list_activity.dart/list_activity_utile.dart';
import 'package:tuple/tuple.dart';
import 'package:universal_html/html.dart' as html;
import 'package:file_picker/file_picker.dart';
@ -22,10 +25,9 @@ class WebListActivity extends StatefulWidget {
class _WebListActivityState extends State<WebListActivity> {
FilePickerResult? result;
IDataStrategy strategy = RequestApi();
final ListActivityUtile _utile = ListActivityUtile();
int firstActivityIndex = 0;
//late File x = File(file.path);
/*
void readFile(html.File file) async {
ManagerFile x = ManagerFile();
final reader = html.FileReader();
@ -34,13 +36,65 @@ class _WebListActivityState extends State<WebListActivity> {
if (reader.readyState == html.FileReader.DONE) {
Uint8List bytes = reader.result as Uint8List;
List<dynamic> result = x.readFitFileWeb(bytes);
Provider.of<User>(context, listen: false).addActivity(
ActivityOfUser("Date random", "${file.name} Categorie", "", ""));
Provider.of<User>(context, listen: false)
.addActivity(ActivityOfUser(file.name, result));
.listActivity
.last
.contentActivity = result;
}
});
}*/
void addFile(html.File file) async {
FileReader reader = html.FileReader();
reader.readAsArrayBuffer(file);
reader.onLoadEnd.listen((event) async {
if (reader.readyState == html.FileReader.DONE) {
Uint8List bytes = reader.result as Uint8List;
String filename = file.name;
String categoryActivity = filename.split("_").first.toLowerCase();
String dateActivity = filename.split("_")[1].split("T").first;
Tuple2<bool, String> result = await strategy.uploadFileByte(
Provider.of<User>(context, listen: false).token,
bytes,
filename,
categoryActivity,
dateActivity);
if (result.item1 == false) {
// Afficher msg d'erreur
print("Upload - ${result.item2}");
return;
}
getFiles();
}
});
}
List lastWorkoutArr = [];
// -- On doit garder cet fonction dans la page pour pouvoir afficher les msg -- //
void getFiles() async {
Tuple2 result = await strategy
.getFiles(Provider.of<User>(context, listen: false).token);
if (result.item1 == false) {
print("GetFiles - ${result.item2}");
// Afficher une message d'erreur
return;
}
Provider.of<User>(context, listen: false).listActivity.clear();
for (Map<String, dynamic> element in result.item2) {
Provider.of<User>(context, listen: false).addActivity(ActivityOfUser(
element["creation_date"].toString(),
element["category"].toString(),
element["uuid"].toString(),
element["filename"].toString()));
}
await _utile.getContentOnTheFirstFileWeb(context);
return;
}
@override
Widget build(BuildContext context) {
@ -66,6 +120,13 @@ class _WebListActivityState extends State<WebListActivity> {
fontSize: 16,
fontWeight: FontWeight.w700),
),
TextButton(
onPressed: getFiles,
child: Text("Get activity",
style: TextStyle(
color: TColor.gray,
fontSize: 14,
fontWeight: FontWeight.w700))),
TextButton(
onPressed: () async {
html.FileUploadInputElement uploadInput =
@ -75,8 +136,7 @@ class _WebListActivityState extends State<WebListActivity> {
uploadInput.onChange.listen((e) {
final files = uploadInput.files;
if (files != null && files.isNotEmpty) {
readFile(
files[0]); // Lecture du fichier sélectionné
addFile(files[0]); // Lecture du fichier sélectionné
}
});
},
@ -94,7 +154,7 @@ class _WebListActivityState extends State<WebListActivity> {
? Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 20),
const SizedBox(height: 20),
Text(
"Vous n'avez pas d'activités pour le moment, veuillez en ajouter.",
style: TextStyle(
@ -117,7 +177,7 @@ class _WebListActivityState extends State<WebListActivity> {
itemBuilder: (context, index) {
var activityObj =
Provider.of<User>(context, listen: true)
.listActivity[index] as ActivityOfUser;
.listActivity[index];
var activityMap = activityObj.toMap();
bool isFirstActivity = false;
@ -144,7 +204,8 @@ class _WebListActivityState extends State<WebListActivity> {
Provider.of<User>(context, listen: false)
.removeActivity(activityObj);
Provider.of<User>(context, listen: false)
.insertActivity(0, activityObj);
.insertActivityTopWeb(
activityObj, context);
},
isFirstActivity: isFirstActivity,
),

@ -5,7 +5,6 @@ import 'package:smartfit_app_mobile/modele/user.dart';
import 'package:smartfit_app_mobile/view/home/no_activity_view.dart';
import 'package:smartfit_app_mobile/view/map/mobile/mobile_my_map.dart';
import 'package:smartfit_app_mobile/view/map/web/web_my_map.dart';
import 'package:smartfit_app_mobile/view/profile/profile_view.dart';
class MyMap extends StatefulWidget {
const MyMap({Key? key}) : super(key: key);

Loading…
Cancel
Save