Add audio in web + update code for resource ..

This commit is contained in:
Fransolet Thomas 2022-10-27 17:32:44 +02:00
parent ddda68c911
commit eddc4005ae
25 changed files with 766 additions and 89 deletions

View File

@ -0,0 +1,165 @@
import 'package:auto_size_text/auto_size_text.dart';
import 'package:flutter/material.dart';
import 'package:manager_app/Components/loading_common.dart';
import 'package:manager_app/app_context.dart';
import 'package:manager_app/constants.dart';
import 'package:manager_app/Screens/Resources/select_resource_modal.dart';
import 'package:managerapi/api.dart';
import 'package:provider/provider.dart';
class AudioInputContainer extends StatefulWidget {
final Color color;
final String label;
final String initialValue;
final ValueChanged<ResourceDTO> onChanged;
final BoxFit imageFit;
final bool isSmall;
final double fontSize;
const AudioInputContainer({
Key key,
this.color = kSecond,
this.label,
this.initialValue,
this.onChanged,
this.imageFit = BoxFit.cover,
this.isSmall = false,
this.fontSize = 25
}) : super(key: key);
@override
_AudioInputContainerState createState() => _AudioInputContainerState();
}
class _AudioInputContainerState extends State<AudioInputContainer> {
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: AutoSizeText(
widget.label,
style: TextStyle(fontSize: widget.fontSize, fontWeight: FontWeight.w300),
maxLines: 2,
maxFontSize: widget.fontSize,
textAlign: TextAlign.center,
)
),
Container(
//color: widget.isSmall ? Colors.cyanAccent: Colors.red,
child: Padding(
padding: EdgeInsets.only(left: widget.isSmall ? 5 : 10, top: 10, bottom: 10),
child: Container(
width: size.width *0.08,
height: size.width *0.08,
child: InkWell(
onTap: () async {
var result = await showSelectResourceModal(
"Sélectionner une ressource",
1,
[ResourceType.audio],
context
);
if (result != null) {
setState(() {
resourceIdToShow = result.id;
});
widget.onChanged(result);
}
},
child: getElement(widget.initialValue, context, widget.isSmall),
),
),
),
),
],
),
);
}
getElement(String initialValue, BuildContext context, bool isSmall) {
if (resourceIdToShow != null) {
Size size = MediaQuery.of(context).size;
final appContext = Provider.of<AppContext>(context);
return FutureBuilder(
future: getResource(resourceIdToShow, appContext),
builder: (context, AsyncSnapshot<dynamic> snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.data != null) {
return Container(
decoration: boxDecoration(snapshot.data, appContext),
child: Center(child: AutoSizeText("Audio")),
);
} else {
return Text("No data");
}
} else if (snapshot.connectionState == ConnectionState.none) {
return Text("No data");
} else {
return Center(
child: Container(
height: size.height * 0.1,
child: LoadingCommon()
)
);
}
}
);
} else {
return Container(
decoration: BoxDecoration(
color: widget.color,
borderRadius: BorderRadius.circular(20),
),
child: Padding(
padding: const EdgeInsets.only(left: 5, right: 5, top: 15, bottom: 15),
child: Center(
child: AutoSizeText(
"Choisir un fichier audio",
style: TextStyle(color: kWhite),
maxLines: 1,
)
),
)
);
}
}
Future<ResourceDTO> getResource(String resourceIdToShow, dynamic appContext) async {
ResourceDTO resource = await appContext.getContext().clientAPI.resourceApi.resourceGetDetail(resourceIdToShow);
return resource;
}
boxDecoration(ResourceDTO resourceDTO, appContext) {
return BoxDecoration(
shape: BoxShape.rectangle,
color: kWhite,
borderRadius: BorderRadius.circular(30.0),
/*image: new DecorationImage(
fit: widget.imageFit,
image: resourceDTO.type != null ? new NetworkImage(
resourceDTO.type == ResourceType.image ? appContext.getContext().clientAPI.resourceApi.apiClient.basePath+"/api/Resource/"+ resourceDTO.id : resourceDTO.data,
) : null,
),*/
boxShadow: [
BoxShadow(
spreadRadius: 0.5,
blurRadius: 1,
offset: Offset(0, 1.5), // changes position of shadow
),
],
);
}
}

View File

