From 62850430b7b9057ab1f8f2fcc415afed1e61a727 Mon Sep 17 00:00:00 2001 From: James Hugman Date: Tue, 16 Jul 2019 22:20:07 +0100 Subject: [PATCH] Closes AC#3695 - Add UI to open current page in external app --- .../mozilla/fenix/browser/BrowserFragment.kt | 26 +++++++++++++++- .../org/mozilla/fenix/components/UseCases.kt | 3 ++ .../quickactionsheet/QuickActionComponent.kt | 8 ++++- .../quickactionsheet/QuickActionUIView.kt | 8 +++++ ...brary_icon_app_links_circle_background.xml | 30 +++++++++++++++++++ .../res/layout/layout_quick_action_sheet.xml | 14 +++++++++ app/src/main/res/values/colors.xml | 3 ++ app/src/main/res/values/strings.xml | 2 ++ 8 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 app/src/main/res/drawable/library_icon_app_links_circle_background.xml diff --git a/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt b/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt index 3e9f202c1..180a11279 100644 --- a/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt @@ -175,12 +175,14 @@ class BrowserFragment : Fragment(), BackHandler { this, QuickActionViewModel::class.java ) { + val appLink = requireComponents.useCases.appLinksUseCases.appLinkRedirect QuickActionViewModel( QuickActionState( readable = getSessionById()?.readerable ?: false, bookmarked = findBookmarkedURL(getSessionById()), readerActive = getSessionById()?.readerMode ?: false, - bounceNeeded = false + bounceNeeded = false, + isAppLink = getSessionById()?.let { appLink.invoke(it.url).hasExternalApp() } ?: false ) ) } @@ -538,6 +540,20 @@ class BrowserFragment : Fragment(), BackHandler { feature.showControls() } } + is QuickActionAction.OpenAppLinkPressed -> { + appLinksFeature.withFeature { feature -> + val getRedirect = requireComponents.useCases.appLinksUseCases.appLinkRedirect + + val redirect = getSessionById()?.let { session -> + getRedirect.invoke(session.url) + } ?: return@withFeature + + redirect.appIntent?.flags = Intent.FLAG_ACTIVITY_NEW_TASK + + val openAppLink = requireComponents.useCases.appLinksUseCases.openAppLink + openAppLink.invoke(redirect) + } + } } } @@ -874,6 +890,7 @@ class BrowserFragment : Fragment(), BackHandler { override fun onUrlChanged(session: Session, url: String) { super.onUrlChanged(session, url) updateBookmarkState(session) + updateAppLinksState(session) } } getSessionById()?.register(observer, this) @@ -916,6 +933,13 @@ class BrowserFragment : Fragment(), BackHandler { } } + private fun updateAppLinksState(session: Session) { + val url = session.url + val appLinks = requireComponents.useCases.appLinksUseCases.appLinkRedirect + getManagedEmitter() + .onNext(QuickActionChange.AppLinkStateChange(appLinks.invoke(url).hasExternalApp())) + } + private val collectionStorageObserver = object : TabCollectionStorage.Observer { override fun onCollectionCreated(title: String, sessions: List) { super.onCollectionCreated(title, sessions) diff --git a/app/src/main/java/org/mozilla/fenix/components/UseCases.kt b/app/src/main/java/org/mozilla/fenix/components/UseCases.kt index e49340d4a..2f018465b 100644 --- a/app/src/main/java/org/mozilla/fenix/components/UseCases.kt +++ b/app/src/main/java/org/mozilla/fenix/components/UseCases.kt @@ -8,6 +8,7 @@ import android.content.Context import mozilla.components.browser.search.SearchEngineManager import mozilla.components.browser.session.SessionManager import mozilla.components.concept.engine.Settings +import mozilla.components.feature.app.links.AppLinksUseCases import mozilla.components.feature.search.SearchUseCases import mozilla.components.feature.session.SessionUseCases import mozilla.components.feature.session.SettingsUseCases @@ -44,4 +45,6 @@ class UseCases( * Use cases that provide settings management. */ val settingsUseCases by lazy { SettingsUseCases(engineSettings, sessionManager) } + + val appLinksUseCases by lazy { AppLinksUseCases(context.applicationContext) } } diff --git a/app/src/main/java/org/mozilla/fenix/quickactionsheet/QuickActionComponent.kt b/app/src/main/java/org/mozilla/fenix/quickactionsheet/QuickActionComponent.kt index 263918bab..4bd363c50 100644 --- a/app/src/main/java/org/mozilla/fenix/quickactionsheet/QuickActionComponent.kt +++ b/app/src/main/java/org/mozilla/fenix/quickactionsheet/QuickActionComponent.kt @@ -36,7 +36,8 @@ data class QuickActionState( val readable: Boolean, val bookmarked: Boolean, val readerActive: Boolean, - val bounceNeeded: Boolean + val bounceNeeded: Boolean, + val isAppLink: Boolean ) : ViewState sealed class QuickActionAction : Action { @@ -47,12 +48,14 @@ sealed class QuickActionAction : Action { object BookmarkPressed : QuickActionAction() object ReadPressed : QuickActionAction() object ReadAppearancePressed : QuickActionAction() + object OpenAppLinkPressed : QuickActionAction() } sealed class QuickActionChange : Change { data class BookmarkedStateChange(val bookmarked: Boolean) : QuickActionChange() data class ReadableStateChange(val readable: Boolean) : QuickActionChange() data class ReaderActiveStateChange(val active: Boolean) : QuickActionChange() + data class AppLinkStateChange(val isAppLink: Boolean) : QuickActionChange() object BounceNeededChange : QuickActionChange() } @@ -74,6 +77,9 @@ class QuickActionViewModel( is QuickActionChange.ReaderActiveStateChange -> { state.copy(readerActive = change.active) } + is QuickActionChange.AppLinkStateChange -> { + state.copy(isAppLink = change.isAppLink) + } } } } diff --git a/app/src/main/java/org/mozilla/fenix/quickactionsheet/QuickActionUIView.kt b/app/src/main/java/org/mozilla/fenix/quickactionsheet/QuickActionUIView.kt index b65d0dfa7..6ae82163f 100644 --- a/app/src/main/java/org/mozilla/fenix/quickactionsheet/QuickActionUIView.kt +++ b/app/src/main/java/org/mozilla/fenix/quickactionsheet/QuickActionUIView.kt @@ -79,6 +79,10 @@ class QuickActionUIView( actionEmitter.onNext(QuickActionAction.ReadAppearancePressed) quickActionSheetBehavior.state = BottomSheetBehavior.STATE_COLLAPSED } + view.quick_action_open_app_link.setOnClickListener { + actionEmitter.onNext(QuickActionAction.OpenAppLinkPressed) + quickActionSheetBehavior.state = BottomSheetBehavior.STATE_COLLAPSED + } } /** @@ -133,6 +137,10 @@ class QuickActionUIView( if (it.bounceNeeded && Settings.getInstance(view.context).shouldAutoBounceQuickActionSheet) { quickActionSheet.bounceSheet() } + + view.quick_action_open_app_link.apply { + visibility = if (it.isAppLink) View.VISIBLE else View.GONE + } } private fun updateReaderModeButton(withNotification: Boolean) { diff --git a/app/src/main/res/drawable/library_icon_app_links_circle_background.xml b/app/src/main/res/drawable/library_icon_app_links_circle_background.xml new file mode 100644 index 000000000..fceb59797 --- /dev/null +++ b/app/src/main/res/drawable/library_icon_app_links_circle_background.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/layout_quick_action_sheet.xml b/app/src/main/res/layout/layout_quick_action_sheet.xml index 4fd69692d..3f82d6ed7 100644 --- a/app/src/main/res/layout/layout_quick_action_sheet.xml +++ b/app/src/main/res/layout/layout_quick_action_sheet.xml @@ -91,6 +91,20 @@ android:textSize="12sp" android:visibility="gone" /> +