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

191 lines
6.3 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 'package:path_provider/path_provider.dart';
import '../../../api/marianumcloud/webdav/queries/listFiles/cacheableFile.dart';
import '../../../api/marianumcloud/webdav/webdavApi.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, {Key? key}) : super(key: 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_outlined : Icons.description_outlined)
),
title: Text(widget.file.name),
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(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(Uri.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);
},
),
),
],
);
});
},
);
}
}