@ -0,0 +1,105 @@
/*import 'dart:async';
import 'package:audioplayers/audioplayers.dart';
import 'package:flutter/material.dart';
class AudioPlayerContainer extends StatefulWidget {
const AudioPlayerContainer({Key? key}) : super(key: key);
@override
_AudioPlayerContainerState createState() => _AudioPlayerContainerState();
}
class _AudioPlayerContainerState extends State<AudioPlayerContainer> {
List<AudioPlayer> players =
List.generate(4, (_) => AudioPlayer()..setReleaseMode(ReleaseMode.stop));
int selectedPlayerIdx = 0;
AudioPlayer get selectedPlayer => players[selectedPlayerIdx];
List<StreamSubscription> streams = [];
@override
void initState() {
super.initState();
players.asMap().forEach((index, player) {
streams.add(
player.onPlayerComplete.listen(
(it) => toast(
'Player complete!',
textKey: Key('toast-player-complete-$index'),
),
),
);
streams.add(
player.onSeekComplete.listen(
(it) => toast(
'Seek complete!',
textKey: Key('toast-seek-complete-$index'),
),
),
);
});
}
@override
void dispose() {
streams.forEach((it) => it.cancel());
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('audioplayers example'),
),
body: Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Center(
child: Tgl(
options: ['P1', 'P2', 'P3', 'P4']
.asMap()
.map((key, value) => MapEntry('player-$key', value)),
selected: selectedPlayerIdx,
onChange: (v) => setState(() => selectedPlayerIdx = v),
),
),
),
Expanded(
child: Tabs(
tabs: [
TabData(
key: 'sourcesTab',
label: 'Src',
content: SourcesTab(player: selectedPlayer),
),
TabData(
key: 'controlsTab',
label: 'Ctrl',
content: ControlsTab(player: selectedPlayer),
),
TabData(
key: 'streamsTab',
label: 'Stream',
content: StreamsTab(player: selectedPlayer),
),
TabData(
key: 'audioContextTab',
label: 'Ctx',
content: AudioContextTab(player: selectedPlayer),
),
TabData(
key: 'loggerTab',
label: 'Log',
content: const LoggerTab(),
),
],
),
),
],
),
);
}
}*/

View File

@ -9,6 +9,9 @@ IconData getResourceIcon(elementType) {
case ResourceType.imageUrl: case ResourceType.imageUrl:
return Icons.image_search; // art_track return Icons.image_search; // art_track
break; break;
case ResourceType.audio:
return Icons.audiotrack; // art_track
break;
case ResourceType.video: case ResourceType.video:
return Icons.slow_motion_video; return Icons.slow_motion_video;
break; break;

View File

@ -67,7 +67,7 @@ class _ImageInputContainerState extends State<ImageInputContainer> {
var result = await showSelectResourceModal( var result = await showSelectResourceModal(
"Sélectionner une ressource", "Sélectionner une ressource",
1, 1,
true, [ResourceType.image, ResourceType.imageUrl],
context context
); );

View File

@ -2,6 +2,7 @@ import 'dart:io';
import 'package:file_picker/file_picker.dart'; import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:manager_app/Components/upload_audio_container.dart';
import 'package:manager_app/Components/upload_image_container.dart'; import 'package:manager_app/Components/upload_image_container.dart';
import 'package:manager_app/Components/upload_online_resources_container.dart'; import 'package:manager_app/Components/upload_online_resources_container.dart';
import 'package:manager_app/constants.dart'; import 'package:manager_app/constants.dart';
@ -29,7 +30,8 @@ class _ResourceTabState extends State<ResourceTab> with SingleTickerProviderStat
void initState() { void initState() {
tabsToShow.add(new Tab(text: "Image local")); tabsToShow.add(new Tab(text: "Image local"));
tabsToShow.add(new Tab(text: "Image en ligne")); tabsToShow.add(new Tab(text: "Image en ligne"));
tabsToShow.add(new Tab(text: "Vidéo en ligne")); tabsToShow.add(new Tab(text: "Audio local"));
//tabsToShow.add(new Tab(text: "Vidéo en ligne"));
_tabController = new TabController(length: 3, vsync: this); _tabController = new TabController(length: 3, vsync: this);
_tabController.addListener(_handleTabSelection); _tabController.addListener(_handleTabSelection);
@ -81,7 +83,7 @@ class _ResourceTabState extends State<ResourceTab> with SingleTickerProviderStat
case 2: case 2:
setState(() { setState(() {
widget.resourceDTO.data = null; widget.resourceDTO.data = null;
widget.resourceDTO.type = ResourceType.videoUrl; widget.resourceDTO.type = ResourceType.audio;
}); });
break; break;
} }
@ -121,8 +123,25 @@ getContent(ResourceDTO resourceDTO, Function onFileUpload, Function onFileUpload
) )
); );
// Online Video // Audio local
tabsToShow.add( tabsToShow.add(
new Padding(
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 16),
child: UploadAudioContainer(
onChanged: (List<File> files) {
onFileUpload(files);
resourceDTO.type = ResourceType.audio;
},
onChangedWeb: (List<PlatformFile> files) {
onFileUploadWeb(files);
resourceDTO.type = ResourceType.audio;
},
),
)
);
// Online Video
/*tabsToShow.add(
new Padding( new Padding(
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 16), padding: EdgeInsets.symmetric(horizontal: 8, vertical: 16),
child: UploadOnlineResourceContainer( child: UploadOnlineResourceContainer(
@ -132,6 +151,6 @@ getContent(ResourceDTO resourceDTO, Function onFileUpload, Function onFileUpload
}, },
), ),
) )
); );*/
return tabsToShow; return tabsToShow;
} }

View File

