Client/lib/view/pages/files/fileElement.dart

198 lines
6.7 KiB
Dart

import 'dart:io';
import 'package:better_open_file/better_open_file.dart';
import 'package:filesize/filesize.dart';
import 'package:flowder/flowder.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:jiffy/jiffy.dart';
import '../../../widget/infoDialog.dart';
import 'package:nextcloud/nextcloud.dart';
import 'package:path_provider/path_provider.dart';
import '../../../api/marianumcloud/webdav/queries/listFiles/cacheableFile.dart';
import '../../../api/marianumcloud/webdav/webdavApi.dart';
import '../../../model/endpointData.dart';
import '../../../widget/centeredLeading.dart';
import '../../../widget/confirmDialog.dart';
import '../../../widget/fileViewer.dart';
import '../../../widget/unimplementedDialog.dart';
import 'files.dart';
class FileElement extends StatefulWidget {
final CacheableFile file;
final List<String> path;
final void Function() refetch;
const FileElement(this.file, this.path, this.refetch, {super.key});
static Future<DownloaderCore> download(BuildContext context, String remotePath, String name, Function(double) onProgress, Function(OpenResult) onDone) async {
Directory paths = await getTemporaryDirectory();
var encodedPath = Uri.encodeComponent(remotePath);
encodedPath = encodedPath.replaceAll('%2F', '/');
String local = paths.path + Platform.pathSeparator + name;
DownloaderUtils options = DownloaderUtils(
progressCallback: (current, total) {
final progress = (current / total) * 100;
onProgress(progress);
},
file: File(local),
progress: ProgressImplementation(),
deleteOnCancel: true,
onDone: () {
//Future<OpenResult> result = OpenFile.open(local); // TODO legacy - refactor: remove onDone parameter
Navigator.of(context).push(MaterialPageRoute(builder: (context) => FileViewer(path: local)));
onDone(OpenResult(message: 'File viewer opened', type: ResultType.done));
// result.then((value) => {
// onDone(value)
// });
},
);
return await Flowder.download(
"${await WebdavApi.webdavConnectString}$encodedPath",
options,
);
}
@override
State<FileElement> createState() => _FileElementState();
}
class _FileElementState extends State<FileElement> {
double percent = 0;
Future<DownloaderCore>? downloadCore;
Widget getSubtitle() {
if(widget.file.currentlyDownloading) {
return Row(
children: [
Container(
margin: const EdgeInsets.only(right: 10),
child: const Text('Download:'),
),
Expanded(
child: LinearProgressIndicator(value: percent/100),
),
Container(
margin: const EdgeInsets.only(left: 10),
child: Text('${percent.round()}%'),
),
],
);
}
return widget.file.isDirectory
? Text('geändert ${Jiffy.parseFromDateTime(widget.file.modifiedAt ?? DateTime.now()).fromNow()}')
: Text('${filesize(widget.file.size)}, ${Jiffy.parseFromDateTime(widget.file.modifiedAt ?? DateTime.now()).fromNow()}');
}
@override
Widget build(BuildContext context) {
return ListTile(
leading: CenteredLeading(
Icon(widget.file.isDirectory ? Icons.folder : Icons.description_outlined)
),
title: Text(widget.file.name, maxLines: 2, overflow: TextOverflow.ellipsis),
subtitle: getSubtitle(),
trailing: Icon(widget.file.isDirectory ? Icons.arrow_right : null),
onTap: () {
if(widget.file.isDirectory) {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) {
return Files(widget.path.toList()..add(widget.file.name));
},
));
} else {
if(EndpointData().getEndpointMode() == EndpointMode.stage) {
InfoDialog.show(context, 'Virtuelle Dateien im Staging Prozess können nicht heruntergeladen werden!');
return;
}
if(widget.file.currentlyDownloading) {
showDialog(
context: context,
builder: (context) => ConfirmDialog(
title: 'Download abbrechen?',
content: 'Möchtest du den Download abbrechen?',
cancelButton: 'Nein',
confirmButton: 'Ja, Abbrechen',
onConfirm: () {
downloadCore?.then((value) {
if(!value.isCancelled) value.cancel();
});
setState(() {
widget.file.currentlyDownloading = false;
percent = 0;
downloadCore = null;
});
},
),
);
return;
}
setState(() {
widget.file.currentlyDownloading = true;
});
downloadCore = FileElement.download(context, widget.file.path, widget.file.name, (progress) {
setState(() => percent = progress);
}, (result) {
if(result.type != ResultType.done) {
showDialog(context: context, builder: (context) {
return AlertDialog(
title: const Text('Download'),
content: Text(result.message),
);
});
}
setState(() {
widget.file.currentlyDownloading = false;
percent = 0;
});
});
}
},
onLongPress: () {
showDialog(context: context, builder: (context) {
return SimpleDialog(
children: [
ListTile(
leading: const Icon(Icons.delete_outline),
title: const Text('Löschen'),
onTap: () {
Navigator.of(context).pop();
showDialog(context: context, builder: (context) => ConfirmDialog(
title: 'Element löschen?',
content: 'Das Element wird unwiederruflich gelöscht.',
onConfirm: () {
WebdavApi.webdav
.then((value) => value.delete(PathUri.parse(widget.file.path)))
.then((value) => widget.refetch());
}
));
},
),
Visibility(
visible: !kReleaseMode,
child: ListTile(
leading: const Icon(Icons.share_outlined),
title: const Text('Teilen'),
onTap: () {
Navigator.of(context).pop();
UnimplementedDialog.show(context);
},
),
),
],
);
});
},
);
}
}