added upload with multiple files #61
@ -1,5 +1,4 @@
|
|||||||
|
|
||||||
import 'dart:developer';
|
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
@ -92,8 +91,6 @@ class _FilesState extends State<Files> {
|
|||||||
ListFilesCache(
|
ListFilesCache(
|
||||||
path: widget.path.isEmpty ? '/' : widget.path.join('/'),
|
path: widget.path.isEmpty ? '/' : widget.path.join('/'),
|
||||||
onUpdate: (ListFilesResponse d) {
|
onUpdate: (ListFilesResponse d) {
|
||||||
log('_query');
|
|
||||||
if(!context.mounted) return; // prevent setState when widget is possibly already disposed
|
|
||||||
d.files.removeWhere((element) => element.name.isEmpty || element.name == widget.path.lastOrNull());
|
d.files.removeWhere((element) => element.name.isEmpty || element.name == widget.path.lastOrNull());
|
||||||
setState(() {
|
setState(() {
|
||||||
Pupsi marked this conversation as resolved
Outdated
|
|||||||
data = d;
|
data = d;
|
||||||
Pupsi marked this conversation as resolved
Outdated
MineTec
commented
kommentar raus kommentar raus
|
|||||||
|
@ -6,6 +6,7 @@ import 'package:nextcloud/nextcloud.dart';
|
|||||||
import 'package:uuid/uuid.dart';
|
import 'package:uuid/uuid.dart';
|
||||||
|
|
||||||
import '../../../api/marianumcloud/webdav/webdavApi.dart';
|
import '../../../api/marianumcloud/webdav/webdavApi.dart';
|
||||||
|
import '../../../widget/confirmDialog.dart';
|
||||||
import '../../../widget/focusBehaviour.dart';
|
import '../../../widget/focusBehaviour.dart';
|
||||||
|
|
||||||
class FilesUploadDialog extends StatefulWidget {
|
class FilesUploadDialog extends StatefulWidget {
|
||||||
@ -32,29 +33,34 @@ class UploadableFile {
|
|||||||
|
|
||||||
|
|
||||||
class _FilesUploadDialogState extends State<FilesUploadDialog> {
|
class _FilesUploadDialogState extends State<FilesUploadDialog> {
|
||||||
Pupsi marked this conversation as resolved
MineTec
commented
variable nicht leer initialisieren und durch addAll popularisieren du kannst die variable hier late setzen und im initState setzen variable nicht leer initialisieren und durch addAll popularisieren
du kannst die variable hier late setzen und im initState setzen
|
|||||||
final List<UploadableFile> _uploadableFiles = [];
|
late List<UploadableFile> _uploadableFiles;
|
||||||
bool _isUploading = false;
|
bool _isUploading = false;
|
||||||
Pupsi marked this conversation as resolved
MineTec
commented
passenderer Variablenname passenderer Variablenname `_overallProgressValue`
damit klar ist das sie den Gesamtfortschritt wiederspiegelt
|
|||||||
double _progressValue = 0.0;
|
double _overallProgressValue = 0.0;
|
||||||
String _infoText = '';
|
String _infoText = '';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
|
||||||
_uploadableFiles.addAll(widget.filePaths.map((filePath) {
|
_uploadableFiles = widget.filePaths.map((filePath) {
|
||||||
String fileName = filePath.split(Platform.pathSeparator).last;
|
String fileName = filePath.split(Platform.pathSeparator).last;
|
||||||
return UploadableFile(filePath, fileName);
|
return UploadableFile(filePath, fileName);
|
||||||
}));
|
}).toList();
|
||||||
|
|
||||||
|
/*_uploadableFiles.addAll(widget.filePaths.map((filePath) {
|
||||||
Pupsi marked this conversation as resolved
Outdated
MineTec
commented
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
|
|||||||
|
String fileName = filePath.split(Platform.pathSeparator).last;
|
||||||
Pupsi marked this conversation as resolved
MineTec
commented
ungenutzer code raus ungenutzer code raus
|
|||||||
|
return UploadableFile(filePath, fileName);
|
||||||
|
}));*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void showErrorMessage(int errorCode){
|
void showHttpErrorCode(int httpErrorCode){
|
||||||
showDialog(
|
showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
return 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: $errorCode'),
|
content: Text('Error code: $httpErrorCode'),
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.of(context).pop(),
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
@ -66,31 +72,27 @@ class _FilesUploadDialogState extends State<FilesUploadDialog> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void uploadSelectedFiles({bool override = false}) async {
|
void uploadFiles({bool override = false}) async {
|
||||||
setState(() {
|
setState(() {
|
||||||
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)`
|
|||||||
_isUploading = true;
|
_isUploading = true;
|
||||||
_infoText = 'Vorbereiten';
|
_infoText = 'Vorbereiten';
|
||||||
|
for (var file in _uploadableFiles) {
|
||||||
|
file.isConflicting = false;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
for (var element in _uploadableFiles) {
|
|
||||||
setState(() {
|
|
||||||
element.isConflicting = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
WebDavClient webdavClient = await WebdavApi.webdav;
|
WebDavClient webdavClient = await WebdavApi.webdav;
|
||||||
|
|
||||||
if (!override) {
|
if (!override) {
|
||||||
List<WebDavResponse> result = (await webdavClient.propfind(PathUri.parse(widget.remotePath))).responses;
|
List<WebDavResponse> result = (await webdavClient.propfind(PathUri.parse(widget.remotePath))).responses;
|
||||||
Pupsi marked this conversation as resolved
MineTec
commented
umschreiben in fluente schreibweise
umschreiben in fluente schreibweise
```
conflictingFiles = _uploadableFiles.where(...)
```
|
|||||||
List<UploadableFile> conflictingFiles = [];
|
List<UploadableFile> conflictingFiles = _uploadableFiles.where((file) {
|
||||||
|
|
||||||
for (var file in _uploadableFiles) {
|
|
||||||
String fileName = file.fileName;
|
String fileName = file.fileName;
|
||||||
if (result.any((element) => Uri.decodeComponent(element.href!).endsWith('/$fileName'))) {
|
if (result.any((element) => Uri.decodeComponent(element.href!).endsWith('/$fileName'))) {
|
||||||
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
|
|||||||
// konflikt
|
// konflikt
|
||||||
conflictingFiles.add(file);
|
return true;
|
||||||
}
|
}
|
||||||
}
|
return false;
|
||||||
|
}).toList();
|
||||||
|
|
||||||
if(conflictingFiles.isNotEmpty) {
|
if(conflictingFiles.isNotEmpty) {
|
||||||
bool replaceFiles = await showDialog(
|
bool replaceFiles = await showDialog(
|
||||||
@ -120,9 +122,23 @@ class _FilesUploadDialogState extends State<FilesUploadDialog> {
|
|||||||
),
|
),
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.pop(context, true);
|
showDialog(
|
||||||
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
|
|||||||
|
context: context,
|
||||||
|
builder: (context) {
|
||||||
|
return ConfirmDialog(
|
||||||
|
title: 'Bist du sicher?',
|
||||||
|
content: '',
|
||||||
|
onConfirm: () {
|
||||||
|
Navigator.pop(context, true);
|
||||||
|
},
|
||||||
|
confirmButton: 'Ja',
|
||||||
|
cancelButton: 'Nein',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
},
|
},
|
||||||
child: const Text('Ersetzen', textAlign: TextAlign.center),
|
child: const Text('Überschreiben', textAlign: TextAlign.center),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
@ -135,7 +151,7 @@ class _FilesUploadDialogState extends State<FilesUploadDialog> {
|
|||||||
}
|
}
|
||||||
setState(() {
|
setState(() {
|
||||||
_isUploading = false;
|
_isUploading = false;
|
||||||
_progressValue = 0.0;
|
_overallProgressValue = 0.0;
|
||||||
_infoText = '';
|
_infoText = '';
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
@ -163,7 +179,7 @@ class _FilesUploadDialogState extends State<FilesUploadDialog> {
|
|||||||
onProgress: (progress) {
|
onProgress: (progress) {
|
||||||
setState(() {
|
setState(() {
|
||||||
file._uploadProgress = progress;
|
file._uploadProgress = progress;
|
||||||
_progressValue = ((progress + _uploadableFiles.indexOf(file)) / _uploadableFiles.length).toDouble();
|
_overallProgressValue = ((progress + _uploadableFiles.indexOf(file)) / _uploadableFiles.length).toDouble();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -172,11 +188,11 @@ class _FilesUploadDialogState extends State<FilesUploadDialog> {
|
|||||||
// error code
|
// error code
|
||||||
setState(() {
|
setState(() {
|
||||||
_isUploading = false;
|
_isUploading = false;
|
||||||
_progressValue = 0.0;
|
_overallProgressValue = 0.0;
|
||||||
_infoText = '';
|
_infoText = '';
|
||||||
});
|
});
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
showErrorMessage(uploadTask.statusCode);
|
showHttpErrorCode(uploadTask.statusCode);
|
||||||
} else {
|
} else {
|
||||||
uploadetFilePaths.add(fullRemotePath);
|
uploadetFilePaths.add(fullRemotePath);
|
||||||
}
|
}
|
||||||
@ -184,7 +200,7 @@ class _FilesUploadDialogState extends State<FilesUploadDialog> {
|
|||||||
|
|
||||||
setState(() {
|
setState(() {
|
||||||
_isUploading = false;
|
_isUploading = false;
|
||||||
_progressValue = 0.0;
|
_overallProgressValue = 0.0;
|
||||||
_infoText = '';
|
_infoText = '';
|
||||||
});
|
});
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
@ -296,13 +312,13 @@ class _FilesUploadDialogState extends State<FilesUploadDialog> {
|
|||||||
Visibility(
|
Visibility(
|
||||||
visible: _isUploading,
|
visible: _isUploading,
|
||||||
replacement: TextButton(
|
replacement: TextButton(
|
||||||
onPressed: () => uploadSelectedFiles(override: widget.uniqueNames),
|
onPressed: () => uploadFiles(override: widget.uniqueNames),
|
||||||
child: const Text('Hochladen'),
|
child: const Text('Hochladen'),
|
||||||
),
|
),
|
||||||
child: Stack(
|
child: Stack(
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
children: [
|
children: [
|
||||||
CircularProgressIndicator(value: _progressValue),
|
CircularProgressIndicator(value: _overallProgressValue),
|
||||||
Center(child: Text(_infoText)),
|
Center(child: Text(_infoText)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
raus