From 419a4a78cf66f5596d6fd4e45b5921b19d6461e3 Mon Sep 17 00:00:00 2001 From: ashilkn Date: Wed, 5 Jun 2024 12:54:53 +0530 Subject: [PATCH] [mob][photos] Fix share outside of ente not working at multiple places on iPad For the ios share sheet to be shown properly on iPad, the position of the button that triggered it needs to be known, which requires BuildContext and GlobalKey of the button, which is difficult to pass from some parts of code. So to make it work, we pass a default point on the screen so that the share sheet at least shows up --- .../file_selection_actions_widget.dart | 7 ++- mobile/lib/utils/share_util.dart | 47 +++++++++++++++---- 2 files changed, 45 insertions(+), 9 deletions(-) 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; +}