For #3772 - Update FXA sign in UI (#3933)

This commit is contained in:
Emily Kager 2019-07-10 22:20:06 -04:00 committed by Colin Lee
parent 547c5d7bbe
commit c81dd0a4a8
9 changed files with 257 additions and 157 deletions

View File

@ -81,7 +81,6 @@ private fun onboardingAdapterItems(onboardingState: OnboardingState): List<Adapt
items.addAll(when (onboardingState) {
OnboardingState.SignedOut -> {
listOf(
AdapterItem.OnboardingSectionHeader { it.getString(R.string.onboarding_fxa_section_header) },
AdapterItem.OnboardingFirefoxAccount(onboardingState)
)
}

View File

@ -22,7 +22,11 @@ import org.mozilla.fenix.ext.requireComponents
class PairFragment : Fragment(), BackHandler {
private val qrFeature = ViewBoundFeatureWrapper<QrFeature>()
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_pair, container, false)
}
@ -30,8 +34,12 @@ class PairFragment : Fragment(), BackHandler {
super.onViewCreated(view, savedInstanceState)
val instructionsText = view.findViewById(R.id.pair_instructions) as TextView
instructionsText.setText(HtmlCompat.fromHtml(getString(R.string.pair_instructions),
HtmlCompat.FROM_HTML_MODE_LEGACY))
instructionsText.setText(
HtmlCompat.fromHtml(
getString(R.string.pair_instructions),
HtmlCompat.FROM_HTML_MODE_LEGACY
)
)
qrFeature.set(
QrFeature(
@ -59,7 +67,7 @@ class PairFragment : Fragment(), BackHandler {
override fun onResume() {
super.onResume()
(activity as AppCompatActivity).title = getString(R.string.preferences_sync)
(activity as AppCompatActivity).title = getString(R.string.sync_scan_code)
(activity as AppCompatActivity).supportActionBar?.show()
}
@ -74,7 +82,11 @@ class PairFragment : Fragment(), BackHandler {
private const val REQUEST_CODE_CAMERA_PERMISSIONS = 1
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<String>,
grantResults: IntArray
) {
when (requestCode) {
REQUEST_CODE_CAMERA_PERMISSIONS -> qrFeature.withFeature {
it.onPermissionsResult(permissions, grantResults)

View File

@ -1,58 +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.settings
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.core.text.HtmlCompat
import androidx.fragment.app.DialogFragment
import androidx.navigation.fragment.NavHostFragment.findNavController
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.nav
class PairInstructionsFragment : BottomSheetDialogFragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(DialogFragment.STYLE_NO_TITLE, R.style.FirefoxAccountsDialogStyle)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_pair_instructions, container, false)
}
override fun onResume() {
super.onResume()
(activity as AppCompatActivity).title = getString(R.string.preferences_sync)
(activity as AppCompatActivity).supportActionBar?.show()
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val instructionsText = view.findViewById(R.id.pair_instructions_info) as TextView
instructionsText.text = HtmlCompat.fromHtml(
getString(R.string.pair_instructions),
HtmlCompat.FROM_HTML_MODE_LEGACY
)
val openCamera = view.findViewById(R.id.pair_open_camera) as Button
openCamera.setOnClickListener {
val directions = PairInstructionsFragmentDirections.actionPairInstructionsFragmentToPairFragment()
nav(R.id.pairInstructionsFragment, directions)
}
val cancelCamera = view.findViewById(R.id.pair_cancel) as Button
cancelCamera.setOnClickListener {
findNavController(this@PairInstructionsFragment).navigateUp()
}
}
}

View File

@ -25,8 +25,10 @@ import kotlinx.coroutines.launch
import mozilla.components.concept.sync.AccountObserver
import mozilla.components.concept.sync.OAuthAccount
import mozilla.components.concept.sync.Profile
import mozilla.components.support.ktx.android.content.hasCamera
import org.mozilla.fenix.BrowserDirection
import org.mozilla.fenix.Config
import org.mozilla.fenix.Experiments
import org.mozilla.fenix.FenixApplication
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R
@ -54,6 +56,7 @@ import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.getPreferenceKey
import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.isInExperiment
import org.mozilla.fenix.utils.ItsNotBrokenSnack
@SuppressWarnings("TooManyFunctions", "LargeClass")
@ -222,8 +225,21 @@ class SettingsFragment : PreferenceFragmentCompat(), AccountObserver {
private fun getClickListenerForSignIn(): OnPreferenceClickListener {
return OnPreferenceClickListener {
val directions = SettingsFragmentDirections.actionSettingsFragmentToTurnOnSyncFragment()
Navigation.findNavController(view!!).navigate(directions)
// Do not navigate to pairing UI if camera not available or pairing is disabled
if (context?.hasCamera() == true &&
context?.isInExperiment(Experiments.asFeatureFxAPairingDisabled) == false
) {
val directions = SettingsFragmentDirections.actionSettingsFragmentToTurnOnSyncFragment()
Navigation.findNavController(view!!).navigate(directions)
} else {
requireComponents.services.accountsAuthFeature.beginAuthentication(requireContext())
// TODO The sign-in web content populates session history,
// so pressing "back" after signing in won't take us back into the settings screen, but rather up the
// session history stack.
// We could auto-close this tab once we get to the end of the authentication process?
// Via an interceptor, perhaps.
requireComponents.analytics.metrics.track(Event.SyncAuthSignIn)
}
true
}
}
@ -388,7 +404,7 @@ class SettingsFragment : PreferenceFragmentCompat(), AccountObserver {
preferenceFirefoxAccount?.displayName = profile?.displayName
preferenceFirefoxAccount?.email = profile?.email
// Signed-in, need to re-authenticate.
// Signed-in, need to re-authenticate.
} else if (account != null && accountManager.accountNeedsReauth()) {
preferenceFirefoxAccount?.isVisible = false
preferenceFirefoxAccountAuthError?.isVisible = true
@ -399,7 +415,7 @@ class SettingsFragment : PreferenceFragmentCompat(), AccountObserver {
preferenceFirefoxAccountAuthError?.email = profile?.email
// Signed-out.
// Signed-out.
} else {
preferenceSignIn?.isVisible = true
preferenceSignIn?.onPreferenceClickListener = getClickListenerForSignIn()

View File

@ -5,25 +5,25 @@
package org.mozilla.fenix.settings
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import androidx.core.text.HtmlCompat
import androidx.fragment.app.Fragment
import androidx.navigation.Navigation
import androidx.navigation.fragment.NavHostFragment.findNavController
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import kotlinx.android.synthetic.main.fragment_turn_on_sync.view.*
import mozilla.components.concept.sync.AccountObserver
import mozilla.components.concept.sync.OAuthAccount
import mozilla.components.concept.sync.Profile
import mozilla.components.support.ktx.android.content.hasCamera
import org.mozilla.fenix.Experiments
import org.mozilla.fenix.R
import org.mozilla.fenix.components.FenixSnackbar
import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.ext.getPreferenceKey
import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.isInExperiment
@SuppressWarnings("TooManyFunctions")
class TurnOnSyncFragment : PreferenceFragmentCompat(), AccountObserver {
class TurnOnSyncFragment : Fragment(), AccountObserver {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
requireComponents.analytics.metrics.track(Event.SyncAuthOpened)
@ -46,25 +46,19 @@ class TurnOnSyncFragment : PreferenceFragmentCompat(), AccountObserver {
(activity as AppCompatActivity).supportActionBar?.show()
}
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.turn_on_sync_preferences, rootKey)
val preferenceSignIn =
findPreference<Preference>(context!!.getPreferenceKey(R.string.pref_key_sync_sign_in))
val preferencePairSignIn =
findPreference<Preference>(context!!.getPreferenceKey(R.string.pref_key_sync_pair))
preferenceSignIn?.onPreferenceClickListener = getClickListenerForSignIn()
preferencePairSignIn?.onPreferenceClickListener = getClickListenerForPairing()
preferencePairSignIn?.isVisible = context?.hasCamera() ?: true
// if FxA pairing has been turned off on the server
if (context?.isInExperiment(Experiments.asFeatureFxAPairingDisabled)!!) {
preferencePairSignIn?.isVisible = false
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.fragment_turn_on_sync, container, false)
view.sign_in_scan_button.setOnClickListener(getClickListenerForPairing())
view.sign_in_email_button.setOnClickListener(getClickListenerForSignIn())
view.sign_in_instructions.text = HtmlCompat.fromHtml(
getString(R.string.sign_in_instructions),
HtmlCompat.FROM_HTML_MODE_LEGACY
)
return view
}
private fun getClickListenerForSignIn(): Preference.OnPreferenceClickListener {
return Preference.OnPreferenceClickListener {
private fun getClickListenerForSignIn(): View.OnClickListener {
return View.OnClickListener {
requireComponents.services.accountsAuthFeature.beginAuthentication(requireContext())
// TODO The sign-in web content populates session history,
// so pressing "back" after signing in won't take us back into the settings screen, but rather up the
@ -76,9 +70,9 @@ class TurnOnSyncFragment : PreferenceFragmentCompat(), AccountObserver {
}
}
private fun getClickListenerForPairing(): Preference.OnPreferenceClickListener {
return Preference.OnPreferenceClickListener {
val directions = TurnOnSyncFragmentDirections.actionTurnOnSyncFragmentToPairInstructionsFragment()
private fun getClickListenerForPairing(): View.OnClickListener {
return View.OnClickListener {
val directions = TurnOnSyncFragmentDirections.actionTurnOnSyncFragmentToPairFragment()
Navigation.findNavController(view!!).navigate(directions)
requireComponents.analytics.metrics.track(Event.SyncAuthScanPairing)
@ -95,4 +89,5 @@ class TurnOnSyncFragment : PreferenceFragmentCompat(), AccountObserver {
override fun onAuthenticationProblems() {}
override fun onError(error: Exception) {}
override fun onLoggedOut() {}
override fun onProfileUpdated(profile: Profile) {} }
override fun onProfileUpdated(profile: Profile) {}
}

View File

@ -0,0 +1,119 @@
<vector android:height="24dp" android:viewportHeight="165"
android:viewportWidth="320" android:width="24dp"
xmlns:aapt="http://schemas.android.com/aapt" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillType="nonZero"
android:pathData="M95,139.38C95,148.42 87.69,155.757 78.65,155.79L12.94,155.79C6.149,155.598 0.744,150.038 0.744,143.245C0.744,136.452 6.149,130.892 12.94,130.7C13.951,130.71 14.958,130.837 15.94,131.08C15.715,130.126 15.6,129.15 15.6,128.17C15.606,123.372 18.267,118.972 22.512,116.737C26.758,114.502 31.891,114.8 35.85,117.51C38.589,106.899 48.797,99.986 59.667,101.38C70.536,102.775 78.669,112.041 78.64,123C87.672,123.028 94.984,130.348 95,139.38Z"
android:strokeColor="#00000000" android:strokeWidth="1">
<aapt:attr name="android:fillColor">
<gradient android:centerX="120.00696"
android:centerY="242.45819"
android:gradientRadius="177.08046" android:type="radial">
<item android:color="#00CDCDD4" android:offset="0.26"/>
<item android:color="#05CDCDD4" android:offset="0.4"/>
<item android:color="#14CDCDD4" android:offset="0.55"/>
<item android:color="#2DCDCDD4" android:offset="0.69"/>
<item android:color="#33CDCDD4" android:offset="0.72"/>
</gradient>
</aapt:attr>
</path>
<path android:fillType="nonZero"
android:pathData="M300.2,45.32C298.677,45.319 297.159,45.503 295.68,45.87C296.014,44.437 296.182,42.971 296.18,41.5C296.169,34.267 292.158,27.634 285.757,24.265C279.357,20.896 271.618,21.345 265.65,25.43C261.492,9.481 246.135,-0.898 229.786,1.192C213.437,3.281 201.184,17.188 201.17,33.67C187.573,33.67 176.55,44.693 176.55,58.29C176.55,71.887 187.573,82.91 201.17,82.91L300.17,82.91C306.988,83.067 313.357,79.52 316.812,73.64C320.267,67.76 320.267,60.47 316.812,54.59C313.357,48.71 306.988,45.163 300.17,45.32L300.2,45.32Z"
android:strokeColor="#00000000" android:strokeWidth="1">
<aapt:attr name="android:fillColor">
<gradient android:centerX="21.158506"
android:centerY="217.8521"
android:gradientRadius="261.74274" android:type="radial">
<item android:color="#00CDCDD4" android:offset="0.27"/>
<item android:color="#05CDCDD4" android:offset="0.46"/>
<item android:color="#14CDCDD4" android:offset="0.66"/>
<item android:color="#2DCDCDD4" android:offset="0.86"/>
<item android:color="#33CDCDD4" android:offset="0.9"/>
</gradient>
</aapt:attr>
</path>
<path android:fillType="nonZero"
android:pathData="M15,90.19C14.945,68.729 32.28,51.278 53.74,51.19L262.16,50.36C276.195,50.086 289.289,57.397 296.419,69.49C303.549,81.582 303.609,96.579 296.576,108.728C289.542,120.877 276.507,128.292 262.47,128.13L54,128.93C32.539,128.985 15.088,111.65 15,90.19Z"
android:strokeColor="#00000000" android:strokeWidth="1">
<aapt:attr name="android:fillColor">
<gradient android:centerX="185.28891"
android:centerY="167.69759"
android:gradientRadius="195.69775" android:type="radial">
<item android:color="#00CDCDD4" android:offset="0.4"/>
<item android:color="#05CDCDD4" android:offset="0.58"/>
<item android:color="#14CDCDD4" android:offset="0.77"/>
<item android:color="#2DCDCDD4" android:offset="0.96"/>
<item android:color="#33CDCDD4" android:offset="1"/>
</gradient>
</aapt:attr>
</path>
<path android:fillType="nonZero"
android:pathData="M220,110L216,110L216,18C216,13.582 212.418,10 208,10L76,10C71.582,10 68,13.582 68,18L68,110L64,110C61.791,110 60,111.791 60,114L60,118C60,120.209 61.791,122 64,122L220,122C222.209,122 224,120.209 224,118L224,114C224,111.791 222.209,110 220,110Z"
android:strokeColor="#00000000" android:strokeWidth="1">
<aapt:attr name="android:fillColor">
<gradient android:endX="213.72" android:endY="34.966473"
android:startX="37.02" android:startY="117.37276" android:type="linear">
<item android:color="#FFB833E1" android:offset="0.22"/>
<item android:color="#FFFF4F5E" android:offset="0.91"/>
</gradient>
</aapt:attr>
</path>
<path android:fillColor="#FFFFFF" android:fillType="nonZero"
android:pathData="M76,16L208,16A2,2 0,0 1,210 18L210,102A2,2 0,0 1,208 104L76,104A2,2 0,0 1,74 102L74,18A2,2 0,0 1,76 16z"
android:strokeColor="#00000000" android:strokeWidth="1"/>
<path android:fillColor="#FF848B" android:fillType="nonZero"
android:pathData="M132,114.5L152,114.5A2,2 0,0 1,154 116.5L154,116.5A2,2 0,0 1,152 118.5L132,118.5A2,2 0,0 1,130 116.5L130,116.5A2,2 0,0 1,132 114.5z"
android:strokeColor="#00000000" android:strokeWidth="1"/>
<path android:fillType="nonZero"
android:pathData="M123.43,60L140.57,60C140.949,60 141.313,59.849 141.581,59.581C141.849,59.313 142,58.949 142,58.57L142,41.43C142,40.64 141.36,40 140.57,40L123.43,40C123.051,40 122.687,40.151 122.419,40.419C122.151,40.687 122,41.051 122,41.43L122,58.57C122,59.36 122.64,60 123.43,60L123.43,60ZM127.71,45.71L136.29,45.71L136.29,54.29L127.71,54.29L127.71,45.71ZM161.29,40L145.57,40C145.178,40 144.86,40.318 144.86,40.71L144.86,45C144.86,45.392 145.178,45.71 145.57,45.71L149.86,45.71C150.05,45.71 150.232,45.786 150.366,45.921C150.499,46.057 150.573,46.24 150.57,46.43L150.57,50.71C150.57,51.108 150.892,51.43 151.29,51.43L155.57,51.43C155.968,51.43 156.29,51.108 156.29,50.71L156.29,46.43C156.287,46.24 156.361,46.057 156.494,45.921C156.628,45.786 156.81,45.71 157,45.71L161.29,45.71C161.682,45.71 162,45.392 162,45L162,40.71C162,40.522 161.925,40.341 161.792,40.208C161.659,40.075 161.478,40 161.29,40ZM145.57,57.14L149.86,57.14C150.252,57.14 150.57,56.822 150.57,56.43L150.57,52.14C150.57,51.748 150.252,51.43 149.86,51.43L145.57,51.43C145.178,51.43 144.86,51.748 144.86,52.14L144.86,56.43C144.86,56.822 145.178,57.14 145.57,57.14ZM161.29,51.43L157,51.43C156.812,51.43 156.631,51.505 156.498,51.638C156.365,51.771 156.29,51.952 156.29,52.14L156.29,56.43C156.29,56.62 156.214,56.802 156.079,56.936C155.943,57.069 155.76,57.143 155.57,57.14L151.29,57.14C150.892,57.14 150.57,57.462 150.57,57.86L150.57,62.14C150.573,62.33 150.499,62.513 150.366,62.649C150.232,62.784 150.05,62.86 149.86,62.86L145.57,62.86C145.178,62.86 144.86,63.178 144.86,63.57L144.86,67.86C144.86,68.252 145.178,68.57 145.57,68.57L149.86,68.57C150.05,68.57 150.232,68.646 150.366,68.781C150.499,68.917 150.573,69.1 150.57,69.29L150.57,73.57C150.57,73.968 150.892,74.29 151.29,74.29L155.57,74.29C155.76,74.287 155.943,74.361 156.079,74.494C156.214,74.628 156.29,74.81 156.29,75L156.29,79.29C156.29,79.478 156.365,79.659 156.498,79.792C156.631,79.925 156.812,80 157,80L161.29,80C161.682,80 162,79.682 162,79.29L162,69.29C162.003,69.1 161.929,68.917 161.796,68.781C161.662,68.646 161.48,68.57 161.29,68.57L157,68.57C156.812,68.57 156.631,68.495 156.498,68.362C156.365,68.229 156.29,68.048 156.29,67.86L156.29,63.57C156.29,63.382 156.365,63.201 156.498,63.068C156.631,62.935 156.812,62.86 157,62.86L161.29,62.86C161.48,62.86 161.662,62.784 161.796,62.649C161.929,62.513 162.003,62.33 162,62.14L162,52.14C162,51.748 161.682,51.43 161.29,51.43L161.29,51.43ZM149.86,74.29L145.57,74.29C145.178,74.29 144.86,74.608 144.86,75L144.86,79.29C144.86,79.682 145.178,80 145.57,80L149.86,80C150.252,80 150.57,79.682 150.57,79.29L150.57,75C150.57,74.608 150.252,74.29 149.86,74.29ZM134.14,62.86C133.748,62.86 133.43,63.178 133.43,63.57L133.43,67.86C133.43,68.252 133.748,68.57 134.14,68.57L138.43,68.57C138.822,68.57 139.14,68.252 139.14,67.86L139.14,63.57C139.14,63.178 138.822,62.86 138.43,62.86L134.14,62.86ZM122.71,68.57L127,68.57C127.392,68.57 127.71,68.252 127.71,67.86L127.71,63.57C127.71,63.178 127.392,62.86 127,62.86L122.71,62.86C122.318,62.86 122,63.178 122,63.57L122,67.86C122,68.252 122.318,68.57 122.71,68.57L122.71,68.57ZM138.43,74.29L134.14,74.29C133.95,74.29 133.768,74.214 133.634,74.079C133.501,73.943 133.427,73.76 133.43,73.57L133.43,69.29C133.43,68.892 133.108,68.57 132.71,68.57L128.43,68.57C128.032,68.57 127.71,68.892 127.71,69.29L127.71,73.57C127.713,73.76 127.639,73.943 127.506,74.079C127.372,74.214 127.19,74.29 127,74.29L122.71,74.29C122.318,74.29 122,74.608 122,75L122,79.29C122,79.682 122.318,80 122.71,80L138.43,80C138.618,80 138.799,79.925 138.932,79.792C139.065,79.659 139.14,79.478 139.14,79.29L139.14,75C139.14,74.812 139.065,74.631 138.932,74.498C138.799,74.365 138.618,74.29 138.43,74.29L138.43,74.29ZM144.86,69.29C144.86,68.892 144.538,68.57 144.14,68.57L139.86,68.57C139.462,68.57 139.14,68.892 139.14,69.29L139.14,73.57C139.14,73.968 139.462,74.29 139.86,74.29L144.14,74.29C144.538,74.29 144.86,73.968 144.86,73.57L144.86,69.29Z"
android:strokeColor="#00000000" android:strokeWidth="1">
<aapt:attr name="android:fillColor">
<gradient android:endX="174.83388" android:endY="27.38"
android:startX="117.74969" android:startY="84.46" android:type="linear">
<item android:color="#FF952BB9" android:offset="0.22"/>
<item android:color="#FFE22850" android:offset="0.91"/>
</gradient>
</aapt:attr>
</path>
<path android:fillColor="#FFFFFF" android:fillType="nonZero"
android:pathData="M192,45L248,45A10,10 0,0 1,258 55L258,155A10,10 0,0 1,248 165L192,165A10,10 0,0 1,182 155L182,55A10,10 0,0 1,192 45z"
android:strokeColor="#00000000" android:strokeWidth="1"/>
<path android:fillType="nonZero"
android:pathData="M192,47L248,47A8,8 0,0 1,256 55L256,155A8,8 0,0 1,248 163L192,163A8,8 0,0 1,184 155L184,55A8,8 0,0 1,192 47z"
android:strokeColor="#00000000" android:strokeWidth="1">
<aapt:attr name="android:fillColor">
<gradient android:endX="259.1805" android:endY="3.3"
android:startX="175.48756" android:startY="220.54" android:type="linear">
<item android:color="#FF592ACB" android:offset="0.28"/>
<item android:color="#FF824DE5" android:offset="0.58"/>
<item android:color="#FFA067F8" android:offset="0.85"/>
<item android:color="#FFAB71FF" android:offset="1"/>
</gradient>
</aapt:attr>
</path>
<path android:fillColor="#FFFFFF" android:fillType="nonZero"
android:pathData="M190,55L250,55A2,2 0,0 1,252 57L252,153A2,2 0,0 1,250 155L190,155A2,2 0,0 1,188 153L188,57A2,2 0,0 1,190 55z"
android:strokeColor="#00000000" android:strokeWidth="1"/>
<path android:fillColor="#C689FF" android:fillType="nonZero"
android:pathData="M211,158L229,158A1,1 0,0 1,230 159L230,159A1,1 0,0 1,229 160L211,160A1,1 0,0 1,210 159L210,159A1,1 0,0 1,211 158z"
android:strokeColor="#00000000" android:strokeWidth="1"/>
<path android:fillColor="#C689FF" android:fillType="nonZero"
android:pathData="M211,50L229,50A1,1 0,0 1,230 51L230,51A1,1 0,0 1,229 52L211,52A1,1 0,0 1,210 51L210,51A1,1 0,0 1,211 50z"
android:strokeColor="#00000000" android:strokeWidth="1"/>
<path android:fillType="nonZero"
android:pathData="M212.21,80L206.15,80C202.756,80.006 200.006,82.756 200,86.15L200,92.21C200,93.215 200.815,94.03 201.82,94.03C202.825,94.03 203.64,93.215 203.64,92.21L203.64,86.15C203.64,85.484 203.904,84.846 204.375,84.375C204.846,83.904 205.484,83.64 206.15,83.64L212.21,83.64C213.215,83.64 214.03,82.825 214.03,81.82C214.03,80.815 213.215,80 212.21,80L212.21,80ZM233.85,80L227.79,80C227.14,80 226.539,80.347 226.214,80.91C225.889,81.473 225.889,82.167 226.214,82.73C226.539,83.293 227.14,83.64 227.79,83.64L233.85,83.64C235.236,83.64 236.36,84.764 236.36,86.15L236.36,92.21C236.36,93.215 237.175,94.03 238.18,94.03C239.185,94.03 240,93.215 240,92.21L240,86.15C239.994,82.756 237.244,80.006 233.85,80L233.85,80ZM238.18,106C237.177,106.005 236.365,106.817 236.36,107.82L236.36,113.88C236.36,115.266 235.236,116.39 233.85,116.39L227.79,116.39C226.785,116.39 225.97,117.205 225.97,118.21C225.97,119.215 226.785,120.03 227.79,120.03L233.85,120.03C237.244,120.024 239.994,117.274 240,113.88L240,107.82C240,106.815 239.185,106 238.18,106L238.18,106ZM212.18,116.39L206.12,116.39C204.734,116.39 203.61,115.266 203.61,113.88L203.61,107.82C203.61,106.815 202.795,106 201.79,106C200.785,106 199.97,106.815 199.97,107.82L199.97,113.88C199.976,117.274 202.726,120.024 206.12,120.03L212.18,120.03C213.185,120.03 214,119.215 214,118.21C214,117.205 213.185,116.39 212.18,116.39L212.18,116.39Z"
android:strokeColor="#00000000" android:strokeWidth="1">
<aapt:attr name="android:fillColor">
<gradient android:endX="240.25" android:endY="79.75"
android:startX="197.06" android:startY="122.94" android:type="linear">
<item android:color="#FF45278D" android:offset="0"/>
<item android:color="#FF5E35BC" android:offset="0.45"/>
<item android:color="#FF6F3FDA" android:offset="0.8"/>
<item android:color="#FF7542E5" android:offset="1"/>
</gradient>
</aapt:attr>
</path>
<path android:fillAlpha="0.2" android:fillColor="#9059FF"
android:fillType="nonZero"
android:pathData="M250,55L190,55C188.895,55 188,55.895 188,57L188,153C188,154.105 188.895,155 190,155L250,155C251.105,155 252,154.105 252,153L252,57C252,55.895 251.105,55 250,55ZM237,114C237,115.657 235.657,117 234,117L206,117C204.343,117 203,115.657 203,114L203,86C203,84.343 204.343,83 206,83L234,83C235.657,83 237,84.343 237,86L237,114Z"
android:strokeAlpha="0.2" android:strokeColor="#00000000" android:strokeWidth="1"/>
</vector>

View File

@ -1,48 +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/. -->
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/pair_instructions_fragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?foundation"
android:padding="8dp">
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" />
<TextView
android:id="@+id/pair_instructions_info"
style="@style/QuickSettingsText.Icon"
android:layout_width="wrap_content"
android:layout_height="@dimen/quicksettings_item_height"
android:layout_marginTop="24dp"
android:drawableStart="@drawable/ic_qr"
android:text="@string/pair_instructions"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/pair_cancel"
style="@style/SitePermissionCancelButton"
android:text="@string/pair_cancel"
app:layout_constraintEnd_toStartOf="@+id/pair_open_camera"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toEndOf="@+id/guideline"
app:layout_constraintTop_toBottomOf="@+id/pair_instructions_info" />
<Button
android:id="@+id/pair_open_camera"
style="@style/SitePermissionPrimaryButton"
android:text="@string/pair_open_camera"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toEndOf="@+id/pair_cancel"
app:layout_constraintTop_toTopOf="@+id/pair_cancel" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,76 @@
<?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/. -->
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="24dp">
<TextView
android:id="@+id/title_sign_in"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/sign_in_with_camera"
android:textAppearance="@style/Header16TextStyle"
android:textColor="?primaryText"
android:textSize="18sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/sign_in_image"
android:layout_width="320dp"
android:layout_height="166dp"
android:layout_marginTop="16dp"
android:adjustViewBounds="true"
android:background="@drawable/ic_scan"
android:importantForAccessibility="no"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/title_sign_in" />
<TextView
android:id="@+id/sign_in_instructions"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:gravity="center"
android:text="@string/sign_in_instructions"
android:textColor="?primaryText"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/sign_in_image" />
<com.google.android.material.button.MaterialButton
android:id="@+id/sign_in_scan_button"
style="@style/Widget.MaterialComponents.Button.TextButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:letterSpacing="0"
android:text="@string/sign_in_ready_for_scan"
android:textAllCaps="false"
android:textColor="?contrastText"
android:textStyle="bold"
app:backgroundTint="?accent"
app:icon="@drawable/ic_qr"
app:iconGravity="textStart"
app:iconPadding="8dp"
app:iconTint="?contrastText"
app:layout_constraintTop_toBottomOf="@id/sign_in_instructions" />
<com.google.android.material.button.MaterialButton
android:id="@+id/sign_in_email_button"
style="@style/ThemeIndependentMaterialGreyButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="@string/sign_in_with_email"
app:layout_constraintTop_toBottomOf="@id/sign_in_scan_button" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -335,21 +335,10 @@
app:popUpTo="@+id/settingsFragment"
app:popUpToInclusive="true" />
<action
android:id="@+id/action_turnOnSyncFragment_to_pairInstructionsFragment"
app:destination="@id/pairInstructionsFragment" />
android:id="@+id/action_turnOnSyncFragment_to_pairFragment"
app:destination="@id/pairFragment" />
</fragment>
<dialog
android:id="@+id/pairInstructionsFragment"
android:name="org.mozilla.fenix.settings.PairInstructionsFragment"
android:label="PairInstructionsFragment">
<action
android:id="@+id/action_pairInstructionsFragment_to_pairFragment"
app:destination="@id/pairFragment"
app:popUpTo="@+id/pairInstructionsFragment"
app:popUpToInclusive="true" />
</dialog>
<fragment
android:id="@+id/pairFragment"
android:name="org.mozilla.fenix.settings.PairFragment"