From 82e5fbdc1aa9dcb1ed5decdef50a769b533a476f Mon Sep 17 00:00:00 2001 From: Enzo Date: Wed, 22 Nov 2023 09:19:11 +0100 Subject: [PATCH] list activity web + mobile --- lib/modele/api/i_data_strategy.dart | 3 + lib/modele/api/request_api.dart | 39 ++++++++++ lib/modele/user.dart | 10 ++- .../list_activity_utile.dart | 15 +++- .../activity/mobile/mobile_list_activity.dart | 13 ++-- lib/view/activity/web/web_list_activity.dart | 73 +++++++++++++++++-- 6 files changed, 136 insertions(+), 17 deletions(-) diff --git a/lib/modele/api/i_data_strategy.dart b/lib/modele/api/i_data_strategy.dart index 9d6edb0..49c4940 100644 --- a/lib/modele/api/i_data_strategy.dart +++ b/lib/modele/api/i_data_strategy.dart @@ -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> uploadFile(String token, File file); + Future> uploadFileByte(String token, + Uint8List contentFile, String nameFile, String category, String date); // 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 c4c700e..8d0756f 100644 --- a/lib/modele/api/request_api.dart +++ b/lib/modele/api/request_api.dart @@ -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; @@ -182,6 +183,44 @@ class RequestApi extends IDataStrategy { return const Tuple2(false, "Fail "); } + @override + Future> uploadFileByte( + String token, + Uint8List contentFile, + String nameFile, + String category, + String date) async { + final uri = Uri.parse('$urlApi/user/files'); + Map 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 getInfoUser(String token) async { final response = await http.get(Uri.parse('$urlApi/user/info'), diff --git a/lib/modele/user.dart b/lib/modele/user.dart index e67dca4..c067711 100644 --- a/lib/modele/user.dart +++ b/lib/modele/user.dart @@ -24,9 +24,15 @@ class User extends ChangeNotifier { notifyListeners(); } - void insertActivityTop(ActivityOfUser activity, BuildContext context) { + void insertActivityTopMobile(ActivityOfUser activity, BuildContext context) { listActivity.insert(0, activity); - ListActivityUtile().getContentOnTheFirstFile(context); + ListActivityUtile().getContentOnTheFirstFileMobile(context); + notifyListeners(); + } + + void insertActivityTopWeb(ActivityOfUser activity, BuildContext context) { + listActivity.insert(0, activity); + ListActivityUtile().getContentOnTheFirstFileWeb(context); notifyListeners(); } } diff --git a/lib/modele/utile/list_activity.dart/list_activity_utile.dart b/lib/modele/utile/list_activity.dart/list_activity_utile.dart index 776411f..23da587 100644 --- a/lib/modele/utile/list_activity.dart/list_activity_utile.dart +++ b/lib/modele/utile/list_activity.dart/list_activity_utile.dart @@ -12,7 +12,7 @@ class ListActivityUtile { final IDataStrategy _strategy = RequestApi(); final ManagerFile _managerFile = ManagerFile(); - Future getContentOnTheFirstFile(BuildContext context) async { + Future getContentOnTheFirstFileMobile(BuildContext context) async { Tuple2 result = await _strategy.getFile( Provider.of(context, listen: false).token, Provider.of(context, listen: false).listActivity[0].fileUuid); @@ -28,4 +28,17 @@ class ListActivityUtile { Provider.of(context, listen: false).listActivity[0].contentActivity = await _managerFile.readFitFileWhithFile(file); } + + Future getContentOnTheFirstFileWeb(BuildContext context) async { + User user = Provider.of(context, listen: false); + Tuple2 result = + await _strategy.getFile(user.token, user.listActivity[0].fileUuid); + if (result.item1 == false) { + //Erreur + //print(result); + return; + } + Provider.of(context, listen: false).listActivity[0].contentActivity = + await _managerFile.readFitFileWeb(result.item2); + } } diff --git a/lib/view/activity/mobile/mobile_list_activity.dart b/lib/view/activity/mobile/mobile_list_activity.dart index 8f4db7b..91987cc 100644 --- a/lib/view/activity/mobile/mobile_list_activity.dart +++ b/lib/view/activity/mobile/mobile_list_activity.dart @@ -21,8 +21,9 @@ class MobileListActivity extends StatefulWidget { class _MobileListActivity extends State { FilePickerResult? result; - IDataStrategy strategy = RequestApi(); + final IDataStrategy strategy = RequestApi(); final ListActivityUtile _utile = ListActivityUtile(); + int firstActivityIndex = 0; /* Future readFile(String nom) async { @@ -74,18 +75,13 @@ class _MobileListActivity extends State { element["uuid"].toString(), element["filename"].toString())); } - _utile.getContentOnTheFirstFile(context); + await _utile.getContentOnTheFirstFileMobile(context); return; } @override Widget build(BuildContext context) { var media = MediaQuery.of(context).size; - int firstActivityIndex = 0; - - if (Provider.of(context).listActivity.isNotEmpty) { - _utile.getContentOnTheFirstFile(context); - } return Scaffold( backgroundColor: TColor.white, @@ -190,7 +186,8 @@ class _MobileListActivity extends State { Provider.of(context, listen: false) .removeActivity(activityObj); Provider.of(context, listen: false) - .insertActivityTop(activityObj, context); + .insertActivityTopMobile( + activityObj, context); }, isFirstActivity: isFirstActivity, ), diff --git a/lib/view/activity/web/web_list_activity.dart b/lib/view/activity/web/web_list_activity.dart index cec1c4d..f9e84ab 100644 --- a/lib/view/activity/web/web_list_activity.dart +++ b/lib/view/activity/web/web_list_activity.dart @@ -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,8 +25,9 @@ class WebListActivity extends StatefulWidget { class _WebListActivityState extends State { FilePickerResult? result; IDataStrategy strategy = RequestApi(); + final ListActivityUtile _utile = ListActivityUtile(); int firstActivityIndex = 0; - + /* void readFile(html.File file) async { ManagerFile x = ManagerFile(); final reader = html.FileReader(); @@ -40,6 +44,56 @@ class _WebListActivityState extends State { .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 result = await strategy.uploadFileByte( + Provider.of(context, listen: false).token, + bytes, + filename, + categoryActivity, + dateActivity); + + if (result.item1 == false) { + // Afficher msg d'erreur + print("Upload - ${result.item2}"); + return; + } + getFiles(); + } + }); + } + + // -- On doit garder cet fonction dans la page pour pouvoir afficher les msg -- // + void getFiles() async { + Tuple2 result = await strategy + .getFiles(Provider.of(context, listen: false).token); + if (result.item1 == false) { + print("GetFiles - ${result.item2}"); + // Afficher une message d'erreur + return; + } + Provider.of(context, listen: false).listActivity.clear(); + + for (Map element in result.item2) { + Provider.of(context, listen: false).addActivity(ActivityOfUser( + element["creation_date"].toString(), + element["category"].toString(), + element["uuid"].toString(), + element["filename"].toString())); + } + await _utile.getContentOnTheFirstFileWeb(context); + return; } @override @@ -66,6 +120,13 @@ class _WebListActivityState extends State { 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 { 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 { ? 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 { itemBuilder: (context, index) { var activityObj = Provider.of(context, listen: true) - .listActivity[index] as ActivityOfUser; + .listActivity[index]; var activityMap = activityObj.toMap(); bool isFirstActivity = false; @@ -144,7 +204,8 @@ class _WebListActivityState extends State { Provider.of(context, listen: false) .removeActivity(activityObj); Provider.of(context, listen: false) - .insertActivity(0, activityObj); + .insertActivityTopWeb( + activityObj, context); }, isFirstActivity: isFirstActivity, ),