diff --git a/app/src/main/java/org/mozilla/fenix/BrowserDirection.kt b/app/src/main/java/org/mozilla/fenix/BrowserDirection.kt index aebf52a37..a0538c43d 100644 --- a/app/src/main/java/org/mozilla/fenix/BrowserDirection.kt +++ b/app/src/main/java/org/mozilla/fenix/BrowserDirection.kt @@ -23,5 +23,6 @@ enum class BrowserDirection(@IdRes val fragmentId: Int) { FromExceptions(R.id.exceptionsFragment), FromAbout(R.id.aboutFragment), FromTrackingProtection(R.id.trackingProtectionFragment), - FromDefaultBrowserSettingsFragment(R.id.defaultBrowserSettingsFragment) + FromDefaultBrowserSettingsFragment(R.id.defaultBrowserSettingsFragment), + FromSavedLoginsFragment(R.id.savedLoginsFragment) } diff --git a/app/src/main/java/org/mozilla/fenix/HomeActivity.kt b/app/src/main/java/org/mozilla/fenix/HomeActivity.kt index 1978fe0cd..b87bcdd1c 100644 --- a/app/src/main/java/org/mozilla/fenix/HomeActivity.kt +++ b/app/src/main/java/org/mozilla/fenix/HomeActivity.kt @@ -61,6 +61,7 @@ import org.mozilla.fenix.settings.DefaultBrowserSettingsFragmentDirections import org.mozilla.fenix.settings.SettingsFragmentDirections import org.mozilla.fenix.settings.TrackingProtectionFragmentDirections import org.mozilla.fenix.settings.about.AboutFragmentDirections +import org.mozilla.fenix.settings.logins.SavedLoginsFragmentDirections import org.mozilla.fenix.theme.DefaultThemeManager import org.mozilla.fenix.theme.ThemeManager import org.mozilla.fenix.utils.BrowsersCache @@ -308,6 +309,10 @@ open class HomeActivity : LocaleAwareAppCompatActivity() { DefaultBrowserSettingsFragmentDirections.actionDefaultBrowserSettingsFragmentToBrowserFragment( customTabSessionId ) + BrowserDirection.FromSavedLoginsFragment -> + SavedLoginsFragmentDirections.actionSavedLoginsFragmentToBrowserFragment( + customTabSessionId + ) } private fun load( diff --git a/app/src/main/java/org/mozilla/fenix/settings/SupportUtils.kt b/app/src/main/java/org/mozilla/fenix/settings/SupportUtils.kt index 2257e4b03..36378da43 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/SupportUtils.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/SupportUtils.kt @@ -34,7 +34,8 @@ object SupportUtils { SET_AS_DEFAULT_BROWSER("set-firefox-preview-default"), SEARCH_SUGGESTION("how-search-firefox-preview"), CUSTOM_SEARCH_ENGINES("custom-search-engines"), - UPGRADE_FAQ("firefox-preview-upgrade-faqs") + UPGRADE_FAQ("firefox-preview-upgrade-faqs"), + SYNC_SETUP("how-set-firefox-sync-firefox-preview") } /** diff --git a/app/src/main/java/org/mozilla/fenix/settings/logins/SavedLoginsFragment.kt b/app/src/main/java/org/mozilla/fenix/settings/logins/SavedLoginsFragment.kt index d2e410061..498b49d6f 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/logins/SavedLoginsFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/logins/SavedLoginsFragment.kt @@ -20,11 +20,14 @@ import kotlinx.coroutines.ObsoleteCoroutinesApi import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import mozilla.components.lib.state.ext.consumeFrom +import org.mozilla.fenix.BrowserDirection +import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.R import org.mozilla.fenix.components.StoreProvider import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.showToolbar +import org.mozilla.fenix.settings.SupportUtils class SavedLoginsFragment : Fragment() { private lateinit var savedLoginsStore: SavedLoginsFragmentStore @@ -53,7 +56,7 @@ class SavedLoginsFragment : Fragment() { ) ) } - savedLoginsInteractor = SavedLoginsInteractor(::itemClicked) + savedLoginsInteractor = SavedLoginsInteractor(::itemClicked, ::openLearnMore) savedLoginsView = SavedLoginsView(view.savedLoginsLayout, savedLoginsInteractor) lifecycleScope.launch(Main) { loadAndMapLogins() } return view @@ -86,6 +89,15 @@ class SavedLoginsFragment : Fragment() { findNavController().navigate(directions) } + private fun openLearnMore() { + (activity as HomeActivity).openToBrowserAndLoad( + searchTermOrURL = SupportUtils.getGenericSumoURLForTopic + (SupportUtils.SumoTopic.SYNC_SETUP), + newTab = true, + from = BrowserDirection.FromSavedLoginsFragment + ) + } + private suspend fun loadAndMapLogins() { val syncedLogins = withContext(IO) { requireContext().components.core.syncablePasswordsStorage.withUnlocked { diff --git a/app/src/main/java/org/mozilla/fenix/settings/logins/SavedLoginsInteractor.kt b/app/src/main/java/org/mozilla/fenix/settings/logins/SavedLoginsInteractor.kt index c0ef0f842..5aa7ae1c5 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/logins/SavedLoginsInteractor.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/logins/SavedLoginsInteractor.kt @@ -9,9 +9,13 @@ package org.mozilla.fenix.settings.logins * Provides implementations for the SavedLoginsViewInteractor */ class SavedLoginsInteractor( - private val itemClicked: (SavedLoginsItem) -> Unit + private val itemClicked: (SavedLoginsItem) -> Unit, + private val learnMore: () -> Unit ) : SavedLoginsViewInteractor { override fun itemClicked(item: SavedLoginsItem) { itemClicked.invoke(item) } + override fun onLearnMore() { + learnMore.invoke() + } } diff --git a/app/src/main/java/org/mozilla/fenix/settings/logins/SavedLoginsView.kt b/app/src/main/java/org/mozilla/fenix/settings/logins/SavedLoginsView.kt index 450e6f042..5835d0044 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/logins/SavedLoginsView.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/logins/SavedLoginsView.kt @@ -4,6 +4,9 @@ package org.mozilla.fenix.settings.logins +import android.text.SpannableString +import android.text.method.LinkMovementMethod +import android.text.style.UnderlineSpan import android.view.LayoutInflater import android.view.ViewGroup import android.widget.FrameLayout @@ -22,6 +25,8 @@ interface SavedLoginsViewInteractor { * Called whenever one item is clicked */ fun itemClicked(item: SavedLoginsItem) + + fun onLearnMore() } /** @@ -43,10 +48,21 @@ class SavedLoginsView( adapter = loginsAdapter layoutManager = LinearLayoutManager(containerView.context) } + + val learnMoreText = view.saved_passwords_empty_learn_more.text.toString() + val textWithLink = SpannableString(learnMoreText).apply { + setSpan(UnderlineSpan(), 0, learnMoreText.length, 0) + } + with(view.saved_passwords_empty_learn_more) { + movementMethod = LinkMovementMethod.getInstance() + text = textWithLink + setOnClickListener { interactor.onLearnMore() } + } } fun update(state: SavedLoginsFragmentState) { view.saved_logins_list.isVisible = state.items.isNotEmpty() + view.saved_passwords_empty_view.isVisible = state.items.isEmpty() loginsAdapter.submitList(state.items) } } diff --git a/app/src/main/res/layout/component_saved_logins.xml b/app/src/main/res/layout/component_saved_logins.xml index 28ff14a99..a58ebd965 100644 --- a/app/src/main/res/layout/component_saved_logins.xml +++ b/app/src/main/res/layout/component_saved_logins.xml @@ -3,14 +3,44 @@ - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> + + + + + + + diff --git a/app/src/main/res/navigation/nav_graph.xml b/app/src/main/res/navigation/nav_graph.xml index 789ee6de9..4d798eec2 100644 --- a/app/src/main/res/navigation/nav_graph.xml +++ b/app/src/main/res/navigation/nav_graph.xml @@ -662,6 +662,11 @@ + Sign in to Sync Saved logins + + The logins you save or sync to Firefox will show up here. + + Learn more about Sync. Exceptions diff --git a/app/src/test/java/org/mozilla/fenix/settings/logins/SavedLoginsInteractorTest.kt b/app/src/test/java/org/mozilla/fenix/settings/logins/SavedLoginsInteractorTest.kt index 7bfe86b7f..9434f6720 100644 --- a/app/src/test/java/org/mozilla/fenix/settings/logins/SavedLoginsInteractorTest.kt +++ b/app/src/test/java/org/mozilla/fenix/settings/logins/SavedLoginsInteractorTest.kt @@ -13,8 +13,10 @@ class SavedLoginsInteractorTest { @Test fun itemClicked() { val savedLoginClicked: (SavedLoginsItem) -> Unit = mockk(relaxed = true) + val learnMore: () -> Unit = mockk(relaxed = true) val interactor = SavedLoginsInteractor( - savedLoginClicked + savedLoginClicked, + learnMore ) val item = SavedLoginsItem("mozilla.org", "username", "password")