diff --git a/app/lib/features/geckoview/features/contextmenu/extensions/hit_result.dart b/app/lib/features/geckoview/features/contextmenu/extensions/hit_result.dart index 92e035a8..47e9701a 100644 --- a/app/lib/features/geckoview/features/contextmenu/extensions/hit_result.dart +++ b/app/lib/features/geckoview/features/contextmenu/extensions/hit_result.dart @@ -37,6 +37,26 @@ extension HitResultJson on HitResult { extension HitResultX on HitResult { Uri? tryGetLink() { + const maxTitleLength = 2500; + + final uri = switch (this) { + UnknownHitResult(src: final src) => src, + ImageHitResult(src: final src, title: final title) => + title.isEmpty ? (src.length > maxTitleLength ? 'image' : src) : title!, + VideoHitResult(src: final src, title: final title) => + title.isEmpty ? src : title!, + AudioHitResult(src: final src, title: final title) => + title.isEmpty ? src : title!, + ImageSrcHitResult(uri: final uri) => uri, + PhoneHitResult() => 'about:blank', + EmailHitResult() => 'about:blank', + GeoHitResult() => 'about:blank', + }; + + return Uri.tryParse(uri); + } + + Uri? tryGetSource() { final uri = switch (this) { UnknownHitResult(src: final src) => src, ImageHitResult(src: final src) => src, @@ -67,7 +87,9 @@ extension HitResultX on HitResult { }; } - bool get hasSrc => tryGetLink() != null; + bool get hasSrc => tryGetSource() != null; + + bool get hasLink => tryGetLink() != null; bool isImage() { return (this is ImageHitResult || this is ImageSrcHitResult) && hasSrc; @@ -82,7 +104,8 @@ extension HitResultX on HitResult { } bool isUri() { - return (this is UnknownHitResult && hasSrc) || this is ImageSrcHitResult; + return (this is UnknownHitResult && hasLink) || + (this is ImageSrcHitResult && hasLink); } bool isHttpLink() { @@ -96,13 +119,13 @@ extension HitResultX on HitResult { bool isIntent() { return this is UnknownHitResult && - hasSrc && + hasLink && tryGetLink()?.scheme == 'intent'; } bool isMailto() { return this is UnknownHitResult && - hasSrc && + hasLink && tryGetLink()?.scheme == 'mailto'; } } diff --git a/app/lib/features/geckoview/features/contextmenu/presentation/candidates/copy_image.dart b/app/lib/features/geckoview/features/contextmenu/presentation/candidates/copy_image.dart index 4f9c72cf..ff2f9cbb 100644 --- a/app/lib/features/geckoview/features/contextmenu/presentation/candidates/copy_image.dart +++ b/app/lib/features/geckoview/features/contextmenu/presentation/candidates/copy_image.dart @@ -41,7 +41,7 @@ class CopyImage extends HookConsumerWidget { title: const Text('Copy image'), onTap: () async { final currentTab = ref.read(selectedTabStateProvider); - final url = hitResult.tryGetLink(); + final url = hitResult.tryGetSource(); if (currentTab != null && url != null) { await GeckoDownloadsService().copyInternetResource( diff --git a/app/lib/features/geckoview/features/contextmenu/presentation/candidates/copy_image_location.dart b/app/lib/features/geckoview/features/contextmenu/presentation/candidates/copy_image_location.dart index e7db1211..ad8fdd1b 100644 --- a/app/lib/features/geckoview/features/contextmenu/presentation/candidates/copy_image_location.dart +++ b/app/lib/features/geckoview/features/contextmenu/presentation/candidates/copy_image_location.dart @@ -41,7 +41,7 @@ class CopyImageLocation extends HookConsumerWidget { leading: const Icon(MdiIcons.imageMarker), title: const Text('Copy image location'), onTap: () async { - await hitResult.tryGetLink().mapNotNull((link) async { + await hitResult.tryGetSource().mapNotNull((link) async { await Clipboard.setData(ClipboardData(text: link.toString())); if (context.mounted) { diff --git a/app/lib/features/geckoview/features/contextmenu/presentation/candidates/open_image_new_tab.dart b/app/lib/features/geckoview/features/contextmenu/presentation/candidates/open_image_new_tab.dart index a290f533..0d9bc52a 100644 --- a/app/lib/features/geckoview/features/contextmenu/presentation/candidates/open_image_new_tab.dart +++ b/app/lib/features/geckoview/features/contextmenu/presentation/candidates/open_image_new_tab.dart @@ -55,7 +55,7 @@ class OpenImageInNewTab extends HookConsumerWidget { final tabId = await ref .read(tabRepositoryProvider.notifier) .addTab( - url: hitResult.tryGetLink(), + url: hitResult.tryGetSource(), parentId: currentTab?.id, selectTab: false, private: isPrivate, diff --git a/app/lib/features/geckoview/features/contextmenu/presentation/candidates/save_image.dart b/app/lib/features/geckoview/features/contextmenu/presentation/candidates/save_image.dart index 4994e29d..d9a3503a 100644 --- a/app/lib/features/geckoview/features/contextmenu/presentation/candidates/save_image.dart +++ b/app/lib/features/geckoview/features/contextmenu/presentation/candidates/save_image.dart @@ -41,7 +41,7 @@ class SaveImage extends HookConsumerWidget { title: const Text('Save image'), onTap: () async { final currentTab = ref.read(selectedTabStateProvider); - final url = hitResult.tryGetLink(); + final url = hitResult.tryGetSource(); if (currentTab != null && url != null) { await GeckoDownloadsService().requestDownload( diff --git a/app/lib/features/geckoview/features/contextmenu/presentation/candidates/share_image.dart b/app/lib/features/geckoview/features/contextmenu/presentation/candidates/share_image.dart index 729a1d72..7a26f1b0 100644 --- a/app/lib/features/geckoview/features/contextmenu/presentation/candidates/share_image.dart +++ b/app/lib/features/geckoview/features/contextmenu/presentation/candidates/share_image.dart @@ -41,7 +41,7 @@ class ShareImage extends HookConsumerWidget { title: const Text('Share image'), onTap: () async { final currentTab = ref.read(selectedTabStateProvider); - final url = hitResult.tryGetLink(); + final url = hitResult.tryGetSource(); if (currentTab != null && url != null) { await GeckoDownloadsService().shareInternetResource(