upload multiple files Windows and Web + if web no remember me

This commit is contained in:
Thomas Fransolet 2021-12-23 13:48:46 +01:00
parent 6b2c74424a
commit 54091ea2db
6 changed files with 112 additions and 54 deletions

View File

@ -1,5 +1,6 @@
import 'dart:io'; import 'dart:io';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.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';
@ -8,10 +9,12 @@ import 'package:managerapi/api.dart';
class ResourceTab extends StatefulWidget { class ResourceTab extends StatefulWidget {
final ResourceDTO resourceDTO; final ResourceDTO resourceDTO;
final Function onFileUpload; final Function onFileUpload;
final Function onFileUploadWeb;
const ResourceTab({ const ResourceTab({
Key key, Key key,
this.resourceDTO, this.resourceDTO,
this.onFileUpload, this.onFileUpload,
this.onFileUploadWeb,
}) : super(key: key); }) : super(key: key);
@override @override
@ -51,7 +54,7 @@ class _ResourceTabState extends State<ResourceTab> with SingleTickerProviderStat
), ),
Expanded( Expanded(
child: TabBarView( child: TabBarView(
children: getContent(widget.resourceDTO, widget.onFileUpload), children: getContent(widget.resourceDTO, widget.onFileUpload, widget.onFileUploadWeb),
controller: _tabController, controller: _tabController,
), ),
), ),
@ -85,7 +88,7 @@ class _ResourceTabState extends State<ResourceTab> with SingleTickerProviderStat
} }
} }
getContent(ResourceDTO resourceDTO, Function onFileUpload) { getContent(ResourceDTO resourceDTO, Function onFileUpload, Function onFileUploadWeb) {
List<Widget> tabsToShow = new List<Widget>(); List<Widget> tabsToShow = new List<Widget>();
// Local Image // Local Image
@ -93,10 +96,14 @@ getContent(ResourceDTO resourceDTO, Function onFileUpload) {
new Padding( new Padding(
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 16), padding: EdgeInsets.symmetric(horizontal: 8, vertical: 16),
child: UploadImageContainer( child: UploadImageContainer(
onChanged: (File file) { onChanged: (List<File> files) {
onFileUpload(file); onFileUpload(files);
resourceDTO.type = ResourceType.image; resourceDTO.type = ResourceType.image;
} },
onChangedWeb: (List<PlatformFile> files) {
onFileUploadWeb(files);
resourceDTO.type = ResourceType.image;
},
), ),
) )
); );

View File

