Add FxA Pairing feature to "Turn On Sync"
parent
a078f9e48b
commit
66a0cd5f9c
@ -0,0 +1,83 @@
|
|||||||
|
/* 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.TextView
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.core.text.HtmlCompat
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import mozilla.components.feature.qr.QrFeature
|
||||||
|
import mozilla.components.support.base.feature.BackHandler
|
||||||
|
import mozilla.components.support.base.feature.ViewBoundFeatureWrapper
|
||||||
|
import org.mozilla.fenix.BrowserDirection
|
||||||
|
import org.mozilla.fenix.HomeActivity
|
||||||
|
import org.mozilla.fenix.R
|
||||||
|
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? {
|
||||||
|
return inflater.inflate(R.layout.fragment_pair, container, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
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))
|
||||||
|
|
||||||
|
qrFeature.set(
|
||||||
|
QrFeature(
|
||||||
|
requireContext(),
|
||||||
|
fragmentManager = requireFragmentManager(),
|
||||||
|
onNeedToRequestPermissions = { permissions ->
|
||||||
|
requestPermissions(permissions, REQUEST_CODE_CAMERA_PERMISSIONS)
|
||||||
|
},
|
||||||
|
onScanResult = { pairingUrl ->
|
||||||
|
requireComponents.services.accountsAuthFeature.beginPairingAuthentication(pairingUrl)
|
||||||
|
view?.let {
|
||||||
|
(activity as HomeActivity).openToBrowser(BrowserDirection.FromSettings)
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
owner = this,
|
||||||
|
view = view
|
||||||
|
)
|
||||||
|
|
||||||
|
qrFeature.withFeature {
|
||||||
|
it.scan(R.id.pair_layout)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
(activity as AppCompatActivity).title = getString(R.string.preferences_sync)
|
||||||
|
(activity as AppCompatActivity).supportActionBar?.show()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBackPressed(): Boolean {
|
||||||
|
return when {
|
||||||
|
qrFeature.onBackPressed() -> true
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val REQUEST_CODE_CAMERA_PERMISSIONS = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
|
||||||
|
when (requestCode) {
|
||||||
|
REQUEST_CODE_CAMERA_PERMISSIONS -> qrFeature.withFeature {
|
||||||
|
it.onPermissionsResult(permissions, grantResults)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,58 @@
|
|||||||
|
/* 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.navigation.Navigation
|
||||||
|
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
||||||
|
import mozilla.components.support.base.feature.BackHandler
|
||||||
|
import org.mozilla.fenix.R
|
||||||
|
|
||||||
|
class PairInstructionsFragment : BottomSheetDialogFragment(), BackHandler {
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
(activity as AppCompatActivity).title = getString(R.string.preferences_sync)
|
||||||
|
}
|
||||||
|
|
||||||
|
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.setText(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(View.OnClickListener {
|
||||||
|
val directions = PairInstructionsFragmentDirections.actionPairInstructionsFragmentToPairFragment()
|
||||||
|
Navigation.findNavController(view!!).navigate(directions)
|
||||||
|
})
|
||||||
|
|
||||||
|
val cancelCamera = view.findViewById(R.id.pair_cancel) as Button
|
||||||
|
cancelCamera.setOnClickListener(View.OnClickListener {
|
||||||
|
onBackPressed()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBackPressed(): Boolean {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
<!-- 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/. -->
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:id="@+id/pair_layout"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/pair_instructions"
|
||||||
|
android:background="#8000"
|
||||||
|
android:layout_marginTop="10dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:text="@string/pair_instructions"
|
||||||
|
android:textSize="20sp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:textColor="@color/photonWhite"/>
|
||||||
|
</RelativeLayout>
|
@ -0,0 +1,58 @@
|
|||||||
|
<!-- 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:orientation="vertical"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?foundation">
|
||||||
|
|
||||||
|
<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_height="@dimen/quicksettings_item_height"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:drawableStart="@drawable/ic_qr"
|
||||||
|
android:text="@string/pair_instructions"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
android:layout_marginTop="24dp"/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/pair_cancel"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="40dp"
|
||||||
|
style="@style/SitePermissionButton"
|
||||||
|
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"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
style="@style/SitePermissionButton"
|
||||||
|
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"
|
||||||
|
android:backgroundTint="?accent"
|
||||||
|
android:textColor="?contrastText"
|
||||||
|
/>
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
Loading…
Reference in New Issue