added upload with multiple files #61
@ -65,9 +65,7 @@ class SortOptions {
|
|||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
static BetterSortOption getOption(SortOption option) {
|
static BetterSortOption getOption(SortOption option) => options[option]!;
|
||||||
return options[option]!;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class _FilesState extends State<Files> {
|
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;
|
if(paths == null) return;
|
||||||
|
|
||||||
pushScreen(
|
pushScreen(
|
||||||
|
@ -43,21 +43,15 @@ class _FilesUploadDialogState extends State<FilesUploadDialog> {
|
|||||||
super.initState();
|
super.initState();
|
||||||
|
|
||||||
_uploadableFiles = widget.filePaths.map((filePath) {
|
_uploadableFiles = widget.filePaths.map((filePath) {
|
||||||
String fileName = filePath.split(Platform.pathSeparator).last;
|
var fileName = filePath.split(Platform.pathSeparator).last;
|
||||||
return UploadableFile(filePath, fileName);
|
return UploadableFile(filePath, fileName);
|
||||||
}).toList();
|
}).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
|
|||||||
void showHttpErrorCode(int httpErrorCode){
|
void showHttpErrorCode(int httpErrorCode){
|
||||||
Pupsi marked this conversation as resolved
MineTec
commented
ungenutzer code raus ungenutzer code raus
|
|||||||
showDialog(
|
showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) => AlertDialog(
|
||||||
return AlertDialog(
|
|
||||||
title: const Text('Ein Fehler ist aufgetreten'),
|
title: const Text('Ein Fehler ist aufgetreten'),
|
||||||
contentPadding: const EdgeInsets.all(10),
|
contentPadding: const EdgeInsets.all(10),
|
||||||
content: Text('Error code: $httpErrorCode'),
|
content: Text('Error code: $httpErrorCode'),
|
||||||
@ -67,12 +61,11 @@ class _FilesUploadDialogState extends State<FilesUploadDialog> {
|
|||||||
child: const Text('Schließen', textAlign: TextAlign.center),
|
child: const Text('Schließen', textAlign: TextAlign.center),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
)
|
||||||
}
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void uploadFiles({bool override = false}) async {
|
Future<void> uploadFiles({bool override = false}) async {
|
||||||
setState(() {
|
setState(() {
|
||||||
Pupsi marked this conversation as resolved
MineTec
commented
dein ehemaliger name dein ehemaliger name `upload` ist in diesem kontext doch besser, vielleicht auch `uploadFiles`
|
|||||||
_isUploading = true;
|
_isUploading = true;
|
||||||
_infoText = 'Vorbereiten';
|
_infoText = 'Vorbereiten';
|
||||||
@ -81,41 +74,33 @@ class _FilesUploadDialogState extends State<FilesUploadDialog> {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Pupsi marked this conversation as resolved
MineTec
commented
setState für jede datei auszuführen ist unnötig und ressourcenintensiv. Mit setState auf zeile 70 verbinden und inline schreiben mit
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) {
|
if (!override) {
|
||||||
List<WebDavResponse> result = (await webdavClient.propfind(PathUri.parse(widget.remotePath))).responses;
|
var result = (await webdavClient.propfind(PathUri.parse(widget.remotePath))).responses;
|
||||||
List<UploadableFile> conflictingFiles = _uploadableFiles.where((file) {
|
var conflictingFiles = _uploadableFiles.where((file) {
|
||||||
String fileName = file.fileName;
|
var fileName = file.fileName;
|
||||||
if (result.any((element) => Uri.decodeComponent(element.href!).endsWith('/$fileName'))) {
|
return result.any((element) => Uri.decodeComponent(element.href!).endsWith('/$fileName'));
|
||||||
// konflikt
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}).toList();
|
}).toList();
|
||||||
|
|
||||||
if(conflictingFiles.isNotEmpty) {
|
if(conflictingFiles.isNotEmpty) {
|
||||||
bool replaceFiles = await showDialog(
|
bool replaceFiles = await showDialog(
|
||||||
Pupsi marked this conversation as resolved
MineTec
commented
umschreiben in fluente schreibweise
umschreiben in fluente schreibweise
```
conflictingFiles = _uploadableFiles.where(...)
```
|
|||||||
context: context,
|
context: context,
|
||||||
barrierDismissible: false,
|
barrierDismissible: false,
|
||||||
builder: (context) {
|
builder: (context) => AlertDialog(
|
||||||
Pupsi marked this conversation as resolved
Outdated
MineTec
commented
einfaches return
ggf auch ohne return als pfeilsyntax einfaches return
`return result.any((element) => Uri.decodeComponent(element.href!).endsWith('/$fileName'))`
ggf auch ohne return als pfeilsyntax
|
|||||||
return AlertDialog(
|
|
||||||
contentPadding: const EdgeInsets.all(10),
|
contentPadding: const EdgeInsets.all(10),
|
||||||
title: const Text('Konflikt', textAlign: TextAlign.center),
|
title: const Text('Konflikt', textAlign: TextAlign.center),
|
||||||
content: conflictingFiles.length == 1 ?
|
content: conflictingFiles.length == 1 ?
|
||||||
Text(
|
Text(
|
||||||
'Eine Datei mit dem Namen "${conflictingFiles.map((e) => e.fileName).first}" existiert bereits.\n'
|
'Eine Datei mit dem Namen "${conflictingFiles.map((e) => e.fileName).first}" existiert bereits.',
|
||||||
'(Datei ${_uploadableFiles.indexOf(conflictingFiles.first)+1})',
|
|
||||||
textAlign: TextAlign.left,
|
textAlign: TextAlign.left,
|
||||||
) :
|
) :
|
||||||
SingleChildScrollView(
|
SingleChildScrollView(
|
||||||
child: Text(
|
child: Text(
|
||||||
'${conflictingFiles.length} Dateien mit den Namen: ${conflictingFiles.map((e) => '\n${e.fileName}').join(', ')}\n existieren bereits.\n'
|
'${conflictingFiles.length} Dateien mit folgenden Namen existieren bereits: \n${conflictingFiles.map((e) => '\n - ${e.fileName}').join('')}',
|
||||||
'(Dateien ${conflictingFiles.map((e) => _uploadableFiles.indexOf(e)+1).join(', ')})',
|
|
||||||
textAlign: TextAlign.left,
|
textAlign: TextAlign.left,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
@ -127,55 +112,52 @@ class _FilesUploadDialogState extends State<FilesUploadDialog> {
|
|||||||
onPressed: () {
|
onPressed: () {
|
||||||
showDialog(
|
showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) {
|
builder: (context) => ConfirmDialog(
|
||||||
return ConfirmDialog(
|
title: 'Bestätigen?',
|
||||||
title: 'Bestätigen',
|
content: 'Bist du sicher, dass du ${conflictingFiles.length} Dateien überschreiben möchtest?',
|
||||||
content: 'Bist du sicher, dass du ${conflictingFiles.map((e) => e.fileName).toList()} überschreiben möchtest?',
|
|
||||||
onConfirm: () {
|
onConfirm: () {
|
||||||
Navigator.pop(context, true);
|
Navigator.pop(context, true);
|
||||||
Pupsi marked this conversation as resolved
Outdated
MineTec
commented
`Umbenennen`
Pupsi
commented
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',
|
confirmButton: 'Ja',
|
||||||
cancelButton: 'Nein',
|
cancelButton: 'Nein',
|
||||||
);
|
),
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
Pupsi marked this conversation as resolved
Outdated
MineTec
commented
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),
|
child: const Text('Überschreiben', textAlign: TextAlign.center),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
)
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if(!replaceFiles) {
|
if(!replaceFiles) {
|
||||||
for (var element in conflictingFiles) {
|
|
||||||
element.isConflicting = true;
|
|
||||||
}
|
|
||||||
setState(() {
|
setState(() {
|
||||||
_isUploading = false;
|
_isUploading = false;
|
||||||
_overallProgressValue = 0.0;
|
_overallProgressValue = 0.0;
|
||||||
_infoText = '';
|
_infoText = '';
|
||||||
|
for (var element in conflictingFiles) {
|
||||||
|
element.isConflicting = true;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> uploadetFilePaths = [];
|
var uploadetFilePaths = <String>[];
|
||||||
for (var file in _uploadableFiles) {
|
for (var file in _uploadableFiles) {
|
||||||
String fileName = file.fileName;
|
var fileName = file.fileName;
|
||||||
String filePath = file.filePath;
|
var filePath = file.filePath;
|
||||||
Pupsi marked this conversation as resolved
Outdated
MineTec
commented
state variablen in setState ändern state variablen in setState ändern
|
|||||||
|
|
||||||
if(widget.uniqueNames) fileName = '${fileName.split('.').first}-${const Uuid().v4()}.${fileName.split('.').last}';
|
if(widget.uniqueNames) fileName = '${fileName.split('.').first}-${const Uuid().v4()}.${fileName.split('.').last}';
|
||||||
|
|
||||||
String fullRemotePath = '${widget.remotePath}/$fileName';
|
var fullRemotePath = '${widget.remotePath}/$fileName';
|
||||||
|
|
||||||
setState(() {
|
setState(() {
|
||||||
_infoText = '${_uploadableFiles.indexOf(file) + 1}/${_uploadableFiles.length}';
|
_infoText = '${_uploadableFiles.indexOf(file) + 1}/${_uploadableFiles.length}';
|
||||||
});
|
});
|
||||||
|
|
||||||
HttpClientResponse uploadTask = await webdavClient.putFile(
|
var uploadTask = await webdavClient.putFile(
|
||||||
File(filePath),
|
File(filePath),
|
||||||
FileStat.statSync(filePath),
|
FileStat.statSync(filePath),
|
||||||
PathUri.parse(fullRemotePath),
|
PathUri.parse(fullRemotePath),
|
||||||
@ -211,8 +193,7 @@ class _FilesUploadDialogState extends State<FilesUploadDialog> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) => Scaffold(
|
||||||
return Scaffold(
|
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: const Text('Dateien hochladen'),
|
title: const Text('Dateien hochladen'),
|
||||||
automaticallyImplyLeading: false,
|
automaticallyImplyLeading: false,
|
||||||
@ -318,6 +299,15 @@ class _FilesUploadDialogState extends State<FilesUploadDialog> {
|
|||||||
onPressed: () => uploadFiles(override: widget.uniqueNames),
|
onPressed: () => uploadFiles(override: widget.uniqueNames),
|
||||||
child: const Text('Hochladen'),
|
child: const Text('Hochladen'),
|
||||||
),
|
),
|
||||||
|
child: Visibility(
|
||||||
|
visible: _infoText.length < 5,
|
||||||
|
replacement: Row(
|
||||||
|
children: [
|
||||||
|
Text(_infoText),
|
||||||
|
const SizedBox(width: 15),
|
||||||
|
CircularProgressIndicator(value: _overallProgressValue),
|
||||||
|
],
|
||||||
|
),
|
||||||
child: Stack(
|
child: Stack(
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
children: [
|
children: [
|
||||||
@ -326,6 +316,9 @@ class _FilesUploadDialogState extends State<FilesUploadDialog> {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
|
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -333,5 +326,4 @@ class _FilesUploadDialogState extends State<FilesUploadDialog> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
|
||||||
}
|
}
|
@ -35,7 +35,7 @@ class _ChatTextfieldState extends State<ChatTextfield> {
|
|||||||
|
|
||||||
void share(String shareFolder, List<String> filePaths) {
|
void share(String shareFolder, List<String> filePaths) {
|
||||||
for (var element in filePaths) {
|
for (var element in filePaths) {
|
||||||
String fileName = element.split(Platform.pathSeparator).last;
|
var fileName = element.split(Platform.pathSeparator).last;
|
||||||
FileSharingApi().share(FileSharingApiParams(
|
FileSharingApi().share(FileSharingApiParams(
|
||||||
shareType: 10,
|
shareType: 10,
|
||||||
shareWith: widget.sendToToken,
|
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;
|
if (paths == null) return;
|
||||||
|
|
||||||
String shareFolder = 'MarianumMobile';
|
var shareFolder = 'MarianumMobile';
|
||||||
WebdavApi.webdav.then((webdav) {
|
WebdavApi.webdav.then((webdav) {
|
||||||
webdav.mkcol(PathUri.parse('/$shareFolder'));
|
webdav.mkcol(PathUri.parse('/$shareFolder'));
|
||||||
});
|
});
|
||||||
|
was ist das für ein error code? Ein http status code?
Falls ja variable enstprechend umbenennen und in der message auch angeben