added upload with multiple files #61

Merged
MineTec merged 7 commits from develop-uploadMultipleFiles into develop 2024-04-09 08:21:55 +00:00
5 changed files with 376 additions and 278 deletions
Showing only changes of commit d8c72a5d28 - Show all commits

View File

@ -65,9 +65,7 @@ class SortOptions {
)
};
static BetterSortOption getOption(SortOption option) {
return options[option]!;
}
static BetterSortOption getOption(SortOption option) => options[option]!;
}
class _FilesState extends State<Files> {
@ -99,7 +97,7 @@ class _FilesState extends State<Files> {
);
}
void mediaUpload(List<String>? paths) async {
Future<void> mediaUpload(List<String>? paths) async {
if(paths == null) return;
pushScreen(

View File

@ -43,21 +43,15 @@ class _FilesUploadDialogState extends State<FilesUploadDialog> {
super.initState();
_uploadableFiles = widget.filePaths.map((filePath) {
String fileName = filePath.split(Platform.pathSeparator).last;
var fileName = filePath.split(Platform.pathSeparator).last;
return UploadableFile(filePath, fileName);
}).toList();
/*_uploadableFiles.addAll(widget.filePaths.map((filePath) {
String fileName = filePath.split(Platform.pathSeparator).last;
return UploadableFile(filePath, fileName);
}));*/
}
Pupsi marked this conversation as resolved Outdated

was ist das für ein error code? Ein http status code?

Falls ja variable enstprechend umbenennen und in der message auch angeben

was ist das für ein error code? Ein http status code? Falls ja variable enstprechend umbenennen und in der message auch angeben
void showHttpErrorCode(int httpErrorCode){
Pupsi marked this conversation as resolved
Review

ungenutzer code raus

ungenutzer code raus
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
builder: (BuildContext context) => AlertDialog(
title: const Text('Ein Fehler ist aufgetreten'),
contentPadding: const EdgeInsets.all(10),
content: Text('Error code: $httpErrorCode'),
@ -67,12 +61,11 @@ class _FilesUploadDialogState extends State<FilesUploadDialog> {
child: const Text('Schließen', textAlign: TextAlign.center),
),
],
);
}
)
);
}
void uploadFiles({bool override = false}) async {
Future<void> uploadFiles({bool override = false}) async {
setState(() {
Pupsi marked this conversation as resolved
Review

dein ehemaliger name upload ist in diesem kontext doch besser, vielleicht auch uploadFiles

dein ehemaliger name `upload` ist in diesem kontext doch besser, vielleicht auch `uploadFiles`
_isUploading = true;
_infoText = 'Vorbereiten';
@ -81,41 +74,33 @@ class _FilesUploadDialogState extends State<FilesUploadDialog> {
}
});
Pupsi marked this conversation as resolved
Review

setState für jede datei auszuführen ist unnötig und ressourcenintensiv.

Mit setState auf zeile 70 verbinden und inline schreiben mit

_uploadableFiles.foreach(f => f.isConflicting = false)

setState für jede datei auszuführen ist unnötig und ressourcenintensiv. Mit setState auf zeile 70 verbinden und inline schreiben mit `_uploadableFiles.foreach(f => f.isConflicting = false)`
WebDavClient webdavClient = await WebdavApi.webdav;
var webdavClient = await WebdavApi.webdav;
if (!override) {
List<WebDavResponse> result = (await webdavClient.propfind(PathUri.parse(widget.remotePath))).responses;
List<UploadableFile> conflictingFiles = _uploadableFiles.where((file) {
String fileName = file.fileName;
if (result.any((element) => Uri.decodeComponent(element.href!).endsWith('/$fileName'))) {
// konflikt
return true;
}
return false;
var result = (await webdavClient.propfind(PathUri.parse(widget.remotePath))).responses;
var conflictingFiles = _uploadableFiles.where((file) {
var fileName = file.fileName;
return result.any((element) => Uri.decodeComponent(element.href!).endsWith('/$fileName'));
}).toList();
if(conflictingFiles.isNotEmpty) {
bool replaceFiles = await showDialog(
Pupsi marked this conversation as resolved
Review

umschreiben in fluente schreibweise

conflictingFiles = _uploadableFiles.where(...)
umschreiben in fluente schreibweise ``` conflictingFiles = _uploadableFiles.where(...) ```
context: context,
barrierDismissible: false,
builder: (context) {
return AlertDialog(
builder: (context) => AlertDialog(
Pupsi marked this conversation as resolved Outdated

einfaches return

return result.any((element) => Uri.decodeComponent(element.href!).endsWith('/$fileName'))

ggf auch ohne return als pfeilsyntax

einfaches return `return result.any((element) => Uri.decodeComponent(element.href!).endsWith('/$fileName'))` ggf auch ohne return als pfeilsyntax
contentPadding: const EdgeInsets.all(10),
title: const Text('Konflikt', textAlign: TextAlign.center),
content: conflictingFiles.length == 1 ?
Text(
'Eine Datei mit dem Namen "${conflictingFiles.map((e) => e.fileName).first}" existiert bereits.\n'
'(Datei ${_uploadableFiles.indexOf(conflictingFiles.first)+1})',
'Eine Datei mit dem Namen "${conflictingFiles.map((e) => e.fileName).first}" existiert bereits.',
textAlign: TextAlign.left,
) :
SingleChildScrollView(
child: Text(
'${conflictingFiles.length} Dateien mit den Namen: ${conflictingFiles.map((e) => '\n${e.fileName}').join(', ')}\n existieren bereits.\n'
'(Dateien ${conflictingFiles.map((e) => _uploadableFiles.indexOf(e)+1).join(', ')})',
'${conflictingFiles.length} Dateien mit folgenden Namen existieren bereits: \n${conflictingFiles.map((e) => '\n - ${e.fileName}').join('')}',
textAlign: TextAlign.left,
),
),
actions: [
TextButton(
onPressed: () {
@ -127,55 +112,52 @@ class _FilesUploadDialogState extends State<FilesUploadDialog> {
onPressed: () {
showDialog(
context: context,
builder: (context) {
return ConfirmDialog(
title: 'Bestätigen',
content: 'Bist du sicher, dass du ${conflictingFiles.map((e) => e.fileName).toList()} überschreiben möchtest?',
onConfirm: () {
Navigator.pop(context, true);
},
confirmButton: 'Ja',
cancelButton: 'Nein',
);
}
builder: (context) => ConfirmDialog(
title: 'Bestätigen?',
content: 'Bist du sicher, dass du ${conflictingFiles.length} Dateien überschreiben möchtest?',
onConfirm: () {
Navigator.pop(context, true);
Pupsi marked this conversation as resolved Outdated

Umbenennen

`Umbenennen`
Outdated
Review

Passt Bearbeiten nicht besser? Es gibt ja dann auch noch die Möglichkeit neben dem Umbenennen auch die Datei zu löschen oder komplett abzubrechen.

Passt Bearbeiten nicht besser? Es gibt ja dann auch noch die Möglichkeit neben dem Umbenennen auch die Datei zu löschen oder komplett abzubrechen.
},
confirmButton: 'Ja',
cancelButton: 'Nein',
),
);
Pupsi marked this conversation as resolved Outdated

Überschreiben

diese Aktion sollte nochmal ein "Bist du sicher" dialog öffnen. Du kannst hierzu den bestehenden ConfirmDialog verwenden

`Überschreiben` diese Aktion sollte nochmal ein "Bist du sicher" dialog öffnen. Du kannst hierzu den bestehenden ConfirmDialog verwenden
},
child: const Text('Überschreiben', textAlign: TextAlign.center),
),
],
);
}
)
);
if(!replaceFiles) {
for (var element in conflictingFiles) {
element.isConflicting = true;
}
setState(() {
_isUploading = false;
_overallProgressValue = 0.0;
_infoText = '';
for (var element in conflictingFiles) {
element.isConflicting = true;
}
});
return;
}
}
}
List<String> uploadetFilePaths = [];
var uploadetFilePaths = <String>[];
for (var file in _uploadableFiles) {
String fileName = file.fileName;
String filePath = file.filePath;
var fileName = file.fileName;
var filePath = file.filePath;
Pupsi marked this conversation as resolved Outdated

state variablen in setState ändern

state variablen in setState ändern
if(widget.uniqueNames) fileName = '${fileName.split('.').first}-${const Uuid().v4()}.${fileName.split('.').last}';
String fullRemotePath = '${widget.remotePath}/$fileName';
var fullRemotePath = '${widget.remotePath}/$fileName';
setState(() {
_infoText = '${_uploadableFiles.indexOf(file) + 1}/${_uploadableFiles.length}';
});
HttpClientResponse uploadTask = await webdavClient.putFile(
var uploadTask = await webdavClient.putFile(
File(filePath),
FileStat.statSync(filePath),
PathUri.parse(fullRemotePath),
@ -211,8 +193,7 @@ class _FilesUploadDialogState extends State<FilesUploadDialog> {
}
@override
Widget build(BuildContext context) {
return Scaffold(
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(
title: const Text('Dateien hochladen'),
automaticallyImplyLeading: false,
@ -318,13 +299,25 @@ class _FilesUploadDialogState extends State<FilesUploadDialog> {
onPressed: () => uploadFiles(override: widget.uniqueNames),
child: const Text('Hochladen'),
),
child: Stack(
alignment: Alignment.center,
children: [
CircularProgressIndicator(value: _overallProgressValue),
Center(child: Text(_infoText)),
],
child: Visibility(
visible: _infoText.length < 5,
replacement: Row(
children: [
Text(_infoText),
const SizedBox(width: 15),
CircularProgressIndicator(value: _overallProgressValue),
],
),
child: Stack(
alignment: Alignment.center,
children: [
CircularProgressIndicator(value: _overallProgressValue),
Center(child: Text(_infoText)),
],
),
),
),
],
),
@ -333,5 +326,4 @@ class _FilesUploadDialogState extends State<FilesUploadDialog> {
),
),
);
}
}
}

View File

@ -35,7 +35,7 @@ class _ChatTextfieldState extends State<ChatTextfield> {
void share(String shareFolder, List<String> filePaths) {
for (var element in filePaths) {
String fileName = element.split(Platform.pathSeparator).last;
var fileName = element.split(Platform.pathSeparator).last;
FileSharingApi().share(FileSharingApiParams(
shareType: 10,
shareWith: widget.sendToToken,
@ -44,10 +44,10 @@ class _ChatTextfieldState extends State<ChatTextfield> {
}
}
void mediaUpload(List<String>? paths) async {
Future<void> mediaUpload(List<String>? paths) async {
if (paths == null) return;
String shareFolder = 'MarianumMobile';
var shareFolder = 'MarianumMobile';
WebdavApi.webdav.then((webdav) {
webdav.mkcol(PathUri.parse('/$shareFolder'));
});