Add audio in web + update code for resource ..
This commit is contained in:
parent
ddda68c911
commit
eddc4005ae
165
lib/Components/audio_input_container.dart
Normal file
165
lib/Components/audio_input_container.dart
Normal 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
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
105
lib/Components/audio_player.dart
Normal file
105
lib/Components/audio_player.dart
Normal 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(),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}*/
|
||||
@ -9,6 +9,9 @@ IconData getResourceIcon(elementType) {
|
||||
case ResourceType.imageUrl:
|
||||
return Icons.image_search; // art_track
|
||||
break;
|
||||
case ResourceType.audio:
|
||||
return Icons.audiotrack; // art_track
|
||||
break;
|
||||
case ResourceType.video:
|
||||
return Icons.slow_motion_video;
|
||||
break;
|
||||
|
||||
@ -67,7 +67,7 @@ class _ImageInputContainerState extends State<ImageInputContainer> {
|
||||
var result = await showSelectResourceModal(
|
||||
"Sélectionner une ressource",
|
||||
1,
|
||||
true,
|
||||
[ResourceType.image, ResourceType.imageUrl],
|
||||
context
|
||||
);
|
||||
|
||||
|
||||
@ -2,6 +2,7 @@ import 'dart:io';
|
||||
|
||||
import 'package:file_picker/file_picker.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_online_resources_container.dart';
|
||||
import 'package:manager_app/constants.dart';
|
||||
@ -29,7 +30,8 @@ class _ResourceTabState extends State<ResourceTab> with SingleTickerProviderStat
|
||||
void initState() {
|
||||
tabsToShow.add(new Tab(text: "Image local"));
|
||||
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.addListener(_handleTabSelection);
|
||||
@ -81,7 +83,7 @@ class _ResourceTabState extends State<ResourceTab> with SingleTickerProviderStat
|
||||
case 2:
|
||||
setState(() {
|
||||
widget.resourceDTO.data = null;
|
||||
widget.resourceDTO.type = ResourceType.videoUrl;
|
||||
widget.resourceDTO.type = ResourceType.audio;
|
||||
});
|
||||
break;
|
||||
}
|
||||
@ -121,8 +123,25 @@ getContent(ResourceDTO resourceDTO, Function onFileUpload, Function onFileUpload
|
||||
)
|
||||
);
|
||||
|
||||
// Online Video
|
||||
// Audio local
|
||||
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(
|
||||
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 16),
|
||||
child: UploadOnlineResourceContainer(
|
||||
@ -132,6 +151,6 @@ getContent(ResourceDTO resourceDTO, Function onFileUpload, Function onFileUpload
|
||||
},
|
||||
),
|
||||
)
|
||||
);
|
||||
);*/
|
||||
return tabsToShow;
|
||||
}
|
||||
204
lib/Components/upload_audio_container.dart
Normal file
204
lib/Components/upload_audio_container.dart
Normal 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),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
27
lib/Models/resourceTypeModel.dart
Normal file
27
lib/Models/resourceTypeModel.dart
Normal 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}';
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,5 @@
|
||||
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/multi_string_input_container.dart';
|
||||
import 'package:manager_app/Screens/Configurations/Section/SubSection/Slider/listView_card_image.dart';
|
||||
@ -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,
|
||||
child: InkWell(
|
||||
onTap: () async {
|
||||
var result = await showNewOrUpdateImageSlider(null, appContext, context, false, true);
|
||||
var result = await showNewOrUpdateImageSlider(null, appContext, context, true, false);
|
||||
if (result != null)
|
||||
{
|
||||
setState(() {
|
||||
|
||||
@ -91,7 +91,7 @@ class _GeoPointImageListState extends State<GeoPointImageList> {
|
||||
var result = await showSelectResourceModal(
|
||||
"Sélectionner une ressource",
|
||||
1,
|
||||
true,
|
||||
[ResourceType.image, ResourceType.imageUrl],
|
||||
context
|
||||
);
|
||||
if (result != null) {
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
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/fetch_section_icon.dart';
|
||||
import 'package:manager_app/Components/image_input_container.dart';
|
||||
|
||||
@ -147,6 +147,13 @@ boxDecoration(ConfigurationDTO configurationDTO) {
|
||||
color: configurationDTO.id == null ? kSuccess : kTextLightColor,
|
||||
shape: BoxShape.rectangle,
|
||||
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(
|
||||
color: kSecond,
|
||||
|
||||
@ -11,6 +11,7 @@ import 'package:manager_app/Screens/login_screen.dart';
|
||||
import 'package:manager_app/app_context.dart';
|
||||
import 'package:manager_app/constants.dart';
|
||||
import 'package:manager_app/main.dart';
|
||||
import 'package:managerapi/api.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
|
||||
@ -190,7 +191,13 @@ class _BodyState extends State<Body> {
|
||||
case 'resources' :
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: ResourcesScreen()
|
||||
child: ResourcesScreen(
|
||||
resourceTypes: [
|
||||
ResourceType.audio,
|
||||
ResourceType.image,
|
||||
ResourceType.imageUrl
|
||||
]
|
||||
)
|
||||
);
|
||||
break;
|
||||
default:
|
||||
|
||||
@ -16,8 +16,11 @@ getImageForResource(dynamic resourceDTO, AppContext appContext) {
|
||||
fit:BoxFit.fill
|
||||
);
|
||||
break;
|
||||
case ResourceType.audio:
|
||||
return Text("Fichier audio - aucune visualisation possible");
|
||||
break;
|
||||
case ResourceType.video:
|
||||
return Text("THIS IS VIDEO LOCAL");
|
||||
return Text("Vidéo locale - aucune visualisation possible");
|
||||
break;
|
||||
case ResourceType.videoUrl:
|
||||
return Text(resourceDTO.data);
|
||||
|
||||
@ -11,14 +11,14 @@ import 'package:provider/provider.dart';
|
||||
class ResourceBodyGrid extends StatefulWidget {
|
||||
final List<ResourceDTO> resources; //return ResourceDTO
|
||||
final Function onSelect;
|
||||
final bool isImage;
|
||||
final bool isAddButton;
|
||||
final List<ResourceType> resourceTypesIn;
|
||||
const ResourceBodyGrid({
|
||||
Key key,
|
||||
this.resources,
|
||||
this.onSelect,
|
||||
this.isImage,
|
||||
this.isAddButton,
|
||||
this.resourceTypesIn,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
@ -26,7 +26,8 @@ class ResourceBodyGrid extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _ResourceBodyGridState extends State<ResourceBodyGrid> {
|
||||
List<String> filterType;
|
||||
List<String> filterTypes;
|
||||
List<String> currentFilterTypes;
|
||||
String filterSearch = '';
|
||||
List<String> selectedTypes;
|
||||
List<ResourceDTO> resourcesToShow;
|
||||
@ -34,8 +35,9 @@ class _ResourceBodyGridState extends State<ResourceBodyGrid> {
|
||||
@override
|
||||
void initState() {
|
||||
resourcesToShow = widget.resources;
|
||||
filterType = [resource_types[0], resource_types[1]];//, resource_types[2]]; // resource_types[3]
|
||||
selectedTypes = resource_types;
|
||||
currentFilterTypes = resource_types.where((rt) => widget.resourceTypesIn.contains(rt.type)).map((rt) => rt.label).toList();//, resource_types[2]]; // resource_types[3]
|
||||
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();
|
||||
}
|
||||
|
||||
@ -69,8 +71,8 @@ class _ResourceBodyGridState extends State<ResourceBodyGrid> {
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: MultiSelectContainer(
|
||||
label: "Type :",
|
||||
initialValue: filterType,
|
||||
values: widget.isImage ? resource_types.where((type) => type != "video" && type != "video url").toList(): resource_types,
|
||||
initialValue: filterTypes,
|
||||
values: currentFilterTypes,
|
||||
isMultiple: true,
|
||||
onChanged: (result) {
|
||||
setState(() {
|
||||
@ -181,31 +183,8 @@ class _ResourceBodyGridState extends State<ResourceBodyGrid> {
|
||||
|
||||
void filterResource() {
|
||||
resourcesToShow = filterSearch.isEmpty ? widget.resources: widget.resources.where((ResourceDTO resource) => resource.label.toUpperCase().contains(filterSearch.toUpperCase())).toList();
|
||||
|
||||
resource_types.forEach((type) {
|
||||
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;
|
||||
}
|
||||
});
|
||||
var getTypesInSelected = resource_types.where((ft) => selectedTypes.contains(ft.label)).map((rt) => rt.type).toList();
|
||||
resourcesToShow = resourcesToShow.where((resource) => getTypesInSelected.contains(resource.type)).toList();
|
||||
}
|
||||
}
|
||||
|
||||
@ -214,7 +193,7 @@ boxDecoration(dynamic resourceDetailDTO, appContext) {
|
||||
color: resourceDetailDTO.id == null ? kSuccess : kBackgroundColor,
|
||||
shape: BoxShape.rectangle,
|
||||
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,
|
||||
colorFilter: new ColorFilter.mode(Colors.black.withOpacity(0.3), BlendMode.dstATop),
|
||||
image: new NetworkImage(
|
||||
|
||||
@ -18,11 +18,15 @@ class ResourcesScreen extends StatefulWidget {
|
||||
final Function onGetResult; //return ResourceDTO
|
||||
final bool isImage;
|
||||
final bool isAddButton;
|
||||
final bool isFilter;
|
||||
final List<ResourceType> resourceTypes;
|
||||
const ResourcesScreen({
|
||||
Key key,
|
||||
this.isImage = false,
|
||||
this.onGetResult,
|
||||
this.isAddButton = true,
|
||||
this.resourceTypes,
|
||||
this.isFilter = true
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
@ -39,13 +43,13 @@ class _ResourcesScreenState extends State<ResourcesScreen> {
|
||||
Size size = MediaQuery.of(context).size;
|
||||
|
||||
return FutureBuilder(
|
||||
future: getResources(widget.onGetResult, widget.isImage, appContext),
|
||||
future: getResources(widget.onGetResult, widget.isImage, appContext, widget.resourceTypes),
|
||||
builder: (context, AsyncSnapshot<dynamic> snapshot) {
|
||||
if (snapshot.connectionState == ConnectionState.done) {
|
||||
if(snapshot.data != null) {
|
||||
var tempOutput = new List<ResourceDTO>.from(snapshot.data);
|
||||
// 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) {
|
||||
// Main screen
|
||||
if (value.id == null) {
|
||||
@ -81,8 +85,9 @@ class _ResourcesScreenState extends State<ResourcesScreen> {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> getResources(Function onGetResult, bool isImage, AppContext appContext) async {
|
||||
List<ResourceDTO> resources = await (appContext.getContext() as ManagerAppContext).clientAPI.resourceApi.resourceGet(instanceId: (appContext.getContext() as ManagerAppContext).instanceId);
|
||||
Future<void> getResources(Function onGetResult, bool isImage, AppContext appContext, List<ResourceType> types) async {
|
||||
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) {
|
||||
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 {
|
||||
switch(resourceDTO.type) {
|
||||
case ResourceType.audio:
|
||||
case ResourceType.image:
|
||||
case ResourceType.video:
|
||||
|
||||
@ -122,7 +128,7 @@ Future<ResourceDTO> create(ResourceDTO resourceDTO, List<File> files, List<Platf
|
||||
ManagerAppContext managerAppContext = appContext.getContext();
|
||||
request.headers["authorization"]="Bearer ${managerAppContext.token.accessToken}";
|
||||
request.fields['label'] = resourceDTO.label;
|
||||
request.fields['type'] = ResourceType.image.toString();
|
||||
request.fields['type'] = resourceDTO.type.toString();
|
||||
request.fields['instanceId'] = managerAppContext.instanceId;
|
||||
|
||||
var res = await request.send();
|
||||
|
||||
@ -5,7 +5,7 @@ import 'package:manager_app/Screens/Resources/resources_screen.dart';
|
||||
import 'package:manager_app/constants.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;
|
||||
|
||||
var result = await showDialog(
|
||||
@ -28,7 +28,7 @@ dynamic showSelectResourceModal (String text, int maxLines, bool onlyImage, Buil
|
||||
Navigator.pop(context, result);
|
||||
}
|
||||
},
|
||||
isImage: onlyImage,
|
||||
resourceTypes: resourceTypes,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
@ -25,7 +25,7 @@ void showResource(ResourceDTO resourceDTO, AppContext appContext, BuildContext c
|
||||
style: new TextStyle(fontSize: 25, fontWeight: FontWeight.w400)),
|
||||
),
|
||||
Container(
|
||||
height: size.height *0.6,
|
||||
height: size.height *0.5,
|
||||
child: Center(
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
@ -46,7 +46,9 @@ void showResource(ResourceDTO resourceDTO, AppContext appContext, BuildContext c
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
Align(
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Align(
|
||||
alignment: AlignmentDirectional.bottomEnd,
|
||||
child: Container(
|
||||
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,
|
||||
child: Container(
|
||||
width: 200,
|
||||
@ -79,6 +84,7 @@ void showResource(ResourceDTO resourceDTO, AppContext appContext, BuildContext c
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:manager_app/Models/resourceTypeModel.dart';
|
||||
import 'package:managerapi/api.dart';
|
||||
|
||||
// Colors - TO FILL WIT CORRECT COLOR
|
||||
//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> map_types = ["none", "normal", "satellite", "terrain", "hybrid"];
|
||||
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(
|
||||
|
||||
@ -5,6 +5,10 @@
|
||||
import FlutterMacOS
|
||||
import Foundation
|
||||
|
||||
import audioplayers
|
||||
import path_provider_macos
|
||||
|
||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||
AudioplayersPlugin.register(with: registry.registrar(forPlugin: "AudioplayersPlugin"))
|
||||
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||
}
|
||||
|
||||
@ -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)
|
||||
|
||||
# **resourceGet**
|
||||
> List<ResourceDTO> resourceGet(instanceId)
|
||||
> List<ResourceDTO> resourceGet(instanceId, types)
|
||||
|
||||
|
||||
|
||||
@ -117,9 +117,10 @@ import 'package:managerapi/api.dart';
|
||||
|
||||
final api_instance = ResourceApi();
|
||||
final instanceId = instanceId_example; // String |
|
||||
final types = []; // List<ResourceType> |
|
||||
|
||||
try {
|
||||
final result = api_instance.resourceGet(instanceId);
|
||||
final result = api_instance.resourceGet(instanceId, types);
|
||||
print(result);
|
||||
} catch (e) {
|
||||
print('Exception when calling ResourceApi->resourceGet: $e\n');
|
||||
@ -131,6 +132,7 @@ try {
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**instanceId** | **String**| | [optional]
|
||||
**types** | [**List<ResourceType>**](ResourceType.md)| | [optional] [default to const []]
|
||||
|
||||
### Return type
|
||||
|
||||
|
||||
@ -11,8 +11,8 @@ Name | Type | Description | Notes
|
||||
**id** | **String** | | [optional]
|
||||
**type** | [**ResourceType**](ResourceType.md) | | [optional]
|
||||
**label** | **String** | | [optional]
|
||||
**dateCreation** | [**DateTime**](DateTime.md) | | [optional]
|
||||
**data** | **String** | | [optional]
|
||||
**dateCreation** | [**DateTime**](DateTime.md) | | [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)
|
||||
|
||||
@ -146,7 +146,9 @@ class ResourceApi {
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [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.
|
||||
|
||||
final path = r'/api/Resource';
|
||||
@ -160,6 +162,9 @@ class ResourceApi {
|
||||
if (instanceId != null) {
|
||||
queryParams.addAll(_convertParametersForCollectionFormat('', 'instanceId', instanceId));
|
||||
}
|
||||
if (types != null) {
|
||||
queryParams.addAll(_convertParametersForCollectionFormat('multi', 'types', types));
|
||||
}
|
||||
|
||||
final contentTypes = <String>[];
|
||||
final nullableContentType = contentTypes.isNotEmpty ? contentTypes[0] : null;
|
||||
@ -192,8 +197,10 @@ class ResourceApi {
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [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) {
|
||||
throw ApiException(response.statusCode, _decodeBodyBytes(response));
|
||||
}
|
||||
|
||||
@ -676,6 +676,16 @@ paths:
|
||||
type: string
|
||||
nullable: true
|
||||
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:
|
||||
'200':
|
||||
description: ''
|
||||
@ -1756,12 +1766,12 @@ components:
|
||||
label:
|
||||
type: string
|
||||
nullable: true
|
||||
dateCreation:
|
||||
type: string
|
||||
format: date-time
|
||||
data:
|
||||
type: string
|
||||
nullable: true
|
||||
dateCreation:
|
||||
type: string
|
||||
format: date-time
|
||||
instanceId:
|
||||
type: string
|
||||
nullable: true
|
||||
@ -1772,16 +1782,19 @@ components:
|
||||
1 = Video
|
||||
2 = ImageUrl
|
||||
3 = VideoUrl
|
||||
4 = Audio
|
||||
x-enumNames:
|
||||
- Image
|
||||
- Video
|
||||
- ImageUrl
|
||||
- VideoUrl
|
||||
- Audio
|
||||
enum:
|
||||
- 0
|
||||
- 1
|
||||
- 2
|
||||
- 3
|
||||
- 4
|
||||
DeviceDTO:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
|
||||
91
pubspec.lock
91
pubspec.lock
@ -29,6 +29,13 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
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:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -134,6 +141,13 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.1"
|
||||
file:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "6.1.4"
|
||||
file_picker:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -296,6 +310,55 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
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:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -317,6 +380,13 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.4.0"
|
||||
platform:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: platform
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.1.0"
|
||||
plugin_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -331,6 +401,13 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.6.0"
|
||||
process:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: process
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.2.4"
|
||||
provider:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -413,6 +490,13 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.0"
|
||||
uuid:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: uuid
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.0.6"
|
||||
vector_math:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -462,6 +546,13 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
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:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
||||
@ -41,6 +41,7 @@ dependencies:
|
||||
#path_provider: ^2.0.2
|
||||
encrypt: ^5.0.0
|
||||
qr_flutter: ^4.0.0
|
||||
audioplayers: 0.18.3
|
||||
pdf: ^3.6.0
|
||||
multi_select_flutter: ^4.1.2
|
||||
#msix: ^2.1.3
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user