diff --git a/lib/Components/image_input_container.dart b/lib/Components/image_input_container.dart new file mode 100644 index 0000000..f0ea5a9 --- /dev/null +++ b/lib/Components/image_input_container.dart @@ -0,0 +1,96 @@ +import 'package:auto_size_text/auto_size_text.dart'; +import 'package:flutter/material.dart'; +import 'package:manager_app/constants.dart'; +import 'package:manager_app/Screens/Resources/select_resource_modal.dart'; + +class ImageInputContainer extends StatefulWidget { + final Color color; + final String label; + final String initialValue; + final ValueChanged onChanged; + const ImageInputContainer({ + Key key, + this.color = kSecond, + this.label, + this.initialValue, + this.onChanged, + }) : super(key: key); + + @override + _ImageInputContainerState createState() => _ImageInputContainerState(); +} + +class _ImageInputContainerState extends State { + String resourceIdToShow; + + @override + void initState() { + resourceIdToShow = widget.initialValue; + super.initState(); + } + + @override + Widget build(BuildContext context) { + Size size = MediaQuery.of(context).size; + return Container( + child: Row( + children: [ + Align( + alignment: AlignmentDirectional.centerStart, + child: Text(widget.label, style: TextStyle(fontSize: 25, fontWeight: FontWeight.w300)) + ), + Padding( + padding: const EdgeInsets.all(10.0), + child: Container( + width: size.width *0.2, + child: InkWell( + onTap: () { + showSelectResourceModal( + "Sélectionner une ressource", + (String resourceId) { + print('ON GET RESULT PARENT INPUT '); + widget.onChanged(resourceId); + setState(() { + print(resourceId); + resourceIdToShow = resourceId; + print('Set State'); + }); + }, + 1, + context + ); + }, + child: getElement(widget.initialValue, context), + ), + ), + ), + ], + ), + ); + } + + getElement(String initialValue, BuildContext context) { + print("getElement"); + print(resourceIdToShow); + if (resourceIdToShow != null) { + return Text("Show image todo"); + } else { + return Container( + decoration: BoxDecoration( + color: widget.color, + borderRadius: BorderRadius.circular(50), + ), + child: Padding( + padding: const EdgeInsets.only(left: 5, right: 5, top: 15, bottom: 15), + child: Center( + child: AutoSizeText( + "Choisir une image", + style: TextStyle(color: kWhite), + maxLines: 2, + ) + ), + ) + ); + } + } +} \ No newline at end of file diff --git a/lib/Components/multi_string_input_container.dart b/lib/Components/multi_string_input_container.dart index 4cdc897..88a1b3e 100644 --- a/lib/Components/multi_string_input_container.dart +++ b/lib/Components/multi_string_input_container.dart @@ -3,7 +3,6 @@ import 'dart:convert'; import 'package:auto_size_text/auto_size_text.dart'; import 'package:flutter/material.dart'; import 'package:manager_app/Components/multi_input_modal.dart'; -import 'package:manager_app/Components/rounded_input_field.dart'; import 'package:manager_app/constants.dart'; import 'package:managerapi/api.dart'; @@ -55,6 +54,7 @@ class MultiStringContainer extends StatelessWidget { child: Center( child: AutoSizeText( "Changer les traductions", + style: TextStyle(color: kWhite), maxLines: 2, ) ), diff --git a/lib/Components/resource_tab.dart b/lib/Components/resource_tab.dart index be71ea8..c05152b 100644 --- a/lib/Components/resource_tab.dart +++ b/lib/Components/resource_tab.dart @@ -62,8 +62,6 @@ class _ResourceTabState extends State with SingleTickerProviderStat } void _handleTabSelection() { - print("_handleTabSelection"); - print(_tabController.index); switch(_tabController.index) { case 0: setState(() { @@ -90,18 +88,12 @@ class _ResourceTabState extends State with SingleTickerProviderStat getContent(ResourceDetailDTO resourceDetailDTO, Function onFileUpload) { List tabsToShow = new List(); - print("getContent"); - print(resourceDetailDTO); - // Local Image tabsToShow.add( new Padding( padding: EdgeInsets.symmetric(horizontal: 8, vertical: 16), child: UploadImageContainer( onChanged: (File file) { - print("ONCHANGED image"); - print(file.path); - //fileToSend = file; onFileUpload(file); resourceDetailDTO.type = ResourceType.image; } @@ -129,7 +121,6 @@ getContent(ResourceDetailDTO resourceDetailDTO, Function onFileUpload) { child: UploadOnlineResourceContainer( resourceDetailDTO: resourceDetailDTO, onChanged: (ResourceDetailDTO value) { - print("ONcHanged UploadOnlineResourceContainer parent"); resourceDetailDTO = value; }, ), diff --git a/lib/Components/upload_image_container.dart b/lib/Components/upload_image_container.dart index f505975..07a26da 100644 --- a/lib/Components/upload_image_container.dart +++ b/lib/Components/upload_image_container.dart @@ -74,7 +74,20 @@ class _UploadImageContainerState extends State with Single if (snapshot.connectionState == ConnectionState.done) { return Container( height: 300, - child: DartVLC(file: snapshot.data) + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: Text("La prévisualisation de la vidéo n'est pas disponible"), + ), + Icon( + Icons.ondemand_video_sharp, + size: 35, + ), + ], + ), + //DartVLC(file: snapshot.data) ); } else if (snapshot.connectionState == ConnectionState.none) { return Text("No data"); @@ -151,23 +164,4 @@ class _UploadImageContainerState extends State with Single ), ); } -} - -Upload(File imageFile) async { - var stream = new http.ByteStream(DelegatingStream.typed(imageFile.openRead())); - var length = await imageFile.length(); - - var uri = Uri.parse("upload URL TEST"); - - var request = new http.MultipartRequest("POST", uri); - var multipartFile = new http.MultipartFile('file', stream, length, - filename: basename(imageFile.path)); - //contentType: new MediaType('image', 'png')); - - request.files.add(multipartFile); - var response = await request.send(); - print(response.statusCode); - response.stream.transform(utf8.decoder).listen((value) { - print(value); - }); } \ No newline at end of file diff --git a/lib/Components/upload_online_resources_container.dart b/lib/Components/upload_online_resources_container.dart index 19940cd..f1c7222 100644 --- a/lib/Components/upload_online_resources_container.dart +++ b/lib/Components/upload_online_resources_container.dart @@ -1,5 +1,6 @@ import 'dart:io'; import 'package:dart_vlc/dart_vlc.dart'; +import 'package:flutter/cupertino.dart'; import 'package:manager_app/Components/rounded_input_field.dart'; import 'package:manager_app/Components/string_input_container.dart'; import 'package:manager_app/Components/vlc_viewer.dart'; @@ -37,7 +38,20 @@ class _UploadOnlineResourceContainerState extends State snapshot) { if (snapshot.connectionState == ConnectionState.done) { @@ -51,7 +65,7 @@ class _UploadOnlineResourceContainerState extends State { sectionDTO.type = SectionType.fromJson(tempOutput[0]); }, ), - StringInputContainer( + + ImageInputContainer( label: "Image :", initialValue: sectionDTO.imageId, + color: kPrimaryColor, onChanged: (value) { + print("received value in grant older"); sectionDTO.imageId = value; }, ), @@ -154,6 +158,7 @@ class _SectionDetailScreenState extends State { children: [ MultiStringContainer( label: "Titre :", + color: kPrimaryColor, initialValue: sectionDTO.title, onGetResult: (value) { if (sectionDTO.title != value) { @@ -165,6 +170,7 @@ class _SectionDetailScreenState extends State { ), MultiStringContainer( label: "Description :", + color: kPrimaryColor, initialValue: sectionDTO.description, onGetResult: (value) { if (sectionDTO.description != value) { diff --git a/lib/Screens/Resources/fetch_image_for_resource.dart b/lib/Screens/Resources/fetch_image_for_resource.dart new file mode 100644 index 0000000..3e0620b --- /dev/null +++ b/lib/Screens/Resources/fetch_image_for_resource.dart @@ -0,0 +1,26 @@ +import 'package:manager_app/app_context.dart'; +import 'package:managerapi/api.dart'; +import 'package:flutter/material.dart'; + +getImageForResource(ResourceDTO resourceDTO, AppContext appContext) { + switch(resourceDTO.type) { + case ResourceType.image: + return Image.network( + appContext.getContext().clientAPI.resourceApi.apiClient.basePath+"/api/Resource/"+ resourceDTO.id, + fit:BoxFit.fill + ); + break; + case ResourceType.imageUrl: + return Image.network( + resourceDTO.data, + fit:BoxFit.fill + ); + break; + case ResourceType.video: + return Text("THIS IS VIDEO LOCAL"); + break; + case ResourceType.videoUrl: + return Text(resourceDTO.data); + break; + } +} \ No newline at end of file diff --git a/lib/Screens/Resources/new_resource_popup.dart b/lib/Screens/Resources/new_resource_popup.dart index 988474c..9a68bd4 100644 --- a/lib/Screens/Resources/new_resource_popup.dart +++ b/lib/Screens/Resources/new_resource_popup.dart @@ -46,7 +46,6 @@ void showNewResource(AppContext appContext, BuildContext context) { child: ResourceTab( resourceDetailDTO: resourceDetailDTO, onFileUpload: (File file) { - print("Received onFileUpload - nEW RESSOURCE"); fileToSend = file; }, ) @@ -101,41 +100,68 @@ void showNewResource(AppContext appContext, BuildContext context) { void create(ResourceDetailDTO resourceDetailDTO, File file, AppContext appContext, context) async { if (resourceDetailDTO.label != null) { - Navigator.of(context).pop(); + switch(resourceDetailDTO.type) { + case ResourceType.image: + case ResourceType.video: + if (file != null) { + var request = http.MultipartRequest('POST', Uri.parse(appContext.getContext().clientAPI.resourceApi.apiClient.basePath+"/api/Resource/upload")); + request.files.add( + await http.MultipartFile( + 'picture', + file.readAsBytes().asStream(), + file.lengthSync(), + filename: file.path.toString().split("/").last + ) + ); - print(resourceDetailDTO.type); - if(resourceDetailDTO.type == ResourceType.image || resourceDetailDTO.type == ResourceType.video) { - var request = http.MultipartRequest('POST', Uri.parse(appContext.getContext().clientAPI.resourceApi.apiClient.basePath+"/api/Resource/upload")); - request.files.add( - await http.MultipartFile( - 'picture', - file.readAsBytes().asStream(), - file.lengthSync(), - filename: file.path.toString().split("/").last - ) - ); + // Todo Add header with bearer token (get via managercontext - token value) + //request.headers.addEntries(newEntries) - // Todo Add header with bearer token (get via managercontext - token value) - //request.headers.addEntries(newEntries) + request.fields['label'] = resourceDetailDTO.label; + request.fields['type'] = ResourceType.image.toString(); - request.fields['label'] = resourceDetailDTO.label; - request.fields['type'] = ResourceType.image.toString(); + var res = await request.send(); - var res = await request.send(); + if (res.statusCode == 200) { + // To refresh only (UGLY COOOOODE) + ManagerAppContext managerAppContext = appContext.getContext(); + appContext.setContext(managerAppContext); - print("RESULT"); - print(res.statusCode); - // TODO add message if status code not ok + showNotification(Colors.green, kWhite, 'La ressource a été créée avec succès', context); + } else { + showNotification(kPrimaryColor, kWhite, 'Une erreur est survenue lors de la création de la ressource', context); + } - } else { - ResourceDetailDTO newResource = await appContext.getContext().clientAPI.resourceApi.resourceCreate(resourceDetailDTO); + } else { + showNotification(Colors.orange, kWhite, 'Aucun fichier n\'a été chargé', context); + } + Navigator.of(context).pop(); + break; + case ResourceType.imageUrl: + case ResourceType.videoUrl: + if (resourceDetailDTO.data != null) { + // test if Correct url + bool _validURL = Uri.parse(resourceDetailDTO.data).isAbsolute; + if(_validURL) { + Navigator.of(context).pop(); + + ResourceDetailDTO newResource = await appContext.getContext().clientAPI.resourceApi.resourceCreate(resourceDetailDTO); + + // To refresh only (UGLY COOOOODE) + ManagerAppContext managerAppContext = appContext.getContext(); + appContext.setContext(managerAppContext); + + showNotification(Colors.green, kWhite, 'La ressource a été créée avec succès', context); + } else { + showNotification(Colors.orange, kWhite, 'L\'url est invalide', context); + } + } else { + showNotification(Colors.orange, kWhite, 'Veuillez remplir le champ URL', context); + } + break; } - - // To refresh only (UGLY COOOOODE) - ManagerAppContext managerAppContext = appContext.getContext(); - appContext.setContext(managerAppContext); - - showNotification(Colors.green, kWhite, 'La ressource a été créée avec succès', context); + } else { + showNotification(Colors.orange, kWhite, 'Veuillez donner un nom à la ressource', context); } } diff --git a/lib/Screens/Resources/resources_screen.dart b/lib/Screens/Resources/resources_screen.dart index e55db6d..1491748 100644 --- a/lib/Screens/Resources/resources_screen.dart +++ b/lib/Screens/Resources/resources_screen.dart @@ -1,8 +1,6 @@ import 'package:auto_size_text/auto_size_text.dart'; import 'package:flutter/material.dart'; import 'package:manager_app/Components/fetch_resource_icon.dart'; -import 'package:manager_app/Components/fetch_section_icon.dart'; -import 'package:manager_app/Models/managerContext.dart'; import 'package:manager_app/Screens/Resources/new_resource_popup.dart'; import 'package:manager_app/Screens/Resources/show_resource_popup.dart'; import 'package:manager_app/app_context.dart'; @@ -10,8 +8,16 @@ import 'package:manager_app/constants.dart'; import 'package:managerapi/api.dart'; import 'package:provider/provider.dart'; +import 'fetch_image_for_resource.dart'; + class ResourcesScreen extends StatefulWidget { - ResourcesScreen({Key key}) : super(key: key); + final Function onGetResult; + final bool isImage; + const ResourcesScreen({ + Key key, + this.isImage, + this.onGetResult, + }) : super(key: key); @override _ResourcesScreenState createState() => _ResourcesScreenState(); @@ -52,14 +58,25 @@ class _ResourcesScreenState extends State { gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 6), itemCount: data.length, itemBuilder: (BuildContext context, int index) { - return // User Picture + return InkWell( onTap: () { - if (data[index].id == null) { - showNewResource(appContext, context); + if (widget.onGetResult == null) { + // Main screen + if (data[index].id == null) { + showNewResource(appContext, context); + } else { + showResource(data[index], appContext, context, size); + } } else { - showResource(data[index], appContext, context, size); + if (data[index].id == null) { + showNewResource(appContext, context); + } else { + // Result for select modal + widget.onGetResult(data[index].id); + } } + }, child: Container( decoration: boxDecoration(data[index]), @@ -90,13 +107,10 @@ class _ResourcesScreenState extends State { ), ), Container( - height: size.height *0.08, - child: Center( - child: Image.network( - resource.type == ResourceType.image ? appContext.getContext().clientAPI.resourceApi.apiClient.basePath+"/api/Resource/"+ resource.id : "https://miro.medium.com/max/1920/1*8wFh-pEuwyAGa1IaKb-lEw.png", - fit:BoxFit.fill - ), - ), + height: size.height *0.08, + child: Center( + child: getImageForResource(resource, appContext), + ) ), Align( alignment: Alignment.bottomRight, diff --git a/lib/Screens/Resources/select_resource_modal.dart b/lib/Screens/Resources/select_resource_modal.dart new file mode 100644 index 0000000..6f0f3c7 --- /dev/null +++ b/lib/Screens/Resources/select_resource_modal.dart @@ -0,0 +1,96 @@ +import 'package:flutter/material.dart'; +import 'package:manager_app/Components/rounded_button.dart'; +import 'package:manager_app/Components/string_input_container.dart'; +import 'package:manager_app/Screens/Resources/resources_screen.dart'; +import 'package:manager_app/constants.dart'; +import 'package:managerapi/api.dart'; + +showSelectResourceModal (String text, Function onGetResult, int maxLines, BuildContext mainContext) { /*Function onSelect,*/ + Size size = MediaQuery.of(mainContext).size; + + showDialog( + builder: (BuildContext context) => AlertDialog( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(20.0)) + ), + title: Center(child: Text(text)), + content: SingleChildScrollView( + child: Column( + children: [ + Container( + width: size.width * 0.6, + height: size.height * 0.6, + child: ResourcesScreen( + onGetResult: (String resourceId) { + if (resourceId != null) { + onGetResult(resourceId); + Navigator.of(mainContext).pop(); + } + }, + isImage: true, + ), + ), + /*Column( + children: showValues(newValues), + ),*/ + ], + ) + ), + actions: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Container( + width: 180, + height: 70, + child: RoundedButton( + text: "Annuler", + icon: Icons.undo, + color: kSecond, + press: () { + //onGetResult(values); + print("TODO onGetResult"); + Navigator.of(context).pop(); + }, + fontSize: 20, + ), + ), + /*Container( + width: 180, + height: 70, + child: RoundedButton( + text: "Valider", + icon: Icons.check, + color: kPrimaryColor, + textColor: kWhite, + press: () { + print("TODO Valider resource selected"); + Navigator.of(context).pop(); + }, + fontSize: 20, + ), + ),*/ + ], + ), + ], + ), context: mainContext + ); +} + +showValues(List newValues) { + List valuesToShow = new List(); + newValues.forEach((newValue) { + valuesToShow.add( + new StringInputContainer( + color: Colors.lightBlue, + label: newValue.language, + initialValue: newValue.value, + onChanged: (String value) { + newValue.value = value; + }, + )); + }); + return valuesToShow; +} + + diff --git a/lib/Screens/Resources/show_resource_popup.dart b/lib/Screens/Resources/show_resource_popup.dart index 4b80fbb..54c3ec3 100644 --- a/lib/Screens/Resources/show_resource_popup.dart +++ b/lib/Screens/Resources/show_resource_popup.dart @@ -6,9 +6,10 @@ import 'package:manager_app/Models/managerContext.dart'; import 'package:manager_app/app_context.dart'; import 'package:manager_app/constants.dart'; import 'package:managerapi/api.dart'; -import 'package:intl/intl.dart'; -void showResource(ResourceDTO resourceDTO,AppContext appContext, BuildContext context, Size size) { +import 'fetch_image_for_resource.dart'; + +void showResource(ResourceDTO resourceDTO, AppContext appContext, BuildContext context, Size size) { showDialog( builder: (BuildContext context) => AlertDialog( shape: RoundedRectangleBorder( @@ -33,10 +34,7 @@ void showResource(ResourceDTO resourceDTO,AppContext appContext, BuildContext co ), child: Padding( padding: const EdgeInsets.all(10.0), - child: Image.network( - resourceDTO.type == ResourceType.image ? appContext.getContext().clientAPI.resourceApi.apiClient.basePath+"/api/Resource/"+ resourceDTO.id : "https://miro.medium.com/max/1920/1*8wFh-pEuwyAGa1IaKb-lEw.png", - fit:BoxFit.scaleDown - ), + child: getImageForResource(resourceDTO, appContext), ), ), ), diff --git a/manager_api/.openapi-generator/FILES b/manager_api/.openapi-generator/FILES index b36a968..ad09734 100644 --- a/manager_api/.openapi-generator/FILES +++ b/manager_api/.openapi-generator/FILES @@ -52,4 +52,3 @@ lib/model/translation_dto.dart lib/model/user.dart lib/model/user_detail_dto.dart pubspec.yaml -test/resource_type_test.dart diff --git a/manager_api/doc/ResourceDTO.md b/manager_api/doc/ResourceDTO.md index a41da03..91f91a8 100644 --- a/manager_api/doc/ResourceDTO.md +++ b/manager_api/doc/ResourceDTO.md @@ -11,6 +11,7 @@ Name | Type | Description | Notes **id** | **String** | | [optional] **type** | [**ResourceType**](ResourceType.md) | | [optional] **label** | **String** | | [optional] +**data** | **String** | | [optional] [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/manager_api/lib/model/resource_dto.dart b/manager_api/lib/model/resource_dto.dart index e069989..f5d5447 100644 --- a/manager_api/lib/model/resource_dto.dart +++ b/manager_api/lib/model/resource_dto.dart @@ -15,6 +15,7 @@ class ResourceDTO { this.id, this.type, this.label, + this.data, }); String id; @@ -23,20 +24,24 @@ class ResourceDTO { String label; + String data; + @override bool operator ==(Object other) => identical(this, other) || other is ResourceDTO && other.id == id && other.type == type && - other.label == label; + other.label == label && + other.data == data; @override int get hashCode => (id == null ? 0 : id.hashCode) + (type == null ? 0 : type.hashCode) + - (label == null ? 0 : label.hashCode); + (label == null ? 0 : label.hashCode) + + (data == null ? 0 : data.hashCode); @override - String toString() => 'ResourceDTO[id=$id, type=$type, label=$label]'; + String toString() => 'ResourceDTO[id=$id, type=$type, label=$label, data=$data]'; Map toJson() { final json = {}; @@ -49,6 +54,9 @@ class ResourceDTO { if (label != null) { json[r'label'] = label; } + if (data != null) { + json[r'data'] = data; + } return json; } @@ -60,6 +68,7 @@ class ResourceDTO { id: json[r'id'], type: ResourceType.fromJson(json[r'type']), label: json[r'label'], + data: json[r'data'], ); static List listFromJson(List json, {bool emptyIsNull, bool growable,}) => diff --git a/manager_api/swagger.yaml b/manager_api/swagger.yaml index 4428a95..52b1742 100644 --- a/manager_api/swagger.yaml +++ b/manager_api/swagger.yaml @@ -1193,6 +1193,9 @@ components: label: type: string nullable: true + data: + type: string + nullable: true ResourceType: type: string description: ''