@ -0,0 +1,204 @@
import 'dart:io';
import 'package:file_picker/file_picker.dart';
import 'package:manager_app/constants.dart';
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart' show kIsWeb;
class UploadAudioContainer extends StatefulWidget {
final ValueChanged<List<File>> onChanged;
final ValueChanged<List<PlatformFile>> onChangedWeb;
const UploadAudioContainer({
Key key,
this.onChanged,
this.onChangedWeb,
}) : super(key: key);
@override
_UploadAudioContainerState createState() => _UploadAudioContainerState();
}
class _UploadAudioContainerState extends State<UploadAudioContainer> with SingleTickerProviderStateMixin {
var filePath;
File fileToShow;
String fileToShowWeb;
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
return Container(
width: size.width *0.5,
height: size.height *0.5,
child: displayElement(),
);
}
String getFileName(filePath) {
return (filePath.toString().split('\\').last);
}
Future<void> filePicker() async {
FilePickerResult result;
if (kIsWeb) {
result = await FilePicker.platform.pickFiles(
type: FileType.custom,
dialogTitle: 'Sélectionner un fichier audio mp3',
allowMultiple: true,
allowedExtensions: ['mp3'],
);
if (result != null) {
List<PlatformFile> files = result.files;
setState(() {
filePath = "Fichiers"; // Only show one picture
fileToShowWeb = "Aucun aperçu possible"; // Only show one picture
widget.onChangedWeb(files);
});
}
} else {
result = await FilePicker.platform.pickFiles(
type: FileType.custom,
dialogTitle: 'Sélectionner un fichier audio mp3',
allowMultiple: true,
allowedExtensions: ['mp3'],
);
List<File> files = result.paths.map((path) => File(path)).toList();
var file = files[0];
setState(() {
filePath = file.path; // Only show one picture
fileToShow = file; // Only show one picture
widget.onChanged(files);
});
}
/*final file = OpenFilePicker()
..filterSpecification = {
'Images (*.jpg; *.jpeg;*.png)': '*.jpg;*.jpeg;*.png',
//'Video (*.mp4)': '*.mp4',
//'All Files': '*.*'
}
..defaultFilterIndex = 0
..title = 'Sélectionner un fichier';
final result = file.getFile();
if (result != null) {
setState(() {
filePath = result.path;
fileToShow = result;
widget.onChanged(result);
});
}*/
}
showFile() {
if (getFileName(filePath).contains(".mp4")) {
/*return FutureBuilder(
future: loadFile(fileToShow),
builder: (context, AsyncSnapshot<dynamic> snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return Container(
height: 300,
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");
} else {
return Center(
child: Container(
height: 200,
child: LoadingCommon()
)
);
}
}
);*/
} else {
if (kIsWeb) {
return null;
} else {
return Text("TODO player affiché ou pas ?");/*Image.file(
fileToShow,
height: 200,
fit:BoxFit.scaleDown
);*/
}
}
}
loadFile(File fileToShow) async {
//return await Media.file(fileToShow);
return null; // Useless no mp4 for now
}
displayElement() {
if (fileToShow == null && fileToShowWeb == null) return Center(
child: InkWell(
onTap: () async {
filePicker();
},
child: Container(
decoration: BoxDecoration(
color: kPrimaryColor,
borderRadius: BorderRadius.circular(15)
),
child: Padding(
padding: const EdgeInsets.only(left: 25.0, right: 25.0, top: 15.0, bottom: 15.0),
child: Text(
"Ajouter un ou plusieurs fichiers",
style: new TextStyle(color: kWhite),
),
)
),
),
);
if (fileToShow != null || fileToShowWeb != null)
return Container(
margin: EdgeInsets.all(8.0),
child: Card(
color: kBackgroundColor,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(8.0))),
child: InkWell(
onTap: () async {
filePicker();
},
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(8.0),
topRight: Radius.circular(8.0),
),
child: showFile()
),
ListTile(
title: Text(getFileName(filePath)),
subtitle: Text(filePath),
),
],
),
),
),
);
}
}

View File

