Closes #2593: FxA automatic sign-in integration
parent
210864186b
commit
ae33234bbc
|
@ -5,6 +5,7 @@
|
||||||
package org.mozilla.fenix.home
|
package org.mozilla.fenix.home
|
||||||
|
|
||||||
import android.animation.Animator
|
import android.animation.Animator
|
||||||
|
import android.content.Context
|
||||||
import android.content.DialogInterface
|
import android.content.DialogInterface
|
||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
||||||
import android.graphics.drawable.BitmapDrawable
|
import android.graphics.drawable.BitmapDrawable
|
||||||
|
@ -158,7 +159,7 @@ class HomeFragment : Fragment(), AccountObserver {
|
||||||
): View? {
|
): View? {
|
||||||
val view = inflater.inflate(R.layout.fragment_home, container, false)
|
val view = inflater.inflate(R.layout.fragment_home, container, false)
|
||||||
|
|
||||||
val mode = currentMode()
|
val mode = currentMode(view.context)
|
||||||
|
|
||||||
sessionControlComponent = SessionControlComponent(
|
sessionControlComponent = SessionControlComponent(
|
||||||
view.homeLayout,
|
view.homeLayout,
|
||||||
|
@ -300,7 +301,7 @@ class HomeFragment : Fragment(), AccountObserver {
|
||||||
getManagedEmitter<SessionControlChange>().onNext(
|
getManagedEmitter<SessionControlChange>().onNext(
|
||||||
SessionControlChange.Change(
|
SessionControlChange.Change(
|
||||||
tabs = getListOfSessions().toTabs(),
|
tabs = getListOfSessions().toTabs(),
|
||||||
mode = currentMode(),
|
mode = currentMode(context!!),
|
||||||
collections = requireComponents.core.tabCollectionStorage.cachedTabCollections
|
collections = requireComponents.core.tabCollectionStorage.cachedTabCollections
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -325,7 +326,7 @@ class HomeFragment : Fragment(), AccountObserver {
|
||||||
is OnboardingAction.Finish -> {
|
is OnboardingAction.Finish -> {
|
||||||
onboarding.finish()
|
onboarding.finish()
|
||||||
|
|
||||||
val mode = currentMode()
|
val mode = currentMode(context!!)
|
||||||
getManagedEmitter<SessionControlChange>().onNext(SessionControlChange.ModeChange(mode))
|
getManagedEmitter<SessionControlChange>().onNext(SessionControlChange.ModeChange(mode))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -705,12 +706,18 @@ class HomeFragment : Fragment(), AccountObserver {
|
||||||
nav(R.id.homeFragment, directions)
|
nav(R.id.homeFragment, directions)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun currentMode(): Mode = if (!onboarding.userHasBeenOnboarded()) {
|
private fun currentMode(context: Context): Mode = if (!onboarding.userHasBeenOnboarded()) {
|
||||||
val account = requireComponents.backgroundServices.accountManager.authenticatedAccount()
|
val accountManager = requireComponents.backgroundServices.accountManager
|
||||||
if (account == null) {
|
val account = accountManager.authenticatedAccount()
|
||||||
Mode.Onboarding(OnboardingState.SignedOut)
|
if (account != null) {
|
||||||
|
Mode.Onboarding(OnboardingState.SignedIn)
|
||||||
} else {
|
} else {
|
||||||
Mode.Onboarding(OnboardingState.ManuallySignedIn)
|
val availableAccounts = accountManager.shareableAccounts(context)
|
||||||
|
if (availableAccounts.isEmpty()) {
|
||||||
|
Mode.Onboarding(OnboardingState.SignedOutNoAutoSignIn)
|
||||||
|
} else {
|
||||||
|
Mode.Onboarding(OnboardingState.SignedOutCanAutoSignIn(availableAccounts[0]))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if ((activity as HomeActivity).browsingModeManager.isPrivate) {
|
} else if ((activity as HomeActivity).browsingModeManager.isPrivate) {
|
||||||
Mode.Private
|
Mode.Private
|
||||||
|
@ -719,12 +726,22 @@ class HomeFragment : Fragment(), AccountObserver {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun emitAccountChanges() {
|
private fun emitAccountChanges() {
|
||||||
val mode = currentMode()
|
context?.let {
|
||||||
getManagedEmitter<SessionControlChange>().onNext(SessionControlChange.ModeChange(mode))
|
val mode = currentMode(it)
|
||||||
|
getManagedEmitter<SessionControlChange>().onNext(SessionControlChange.ModeChange(mode))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onAuthenticated(account: OAuthAccount) {
|
||||||
|
view?.let {
|
||||||
|
FenixSnackbar.make(it, Snackbar.LENGTH_SHORT).setText(
|
||||||
|
it.context.getString(R.string.onboarding_firefox_account_sync_is_on)
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
emitAccountChanges()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onAuthenticationProblems() = emitAccountChanges()
|
override fun onAuthenticationProblems() = emitAccountChanges()
|
||||||
override fun onAuthenticated(account: OAuthAccount) = emitAccountChanges()
|
|
||||||
override fun onLoggedOut() = emitAccountChanges()
|
override fun onLoggedOut() = emitAccountChanges()
|
||||||
override fun onProfileUpdated(profile: Profile) = emitAccountChanges()
|
override fun onProfileUpdated(profile: Profile) = emitAccountChanges()
|
||||||
|
|
||||||
|
|
|
@ -22,9 +22,10 @@ import org.mozilla.fenix.home.sessioncontrol.viewholders.SaveTabGroupViewHolder
|
||||||
import org.mozilla.fenix.home.sessioncontrol.viewholders.TabHeaderViewHolder
|
import org.mozilla.fenix.home.sessioncontrol.viewholders.TabHeaderViewHolder
|
||||||
import org.mozilla.fenix.home.sessioncontrol.viewholders.TabInCollectionViewHolder
|
import org.mozilla.fenix.home.sessioncontrol.viewholders.TabInCollectionViewHolder
|
||||||
import org.mozilla.fenix.home.sessioncontrol.viewholders.TabViewHolder
|
import org.mozilla.fenix.home.sessioncontrol.viewholders.TabViewHolder
|
||||||
|
import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.OnboardingAutomaticSignInViewHolder
|
||||||
import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.OnboardingFinishViewHolder
|
import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.OnboardingFinishViewHolder
|
||||||
import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.OnboardingFirefoxAccountViewHolder
|
|
||||||
import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.OnboardingHeaderViewHolder
|
import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.OnboardingHeaderViewHolder
|
||||||
|
import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.OnboardingManualSignInViewHolder
|
||||||
import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.OnboardingPrivacyNoticeViewHolder
|
import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.OnboardingPrivacyNoticeViewHolder
|
||||||
import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.OnboardingPrivateBrowsingViewHolder
|
import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.OnboardingPrivateBrowsingViewHolder
|
||||||
import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.OnboardingSectionHeaderViewHolder
|
import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.OnboardingSectionHeaderViewHolder
|
||||||
|
@ -67,9 +68,12 @@ sealed class AdapterItem(@LayoutRes val viewType: Int) {
|
||||||
) : AdapterItem(OnboardingSectionHeaderViewHolder.LAYOUT_ID) {
|
) : AdapterItem(OnboardingSectionHeaderViewHolder.LAYOUT_ID) {
|
||||||
override fun sameAs(other: AdapterItem) = other is OnboardingSectionHeader && labelBuilder == other.labelBuilder
|
override fun sameAs(other: AdapterItem) = other is OnboardingSectionHeader && labelBuilder == other.labelBuilder
|
||||||
}
|
}
|
||||||
data class OnboardingFirefoxAccount(
|
data class OnboardingManualSignIn(
|
||||||
val state: OnboardingState
|
val state: OnboardingState
|
||||||
) : AdapterItem(OnboardingFirefoxAccountViewHolder.LAYOUT_ID)
|
) : AdapterItem(OnboardingManualSignInViewHolder.LAYOUT_ID)
|
||||||
|
data class OnboardingAutomaticSignIn(
|
||||||
|
val state: OnboardingState
|
||||||
|
) : AdapterItem(OnboardingAutomaticSignInViewHolder.LAYOUT_ID)
|
||||||
object OnboardingThemePicker : AdapterItem(OnboardingThemePickerViewHolder.LAYOUT_ID)
|
object OnboardingThemePicker : AdapterItem(OnboardingThemePickerViewHolder.LAYOUT_ID)
|
||||||
object OnboardingTrackingProtection : AdapterItem(OnboardingTrackingProtectionViewHolder.LAYOUT_ID)
|
object OnboardingTrackingProtection : AdapterItem(OnboardingTrackingProtectionViewHolder.LAYOUT_ID)
|
||||||
object OnboardingPrivateBrowsing : AdapterItem(OnboardingPrivateBrowsingViewHolder.LAYOUT_ID)
|
object OnboardingPrivateBrowsing : AdapterItem(OnboardingPrivateBrowsingViewHolder.LAYOUT_ID)
|
||||||
|
@ -108,7 +112,8 @@ class SessionControlAdapter(
|
||||||
TabInCollectionViewHolder.LAYOUT_ID -> TabInCollectionViewHolder(view, actionEmitter)
|
TabInCollectionViewHolder.LAYOUT_ID -> TabInCollectionViewHolder(view, actionEmitter)
|
||||||
OnboardingHeaderViewHolder.LAYOUT_ID -> OnboardingHeaderViewHolder(view)
|
OnboardingHeaderViewHolder.LAYOUT_ID -> OnboardingHeaderViewHolder(view)
|
||||||
OnboardingSectionHeaderViewHolder.LAYOUT_ID -> OnboardingSectionHeaderViewHolder(view)
|
OnboardingSectionHeaderViewHolder.LAYOUT_ID -> OnboardingSectionHeaderViewHolder(view)
|
||||||
OnboardingFirefoxAccountViewHolder.LAYOUT_ID -> OnboardingFirefoxAccountViewHolder(view)
|
OnboardingAutomaticSignInViewHolder.LAYOUT_ID -> OnboardingAutomaticSignInViewHolder(view)
|
||||||
|
OnboardingManualSignInViewHolder.LAYOUT_ID -> OnboardingManualSignInViewHolder(view)
|
||||||
OnboardingThemePickerViewHolder.LAYOUT_ID -> OnboardingThemePickerViewHolder(view)
|
OnboardingThemePickerViewHolder.LAYOUT_ID -> OnboardingThemePickerViewHolder(view)
|
||||||
OnboardingTrackingProtectionViewHolder.LAYOUT_ID -> OnboardingTrackingProtectionViewHolder(view)
|
OnboardingTrackingProtectionViewHolder.LAYOUT_ID -> OnboardingTrackingProtectionViewHolder(view)
|
||||||
OnboardingPrivateBrowsingViewHolder.LAYOUT_ID -> OnboardingPrivateBrowsingViewHolder(view)
|
OnboardingPrivateBrowsingViewHolder.LAYOUT_ID -> OnboardingPrivateBrowsingViewHolder(view)
|
||||||
|
@ -145,8 +150,13 @@ class SessionControlAdapter(
|
||||||
is OnboardingSectionHeaderViewHolder -> holder.bind(
|
is OnboardingSectionHeaderViewHolder -> holder.bind(
|
||||||
(item as AdapterItem.OnboardingSectionHeader).labelBuilder
|
(item as AdapterItem.OnboardingSectionHeader).labelBuilder
|
||||||
)
|
)
|
||||||
is OnboardingFirefoxAccountViewHolder -> holder.bind(
|
is OnboardingManualSignInViewHolder -> holder.bind()
|
||||||
(item as AdapterItem.OnboardingFirefoxAccount).state == OnboardingState.AutoSignedIn
|
is OnboardingAutomaticSignInViewHolder -> holder.bind(
|
||||||
|
(
|
||||||
|
(
|
||||||
|
item as AdapterItem.OnboardingAutomaticSignIn
|
||||||
|
).state as OnboardingState.SignedOutCanAutoSignIn
|
||||||
|
).withAccount
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ import androidx.recyclerview.widget.RecyclerView
|
||||||
import io.reactivex.Observer
|
import io.reactivex.Observer
|
||||||
import kotlinx.android.parcel.Parcelize
|
import kotlinx.android.parcel.Parcelize
|
||||||
import mozilla.components.browser.session.Session
|
import mozilla.components.browser.session.Session
|
||||||
|
import mozilla.components.service.fxa.sharing.ShareableAccount
|
||||||
import org.mozilla.fenix.ext.components
|
import org.mozilla.fenix.ext.components
|
||||||
import org.mozilla.fenix.mvi.ViewState
|
import org.mozilla.fenix.mvi.ViewState
|
||||||
import org.mozilla.fenix.mvi.Change
|
import org.mozilla.fenix.mvi.Change
|
||||||
|
@ -69,13 +70,13 @@ fun List<Tab>.toSessionBundle(context: Context): MutableList<Session> {
|
||||||
/**
|
/**
|
||||||
* Describes various onboarding states.
|
* Describes various onboarding states.
|
||||||
*/
|
*/
|
||||||
enum class OnboardingState {
|
sealed class OnboardingState {
|
||||||
// Signed out, no account carried over from Fennec.
|
// Signed out, without an option to auto-login using a shared FxA account.
|
||||||
SignedOut,
|
object SignedOutNoAutoSignIn : OnboardingState()
|
||||||
// Auto-signed in, via a Fennec account.
|
// Signed out, with an option to auto-login into a shared FxA account.
|
||||||
AutoSignedIn,
|
data class SignedOutCanAutoSignIn(val withAccount: ShareableAccount) : OnboardingState()
|
||||||
// Manually signed in while in onboarding.
|
// Signed in.
|
||||||
ManuallySignedIn
|
object SignedIn : OnboardingState()
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class Mode {
|
sealed class Mode {
|
||||||
|
|
|
@ -79,17 +79,17 @@ private fun onboardingAdapterItems(onboardingState: OnboardingState): List<Adapt
|
||||||
|
|
||||||
// Customize FxA items based on where we are with the account state:
|
// Customize FxA items based on where we are with the account state:
|
||||||
items.addAll(when (onboardingState) {
|
items.addAll(when (onboardingState) {
|
||||||
OnboardingState.SignedOut -> {
|
OnboardingState.SignedOutNoAutoSignIn -> {
|
||||||
listOf(
|
listOf(
|
||||||
AdapterItem.OnboardingFirefoxAccount(onboardingState)
|
AdapterItem.OnboardingManualSignIn(onboardingState)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
OnboardingState.AutoSignedIn -> {
|
is OnboardingState.SignedOutCanAutoSignIn -> {
|
||||||
listOf(
|
listOf(
|
||||||
AdapterItem.OnboardingFirefoxAccount(onboardingState)
|
AdapterItem.OnboardingAutomaticSignIn(onboardingState)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
else -> listOf()
|
OnboardingState.SignedIn -> listOf()
|
||||||
})
|
})
|
||||||
|
|
||||||
items.addAll(listOf(
|
items.addAll(listOf(
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
package org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding
|
||||||
|
|
||||||
|
import android.view.View
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.google.android.material.snackbar.Snackbar
|
||||||
|
import kotlinx.android.synthetic.main.onboarding_automatic_signin.view.turn_on_sync_button
|
||||||
|
import kotlinx.android.synthetic.main.onboarding_automatic_signin.view.header_text
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import mozilla.components.service.fxa.sharing.ShareableAccount
|
||||||
|
import org.mozilla.fenix.R
|
||||||
|
import org.mozilla.fenix.components.FenixSnackbar
|
||||||
|
import org.mozilla.fenix.ext.components
|
||||||
|
|
||||||
|
class OnboardingAutomaticSignInViewHolder(private val view: View) : RecyclerView.ViewHolder(view) {
|
||||||
|
private lateinit var shareableAccount: ShareableAccount
|
||||||
|
|
||||||
|
init {
|
||||||
|
view.turn_on_sync_button.setOnClickListener {
|
||||||
|
it.turn_on_sync_button.text = it.context.getString(
|
||||||
|
R.string.onboarding_firefox_account_signing_in
|
||||||
|
)
|
||||||
|
it.turn_on_sync_button.isEnabled = false
|
||||||
|
|
||||||
|
CoroutineScope(Dispatchers.Main).launch {
|
||||||
|
val result = view.context.components.backgroundServices.accountManager
|
||||||
|
.signInWithShareableAccountAsync(shareableAccount).await()
|
||||||
|
if (result) {
|
||||||
|
// Success.
|
||||||
|
} else {
|
||||||
|
// Failed to sign-in (either network problem, or bad credentials). Allow to try again.
|
||||||
|
it.turn_on_sync_button.text = it.context.getString(
|
||||||
|
R.string.onboarding_firefox_account_auto_signin_confirm
|
||||||
|
)
|
||||||
|
it.turn_on_sync_button.isEnabled = true
|
||||||
|
FenixSnackbar.make(it, Snackbar.LENGTH_SHORT).setText(
|
||||||
|
it.context.getString(R.string.onboarding_firefox_account_automatic_signin_failed)
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bind(account: ShareableAccount) {
|
||||||
|
shareableAccount = account
|
||||||
|
view.header_text.text = view.context.getString(
|
||||||
|
R.string.onboarding_firefox_account_auto_signin_header_2, account.email
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val LAYOUT_ID = R.layout.onboarding_automatic_signin
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,55 +0,0 @@
|
||||||
/* 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/. */
|
|
||||||
|
|
||||||
package org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding
|
|
||||||
|
|
||||||
import android.view.View
|
|
||||||
import androidx.appcompat.content.res.AppCompatResources
|
|
||||||
import androidx.navigation.Navigation
|
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
|
||||||
import kotlinx.android.synthetic.main.onboarding_firefox_account.view.*
|
|
||||||
import mozilla.components.support.ktx.android.view.putCompoundDrawablesRelativeWithIntrinsicBounds
|
|
||||||
import org.mozilla.fenix.R
|
|
||||||
import org.mozilla.fenix.home.HomeFragmentDirections
|
|
||||||
|
|
||||||
class OnboardingFirefoxAccountViewHolder(private val view: View) : RecyclerView.ViewHolder(view) {
|
|
||||||
private val avatarAnonymousDrawable by lazy {
|
|
||||||
AppCompatResources.getDrawable(view.context, R.drawable.ic_onboarding_avatar_anonymous)
|
|
||||||
}
|
|
||||||
private val firefoxAccountsDrawable by lazy {
|
|
||||||
AppCompatResources.getDrawable(view.context, R.drawable.ic_onboarding_firefox_accounts)
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
view.turn_on_sync_button.setOnClickListener {
|
|
||||||
val directions = HomeFragmentDirections.actionHomeFragmentToTurnOnSyncFragment()
|
|
||||||
Navigation.findNavController(view).navigate(directions)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun bind(autoSignedIn: Boolean) {
|
|
||||||
updateHeaderText(autoSignedIn)
|
|
||||||
updateButtonVisibility(autoSignedIn)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun updateButtonVisibility(autoSignedIn: Boolean) {
|
|
||||||
view.turn_on_sync_button.visibility = if (autoSignedIn) View.GONE else View.VISIBLE
|
|
||||||
view.stay_signed_in_button.visibility = if (autoSignedIn) View.VISIBLE else View.GONE
|
|
||||||
view.sign_out_button.visibility = if (autoSignedIn) View.VISIBLE else View.GONE
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun updateHeaderText(autoSignedIn: Boolean) {
|
|
||||||
val icon = if (autoSignedIn) avatarAnonymousDrawable else firefoxAccountsDrawable
|
|
||||||
view.header_text.putCompoundDrawablesRelativeWithIntrinsicBounds(start = icon)
|
|
||||||
|
|
||||||
val appName = view.context.getString(R.string.app_name)
|
|
||||||
view.header_text.text =
|
|
||||||
if (autoSignedIn) view.context.getString(R.string.onboarding_firefox_account_auto_signin_header)
|
|
||||||
else view.context.getString(R.string.onboarding_firefox_account_header, appName)
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
const val LAYOUT_ID = R.layout.onboarding_firefox_account
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
package org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding
|
||||||
|
|
||||||
|
import android.view.View
|
||||||
|
import androidx.navigation.Navigation
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import kotlinx.android.synthetic.main.onboarding_manual_signin.view.*
|
||||||
|
import org.mozilla.fenix.R
|
||||||
|
import org.mozilla.fenix.home.HomeFragmentDirections
|
||||||
|
|
||||||
|
class OnboardingManualSignInViewHolder(private val view: View) : RecyclerView.ViewHolder(view) {
|
||||||
|
init {
|
||||||
|
view.turn_on_sync_button.setOnClickListener {
|
||||||
|
val directions = HomeFragmentDirections.actionHomeFragmentToTurnOnSyncFragment()
|
||||||
|
Navigation.findNavController(view).navigate(directions)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bind() {
|
||||||
|
val appName = view.context.getString(R.string.app_name)
|
||||||
|
view.header_text.text = view.context.getString(R.string.onboarding_firefox_account_header, appName)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val LAYOUT_ID = R.layout.onboarding_manual_signin
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
<?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/. -->
|
||||||
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
style="@style/OnboardingCardDark"
|
||||||
|
android:id="@+id/onboarding_card"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatTextView
|
||||||
|
android:id="@+id/header_text"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="14dp"
|
||||||
|
tools:text="@string/onboarding_firefox_account_auto_signin_header_2"
|
||||||
|
android:drawableStart="@drawable/ic_onboarding_avatar_anonymous"
|
||||||
|
android:drawablePadding="12dp"
|
||||||
|
android:textAppearance="@style/Header16TextStyle"
|
||||||
|
android:textColor="@color/onboarding_card_primary_text_dark" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/turn_on_sync_button"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:background="@drawable/button_background"
|
||||||
|
android:clickable="true"
|
||||||
|
android:focusable="true"
|
||||||
|
android:gravity="center"
|
||||||
|
android:padding="10dp"
|
||||||
|
android:text="@string/onboarding_firefox_account_auto_signin_confirm"
|
||||||
|
android:textAllCaps="false"
|
||||||
|
android:textColor="?neutral"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
app:backgroundTint="@color/onboarding_card_button_background_dark" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
|
@ -18,7 +18,7 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginBottom="14dp"
|
android:layout_marginBottom="14dp"
|
||||||
tools:text="@string/onboarding_firefox_account_header"
|
tools:text="@string/onboarding_firefox_account_header"
|
||||||
tools:drawableStart="@drawable/ic_onboarding_firefox_accounts"
|
android:drawableStart="@drawable/ic_onboarding_firefox_accounts"
|
||||||
android:drawablePadding="12dp"
|
android:drawablePadding="12dp"
|
||||||
android:textAppearance="@style/Header16TextStyle"
|
android:textAppearance="@style/Header16TextStyle"
|
||||||
android:textColor="@color/onboarding_card_primary_text_dark" />
|
android:textColor="@color/onboarding_card_primary_text_dark" />
|
||||||
|
@ -39,38 +39,4 @@
|
||||||
android:textSize="14sp"
|
android:textSize="14sp"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
app:backgroundTint="@color/onboarding_card_button_background_dark" />
|
app:backgroundTint="@color/onboarding_card_button_background_dark" />
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/stay_signed_in_button"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="16dp"
|
|
||||||
android:background="@drawable/button_background"
|
|
||||||
android:backgroundTint="@color/onboarding_card_button_background_dark"
|
|
||||||
android:clickable="true"
|
|
||||||
android:focusable="true"
|
|
||||||
android:gravity="center"
|
|
||||||
android:padding="10dp"
|
|
||||||
android:text="@string/onboarding_firefox_account_stay_signed_in"
|
|
||||||
android:textAllCaps="false"
|
|
||||||
android:textColor="?neutral"
|
|
||||||
android:textSize="14sp"
|
|
||||||
android:textStyle="bold"
|
|
||||||
android:visibility="gone" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/sign_out_button"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="16dp"
|
|
||||||
android:background="@drawable/button_background"
|
|
||||||
android:backgroundTint="@color/onboarding_card_button_background_dark"
|
|
||||||
android:clickable="true"
|
|
||||||
android:focusable="true"
|
|
||||||
android:padding="10dp"
|
|
||||||
android:text="@string/onboarding_firefox_account_sign_out"
|
|
||||||
android:textAllCaps="false"
|
|
||||||
android:textColor="?neutral"
|
|
||||||
android:textSize="12sp"
|
|
||||||
android:visibility="gone" />
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
|
@ -641,13 +641,19 @@
|
||||||
<string name="onboarding_firefox_account_header">Get the most out of %s.</string>
|
<string name="onboarding_firefox_account_header">Get the most out of %s.</string>
|
||||||
<!-- text for the firefox account onboarding card header when we detect you're already signed in to
|
<!-- text for the firefox account onboarding card header when we detect you're already signed in to
|
||||||
another Firefox browser. (The word `Firefox` should not be translated -->
|
another Firefox browser. (The word `Firefox` should not be translated -->
|
||||||
<string name="onboarding_firefox_account_auto_signin_header">You are signed in to another Firefox browser on this phone.</string>
|
<string name="onboarding_firefox_account_auto_signin_header_2">You are signed in as %s on another Firefox browser on this phone. Would you like to sign in with this account?</string>
|
||||||
<!-- text for the button to sign into your Firefox account. The word "Firefox" should not be translated -->
|
<!-- text for the button to confirm automatic sign-in -->
|
||||||
|
<string name="onboarding_firefox_account_auto_signin_confirm">Yes, sign me in</string>
|
||||||
|
<!-- text for the automatic sign-in button while signing in is in process -->
|
||||||
|
<string name="onboarding_firefox_account_signing_in">Signing in…</string>
|
||||||
|
<!-- text for the button to manually sign into Firefox account. The word "Firefox" should not be translated -->
|
||||||
<string name="onboarding_firefox_account_sign_in">Sign in to Firefox</string>
|
<string name="onboarding_firefox_account_sign_in">Sign in to Firefox</string>
|
||||||
<!-- text for the button to stay signed into your Firefox account. -->
|
<!-- text for the button to stay signed out when presented with an option to automatically sign-in. -->
|
||||||
<string name="onboarding_firefox_account_stay_signed_in">Stay signed in</string>
|
<string name="onboarding_firefox_account_stay_signed_out">Stay signed out</string>
|
||||||
<!-- text for the button to sign out of your Firefox account. -->
|
<!-- text to display in the snackbar once account is signed-in -->
|
||||||
<string name="onboarding_firefox_account_sign_out">Sign out</string>
|
<string name="onboarding_firefox_account_sync_is_on">Sync is on</string>
|
||||||
|
<!-- text to display in the snackbar if automatic sign-in fails. user may try again -->
|
||||||
|
<string name="onboarding_firefox_account_automatic_signin_failed">Failed to sign-in</string>
|
||||||
<!-- text for the tracking protection onboarding card header -->
|
<!-- text for the tracking protection onboarding card header -->
|
||||||
<string name="onboarding_tracking_protection_header">Protect yourself</string>
|
<string name="onboarding_tracking_protection_header">Protect yourself</string>
|
||||||
<!-- text for the tracking protection card description
|
<!-- text for the tracking protection card description
|
||||||
|
|
Loading…
Reference in New Issue