1
0
Fork 0

Closes #773 - Add shortcuts to homescreen (#4925)

master
Tiger Oakes 2019-08-29 15:45:11 -04:00 committed by Colin Lee
parent ca118033a2
commit f740d4382a
13 changed files with 85 additions and 16 deletions

View File

@ -353,6 +353,7 @@ dependencies {
implementation Deps.mozilla_feature_media implementation Deps.mozilla_feature_media
implementation Deps.mozilla_feature_prompts implementation Deps.mozilla_feature_prompts
implementation Deps.mozilla_feature_push implementation Deps.mozilla_feature_push
implementation Deps.mozilla_feature_pwa
implementation Deps.mozilla_feature_qr implementation Deps.mozilla_feature_qr
implementation Deps.mozilla_feature_search implementation Deps.mozilla_feature_search
implementation Deps.mozilla_feature_session implementation Deps.mozilla_feature_session

View File

@ -19,7 +19,9 @@ class Components(private val context: Context) {
val services by lazy { Services(backgroundServices.accountManager) } val services by lazy { Services(backgroundServices.accountManager) }
val core by lazy { Core(context) } val core by lazy { Core(context) }
val search by lazy { Search(context) } val search by lazy { Search(context) }
val useCases by lazy { UseCases(context, core.sessionManager, core.engine.settings, search.searchEngineManager) } val useCases by lazy {
UseCases(context, core.sessionManager, core.engine.settings, search.searchEngineManager, core.client)
}
val utils by lazy { Utilities(context, core.sessionManager, useCases.sessionUseCases, useCases.searchUseCases) } val utils by lazy { Utilities(context, core.sessionManager, useCases.sessionUseCases, useCases.searchUseCases) }
val analytics by lazy { Analytics(context) } val analytics by lazy { Analytics(context) }
val publicSuffixList by lazy { PublicSuffixList(context) } val publicSuffixList by lazy { PublicSuffixList(context) }

View File

@ -8,7 +8,9 @@ import android.content.Context
import mozilla.components.browser.search.SearchEngineManager import mozilla.components.browser.search.SearchEngineManager
import mozilla.components.browser.session.SessionManager import mozilla.components.browser.session.SessionManager
import mozilla.components.concept.engine.Settings import mozilla.components.concept.engine.Settings
import mozilla.components.concept.fetch.Client
import mozilla.components.feature.app.links.AppLinksUseCases import mozilla.components.feature.app.links.AppLinksUseCases
import mozilla.components.feature.pwa.WebAppUseCases
import mozilla.components.feature.search.SearchUseCases import mozilla.components.feature.search.SearchUseCases
import mozilla.components.feature.session.SessionUseCases import mozilla.components.feature.session.SessionUseCases
import mozilla.components.feature.session.SettingsUseCases import mozilla.components.feature.session.SettingsUseCases
@ -24,7 +26,8 @@ class UseCases(
private val context: Context, private val context: Context,
private val sessionManager: SessionManager, private val sessionManager: SessionManager,
private val engineSettings: Settings, private val engineSettings: Settings,
private val searchEngineManager: SearchEngineManager private val searchEngineManager: SearchEngineManager,
private val httpClient: Client
) { ) {
/** /**
* Use cases that provide engine interactions for a given browser session. * Use cases that provide engine interactions for a given browser session.
@ -47,4 +50,6 @@ class UseCases(
val settingsUseCases by lazy { SettingsUseCases(engineSettings, sessionManager) } val settingsUseCases by lazy { SettingsUseCases(engineSettings, sessionManager) }
val appLinksUseCases by lazy { AppLinksUseCases(context.applicationContext) } val appLinksUseCases by lazy { AppLinksUseCases(context.applicationContext) }
val webAppUseCases by lazy { WebAppUseCases(context, sessionManager, httpClient, supportWebApps = false) }
} }

View File

@ -23,13 +23,15 @@ class Utilities(
private val searchUseCases: SearchUseCases private val searchUseCases: SearchUseCases
) { ) {
/** /**
* Provides intent processing functionality for CustomTab, ACTION_VIEW * Provides intent processing functionality for ACTION_VIEW and ACTION_SEND intents.
* and ACTION_SEND intents.
*/ */
val intentProcessor by lazy { val intentProcessor by lazy {
TabIntentProcessor(sessionManager, sessionUseCases.loadUrl, searchUseCases.newTabSearch, isPrivate = false) TabIntentProcessor(sessionManager, sessionUseCases.loadUrl, searchUseCases.newTabSearch, isPrivate = false)
} }
/**
* Provides intent processing functionality for ACTION_VIEW and ACTION_SEND intents in private tabs.
*/
val privateIntentProcessor by lazy { val privateIntentProcessor by lazy {
TabIntentProcessor(sessionManager, sessionUseCases.loadUrl, searchUseCases.newTabSearch, isPrivate = true) TabIntentProcessor(sessionManager, sessionUseCases.loadUrl, searchUseCases.newTabSearch, isPrivate = true)
} }

View File

@ -253,7 +253,7 @@ sealed class Event {
enum class Item { enum class Item {
SETTINGS, LIBRARY, HELP, DESKTOP_VIEW_ON, DESKTOP_VIEW_OFF, FIND_IN_PAGE, NEW_TAB, SETTINGS, LIBRARY, HELP, DESKTOP_VIEW_ON, DESKTOP_VIEW_OFF, FIND_IN_PAGE, NEW_TAB,
NEW_PRIVATE_TAB, SHARE, REPORT_SITE_ISSUE, BACK, FORWARD, RELOAD, STOP, OPEN_IN_FENIX, NEW_PRIVATE_TAB, SHARE, REPORT_SITE_ISSUE, BACK, FORWARD, RELOAD, STOP, OPEN_IN_FENIX,
SAVE_TO_COLLECTION SAVE_TO_COLLECTION, ADD_TO_HOMESCREEN
} }
override val extras: Map<Events.browserMenuActionKeys, String>? override val extras: Map<Events.browserMenuActionKeys, String>?

View File

@ -11,14 +11,16 @@ import androidx.core.widget.NestedScrollView
import androidx.navigation.NavController import androidx.navigation.NavController
import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetBehavior
import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.ObsoleteCoroutinesApi import kotlinx.coroutines.ObsoleteCoroutinesApi
import kotlinx.coroutines.launch
import mozilla.components.browser.session.Session import mozilla.components.browser.session.Session
import mozilla.components.concept.engine.EngineView import mozilla.components.concept.engine.EngineView
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.browser.browsingmode.BrowsingModeManager
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.browser.BrowserFragment import org.mozilla.fenix.browser.BrowserFragment
import org.mozilla.fenix.browser.BrowserFragmentDirections import org.mozilla.fenix.browser.BrowserFragmentDirections
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.browser.browsingmode.BrowsingModeManager
import org.mozilla.fenix.collections.CreateCollectionViewModel import org.mozilla.fenix.collections.CreateCollectionViewModel
import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.components
@ -86,6 +88,11 @@ class DefaultBrowserToolbarController(
item.isChecked, item.isChecked,
currentSession currentSession
) )
ToolbarMenu.Item.AddToHomeScreen -> {
MainScope().launch {
context.components.useCases.webAppUseCases.addToHomescreen()
}
}
ToolbarMenu.Item.Share -> { ToolbarMenu.Item.Share -> {
val currentUrl = currentSession?.url val currentUrl = currentSession?.url
currentUrl?.apply { currentUrl?.apply {
@ -175,6 +182,7 @@ class DefaultBrowserToolbarController(
ToolbarMenu.Item.OpenInFenix -> Event.BrowserMenuItemTapped.Item.OPEN_IN_FENIX ToolbarMenu.Item.OpenInFenix -> Event.BrowserMenuItemTapped.Item.OPEN_IN_FENIX
ToolbarMenu.Item.Share -> Event.BrowserMenuItemTapped.Item.SHARE ToolbarMenu.Item.Share -> Event.BrowserMenuItemTapped.Item.SHARE
ToolbarMenu.Item.SaveToCollection -> Event.BrowserMenuItemTapped.Item.SAVE_TO_COLLECTION ToolbarMenu.Item.SaveToCollection -> Event.BrowserMenuItemTapped.Item.SAVE_TO_COLLECTION
ToolbarMenu.Item.AddToHomeScreen -> Event.BrowserMenuItemTapped.Item.ADD_TO_HOMESCREEN
} }
context.components.analytics.metrics.track(Event.BrowserMenuItemTapped(eventItem)) context.components.analytics.metrics.track(Event.BrowserMenuItemTapped(eventItem))

View File

@ -11,12 +11,12 @@ import mozilla.components.browser.menu.item.BrowserMenuHighlightableItem
import mozilla.components.browser.menu.item.BrowserMenuImageText import mozilla.components.browser.menu.item.BrowserMenuImageText
import mozilla.components.browser.menu.item.BrowserMenuItemToolbar import mozilla.components.browser.menu.item.BrowserMenuItemToolbar
import mozilla.components.browser.menu.item.BrowserMenuSwitch import mozilla.components.browser.menu.item.BrowserMenuSwitch
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.theme.ThemeManager import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.ext.asActivity import org.mozilla.fenix.ext.asActivity
import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.components
import org.mozilla.fenix.theme.ThemeManager
class DefaultToolbarMenu( class DefaultToolbarMenu(
private val context: Context, private val context: Context,
@ -133,10 +133,22 @@ class DefaultToolbarMenu(
onItemTapped.invoke(ToolbarMenu.Item.Library) onItemTapped.invoke(ToolbarMenu.Item.Library)
}, },
BrowserMenuSwitch(context.getString(R.string.browser_menu_desktop_site), BrowserMenuSwitch(
requestDesktopStateProvider, { checked -> context.getString(R.string.browser_menu_desktop_site),
onItemTapped.invoke(ToolbarMenu.Item.RequestDesktop(checked)) requestDesktopStateProvider
}), ) { checked ->
onItemTapped.invoke(ToolbarMenu.Item.RequestDesktop(checked))
},
BrowserMenuImageText(
context.getString(R.string.browser_menu_add_to_homescreen),
R.drawable.ic_add_to_homescreen,
ThemeManager.resolveAttribute(R.attr.primaryText, context)
) {
onItemTapped.invoke(ToolbarMenu.Item.AddToHomeScreen)
}.apply {
visible = ::shouldShowAddToHomescreen
},
BrowserMenuImageText( BrowserMenuImageText(
context.getString(R.string.browser_menu_find_in_page), context.getString(R.string.browser_menu_find_in_page),
@ -201,4 +213,9 @@ class DefaultToolbarMenu(
items items
} }
private fun shouldShowAddToHomescreen(): Boolean {
return context.components.useCases.webAppUseCases.isPinningSupported() &&
context.components.core.sessionManager.selectedSession != null
}
} }

View File

@ -24,6 +24,7 @@ interface ToolbarMenu {
object ReportIssue : Item() object ReportIssue : Item()
object OpenInFenix : Item() object OpenInFenix : Item()
object SaveToCollection : Item() object SaveToCollection : Item()
object AddToHomeScreen : Item()
} }
val menuBuilder: BrowserMenuBuilder val menuBuilder: BrowserMenuBuilder

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M20.3 4.3L15 9.59V8a1 1 0 0 0-2 0v4a1 1 0 0 0 1 1h4a1 1 0 0 0 0-2h-1.6l5.3-5.3a1 1 0 1 0-1.42-1.42zM16 18a1 1 0 1 0-2 0 1 1 0 0 0 2 0zm1 2H7V4h11.44a0.5 0.5 0 0 0 0.5-0.6A3 3 0 0 0 16 1H8a3 3 0 0 0-3 3v16a3 3 0 0 0 3 3h8a3 3 0 0 0 3-3v-5a1 1 0 0 0-2 0v5zm-3.5 2h-3a0.5 0.5 0 1 1 0-1h3a0.5 0.5 0 1 1 0 1zm-0.5-4a1 1 0 1 0-2 0 1 1 0 0 0 2 0zm-4-1a1 1 0 1 0 0 2 1 1 0 0 0 0-2zm3-3a1 1 0 1 0 0 2 1 1 0 0 0 0-2z"
android:fillColor="?primaryText"/>
</vector>

View File

@ -48,6 +48,8 @@
<string name="browser_menu_your_library">Your Library</string> <string name="browser_menu_your_library">Your Library</string>
<!-- Browser menu toggle that requests a desktop site --> <!-- Browser menu toggle that requests a desktop site -->
<string name="browser_menu_desktop_site">Desktop site</string> <string name="browser_menu_desktop_site">Desktop site</string>
<!-- Browser menu toggle that adds a shortcut to the site on the device home screen. -->
<string name="browser_menu_add_to_homescreen">Add to Home screen</string>
<!-- Browser menu button that opens the find in page menu --> <!-- Browser menu button that opens the find in page menu -->
<string name="browser_menu_find_in_page">Find in page</string> <string name="browser_menu_find_in_page">Find in page</string>
<!-- Browser menu button that creates a private tab --> <!-- Browser menu button that creates a private tab -->

View File

@ -16,7 +16,15 @@ class TestComponents(private val context: Context) : Components(context) {
override val services by lazy { Services(backgroundServices.accountManager) } override val services by lazy { Services(backgroundServices.accountManager) }
override val core by lazy { TestCore(context) } override val core by lazy { TestCore(context) }
override val search by lazy { Search(context) } override val search by lazy { Search(context) }
override val useCases by lazy { UseCases(context, core.sessionManager, core.engine.settings, search.searchEngineManager) } override val useCases by lazy {
UseCases(
context,
core.sessionManager,
core.engine.settings,
search.searchEngineManager,
core.client
)
}
override val utils by lazy { override val utils by lazy {
Utilities( Utilities(
context, context,

View File

@ -22,12 +22,12 @@ import mozilla.components.feature.session.SessionUseCases
import mozilla.components.feature.tabs.TabsUseCases import mozilla.components.feature.tabs.TabsUseCases
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.browser.browsingmode.BrowsingModeManager
import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.browser.BrowserFragment import org.mozilla.fenix.browser.BrowserFragment
import org.mozilla.fenix.browser.BrowserFragmentDirections import org.mozilla.fenix.browser.BrowserFragmentDirections
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.browser.browsingmode.BrowsingModeManager
import org.mozilla.fenix.collections.CreateCollectionViewModel import org.mozilla.fenix.collections.CreateCollectionViewModel
import org.mozilla.fenix.components.Analytics import org.mozilla.fenix.components.Analytics
import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.components.metrics.Event
@ -211,6 +211,15 @@ class DefaultBrowserToolbarControllerTest {
} }
} }
@Test
fun handleToolbarAddToHomeScreenPress() {
val item = ToolbarMenu.Item.AddToHomeScreen
controller.handleToolbarItemInteraction(item)
verify { metrics.track(Event.BrowserMenuItemTapped(Event.BrowserMenuItemTapped.Item.ADD_TO_HOMESCREEN)) }
}
@Test @Test
fun handleToolbarSharePress() { fun handleToolbarSharePress() {
val item = ToolbarMenu.Item.Share val item = ToolbarMenu.Item.Share

View File

@ -123,6 +123,7 @@ object Deps {
const val mozilla_feature_storage = "org.mozilla.components:feature-storage:${Versions.mozilla_android_components}" const val mozilla_feature_storage = "org.mozilla.components:feature-storage:${Versions.mozilla_android_components}"
const val mozilla_feature_prompts = "org.mozilla.components:feature-prompts:${Versions.mozilla_android_components}" const val mozilla_feature_prompts = "org.mozilla.components:feature-prompts:${Versions.mozilla_android_components}"
const val mozilla_feature_push = "org.mozilla.components:feature-push:${Versions.mozilla_android_components}" const val mozilla_feature_push = "org.mozilla.components:feature-push:${Versions.mozilla_android_components}"
const val mozilla_feature_pwa = "org.mozilla.components:feature-pwa:${Versions.mozilla_android_components}"
const val mozilla_feature_toolbar = "org.mozilla.components:feature-toolbar:${Versions.mozilla_android_components}" const val mozilla_feature_toolbar = "org.mozilla.components:feature-toolbar:${Versions.mozilla_android_components}"
const val mozilla_feature_findinpage = "org.mozilla.components:feature-findinpage:${Versions.mozilla_android_components}" const val mozilla_feature_findinpage = "org.mozilla.components:feature-findinpage:${Versions.mozilla_android_components}"
const val mozilla_feature_site_permissions = "org.mozilla.components:feature-sitepermissions:${Versions.mozilla_android_components}" const val mozilla_feature_site_permissions = "org.mozilla.components:feature-sitepermissions:${Versions.mozilla_android_components}"