diff --git a/lib/utils/FileSaver.dart b/lib/utils/FileSaver.dart new file mode 100644 index 0000000..1a1a88c --- /dev/null +++ b/lib/utils/FileSaver.dart @@ -0,0 +1,23 @@ +import 'dart:io'; + +import 'package:permission_handler/permission_handler.dart'; + +// only tested on android! +class FileSaver { + static Future getExternalDocumentPath() async { + var permission = await Permission.storage.status; + if(!permission.isGranted) { + await Permission.storage.request(); + } + var directory = Directory('/storage/emulated/0/Download'); + final externalPath = directory.path; + await Directory(externalPath).create(recursive: true); + return externalPath; + } + + static Future writeBytes(List bytes, String name) async { + final path = await getExternalDocumentPath(); + var file = File('$path/$name'); + return file.writeAsBytes(bytes); + } +} diff --git a/lib/widget/fileViewer.dart b/lib/widget/fileViewer.dart index 085caf4..54f6557 100644 --- a/lib/widget/fileViewer.dart +++ b/lib/widget/fileViewer.dart @@ -9,6 +9,8 @@ import 'package:share_plus/share_plus.dart'; import 'package:syncfusion_flutter_pdfviewer/pdfviewer.dart'; import '../storage/base/settingsProvider.dart'; +import '../utils/FileSaver.dart'; +import 'infoDialog.dart'; import 'placeholderView.dart'; import 'sharePositionOrigin.dart'; @@ -21,6 +23,12 @@ class FileViewer extends StatefulWidget { State createState() => _FileViewerState(); } +enum FileViewingActions { + openExternal, + share, + save +} + class _FileViewerState extends State { PhotoViewController photoViewController = PhotoViewController(); @@ -38,22 +46,57 @@ class _FileViewerState extends State { AppBar appbar({List actions = const []}) => AppBar( title: Text(widget.path.split('/').last), actions: [ - IconButton( - onPressed: () => Navigator.of(context).push( - MaterialPageRoute(builder: (context) => FileViewer(path: widget.path, openExternal: true)) - ), - icon: const Icon(Icons.open_in_new) - ), - IconButton( - onPressed: () { - Share.shareXFiles( - [XFile(widget.path)], - sharePositionOrigin: SharePositionOrigin.get(context), - ); + ...actions, + PopupMenuButton( + onSelected: (value) async { + switch(value) { + case FileViewingActions.openExternal: + Navigator.of(context).push( + MaterialPageRoute(builder: (context) => FileViewer(path: widget.path, openExternal: true)) + ); + break; + case FileViewingActions.share: + SharePlus.instance.share( + ShareParams( + files: [XFile(widget.path)], + sharePositionOrigin: SharePositionOrigin.get(context) + ) + ); + break; + case FileViewingActions.save: + await FileSaver.writeBytes(await File(widget.path).readAsBytes(), widget.path.split('/').last); + if(!context.mounted) return; + InfoDialog.show(context, 'Die Datei wurde im Downloads Ordner gespeichert.'); + break; + } }, - icon: const Icon(Icons.share_outlined), + itemBuilder: (context) => >[ + const PopupMenuItem( + value: FileViewingActions.openExternal, + child: ListTile( + leading: Icon(Icons.open_in_new), + title: Text('Extern öffnen'), + dense: true, + ), + ), + const PopupMenuItem( + value: FileViewingActions.share, + child: ListTile( + leading: Icon(Icons.share_outlined), + title: Text('Teilen'), + dense: true, + ), + ), + if(Platform.isAndroid) const PopupMenuItem( + value: FileViewingActions.save, + child: ListTile( + leading: Icon(Icons.save_alt_outlined), + title: Text('Speichern'), + dense: true, + ), + ), + ], ), - ...actions ], ); diff --git a/pubspec.yaml b/pubspec.yaml index 58f013e..2fb8c8d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -64,6 +64,7 @@ dependencies: open_filex: ^4.7.0 package_info_plus: ^8.1.3 path_provider: ^2.1.5 + permission_handler: ^12.0.1 persistent_bottom_nav_bar_v2: ^6.1.0 photo_view: ^0.15.0 pretty_json: ^2.0.0