@ -1,15 +1,18 @@
import 'dart:io'; import 'dart:io';
//import 'package:dart_vlc/dart_vlc.dart'; import 'dart:typed_data';
import 'package:file_picker/file_picker.dart';
import 'package:manager_app/Components/loading.dart'; import 'package:manager_app/Components/loading.dart';
import 'package:manager_app/constants.dart'; import 'package:manager_app/constants.dart';
//import 'package:filepicker_windows/filepicker_windows.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart' show kIsWeb;
class UploadImageContainer extends StatefulWidget { class UploadImageContainer extends StatefulWidget {
final ValueChanged<File> onChanged; final ValueChanged<List<File>> onChanged;
final ValueChanged<List<PlatformFile>> onChangedWeb;
const UploadImageContainer({ const UploadImageContainer({
Key key, Key key,
this.onChanged, this.onChanged,
this.onChangedWeb,
}) : super(key: key); }) : super(key: key);
@override @override
@ -19,6 +22,7 @@ class UploadImageContainer extends StatefulWidget {
class _UploadImageContainerState extends State<UploadImageContainer> with SingleTickerProviderStateMixin { class _UploadImageContainerState extends State<UploadImageContainer> with SingleTickerProviderStateMixin {
var filePath; var filePath;
File fileToShow; File fileToShow;
String fileToShowWeb;
@override @override
void initState() { void initState() {
@ -39,7 +43,41 @@ class _UploadImageContainerState extends State<UploadImageContainer> with Single
return (filePath.toString().split('\\').last); return (filePath.toString().split('\\').last);
} }
void filePicker() { Future<void> filePicker() async {
FilePickerResult result;
if (kIsWeb) {
result = await FilePicker.platform.pickFiles(
type: FileType.custom,
dialogTitle: 'Sélectionner un fichier',
allowMultiple: true,
allowedExtensions: ['jpg', 'jpeg', 'png'],
);
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',
allowMultiple: true,
allowedExtensions: ['jpg', 'jpeg', 'png'],
);
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() /*final file = OpenFilePicker()
..filterSpecification = { ..filterSpecification = {
'Images (*.jpg; *.png)': '*.jpg;*.png', 'Images (*.jpg; *.png)': '*.jpg;*.png',
@ -63,8 +101,7 @@ class _UploadImageContainerState extends State<UploadImageContainer> with Single
showFile() { showFile() {
if (getFileName(filePath).contains(".mp4")) { if (getFileName(filePath).contains(".mp4")) {
/*return FutureBuilder(
return FutureBuilder(
future: loadFile(fileToShow), future: loadFile(fileToShow),
builder: (context, AsyncSnapshot<dynamic> snapshot) { builder: (context, AsyncSnapshot<dynamic> snapshot) {
if (snapshot.connectionState == ConnectionState.done) { if (snapshot.connectionState == ConnectionState.done) {
@ -96,27 +133,27 @@ class _UploadImageContainerState extends State<UploadImageContainer> with Single
); );
} }
} }
); );*/
/*await Media.file(widget.file)*/
} else { } else {
return Image.file( if (kIsWeb) {
fileToShow, return null;
height: 200, } else {
fit:BoxFit.scaleDown return Image.file(
); fileToShow,
height: 200,
fit:BoxFit.scaleDown
);
}
} }
} }
loadFile(File fileToShow) async { loadFile(File fileToShow) async {
//return await Media.file(fileToShow); //return await Media.file(fileToShow);
return null; return null; // Useless no mp4 for now
} }
displayElement() { displayElement() {
if (fileToShow == null) return Center( if (fileToShow == null && fileToShowWeb == null) return Center(
child: InkWell( child: InkWell(
onTap: () async { onTap: () async {
filePicker(); filePicker();
@ -129,14 +166,14 @@ class _UploadImageContainerState extends State<UploadImageContainer> with Single
child: Padding( child: Padding(
padding: const EdgeInsets.only(left: 25.0, right: 25.0, top: 15.0, bottom: 15.0), padding: const EdgeInsets.only(left: 25.0, right: 25.0, top: 15.0, bottom: 15.0),
child: Text( child: Text(
"Ajouter un fichier", "Ajouter un ou plusieurs fichiers",
style: new TextStyle(color: kWhite), style: new TextStyle(color: kWhite),
), ),
) )
), ),
), ),
); );
if (fileToShow != null) if (fileToShow != null || fileToShowWeb != null)
return Container( return Container(
margin: EdgeInsets.all(8.0), margin: EdgeInsets.all(8.0),
child: Card( child: Card(

View File

@ -1,5 +1,6 @@
import 'dart:io'; import 'dart:io';
import 'package:file_picker/file_picker.dart';
import 'package:manager_app/Components/message_notification.dart'; import 'package:manager_app/Components/message_notification.dart';
import 'package:manager_app/Components/resource_tab.dart'; import 'package:manager_app/Components/resource_tab.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -13,7 +14,8 @@ dynamic showNewResource(AppContext appContext, BuildContext context) async {
ResourceDTO resourceDetailDTO = new ResourceDTO(); ResourceDTO resourceDetailDTO = new ResourceDTO();
Size size = MediaQuery.of(context).size; Size size = MediaQuery.of(context).size;
var fileName; var fileName;
File fileToSend; List<File> filesToSend;
List<PlatformFile> filesToSendWeb;
var result = await showDialog( var result = await showDialog(
builder: (BuildContext context) => AlertDialog( builder: (BuildContext context) => AlertDialog(
@ -43,8 +45,11 @@ dynamic showNewResource(AppContext appContext, BuildContext context) async {
height: size.height *0.5, height: size.height *0.5,
child: ResourceTab( child: ResourceTab(
resourceDTO: resourceDetailDTO, resourceDTO: resourceDetailDTO,
onFileUpload: (File file) { onFileUpload: (List<File> files) {
fileToSend = file; filesToSend = files;
},
onFileUploadWeb: (List<PlatformFile> files) {
filesToSendWeb = files;
}, },
) )
), ),
@ -83,9 +88,9 @@ dynamic showNewResource(AppContext appContext, BuildContext context) async {
color: kPrimaryColor, color: kPrimaryColor,
textColor: kWhite, textColor: kWhite,
press: () { press: () {
if (resourceDetailDTO.label != null) { if (resourceDetailDTO.label != null && resourceDetailDTO.label.trim() != '') {
if (resourceDetailDTO.data != null || fileToSend != null) { if (resourceDetailDTO.data != null || filesToSendWeb.length > 0 || filesToSend.length > 0) {
Navigator.pop(context, [resourceDetailDTO, fileToSend]); Navigator.pop(context, [resourceDetailDTO, filesToSend, filesToSendWeb]);
} else { } else {
showNotification(Colors.orange, kWhite, 'Aucun fichier n\'a été chargé', context, null); showNotification(Colors.orange, kWhite, 'Aucun fichier n\'a été chargé', context, null);
} }

View File

@ -1,6 +1,7 @@
import 'dart:convert'; import 'dart:convert';
import 'dart:developer';
import 'dart:io'; import 'dart:io';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:manager_app/Components/loading.dart'; import 'package:manager_app/Components/loading.dart';
import 'package:manager_app/Components/message_notification.dart'; import 'package:manager_app/Components/message_notification.dart';
@ -13,6 +14,7 @@ import 'package:manager_app/constants.dart';
import 'package:managerapi/api.dart'; import 'package:managerapi/api.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
import 'package:flutter/foundation.dart' show kIsWeb;
class ResourcesScreen extends StatefulWidget { class ResourcesScreen extends StatefulWidget {
final Function onGetResult; //return ResourceDTO final Function onGetResult; //return ResourceDTO
@ -51,7 +53,7 @@ class _ResourcesScreenState extends State<ResourcesScreen> {
var result = await showNewResource(appContext, context); var result = await showNewResource(appContext, context);
if (result != null) if (result != null)
{ {
await create(result[0], result[1], appContext, context); await create(result[0], result[1], result[2], appContext, context);
setState(() {}); // For refresh setState(() {}); // For refresh
} }
} else { } else {
@ -85,19 +87,35 @@ Future<void> getResources(Function onGetResult, bool isImage, dynamic appContext
return resources; return resources;
} }
Future<ResourceDTO> create(ResourceDTO resourceDTO, File file, 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.image: case ResourceType.image:
case ResourceType.video: case ResourceType.video:
var request = http.MultipartRequest('POST', Uri.parse(appContext.getContext().clientAPI.resourceApi.apiClient.basePath+"/api/Resource/upload")); var request = http.MultipartRequest('POST', Uri.parse(appContext.getContext().clientAPI.resourceApi.apiClient.basePath+"/api/Resource/upload"));
request.files.add(
await http.MultipartFile( if (kIsWeb) {
'picture', for (PlatformFile file in filesWeb) {
file.readAsBytes().asStream(), request.files.add(
file.lengthSync(), await http.MultipartFile.fromBytes(
filename: file.path.toString().split("/").last 'picture',
) file.bytes,
); filename: file.name
)
);
}
} else {
for (File file in files) {
request.files.add(
await http.MultipartFile(
'picture',
file.readAsBytes().asStream(),
file.lengthSync(),
filename: file.path.toString().split("/").last
)
);
}
}
ManagerAppContext managerAppContext = appContext.getContext(); ManagerAppContext managerAppContext = appContext.getContext();
request.headers["authorization"]="Bearer ${managerAppContext.token.accessToken}"; request.headers["authorization"]="Bearer ${managerAppContext.token.accessToken}";
@ -108,10 +126,8 @@ Future<ResourceDTO> create(ResourceDTO resourceDTO, File file, AppContext appCon
final respStr = await res.stream.bytesToString(); final respStr = await res.stream.bytesToString();
if (res.statusCode == 200) { if (res.statusCode == 200) {
var result = ResourceDTO.fromJson(jsonDecode(respStr));
showNotification(Colors.green, kWhite, 'La ressource a été créée avec succès', context, null); showNotification(Colors.green, kWhite, 'La ressource a été créée avec succès', context, null);
return null;
return result;
} else { } else {
showNotification(kPrimaryColor, kWhite, 'Une erreur est survenue lors de la création de la ressource', context, null); showNotification(kPrimaryColor, kWhite, 'Une erreur est survenue lors de la création de la ressource', context, null);
} }

View File

@ -13,6 +13,7 @@ import 'package:manager_app/client.dart';
import 'package:manager_app/constants.dart'; import 'package:manager_app/constants.dart';
import 'package:managerapi/api.dart'; import 'package:managerapi/api.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:flutter/foundation.dart' show kIsWeb;
class LoginScreen extends StatefulWidget { class LoginScreen extends StatefulWidget {
final Session session; final Session session;
@ -51,9 +52,6 @@ class _LoginScreenState extends State<LoginScreen> {
LoginDTO loginDTO = new LoginDTO(email: email, password: password); LoginDTO loginDTO = new LoginDTO(email: email, password: password);
TokenDTO token = await clientAPI.authenticationApi.authenticationAuthenticateWithJson(loginDTO); TokenDTO token = await clientAPI.authenticationApi.authenticationAuthenticateWithJson(loginDTO);
print("Token ??");
print(token);
print(token.accessToken);
setAccessToken(token.accessToken); setAccessToken(token.accessToken);
if (isRememberMe) { if (isRememberMe) {
@ -172,7 +170,7 @@ class _LoginScreenState extends State<LoginScreen> {
password = value; password = value;
}, },
), ),
Padding( if(!kIsWeb) Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: Row( child: Row(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,

View File

@ -16,11 +16,6 @@ Future<void> main() async {
String initialRoute; String initialRoute;
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
/*if (Platform.isWindows) {
/*setWindowTitle("Manager");
setWindowMinSize(Size(1250, 850));
setWindowMaxSize(Size(3840, 2160));*/
}*/
initialRoute = '/welcome'; initialRoute = '/welcome';