@ -0,0 +1,27 @@
import 'package:managerapi/api.dart';
class ResourceTypeModel {
String label;
ResourceType type;
ResourceTypeModel({this.label, this.type});
factory ResourceTypeModel.fromJson(Map<String, dynamic> json) {
return new ResourceTypeModel(
label: json['label'] as String,
type: json['type'] as ResourceType,
);
}
Map<String, dynamic> toMap() {
return {
'label': label,
'type': type
};
}
@override
String toString() {
return '{label: $label, type: $type}';
}
}

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:manager_app/Components/audio_input_container.dart';
import 'package:manager_app/Components/check_input_container.dart'; import 'package:manager_app/Components/check_input_container.dart';
import 'package:manager_app/Components/multi_string_input_container.dart'; import 'package:manager_app/Components/multi_string_input_container.dart';
import 'package:manager_app/Screens/Configurations/Section/SubSection/Slider/listView_card_image.dart'; import 'package:manager_app/Screens/Configurations/Section/SubSection/Slider/listView_card_image.dart';
@ -77,7 +78,7 @@ class _ArticleConfigState extends State<ArticleConfig> {
mainAxisAlignment: MainAxisAlignment.spaceAround, mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [ children: [
MultiStringContainer( MultiStringContainer(
label: "Contenu affiché:", label: "Contenu affiché :",
modalLabel: "Contenu", modalLabel: "Contenu",
color: kPrimaryColor, color: kPrimaryColor,
initialValue: articleDTO != null ? articleDTO.content : [], initialValue: articleDTO != null ? articleDTO.content : [],
@ -104,6 +105,26 @@ class _ArticleConfigState extends State<ArticleConfig> {
}); });
}, },
), ),
AudioInputContainer(
label: "Audio :",
initialValue: articleDTO.audioId,
color: kPrimaryColor,
onChanged: (ResourceDTO resource) {
articleDTO.audioId = resource.id;
widget.onChanged(jsonEncode(articleDTO).toString());
},
),
CheckInputContainer(
label: "Lecture auto audio :",
isChecked: articleDTO.isReadAudioAuto,
onChanged: (value) {
setState(() {
//print(value);
articleDTO.isReadAudioAuto = value;
widget.onChanged(jsonEncode(articleDTO).toString());
});
},
),
], ],
), ),
), ),
@ -170,7 +191,7 @@ class _ArticleConfigState extends State<ArticleConfig> {
right: 15, right: 15,
child: InkWell( child: InkWell(
onTap: () async { onTap: () async {
var result = await showNewOrUpdateImageSlider(null, appContext, context, false, true); var result = await showNewOrUpdateImageSlider(null, appContext, context, true, false);
if (result != null) if (result != null)
{ {
setState(() { setState(() {

View File

@ -91,7 +91,7 @@ class _GeoPointImageListState extends State<GeoPointImageList> {
var result = await showSelectResourceModal( var result = await showSelectResourceModal(
"Sélectionner une ressource", "Sélectionner une ressource",
1, 1,
true, [ResourceType.image, ResourceType.imageUrl],
context context
); );
if (result != null) { if (result != null) {

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:manager_app/Components/audio_input_container.dart';
import 'package:manager_app/Components/confirmation_dialog.dart'; import 'package:manager_app/Components/confirmation_dialog.dart';
import 'package:manager_app/Components/fetch_section_icon.dart'; import 'package:manager_app/Components/fetch_section_icon.dart';
import 'package:manager_app/Components/image_input_container.dart'; import 'package:manager_app/Components/image_input_container.dart';

View File

@ -147,6 +147,13 @@ boxDecoration(ConfigurationDTO configurationDTO) {
color: configurationDTO.id == null ? kSuccess : kTextLightColor, color: configurationDTO.id == null ? kSuccess : kTextLightColor,
shape: BoxShape.rectangle, shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(25.0), borderRadius: BorderRadius.circular(25.0),
image: configurationDTO.imageSource != null ? new DecorationImage(
fit: BoxFit.cover,
colorFilter: new ColorFilter.mode(Colors.black.withOpacity(0.18), BlendMode.dstATop),
image: new NetworkImage(
configurationDTO.imageSource,
),
) : null,
boxShadow: [ boxShadow: [
BoxShadow( BoxShadow(
color: kSecond, color: kSecond,

View File

@ -11,6 +11,7 @@ import 'package:manager_app/Screens/login_screen.dart';
import 'package:manager_app/app_context.dart'; import 'package:manager_app/app_context.dart';
import 'package:manager_app/constants.dart'; import 'package:manager_app/constants.dart';
import 'package:manager_app/main.dart'; import 'package:manager_app/main.dart';
import 'package:managerapi/api.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -190,7 +191,13 @@ class _BodyState extends State<Body> {
case 'resources' : case 'resources' :
return Padding( return Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: ResourcesScreen() child: ResourcesScreen(
resourceTypes: [
ResourceType.audio,
ResourceType.image,
ResourceType.imageUrl
]
)
); );
break; break;
default: default:

View File

@ -16,8 +16,11 @@ getImageForResource(dynamic resourceDTO, AppContext appContext) {
fit:BoxFit.fill fit:BoxFit.fill
); );
break; break;
case ResourceType.audio:
return Text("Fichier audio - aucune visualisation possible");
break;
case ResourceType.video: case ResourceType.video:
return Text("THIS IS VIDEO LOCAL"); return Text("Vidéo locale - aucune visualisation possible");
break; break;
case ResourceType.videoUrl: case ResourceType.videoUrl:
return Text(resourceDTO.data); return Text(resourceDTO.data);

View File

@ -11,14 +11,14 @@ import 'package:provider/provider.dart';
class ResourceBodyGrid extends StatefulWidget { class ResourceBodyGrid extends StatefulWidget {
final List<ResourceDTO> resources; //return ResourceDTO final List<ResourceDTO> resources; //return ResourceDTO
final Function onSelect; final Function onSelect;
final bool isImage;
final bool isAddButton; final bool isAddButton;
final List<ResourceType> resourceTypesIn;
const ResourceBodyGrid({ const ResourceBodyGrid({
Key key, Key key,
this.resources, this.resources,
this.onSelect, this.onSelect,
this.isImage,
this.isAddButton, this.isAddButton,
this.resourceTypesIn,
}) : super(key: key); }) : super(key: key);
@override @override
@ -26,7 +26,8 @@ class ResourceBodyGrid extends StatefulWidget {
} }
class _ResourceBodyGridState extends State<ResourceBodyGrid> { class _ResourceBodyGridState extends State<ResourceBodyGrid> {
List<String> filterType; List<String> filterTypes;
List<String> currentFilterTypes;
String filterSearch = ''; String filterSearch = '';
List<String> selectedTypes; List<String> selectedTypes;
List<ResourceDTO> resourcesToShow; List<ResourceDTO> resourcesToShow;
@ -34,8 +35,9 @@ class _ResourceBodyGridState extends State<ResourceBodyGrid> {
@override @override
void initState() { void initState() {
resourcesToShow = widget.resources; resourcesToShow = widget.resources;
filterType = [resource_types[0], resource_types[1]];//, resource_types[2]]; // resource_types[3] currentFilterTypes = resource_types.where((rt) => widget.resourceTypesIn.contains(rt.type)).map((rt) => rt.label).toList();//, resource_types[2]]; // resource_types[3]
selectedTypes = resource_types; filterTypes = resource_types.where((rt) => widget.resourceTypesIn.contains(rt.type)).map((rt) => rt.label).toList();//, resource_types[2]]; // resource_types[3]
selectedTypes = resource_types.where((rt) => widget.resourceTypesIn.contains(rt.type)).map((rt) => rt.label).toList();
super.initState(); super.initState();
} }
@ -69,8 +71,8 @@ class _ResourceBodyGridState extends State<ResourceBodyGrid> {
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: MultiSelectContainer( child: MultiSelectContainer(
label: "Type :", label: "Type :",
initialValue: filterType, initialValue: filterTypes,
values: widget.isImage ? resource_types.where((type) => type != "video" && type != "video url").toList(): resource_types, values: currentFilterTypes,
isMultiple: true, isMultiple: true,
onChanged: (result) { onChanged: (result) {
setState(() { setState(() {
@ -181,31 +183,8 @@ class _ResourceBodyGridState extends State<ResourceBodyGrid> {
void filterResource() { void filterResource() {
resourcesToShow = filterSearch.isEmpty ? widget.resources: widget.resources.where((ResourceDTO resource) => resource.label.toUpperCase().contains(filterSearch.toUpperCase())).toList(); resourcesToShow = filterSearch.isEmpty ? widget.resources: widget.resources.where((ResourceDTO resource) => resource.label.toUpperCase().contains(filterSearch.toUpperCase())).toList();
var getTypesInSelected = resource_types.where((ft) => selectedTypes.contains(ft.label)).map((rt) => rt.type).toList();
resource_types.forEach((type) { resourcesToShow = resourcesToShow.where((resource) => getTypesInSelected.contains(resource.type)).toList();
switch(type) {
case "image":
if (!selectedTypes.contains(type)) {
resourcesToShow = resourcesToShow.where((resource) => resource.type != ResourceType.image).toList();
}
break;
case "image url":
if (!selectedTypes.contains(type)) {
resourcesToShow = resourcesToShow.where((resource) => resource.type != ResourceType.imageUrl).toList();
}
break;
case "video":
if (!selectedTypes.contains(type)) {
resourcesToShow = resourcesToShow.where((resource) => resource.type != ResourceType.video).toList();
}
break;
case "video url":
if (!selectedTypes.contains(type)) {
resourcesToShow = resourcesToShow.where((resource) => resource.type != ResourceType.videoUrl).toList();
}
break;
}
});
} }
} }
@ -214,7 +193,7 @@ boxDecoration(dynamic resourceDetailDTO, appContext) {
color: resourceDetailDTO.id == null ? kSuccess : kBackgroundColor, color: resourceDetailDTO.id == null ? kSuccess : kBackgroundColor,
shape: BoxShape.rectangle, shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(30.0), borderRadius: BorderRadius.circular(30.0),
image: resourceDetailDTO.id != null && resourceDetailDTO.type != ResourceType.videoUrl ? new DecorationImage( image: resourceDetailDTO.id != null && (resourceDetailDTO.type == ResourceType.image || resourceDetailDTO.type == ResourceType.imageUrl) ? new DecorationImage(
fit: BoxFit.cover, fit: BoxFit.cover,
colorFilter: new ColorFilter.mode(Colors.black.withOpacity(0.3), BlendMode.dstATop), colorFilter: new ColorFilter.mode(Colors.black.withOpacity(0.3), BlendMode.dstATop),
image: new NetworkImage( image: new NetworkImage(

View File

@ -18,11 +18,15 @@ class ResourcesScreen extends StatefulWidget {
final Function onGetResult; //return ResourceDTO final Function onGetResult; //return ResourceDTO
final bool isImage; final bool isImage;
final bool isAddButton; final bool isAddButton;
final bool isFilter;
final List<ResourceType> resourceTypes;
const ResourcesScreen({ const ResourcesScreen({
Key key, Key key,
this.isImage = false, this.isImage = false,
this.onGetResult, this.onGetResult,
this.isAddButton = true, this.isAddButton = true,
this.resourceTypes,
this.isFilter = true
}) : super(key: key); }) : super(key: key);
@override @override
@ -39,13 +43,13 @@ class _ResourcesScreenState extends State<ResourcesScreen> {
Size size = MediaQuery.of(context).size; Size size = MediaQuery.of(context).size;
return FutureBuilder( return FutureBuilder(
future: getResources(widget.onGetResult, widget.isImage, appContext), future: getResources(widget.onGetResult, widget.isImage, appContext, widget.resourceTypes),
builder: (context, AsyncSnapshot<dynamic> snapshot) { builder: (context, AsyncSnapshot<dynamic> snapshot) {
if (snapshot.connectionState == ConnectionState.done) { if (snapshot.connectionState == ConnectionState.done) {
if(snapshot.data != null) { if(snapshot.data != null) {
var tempOutput = new List<ResourceDTO>.from(snapshot.data); var tempOutput = new List<ResourceDTO>.from(snapshot.data);
// tempOutput.add(ResourceDTO(id: null)); // tempOutput.add(ResourceDTO(id: null));
return ResourceBodyGrid(resources: tempOutput, isImage: widget.isImage, isAddButton: widget.isAddButton, onSelect: (value) async { return ResourceBodyGrid(resources: tempOutput, resourceTypesIn: widget.isImage ? resource_types.where((rt) => rt.type == ResourceType.image || rt.type == ResourceType.imageUrl).map((rt) => rt.type).toList() : widget.resourceTypes, isAddButton: widget.isAddButton, onSelect: (value) async {
if (widget.onGetResult == null) { if (widget.onGetResult == null) {
// Main screen // Main screen
if (value.id == null) { if (value.id == null) {
@ -81,8 +85,9 @@ class _ResourcesScreenState extends State<ResourcesScreen> {
} }
} }
Future<void> getResources(Function onGetResult, bool isImage, AppContext appContext) async { Future<void> getResources(Function onGetResult, bool isImage, AppContext appContext, List<ResourceType> types) async {
List<ResourceDTO> resources = await (appContext.getContext() as ManagerAppContext).clientAPI.resourceApi.resourceGet(instanceId: (appContext.getContext() as ManagerAppContext).instanceId); types = types != null ? types : [];
List<ResourceDTO> resources = await (appContext.getContext() as ManagerAppContext).clientAPI.resourceApi.resourceGet(instanceId: (appContext.getContext() as ManagerAppContext).instanceId, types: types);
if (onGetResult != null && isImage) { if (onGetResult != null && isImage) {
resources = resources.where((element) => element.type == ResourceType.image || element.type == ResourceType.imageUrl || element.type == ResourceType.audio).toList(); resources = resources.where((element) => element.type == ResourceType.image || element.type == ResourceType.imageUrl || element.type == ResourceType.audio).toList();
} }
@ -91,6 +96,7 @@ Future<void> getResources(Function onGetResult, bool isImage, AppContext appCont
Future<ResourceDTO> create(ResourceDTO resourceDTO, List<File> files, List<PlatformFile> filesWeb, AppContext appContext, context) async { Future<ResourceDTO> create(ResourceDTO resourceDTO, List<File> files, List<PlatformFile> filesWeb, AppContext appContext, context) async {
switch(resourceDTO.type) { switch(resourceDTO.type) {
case ResourceType.audio:
case ResourceType.image: case ResourceType.image:
case ResourceType.video: case ResourceType.video:
@ -122,7 +128,7 @@ Future<ResourceDTO> create(ResourceDTO resourceDTO, List<File> files, List<Platf
ManagerAppContext managerAppContext = appContext.getContext(); ManagerAppContext managerAppContext = appContext.getContext();
request.headers["authorization"]="Bearer ${managerAppContext.token.accessToken}"; request.headers["authorization"]="Bearer ${managerAppContext.token.accessToken}";
request.fields['label'] = resourceDTO.label; request.fields['label'] = resourceDTO.label;
request.fields['type'] = ResourceType.image.toString(); request.fields['type'] = resourceDTO.type.toString();
request.fields['instanceId'] = managerAppContext.instanceId; request.fields['instanceId'] = managerAppContext.instanceId;
var res = await request.send(); var res = await request.send();

View File

@ -5,7 +5,7 @@ import 'package:manager_app/Screens/Resources/resources_screen.dart';
import 'package:manager_app/constants.dart'; import 'package:manager_app/constants.dart';
import 'package:managerapi/api.dart'; import 'package:managerapi/api.dart';
dynamic showSelectResourceModal (String text, int maxLines, bool onlyImage, BuildContext mainContext) async { /*Function onSelect,*/ dynamic showSelectResourceModal (String text, int maxLines, List<ResourceType> resourceTypes, BuildContext mainContext) async { /*Function onSelect,*/
Size size = MediaQuery.of(mainContext).size; Size size = MediaQuery.of(mainContext).size;
var result = await showDialog( var result = await showDialog(
@ -28,7 +28,7 @@ dynamic showSelectResourceModal (String text, int maxLines, bool onlyImage, Buil
Navigator.pop(context, result); Navigator.pop(context, result);
} }
}, },
isImage: onlyImage, resourceTypes: resourceTypes,
), ),
), ),
], ],

View File

@ -25,7 +25,7 @@ void showResource(ResourceDTO resourceDTO, AppContext appContext, BuildContext c
style: new TextStyle(fontSize: 25, fontWeight: FontWeight.w400)), style: new TextStyle(fontSize: 25, fontWeight: FontWeight.w400)),
), ),
Container( Container(
height: size.height *0.6, height: size.height *0.5,
child: Center( child: Center(
child: Container( child: Container(
decoration: BoxDecoration( decoration: BoxDecoration(
@ -46,7 +46,9 @@ void showResource(ResourceDTO resourceDTO, AppContext appContext, BuildContext c
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceAround, mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [ children: [
Align( Padding(
padding: const EdgeInsets.all(8.0),
child: Align(
alignment: AlignmentDirectional.bottomEnd, alignment: AlignmentDirectional.bottomEnd,
child: Container( child: Container(
width: 175, width: 175,
@ -62,7 +64,10 @@ void showResource(ResourceDTO resourceDTO, AppContext appContext, BuildContext c
), ),
), ),
), ),
Align( ),
Padding(
padding: const EdgeInsets.all(8.0),
child: Align(
alignment: AlignmentDirectional.bottomEnd, alignment: AlignmentDirectional.bottomEnd,
child: Container( child: Container(
width: 200, width: 200,
@ -79,6 +84,7 @@ void showResource(ResourceDTO resourceDTO, AppContext appContext, BuildContext c
), ),
), ),
), ),
),
], ],
), ),
], ],

View File

@ -1,4 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:manager_app/Models/resourceTypeModel.dart';
import 'package:managerapi/api.dart';
// Colors - TO FILL WIT CORRECT COLOR // Colors - TO FILL WIT CORRECT COLOR
//const kBackgroundColor = Color(0xFFFFFFFF); //const kBackgroundColor = Color(0xFFFFFFFF);
@ -17,7 +19,11 @@ const kSuccess = Color(0xFF8bc34a);
const List<String> section_types = ["Map", "Slider", "Video", "Web", "Menu", "Quizz", "Article"]; const List<String> section_types = ["Map", "Slider", "Video", "Web", "Menu", "Quizz", "Article"];
const List<String> map_types = ["none", "normal", "satellite", "terrain", "hybrid"]; const List<String> map_types = ["none", "normal", "satellite", "terrain", "hybrid"];
const List<String> languages = ["FR", "NL", "EN", "DE", "IT", "ES", "CN", "PL"]; const List<String> languages = ["FR", "NL", "EN", "DE", "IT", "ES", "CN", "PL"];
const List<String> resource_types = ["image", "image url"]; // "video url" , "video", List<ResourceTypeModel> resource_types = [
ResourceTypeModel(label: "image", type: ResourceType.image),
ResourceTypeModel(label: "image url", type: ResourceType.imageUrl),
ResourceTypeModel(label: "audio", type: ResourceType.audio)
]; // "video url" , "video", {"label": "image"}, "image url", "audio"
/* /*
const kTextStyle = TextStyle( const kTextStyle = TextStyle(

View File

@ -5,6 +5,10 @@
import FlutterMacOS import FlutterMacOS
import Foundation import Foundation
import audioplayers
import path_provider_macos
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
AudioplayersPlugin.register(with: registry.registrar(forPlugin: "AudioplayersPlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
} }

View File

@ -105,7 +105,7 @@ Name | Type | Description | Notes
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
# **resourceGet** # **resourceGet**
> List<ResourceDTO> resourceGet(instanceId) > List<ResourceDTO> resourceGet(instanceId, types)
@ -117,9 +117,10 @@ import 'package:managerapi/api.dart';
final api_instance = ResourceApi(); final api_instance = ResourceApi();
final instanceId = instanceId_example; // String | final instanceId = instanceId_example; // String |
final types = []; // List<ResourceType> |
try { try {
final result = api_instance.resourceGet(instanceId); final result = api_instance.resourceGet(instanceId, types);
print(result); print(result);
} catch (e) { } catch (e) {
print('Exception when calling ResourceApi->resourceGet: $e\n'); print('Exception when calling ResourceApi->resourceGet: $e\n');
@ -131,6 +132,7 @@ try {
Name | Type | Description | Notes Name | Type | Description | Notes
------------- | ------------- | ------------- | ------------- ------------- | ------------- | ------------- | -------------
**instanceId** | **String**| | [optional] **instanceId** | **String**| | [optional]
**types** | [**List<ResourceType>**](ResourceType.md)| | [optional] [default to const []]
### Return type ### Return type

View File

@ -11,8 +11,8 @@ Name | Type | Description | Notes
**id** | **String** | | [optional] **id** | **String** | | [optional]
**type** | [**ResourceType**](ResourceType.md) | | [optional] **type** | [**ResourceType**](ResourceType.md) | | [optional]
**label** | **String** | | [optional] **label** | **String** | | [optional]
**dateCreation** | [**DateTime**](DateTime.md) | | [optional]
**data** | **String** | | [optional] **data** | **String** | | [optional]
**dateCreation** | [**DateTime**](DateTime.md) | | [optional]
**instanceId** | **String** | | [optional] **instanceId** | **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) [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)

View File

@ -146,7 +146,9 @@ class ResourceApi {
/// Parameters: /// Parameters:
/// ///
/// * [String] instanceId: /// * [String] instanceId:
Future<Response> resourceGetWithHttpInfo({ String instanceId }) async { ///
/// * [List<ResourceType>] types:
Future<Response> resourceGetWithHttpInfo({ String instanceId, List<ResourceType> types }) async {
// Verify required params are set. // Verify required params are set.
final path = r'/api/Resource'; final path = r'/api/Resource';
@ -160,6 +162,9 @@ class ResourceApi {
if (instanceId != null) { if (instanceId != null) {
queryParams.addAll(_convertParametersForCollectionFormat('', 'instanceId', instanceId)); queryParams.addAll(_convertParametersForCollectionFormat('', 'instanceId', instanceId));
} }
if (types != null) {
queryParams.addAll(_convertParametersForCollectionFormat('multi', 'types', types));
}
final contentTypes = <String>[]; final contentTypes = <String>[];
final nullableContentType = contentTypes.isNotEmpty ? contentTypes[0] : null; final nullableContentType = contentTypes.isNotEmpty ? contentTypes[0] : null;
@ -192,8 +197,10 @@ class ResourceApi {
/// Parameters: /// Parameters:
/// ///
/// * [String] instanceId: /// * [String] instanceId:
Future<List<ResourceDTO>> resourceGet({ String instanceId }) async { ///
final response = await resourceGetWithHttpInfo( instanceId: instanceId ); /// * [List<ResourceType>] types:
Future<List<ResourceDTO>> resourceGet({ String instanceId, List<ResourceType> types }) async {
final response = await resourceGetWithHttpInfo( instanceId: instanceId, types: types );
if (response.statusCode >= HttpStatus.badRequest) { if (response.statusCode >= HttpStatus.badRequest) {
throw ApiException(response.statusCode, _decodeBodyBytes(response)); throw ApiException(response.statusCode, _decodeBodyBytes(response));
} }

View File

@ -676,6 +676,16 @@ paths:
type: string type: string
nullable: true nullable: true
x-position: 1 x-position: 1
- name: types
in: query
style: form
explode: true
schema:
type: array
nullable: true
items:
$ref: '#/components/schemas/ResourceType'
x-position: 2
responses: responses:
'200': '200':
description: '' description: ''
@ -1756,12 +1766,12 @@ components:
label: label:
type: string type: string
nullable: true nullable: true
dateCreation:
type: string
format: date-time
data: data:
type: string type: string
nullable: true nullable: true
dateCreation:
type: string
format: date-time
instanceId: instanceId:
type: string type: string
nullable: true nullable: true
@ -1772,16 +1782,19 @@ components:
1 = Video 1 = Video
2 = ImageUrl 2 = ImageUrl
3 = VideoUrl 3 = VideoUrl
4 = Audio
x-enumNames: x-enumNames:
- Image - Image
- Video - Video
- ImageUrl - ImageUrl
- VideoUrl - VideoUrl
- Audio
enum: enum:
- 0 - 0
- 1 - 1
- 2 - 2
- 3 - 3
- 4
DeviceDTO: DeviceDTO:
type: object type: object
additionalProperties: false additionalProperties: false

View File

@ -29,6 +29,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.8.2" version: "2.8.2"
audioplayers:
dependency: "direct main"
description:
name: audioplayers
url: "https://pub.dartlang.org"
source: hosted
version: "0.18.3"
auto_size_text: auto_size_text:
dependency: "direct main" dependency: "direct main"
description: description:
@ -134,6 +141,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.2.1" version: "1.2.1"
file:
dependency: transitive
description:
name: file
url: "https://pub.dartlang.org"
source: hosted
version: "6.1.4"
file_picker: file_picker:
dependency: "direct main" dependency: "direct main"
description: description:
@ -296,6 +310,55 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.2.1" version: "0.2.1"
path_provider:
dependency: transitive
description:
name: path_provider
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.11"
path_provider_android:
dependency: transitive
description:
name: path_provider_android
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.20"
path_provider_ios:
dependency: transitive
description:
name: path_provider_ios
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.11"
path_provider_linux:
dependency: transitive
description:
name: path_provider_linux
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.7"
path_provider_macos:
dependency: transitive
description:
name: path_provider_macos
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.6"
path_provider_platform_interface:
dependency: transitive
description:
name: path_provider_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.5"
path_provider_windows:
dependency: transitive
description:
name: path_provider_windows
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.7"
pdf: pdf:
dependency: "direct main" dependency: "direct main"
description: description:
@ -317,6 +380,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "4.4.0" version: "4.4.0"
platform:
dependency: transitive
description:
name: platform
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.0"
plugin_platform_interface: plugin_platform_interface:
dependency: transitive dependency: transitive
description: description:
@ -331,6 +401,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.6.0" version: "3.6.0"
process:
dependency: transitive
description:
name: process
url: "https://pub.dartlang.org"
source: hosted
version: "4.2.4"
provider: provider:
dependency: "direct main" dependency: "direct main"
description: description:
@ -413,6 +490,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.3.0" version: "1.3.0"
uuid:
dependency: transitive
description:
name: uuid
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.6"
vector_math: vector_math:
dependency: transitive dependency: transitive
description: description:
@ -462,6 +546,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.5.2" version: "2.5.2"
xdg_directories:
dependency: transitive
description:
name: xdg_directories
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.0+2"
xml: xml:
dependency: transitive dependency: transitive
description: description:

View File

@ -41,6 +41,7 @@ dependencies:
#path_provider: ^2.0.2 #path_provider: ^2.0.2
encrypt: ^5.0.0 encrypt: ^5.0.0
qr_flutter: ^4.0.0 qr_flutter: ^4.0.0
audioplayers: 0.18.3
pdf: ^3.6.0 pdf: ^3.6.0
multi_select_flutter: ^4.1.2 multi_select_flutter: ^4.1.2
#msix: ^2.1.3 #msix: ^2.1.3