diff --git a/mobile/lib/ui/viewer/actions/file_selection_actions_widget.dart b/mobile/lib/ui/viewer/actions/file_selection_actions_widget.dart index d9555f8aad..d162ec9ba4 100644 --- a/mobile/lib/ui/viewer/actions/file_selection_actions_widget.dart +++ b/mobile/lib/ui/viewer/actions/file_selection_actions_widget.dart @@ -777,7 +777,12 @@ class _FileSelectionActionsWidgetState final String url = "${_cachedCollectionForSharedLink!.publicURLs?.first?.url}#$collectionKey"; unawaited(Clipboard.setData(ClipboardData(text: url))); - await shareImageAndUrl(placeholderPath!, url, context, sendLinkButtonKey); + await shareImageAndUrl( + placeholderPath!, + url, + context: context, + key: sendLinkButtonKey, + ); if (placeholderPath != null) { final file = File(placeholderPath!); try { diff --git a/mobile/lib/utils/share_util.dart b/mobile/lib/utils/share_util.dart index ec15ee8146..b55730439a 100644 --- a/mobile/lib/utils/share_util.dart +++ b/mobile/lib/utils/share_util.dart @@ -72,8 +72,10 @@ Future share( } } +/// Returns the rect of button if context and key are not null +/// If key is null, returned rect will be at the center of the screen Rect shareButtonRect(BuildContext context, GlobalKey? shareButtonKey) { - Size size = MediaQuery.of(context).size; + Size size = MediaQuery.sizeOf(context); final RenderObject? renderObject = shareButtonKey?.currentContext?.findRenderObject(); RenderBox? renderBox; @@ -92,8 +94,21 @@ Rect shareButtonRect(BuildContext context, GlobalKey? shareButtonKey) { ); } -Future shareText(String text) async { - return Share.share(text); +Future shareText( + String text, { + BuildContext? context, + GlobalKey? key, +}) async { + try { + final sharePosOrigin = _sharePosOrigin(context, key); + return Share.share( + text, + sharePositionOrigin: sharePosOrigin, + ); + } catch (e, s) { + _logger.severe("failed to share text", e, s); + return ShareResult.unavailable; + } } Future> convertIncomingSharedMediaToFile( @@ -214,13 +229,29 @@ void shareSelected( Future shareImageAndUrl( String imagePath, - String url, - BuildContext context, - GlobalKey key, -) async { + String url, { + BuildContext? context, + GlobalKey? key, +}) async { + final sharePosOrigin = _sharePosOrigin(context, key); + await Share.shareXFiles( [XFile(imagePath)], text: url, - sharePositionOrigin: shareButtonRect(context, key), + sharePositionOrigin: sharePosOrigin, ); } + +/// required for ipad https://github.com/flutter/flutter/issues/47220#issuecomment-608453383 +/// This returns the position of the share button if context and key are not null +/// and if not, it returns a default position so that the share sheet on iPad has +/// some position to show up. +Rect _sharePosOrigin(BuildContext? context, GlobalKey? key) { + late final Rect rect; + if (context != null) { + rect = shareButtonRect(context, key); + } else { + rect = const Offset(20.0, 20.0) & const Size(10, 10); + } + return rect; +}