From e705f37ea1c88f40d5953d92f045f625864f22b7 Mon Sep 17 00:00:00 2001 From: Fabian Freund Date: Fri, 20 Mar 2026 05:24:36 +0100 Subject: [PATCH] show minimal contect menu in pwa/custom tabs --- .../android/build.gradle | 1 + .../ExternalAppBrowserFragment.kt | 33 +++++++++++++++++++ .../components/UseCases.kt | 6 ++++ 3 files changed, 40 insertions(+) diff --git a/packages/flutter_mozilla_components/android/build.gradle b/packages/flutter_mozilla_components/android/build.gradle index 80680ec3..0eca7fdf 100644 --- a/packages/flutter_mozilla_components/android/build.gradle +++ b/packages/flutter_mozilla_components/android/build.gradle @@ -120,6 +120,7 @@ dependencies { implementation "org.mozilla.components:feature-accounts-push:$mozillaComponentsVersion" implementation "org.mozilla.components:feature-awesomebar:$mozillaComponentsVersion" implementation "org.mozilla.components:feature-customtabs:$mozillaComponentsVersion" + implementation "org.mozilla.components:feature-contextmenu:$mozillaComponentsVersion" implementation "org.mozilla.components:feature-downloads:$mozillaComponentsVersion" implementation "org.mozilla.components:feature-media:$mozillaComponentsVersion" implementation "org.mozilla.components:feature-tabs:$mozillaComponentsVersion" diff --git a/packages/flutter_mozilla_components/android/src/main/kotlin/eu/weblibre/flutter_mozilla_components/ExternalAppBrowserFragment.kt b/packages/flutter_mozilla_components/android/src/main/kotlin/eu/weblibre/flutter_mozilla_components/ExternalAppBrowserFragment.kt index 4e4fd560..07054073 100644 --- a/packages/flutter_mozilla_components/android/src/main/kotlin/eu/weblibre/flutter_mozilla_components/ExternalAppBrowserFragment.kt +++ b/packages/flutter_mozilla_components/android/src/main/kotlin/eu/weblibre/flutter_mozilla_components/ExternalAppBrowserFragment.kt @@ -25,6 +25,8 @@ import com.mikepenz.iconics.utils.colorInt import com.mikepenz.iconics.utils.sizeDp import eu.weblibre.flutter_mozilla_components.widget.CustomTabToolbar import eu.weblibre.flutter_mozilla_components.widget.CustomTabToolbarFeature +import mozilla.components.feature.contextmenu.ContextMenuCandidate +import mozilla.components.feature.contextmenu.ContextMenuFeature import mozilla.components.browser.state.selector.findCustomTab import mozilla.components.browser.state.state.ExternalAppType import mozilla.components.concept.engine.EngineView @@ -46,6 +48,7 @@ import mozilla.components.support.ktx.android.arch.lifecycle.addObservers class ExternalAppBrowserFragment : BaseBrowserFragment(), UserInteractionHandler { private val customTabsToolbarFeature = ViewBoundFeatureWrapper() + private val contextMenuFeature = ViewBoundFeatureWrapper() private val hideToolbarFeature = ViewBoundFeatureWrapper() private val windowFeature = ViewBoundFeatureWrapper() @@ -78,10 +81,40 @@ class ExternalAppBrowserFragment : BaseBrowserFragment(), UserInteractionHandler } } + private fun createContextMenuCandidates(view: View): List { + return listOf( + ContextMenuCandidate.createCopyLinkCandidate(requireContext(), view), + ContextMenuCandidate.createShareLinkCandidate(requireContext()), + ContextMenuCandidate.createSaveImageCandidate( + requireContext(), + components.useCases.contextMenuUseCases, + ), + ContextMenuCandidate.createSaveVideoAudioCandidate( + requireContext(), + components.useCases.contextMenuUseCases, + ), + ContextMenuCandidate.createCopyImageLocationCandidate(requireContext(), view), + ) + } + override fun onEngineSetupComplete() { val sessionId = customTabSessionId ?: return val store = components.core.store val customTab = store.state.findCustomTab(sessionId) ?: return + val engineView = components.externalAppEngineView ?: return + + contextMenuFeature.set( + feature = ContextMenuFeature( + fragmentManager = parentFragmentManager, + store = store, + candidates = createContextMenuCandidates(requireView()), + engineView = engineView, + useCases = components.useCases.contextMenuUseCases, + tabId = sessionId, + ), + owner = this, + view = requireView(), + ) val isPwaOrTwa = customTab.config.externalAppType == ExternalAppType.PROGRESSIVE_WEB_APP || customTab.config.externalAppType == ExternalAppType.TRUSTED_WEB_ACTIVITY diff --git a/packages/flutter_mozilla_components/android/src/main/kotlin/eu/weblibre/flutter_mozilla_components/components/UseCases.kt b/packages/flutter_mozilla_components/android/src/main/kotlin/eu/weblibre/flutter_mozilla_components/components/UseCases.kt index 3ffbe587..cdca9f1d 100644 --- a/packages/flutter_mozilla_components/android/src/main/kotlin/eu/weblibre/flutter_mozilla_components/components/UseCases.kt +++ b/packages/flutter_mozilla_components/android/src/main/kotlin/eu/weblibre/flutter_mozilla_components/components/UseCases.kt @@ -8,6 +8,7 @@ import android.content.Context import mozilla.components.browser.state.store.BrowserStore import mozilla.components.concept.engine.Engine import mozilla.components.feature.app.links.AppLinksUseCases +import mozilla.components.feature.contextmenu.ContextMenuUseCases import mozilla.components.feature.downloads.DownloadsUseCases import mozilla.components.feature.session.SessionUseCases import mozilla.components.feature.session.SettingsUseCases @@ -47,6 +48,11 @@ class UseCases( */ val downloadsUseCases: DownloadsUseCases by lazy { DownloadsUseCases(store, context) } + /** + * Use cases related to the context menu feature. + */ + val contextMenuUseCases: ContextMenuUseCases by lazy { ContextMenuUseCases(store) } + /** * Use cases related to Custom Tabs. */