import 'dart:io'; import 'dart:math'; import 'package:flutter/material.dart'; import 'package:open_filex/open_filex.dart'; import 'package:photo_view/photo_view.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:share_plus/share_plus.dart'; import 'package:syncfusion_flutter_pdfviewer/pdfviewer.dart'; import '../routing/app_routes.dart'; import '../state/app/modules/settings/bloc/settings_cubit.dart'; import '../utils/file_saver.dart'; import 'info_dialog.dart'; import 'placeholder_view.dart'; import 'share_position_origin.dart'; class FileViewer extends StatefulWidget { final String path; final bool openExternal; const FileViewer({super.key, required this.path, this.openExternal = false}); @override State createState() => _FileViewerState(); } enum FileViewingActions { openExternal, share, save } class _FileViewerState extends State { PhotoViewController photoViewController = PhotoViewController(); late SettingsCubit settings = context.read(); late bool openExternal; @override void initState() { openExternal = settings.val().fileViewSettings.alwaysOpenExternally || widget.openExternal; super.initState(); } @override Widget build(BuildContext context) { AppBar appbar({List actions = const []}) => AppBar( title: Text(widget.path.split('/').last), actions: [ ...actions, PopupMenuButton( onSelected: (value) async { switch(value) { case FileViewingActions.openExternal: AppRoutes.openFileViewer(context, 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; } }, 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, ), ), ], ), ], ); switch(openExternal ? '' : widget.path.split('.').last.toLowerCase()) { case 'png': case 'jpg': case 'jpeg': case 'webp': case 'gif': return Scaffold( appBar: appbar( actions: [ IconButton(onPressed: () { setState(() { photoViewController.rotation += pi/2; }); }, icon: const Icon(Icons.rotate_right)), ] ), backgroundColor: Colors.white, body: PhotoView( controller: photoViewController, maxScale: 3.0, minScale: 0.1, imageProvider: Image.file(File(widget.path)).image, backgroundDecoration: BoxDecoration(color: Theme.of(context).colorScheme.surface), ) ); case 'pdf': return Scaffold( appBar: appbar(), body: SfPdfViewer.file( File(widget.path), ), ); default: OpenFilex.open(widget.path).then((result) { if (!context.mounted) return; Navigator.of(context).pop(); if(result.type != ResultType.done) { showDialog(context: context, builder: (context) => AlertDialog( content: Text(result.message), )); } }); return PlaceholderView( text: 'Datei extern geöffnet', icon: Icons.open_in_new, button: TextButton( onPressed: () => Navigator.of(context).pop(), child: const Text('Zurück'), ), ); } } }