diff --git a/lib/pages/chat/chat.dart b/lib/pages/chat/chat.dart index e93541af..2a812084 100644 --- a/lib/pages/chat/chat.dart +++ b/lib/pages/chat/chat.dart @@ -108,7 +108,7 @@ class ChatController extends State { MessageTypes.File, }.contains(selectedEvents.single.messageType); - void saveSelectedEvent() => selectedEvents.single.saveFile(context); + void saveSelectedEvent(context) => selectedEvents.single.saveFile(context); List selectedEvents = []; diff --git a/lib/pages/chat/chat_view.dart b/lib/pages/chat/chat_view.dart index 920f5354..dc96c80b 100644 --- a/lib/pages/chat/chat_view.dart +++ b/lib/pages/chat/chat_view.dart @@ -46,11 +46,13 @@ class ChatView extends StatelessWidget { onPressed: controller.copyEventsAction, ), if (controller.canSaveSelectedEvent) - IconButton( - icon: Icon(Icons.adaptive.share), - tooltip: L10n.of(context)!.share, - onPressed: controller.saveSelectedEvent, - ), + // Use builder context to correctly position the share dialog on iPad + Builder( + builder: (context) => IconButton( + icon: Icon(Icons.adaptive.share), + tooltip: L10n.of(context)!.share, + onPressed: () => controller.saveSelectedEvent(context), + )), if (controller.canRedactSelectedEvents) IconButton( icon: const Icon(Icons.delete_outlined), diff --git a/lib/pages/homeserver_picker/homeserver_picker_view.dart b/lib/pages/homeserver_picker/homeserver_picker_view.dart index 387622a2..c44e3c94 100644 --- a/lib/pages/homeserver_picker/homeserver_picker_view.dart +++ b/lib/pages/homeserver_picker/homeserver_picker_view.dart @@ -18,6 +18,8 @@ class HomeserverPickerView extends StatelessWidget { final benchmarkResults = controller.benchmarkResults; return LoginScaffold( appBar: AppBar( + elevation: 0, + scrolledUnderElevation: 0, backgroundColor: Colors.transparent, actions: [ IconButton( diff --git a/lib/pages/image_viewer/image_viewer.dart b/lib/pages/image_viewer/image_viewer.dart index fd9a3666..3e8f6290 100644 --- a/lib/pages/image_viewer/image_viewer.dart +++ b/lib/pages/image_viewer/image_viewer.dart @@ -25,10 +25,10 @@ class ImageViewerController extends State { } /// Save this file with a system call. - void saveFileAction() => widget.event.saveFile(context); + void saveFileAction(BuildContext context) => widget.event.saveFile(context); /// Save this file with a system call. - void shareFileAction() => widget.event.shareFile(context); + void shareFileAction(BuildContext context) => widget.event.shareFile(context); static const maxScaleFactor = 1.5; diff --git a/lib/pages/image_viewer/image_viewer_view.dart b/lib/pages/image_viewer/image_viewer_view.dart index ee90da16..c0970446 100644 --- a/lib/pages/image_viewer/image_viewer_view.dart +++ b/lib/pages/image_viewer/image_viewer_view.dart @@ -35,17 +35,19 @@ class ImageViewerView extends StatelessWidget { if (!PlatformInfos.isIOS) IconButton( icon: const Icon(Icons.download_outlined), - onPressed: controller.saveFileAction, + onPressed: () => controller.saveFileAction(context), color: Colors.white, tooltip: L10n.of(context)!.downloadFile, ), if (PlatformInfos.isMobile) - IconButton( - onPressed: controller.shareFileAction, - tooltip: L10n.of(context)!.share, - color: Colors.white, - icon: Icon(Icons.adaptive.share_outlined), - ) + // Use builder context to correctly position the share dialog on iPad + Builder( + builder: (context) => IconButton( + onPressed: () => controller.shareFileAction(context), + tooltip: L10n.of(context)!.share, + color: Colors.white, + icon: Icon(Icons.adaptive.share_outlined), + )) ], ), body: InteractiveViewer( diff --git a/lib/utils/matrix_sdk_extensions.dart/matrix_file_extension.dart b/lib/utils/matrix_sdk_extensions.dart/matrix_file_extension.dart index 64343d8b..e4342182 100644 --- a/lib/utils/matrix_sdk_extensions.dart/matrix_file_extension.dart +++ b/lib/utils/matrix_sdk_extensions.dart/matrix_file_extension.dart @@ -26,10 +26,15 @@ extension MatrixFileExtension on MatrixFile { final tmpDirectory = await getTemporaryDirectory(); final path = '${tmpDirectory.path}$fileName'; await File(path).writeAsBytes(bytes); - final box = context.findRenderObject() as RenderBox; + + // Workaround for iPad from + // https://github.com/fluttercommunity/plus_plugins/tree/main/packages/share_plus/share_plus#ipad + final box = context.findRenderObject() as RenderBox?; + await Share.shareFiles( [path], - sharePositionOrigin: box.localToGlobal(Offset.zero) & box.size, + sharePositionOrigin: + box == null ? null : box.localToGlobal(Offset.zero) & box.size, ); return; } diff --git a/pubspec.lock b/pubspec.lock index 82dacb50..da031916 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1506,7 +1506,7 @@ packages: name: share_plus url: "https://pub.dartlang.org" source: hosted - version: "4.0.9" + version: "4.0.10+1" share_plus_linux: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index ecf3129c..a5033a9f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -78,7 +78,7 @@ dependencies: receive_sharing_intent: ^1.4.5 record: ^4.3.2 scroll_to_index: ^3.0.1 - share_plus: ^4.0.9 + share_plus: ^4.0.10+1 shared_preferences: ^2.0.13 slugify: ^2.0.0 swipe_to_action: ^0.2.0