You've already forked element-android
mirror of
https://github.com/vector-im/element-android.git
synced 2025-07-31 07:04:23 +03:00
Implement link a device flow.
This commit is contained in:
@ -3336,7 +3336,8 @@
|
|||||||
<string name="qr_code_login_header_scan_qr_code_title">Scan QR code</string>
|
<string name="qr_code_login_header_scan_qr_code_title">Scan QR code</string>
|
||||||
<string name="qr_code_login_header_scan_qr_code_description">Use the camera on this device to scan the QR code shown on your other device:</string>
|
<string name="qr_code_login_header_scan_qr_code_description">Use the camera on this device to scan the QR code shown on your other device:</string>
|
||||||
<string name="qr_code_login_header_show_qr_code_title">Sign in with QR code</string>
|
<string name="qr_code_login_header_show_qr_code_title">Sign in with QR code</string>
|
||||||
<string name="qr_code_login_header_show_qr_code_description">Use your signed in device to scan the QR code below:</string>
|
<string name="qr_code_login_header_show_qr_code_new_device_description">Use your signed in device to scan the QR code below:</string>
|
||||||
|
<string name="qr_code_login_header_show_qr_code_link_a_device_description">Scan the QR code below with your device that’s signed out.</string>
|
||||||
<string name="qr_code_login_header_connected_title">Secure connection established</string>
|
<string name="qr_code_login_header_connected_title">Secure connection established</string>
|
||||||
<string name="qr_code_login_header_connected_description">Check your signed in device, the code below should be displayed. Confirm that the code below matches with that device:</string>
|
<string name="qr_code_login_header_connected_description">Check your signed in device, the code below should be displayed. Confirm that the code below matches with that device:</string>
|
||||||
<string name="qr_code_login_header_failed_title">Unsuccessful connection</string>
|
<string name="qr_code_login_header_failed_title">Unsuccessful connection</string>
|
||||||
@ -3344,11 +3345,12 @@
|
|||||||
<string name="qr_code_login_header_failed_timeout_description">The linking wasn’t completed in the required time.</string>
|
<string name="qr_code_login_header_failed_timeout_description">The linking wasn’t completed in the required time.</string>
|
||||||
<string name="qr_code_login_header_failed_denied_description">The request was denied on the other device.</string>
|
<string name="qr_code_login_header_failed_denied_description">The request was denied on the other device.</string>
|
||||||
<string name="qr_code_login_new_device_instruction_1">Open ${app_name} on your other device</string>
|
<string name="qr_code_login_new_device_instruction_1">Open ${app_name} on your other device</string>
|
||||||
<string name="qr_code_login_new_device_instruction_2">Go to Settings -> Security & Privacy</string>
|
<string name="qr_code_login_new_device_instruction_2">Go to Settings -> Security & Privacy -> Show All Sessions</string>
|
||||||
<string name="qr_code_login_new_device_instruction_3">Are you on web? -> Select \'Show QR code\'</string>
|
<string name="qr_code_login_new_device_instruction_3">Select \'Show QR code\'</string>
|
||||||
<string name="qr_code_login_new_device_instruction_4">Are you on a mobile device? -> Select \'Scan QR code\' and then \'Show QR code\'</string>
|
<string name="qr_code_login_link_a_device_scan_qr_code_instruction_1">Start at the sign in screen</string>
|
||||||
<string name="qr_code_login_link_a_device_instruction_1">Open ${app_name} on your other device</string>
|
<string name="qr_code_login_link_a_device_scan_qr_code_instruction_2">Select \'Sign in with QR code\'</string>
|
||||||
<string name="qr_code_login_link_a_device_instruction_2">Select \'Sign in with QR code\'</string>
|
<string name="qr_code_login_link_a_device_show_qr_code_instruction_1">Start at the sign in screen</string>
|
||||||
|
<string name="qr_code_login_link_a_device_show_qr_code_instruction_2">Select \'Scan QR code\'</string>
|
||||||
<string name="qr_code_login_show_qr_code_button">Show QR code in this device</string>
|
<string name="qr_code_login_show_qr_code_button">Show QR code in this device</string>
|
||||||
<string name="qr_code_login_signing_in_a_mobile_device">Signing in a mobile device?</string>
|
<string name="qr_code_login_signing_in_a_mobile_device">Signing in a mobile device?</string>
|
||||||
<string name="qr_code_login_scan_qr_code_button">Scan QR code</string>
|
<string name="qr_code_login_scan_qr_code_button">Scan QR code</string>
|
||||||
@ -3356,5 +3358,7 @@
|
|||||||
<string name="qr_code_login_signing_in">Signing you in</string>
|
<string name="qr_code_login_signing_in">Signing you in</string>
|
||||||
<string name="qr_code_login_status_no_match">No match?</string>
|
<string name="qr_code_login_status_no_match">No match?</string>
|
||||||
<string name="qr_code_login_try_again">Try again</string>
|
<string name="qr_code_login_try_again">Try again</string>
|
||||||
|
<string name="qr_code_login_confirm_security_code">Confirm</string>
|
||||||
|
<string name="qr_code_login_confirm_security_code_description">Please ensure that you know the origin of this code. By linking devices, you will provide someone with full access to your account.</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -26,6 +26,8 @@ import dagger.hilt.android.AndroidEntryPoint
|
|||||||
import im.vector.app.core.extensions.addFragment
|
import im.vector.app.core.extensions.addFragment
|
||||||
import im.vector.app.core.extensions.addFragmentToBackstack
|
import im.vector.app.core.extensions.addFragmentToBackstack
|
||||||
import im.vector.app.core.platform.SimpleFragmentActivity
|
import im.vector.app.core.platform.SimpleFragmentActivity
|
||||||
|
import org.matrix.android.sdk.api.extensions.orFalse
|
||||||
|
import timber.log.Timber
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class QrCodeLoginActivity : SimpleFragmentActivity() {
|
class QrCodeLoginActivity : SimpleFragmentActivity() {
|
||||||
@ -38,19 +40,36 @@ class QrCodeLoginActivity : SimpleFragmentActivity() {
|
|||||||
|
|
||||||
val qrCodeLoginArgs: QrCodeLoginArgs? = intent?.extras?.getParcelable(Mavericks.KEY_ARG)
|
val qrCodeLoginArgs: QrCodeLoginArgs? = intent?.extras?.getParcelable(Mavericks.KEY_ARG)
|
||||||
if (isFirstCreation()) {
|
if (isFirstCreation()) {
|
||||||
if (qrCodeLoginArgs?.loginType == QrCodeLoginType.LOGIN) {
|
when (qrCodeLoginArgs?.loginType) {
|
||||||
addFragment(
|
QrCodeLoginType.LOGIN -> {
|
||||||
views.container,
|
showInstructionsFragment(qrCodeLoginArgs)
|
||||||
QrCodeLoginInstructionsFragment::class.java,
|
}
|
||||||
qrCodeLoginArgs,
|
QrCodeLoginType.LINK_A_DEVICE -> {
|
||||||
tag = FRAGMENT_QR_CODE_INSTRUCTIONS_TAG
|
if (qrCodeLoginArgs.showQrCodeByDefault.orFalse()) {
|
||||||
)
|
handleNavigateToShowQrCodeScreen()
|
||||||
|
} else {
|
||||||
|
showInstructionsFragment(qrCodeLoginArgs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
null -> {
|
||||||
|
Timber.i("QrCodeLoginArgs is null. This is not expected.")
|
||||||
|
finish()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
observeViewEvents()
|
observeViewEvents()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun showInstructionsFragment(qrCodeLoginArgs: QrCodeLoginArgs) {
|
||||||
|
addFragment(
|
||||||
|
views.container,
|
||||||
|
QrCodeLoginInstructionsFragment::class.java,
|
||||||
|
qrCodeLoginArgs,
|
||||||
|
tag = FRAGMENT_QR_CODE_INSTRUCTIONS_TAG
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private fun observeViewEvents() {
|
private fun observeViewEvents() {
|
||||||
viewModel.observeViewEvents {
|
viewModel.observeViewEvents {
|
||||||
when (it) {
|
when (it) {
|
||||||
@ -61,7 +80,7 @@ class QrCodeLoginActivity : SimpleFragmentActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun handleNavigateToShowQrCodeScreen() {
|
private fun handleNavigateToShowQrCodeScreen() {
|
||||||
addFragmentToBackstack(
|
addFragment(
|
||||||
views.container,
|
views.container,
|
||||||
QrCodeLoginShowQrCodeFragment::class.java,
|
QrCodeLoginShowQrCodeFragment::class.java,
|
||||||
tag = FRAGMENT_SHOW_QR_CODE_TAG
|
tag = FRAGMENT_SHOW_QR_CODE_TAG
|
||||||
|
@ -22,4 +22,5 @@ import kotlinx.parcelize.Parcelize
|
|||||||
@Parcelize
|
@Parcelize
|
||||||
data class QrCodeLoginArgs(
|
data class QrCodeLoginArgs(
|
||||||
val loginType: QrCodeLoginType,
|
val loginType: QrCodeLoginType,
|
||||||
|
val showQrCodeByDefault: Boolean,
|
||||||
) : Parcelable
|
) : Parcelable
|
||||||
|
@ -18,7 +18,7 @@ package im.vector.app.features.login.qr
|
|||||||
|
|
||||||
sealed class QrCodeLoginConnectionStatus {
|
sealed class QrCodeLoginConnectionStatus {
|
||||||
object ConnectingToDevice : QrCodeLoginConnectionStatus()
|
object ConnectingToDevice : QrCodeLoginConnectionStatus()
|
||||||
data class Connected(val securityCode: String) : QrCodeLoginConnectionStatus()
|
data class Connected(val securityCode: String, val canConfirmSecurityCode: Boolean) : QrCodeLoginConnectionStatus()
|
||||||
object SigningIn : QrCodeLoginConnectionStatus()
|
object SigningIn : QrCodeLoginConnectionStatus()
|
||||||
data class Failed(val errorType: QrCodeLoginErrorType, val canTryAgain: Boolean) : QrCodeLoginConnectionStatus()
|
data class Failed(val errorType: QrCodeLoginErrorType, val canTryAgain: Boolean) : QrCodeLoginConnectionStatus()
|
||||||
}
|
}
|
||||||
|
@ -21,10 +21,9 @@ import android.os.Bundle
|
|||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.core.view.isVisible
|
|
||||||
import com.airbnb.mvrx.activityViewModel
|
import com.airbnb.mvrx.activityViewModel
|
||||||
import com.airbnb.mvrx.fragmentViewModel
|
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
|
import im.vector.app.R
|
||||||
import im.vector.app.core.extensions.registerStartForActivityResult
|
import im.vector.app.core.extensions.registerStartForActivityResult
|
||||||
import im.vector.app.core.platform.VectorBaseFragment
|
import im.vector.app.core.platform.VectorBaseFragment
|
||||||
import im.vector.app.databinding.FragmentQrCodeLoginInstructionsBinding
|
import im.vector.app.databinding.FragmentQrCodeLoginInstructionsBinding
|
||||||
@ -50,11 +49,20 @@ class QrCodeLoginInstructionsFragment : VectorBaseFragment<FragmentQrCodeLoginIn
|
|||||||
private fun observeViewState() {
|
private fun observeViewState() {
|
||||||
viewModel.onEach {
|
viewModel.onEach {
|
||||||
if (it.loginType == QrCodeLoginType.LOGIN) {
|
if (it.loginType == QrCodeLoginType.LOGIN) {
|
||||||
views.qrCodeLoginInstructionsShowQrCodeButton.isVisible = false
|
views.qrCodeLoginInstructionsView.setInstructions(
|
||||||
views.qrCodeLoginInstructionsAlternativeLayout.isVisible = false
|
listOf(
|
||||||
|
getString(R.string.qr_code_login_new_device_instruction_1),
|
||||||
|
getString(R.string.qr_code_login_new_device_instruction_2),
|
||||||
|
getString(R.string.qr_code_login_new_device_instruction_3),
|
||||||
|
)
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
views.qrCodeLoginInstructionsShowQrCodeButton.isVisible = true
|
views.qrCodeLoginInstructionsView.setInstructions(
|
||||||
views.qrCodeLoginInstructionsAlternativeLayout.isVisible = true
|
listOf(
|
||||||
|
getString(R.string.qr_code_login_link_a_device_scan_qr_code_instruction_1),
|
||||||
|
getString(R.string.qr_code_login_link_a_device_scan_qr_code_instruction_2),
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,6 @@ import androidx.constraintlayout.widget.ConstraintLayout
|
|||||||
import androidx.core.content.res.use
|
import androidx.core.content.res.use
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
import im.vector.app.core.extensions.setTextOrHide
|
|
||||||
import im.vector.app.databinding.ViewQrCodeLoginInstructionsBinding
|
import im.vector.app.databinding.ViewQrCodeLoginInstructionsBinding
|
||||||
|
|
||||||
class QrCodeLoginInstructionsView @JvmOverloads constructor(
|
class QrCodeLoginInstructionsView @JvmOverloads constructor(
|
||||||
@ -55,22 +54,18 @@ class QrCodeLoginInstructionsView @JvmOverloads constructor(
|
|||||||
val instruction1 = typedArray.getString(R.styleable.QrCodeLoginInstructionsView_qrCodeLoginInstruction1)
|
val instruction1 = typedArray.getString(R.styleable.QrCodeLoginInstructionsView_qrCodeLoginInstruction1)
|
||||||
val instruction2 = typedArray.getString(R.styleable.QrCodeLoginInstructionsView_qrCodeLoginInstruction2)
|
val instruction2 = typedArray.getString(R.styleable.QrCodeLoginInstructionsView_qrCodeLoginInstruction2)
|
||||||
val instruction3 = typedArray.getString(R.styleable.QrCodeLoginInstructionsView_qrCodeLoginInstruction3)
|
val instruction3 = typedArray.getString(R.styleable.QrCodeLoginInstructionsView_qrCodeLoginInstruction3)
|
||||||
val instruction4 = typedArray.getString(R.styleable.QrCodeLoginInstructionsView_qrCodeLoginInstruction4)
|
|
||||||
binding.instructions1Layout.isVisible = instruction1 != null
|
binding.instructions1Layout.isVisible = instruction1 != null
|
||||||
binding.instructions2Layout.isVisible = instruction2 != null
|
binding.instructions2Layout.isVisible = instruction2 != null
|
||||||
binding.instructions3Layout.isVisible = instruction3 != null
|
binding.instructions3Layout.isVisible = instruction3 != null
|
||||||
binding.instructions4Layout.isVisible = instruction4 != null
|
|
||||||
binding.instruction1TextView.text = instruction1
|
binding.instruction1TextView.text = instruction1
|
||||||
binding.instruction2TextView.text = instruction2
|
binding.instruction2TextView.text = instruction2
|
||||||
binding.instruction3TextView.text = instruction3
|
binding.instruction3TextView.text = instruction3
|
||||||
binding.instruction4TextView.text = instruction4
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setInstructions(instructions: List<String>) {
|
fun setInstructions(instructions: List<String>) {
|
||||||
setInstruction(binding.instructions1Layout, binding.instruction1TextView, instructions.getOrNull(0))
|
setInstruction(binding.instructions1Layout, binding.instruction1TextView, instructions.getOrNull(0))
|
||||||
setInstruction(binding.instructions2Layout, binding.instruction2TextView, instructions.getOrNull(1))
|
setInstruction(binding.instructions2Layout, binding.instruction2TextView, instructions.getOrNull(1))
|
||||||
setInstruction(binding.instructions3Layout, binding.instruction3TextView, instructions.getOrNull(2))
|
setInstruction(binding.instructions3Layout, binding.instruction3TextView, instructions.getOrNull(2))
|
||||||
setInstruction(binding.instructions4Layout, binding.instruction4TextView, instructions.getOrNull(3))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setInstruction(instructionLayout: LinearLayout, instructionTextView: TextView, instruction: String?) {
|
private fun setInstruction(instructionLayout: LinearLayout, instructionTextView: TextView, instruction: String?) {
|
||||||
|
@ -22,6 +22,7 @@ import android.view.View
|
|||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import com.airbnb.mvrx.activityViewModel
|
import com.airbnb.mvrx.activityViewModel
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
|
import im.vector.app.R
|
||||||
import im.vector.app.core.platform.VectorBaseFragment
|
import im.vector.app.core.platform.VectorBaseFragment
|
||||||
import im.vector.app.databinding.FragmentQrCodeLoginShowQrCodeBinding
|
import im.vector.app.databinding.FragmentQrCodeLoginShowQrCodeBinding
|
||||||
|
|
||||||
@ -49,12 +50,34 @@ class QrCodeLoginShowQrCodeFragment : VectorBaseFragment<FragmentQrCodeLoginShow
|
|||||||
|
|
||||||
private fun observeViewState() {
|
private fun observeViewState() {
|
||||||
viewModel.onEach {
|
viewModel.onEach {
|
||||||
|
setInstructions(it.loginType)
|
||||||
it.generatedQrCodeData?.let { qrCodeData ->
|
it.generatedQrCodeData?.let { qrCodeData ->
|
||||||
showQrCode(qrCodeData)
|
showQrCode(qrCodeData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun setInstructions(loginType: QrCodeLoginType) {
|
||||||
|
if (loginType == QrCodeLoginType.LOGIN) {
|
||||||
|
views.qrCodeLoginShowQrCodeHeaderView.setDescription(getString(R.string.qr_code_login_header_show_qr_code_new_device_description))
|
||||||
|
views.qrCodeLoginShowQrCodeInstructionsView.setInstructions(
|
||||||
|
listOf(
|
||||||
|
getString(R.string.qr_code_login_new_device_instruction_1),
|
||||||
|
getString(R.string.qr_code_login_new_device_instruction_2),
|
||||||
|
getString(R.string.qr_code_login_new_device_instruction_3),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
views.qrCodeLoginShowQrCodeHeaderView.setDescription(getString(R.string.qr_code_login_header_show_qr_code_link_a_device_description))
|
||||||
|
views.qrCodeLoginShowQrCodeInstructionsView.setInstructions(
|
||||||
|
listOf(
|
||||||
|
getString(R.string.qr_code_login_link_a_device_show_qr_code_instruction_1),
|
||||||
|
getString(R.string.qr_code_login_link_a_device_show_qr_code_instruction_2),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun showQrCode(qrCodeData: String) {
|
private fun showQrCode(qrCodeData: String) {
|
||||||
views.qrCodeLoginSHowQrCodeImageView.setData(qrCodeData)
|
views.qrCodeLoginSHowQrCodeImageView.setData(qrCodeData)
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ class QrCodeLoginStatusFragment : VectorBaseFragment<FragmentQrCodeLoginStatusBi
|
|||||||
private fun observeViewState() {
|
private fun observeViewState() {
|
||||||
viewModel.onEach {
|
viewModel.onEach {
|
||||||
when (it.connectionStatus) {
|
when (it.connectionStatus) {
|
||||||
is QrCodeLoginConnectionStatus.Connected -> handleConnectionEstablished(it.connectionStatus)
|
is QrCodeLoginConnectionStatus.Connected -> handleConnectionEstablished(it.connectionStatus, it.loginType)
|
||||||
QrCodeLoginConnectionStatus.ConnectingToDevice -> handleConnectingToDevice()
|
QrCodeLoginConnectionStatus.ConnectingToDevice -> handleConnectingToDevice()
|
||||||
QrCodeLoginConnectionStatus.SigningIn -> handleSigningIn()
|
QrCodeLoginConnectionStatus.SigningIn -> handleSigningIn()
|
||||||
is QrCodeLoginConnectionStatus.Failed -> handleFailed(it.connectionStatus)
|
is QrCodeLoginConnectionStatus.Failed -> handleFailed(it.connectionStatus)
|
||||||
@ -62,6 +62,7 @@ class QrCodeLoginStatusFragment : VectorBaseFragment<FragmentQrCodeLoginStatusBi
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun handleFailed(connectionStatus: QrCodeLoginConnectionStatus.Failed) {
|
private fun handleFailed(connectionStatus: QrCodeLoginConnectionStatus.Failed) {
|
||||||
|
views.qrCodeLoginConfirmSecurityCodeLayout.isVisible = false
|
||||||
views.qrCodeLoginStatusLoadingLayout.isVisible = false
|
views.qrCodeLoginStatusLoadingLayout.isVisible = false
|
||||||
views.qrCodeLoginStatusHeaderView.isVisible = true
|
views.qrCodeLoginStatusHeaderView.isVisible = true
|
||||||
views.qrCodeLoginStatusSecurityCode.isVisible = false
|
views.qrCodeLoginStatusSecurityCode.isVisible = false
|
||||||
@ -85,6 +86,7 @@ class QrCodeLoginStatusFragment : VectorBaseFragment<FragmentQrCodeLoginStatusBi
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun handleConnectingToDevice() {
|
private fun handleConnectingToDevice() {
|
||||||
|
views.qrCodeLoginConfirmSecurityCodeLayout.isVisible = false
|
||||||
views.qrCodeLoginStatusLoadingLayout.isVisible = true
|
views.qrCodeLoginStatusLoadingLayout.isVisible = true
|
||||||
views.qrCodeLoginStatusHeaderView.isVisible = false
|
views.qrCodeLoginStatusHeaderView.isVisible = false
|
||||||
views.qrCodeLoginStatusSecurityCode.isVisible = false
|
views.qrCodeLoginStatusSecurityCode.isVisible = false
|
||||||
@ -95,8 +97,14 @@ class QrCodeLoginStatusFragment : VectorBaseFragment<FragmentQrCodeLoginStatusBi
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun handleSigningIn() {
|
private fun handleSigningIn() {
|
||||||
|
views.qrCodeLoginConfirmSecurityCodeLayout.isVisible = false
|
||||||
views.qrCodeLoginStatusLoadingLayout.isVisible = true
|
views.qrCodeLoginStatusLoadingLayout.isVisible = true
|
||||||
views.qrCodeLoginStatusHeaderView.isVisible = false
|
views.qrCodeLoginStatusHeaderView.apply {
|
||||||
|
isVisible = true
|
||||||
|
setTitle(getString(R.string.dialog_title_success))
|
||||||
|
setDescription("")
|
||||||
|
setImage(R.drawable.ic_tick, ThemeUtils.getColor(requireContext(), R.attr.colorPrimary))
|
||||||
|
}
|
||||||
views.qrCodeLoginStatusSecurityCode.isVisible = false
|
views.qrCodeLoginStatusSecurityCode.isVisible = false
|
||||||
views.qrCodeLoginStatusNoMatchLayout.isVisible = false
|
views.qrCodeLoginStatusNoMatchLayout.isVisible = false
|
||||||
views.qrCodeLoginStatusCancelButton.isVisible = false
|
views.qrCodeLoginStatusCancelButton.isVisible = false
|
||||||
@ -104,11 +112,12 @@ class QrCodeLoginStatusFragment : VectorBaseFragment<FragmentQrCodeLoginStatusBi
|
|||||||
views.qrCodeLoginStatusLoadingTextView.setText(R.string.qr_code_login_signing_in)
|
views.qrCodeLoginStatusLoadingTextView.setText(R.string.qr_code_login_signing_in)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleConnectionEstablished(connectionStatus: QrCodeLoginConnectionStatus.Connected) {
|
private fun handleConnectionEstablished(connectionStatus: QrCodeLoginConnectionStatus.Connected, loginType: QrCodeLoginType) {
|
||||||
|
views.qrCodeLoginConfirmSecurityCodeLayout.isVisible = true
|
||||||
views.qrCodeLoginStatusLoadingLayout.isVisible = false
|
views.qrCodeLoginStatusLoadingLayout.isVisible = false
|
||||||
views.qrCodeLoginStatusHeaderView.isVisible = true
|
views.qrCodeLoginStatusHeaderView.isVisible = true
|
||||||
views.qrCodeLoginStatusSecurityCode.isVisible = true
|
views.qrCodeLoginStatusSecurityCode.isVisible = true
|
||||||
views.qrCodeLoginStatusNoMatchLayout.isVisible = true
|
views.qrCodeLoginStatusNoMatchLayout.isVisible = loginType == QrCodeLoginType.LOGIN
|
||||||
views.qrCodeLoginStatusCancelButton.isVisible = true
|
views.qrCodeLoginStatusCancelButton.isVisible = true
|
||||||
views.qrCodeLoginStatusTryAgainButton.isVisible = false
|
views.qrCodeLoginStatusTryAgainButton.isVisible = false
|
||||||
views.qrCodeLoginStatusSecurityCode.text = connectionStatus.securityCode
|
views.qrCodeLoginStatusSecurityCode.text = connectionStatus.securityCode
|
||||||
|
@ -90,9 +90,10 @@ class QrCodeLoginViewModel @AssistedInject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun onConnectionEstablished(securityCode: String) {
|
private fun onConnectionEstablished(securityCode: String) {
|
||||||
|
val canConfirmSecurityCode = initialState.loginType == QrCodeLoginType.LINK_A_DEVICE
|
||||||
setState {
|
setState {
|
||||||
copy(
|
copy(
|
||||||
connectionStatus = QrCodeLoginConnectionStatus.Connected(securityCode)
|
connectionStatus = QrCodeLoginConnectionStatus.Connected(securityCode, canConfirmSecurityCode)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,16 @@ class FtueAuthCombinedLoginFragment :
|
|||||||
viewModel.handle(OnboardingAction.UserNameEnteredAction.Login(views.loginInput.content()))
|
viewModel.handle(OnboardingAction.UserNameEnteredAction.Login(views.loginInput.content()))
|
||||||
}
|
}
|
||||||
views.loginForgotPassword.debouncedClicks { viewModel.handle(OnboardingAction.PostViewEvent(OnboardingViewEvents.OnForgetPasswordClicked)) }
|
views.loginForgotPassword.debouncedClicks { viewModel.handle(OnboardingAction.PostViewEvent(OnboardingViewEvents.OnForgetPasswordClicked)) }
|
||||||
views.loginWithQrCode.debouncedClicks { navigator.openLoginWithQrCode(requireActivity(), QrCodeLoginArgs(loginType = QrCodeLoginType.LOGIN)) }
|
views.loginWithQrCode.debouncedClicks {
|
||||||
|
navigator
|
||||||
|
.openLoginWithQrCode(
|
||||||
|
requireActivity(),
|
||||||
|
QrCodeLoginArgs(
|
||||||
|
loginType = QrCodeLoginType.LOGIN,
|
||||||
|
showQrCodeByDefault = false,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupSubmitButton() {
|
private fun setupSubmitButton() {
|
||||||
|
@ -37,6 +37,8 @@ import im.vector.app.core.resources.DrawableProvider
|
|||||||
import im.vector.app.databinding.FragmentSettingsDevicesBinding
|
import im.vector.app.databinding.FragmentSettingsDevicesBinding
|
||||||
import im.vector.app.features.crypto.recover.SetupMode
|
import im.vector.app.features.crypto.recover.SetupMode
|
||||||
import im.vector.app.features.crypto.verification.VerificationBottomSheet
|
import im.vector.app.features.crypto.verification.VerificationBottomSheet
|
||||||
|
import im.vector.app.features.login.qr.QrCodeLoginArgs
|
||||||
|
import im.vector.app.features.login.qr.QrCodeLoginType
|
||||||
import im.vector.app.features.settings.devices.v2.filter.DeviceManagerFilterType
|
import im.vector.app.features.settings.devices.v2.filter.DeviceManagerFilterType
|
||||||
import im.vector.app.features.settings.devices.v2.list.NUMBER_OF_OTHER_DEVICES_TO_RENDER
|
import im.vector.app.features.settings.devices.v2.list.NUMBER_OF_OTHER_DEVICES_TO_RENDER
|
||||||
import im.vector.app.features.settings.devices.v2.list.OtherSessionsView
|
import im.vector.app.features.settings.devices.v2.list.OtherSessionsView
|
||||||
@ -86,6 +88,7 @@ class VectorSettingsDevicesFragment :
|
|||||||
initWaitingView()
|
initWaitingView()
|
||||||
initOtherSessionsView()
|
initOtherSessionsView()
|
||||||
initSecurityRecommendationsView()
|
initSecurityRecommendationsView()
|
||||||
|
initQrLoginView()
|
||||||
observeViewEvents()
|
observeViewEvents()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,6 +153,30 @@ class VectorSettingsDevicesFragment :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun initQrLoginView() {
|
||||||
|
views.deviceListHeaderScanQrCodeButton.debouncedClicks {
|
||||||
|
navigator
|
||||||
|
.openLoginWithQrCode(
|
||||||
|
requireActivity(),
|
||||||
|
QrCodeLoginArgs(
|
||||||
|
loginType = QrCodeLoginType.LINK_A_DEVICE,
|
||||||
|
showQrCodeByDefault = false,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
views.deviceListHeaderShowQrCodeButton.debouncedClicks {
|
||||||
|
navigator
|
||||||
|
.openLoginWithQrCode(
|
||||||
|
requireActivity(),
|
||||||
|
QrCodeLoginArgs(
|
||||||
|
loginType = QrCodeLoginType.LINK_A_DEVICE,
|
||||||
|
showQrCodeByDefault = true,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
cleanUpLearnMoreButtonsListeners()
|
cleanUpLearnMoreButtonsListeners()
|
||||||
super.onDestroyView()
|
super.onDestroyView()
|
||||||
|
@ -27,8 +27,7 @@
|
|||||||
app:layout_constraintTop_toBottomOf="@id/qrCodeLoginInstructionsHeaderView"
|
app:layout_constraintTop_toBottomOf="@id/qrCodeLoginInstructionsHeaderView"
|
||||||
app:qrCodeLoginInstruction1="@string/qr_code_login_new_device_instruction_1"
|
app:qrCodeLoginInstruction1="@string/qr_code_login_new_device_instruction_1"
|
||||||
app:qrCodeLoginInstruction2="@string/qr_code_login_new_device_instruction_2"
|
app:qrCodeLoginInstruction2="@string/qr_code_login_new_device_instruction_2"
|
||||||
app:qrCodeLoginInstruction3="@string/qr_code_login_new_device_instruction_3"
|
app:qrCodeLoginInstruction3="@string/qr_code_login_new_device_instruction_3" />
|
||||||
app:qrCodeLoginInstruction4="@string/qr_code_login_new_device_instruction_4" />
|
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/qrCodeLoginInstructionsShowQrCodeButton"
|
android:id="@+id/qrCodeLoginInstructionsShowQrCodeButton"
|
||||||
@ -37,6 +36,7 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginBottom="40dp"
|
android:layout_marginBottom="40dp"
|
||||||
android:text="@string/qr_code_login_show_qr_code_button"
|
android:text="@string/qr_code_login_show_qr_code_button"
|
||||||
|
android:visibility="gone"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent" />
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
@ -46,6 +46,7 @@
|
|||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginBottom="12dp"
|
android:layout_marginBottom="12dp"
|
||||||
|
android:visibility="gone"
|
||||||
app:layout_constraintBottom_toTopOf="@id/qrCodeLoginInstructionsShowQrCodeButton"
|
app:layout_constraintBottom_toTopOf="@id/qrCodeLoginInstructionsShowQrCodeButton"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent">
|
app:layout_constraintStart_toStartOf="parent">
|
||||||
|
@ -13,13 +13,13 @@
|
|||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:qrCodeLoginHeaderDescription="@string/qr_code_login_header_show_qr_code_description"
|
app:qrCodeLoginHeaderDescription="@string/qr_code_login_header_show_qr_code_link_a_device_description"
|
||||||
app:qrCodeLoginHeaderImageBackgroundTint="?colorPrimary"
|
app:qrCodeLoginHeaderImageBackgroundTint="?colorPrimary"
|
||||||
app:qrCodeLoginHeaderImageResource="@drawable/ic_camera"
|
app:qrCodeLoginHeaderImageResource="@drawable/ic_camera"
|
||||||
app:qrCodeLoginHeaderTitle="@string/qr_code_login_header_show_qr_code_title" />
|
app:qrCodeLoginHeaderTitle="@string/qr_code_login_header_show_qr_code_title" />
|
||||||
|
|
||||||
<im.vector.app.features.login.qr.QrCodeLoginInstructionsView
|
<im.vector.app.features.login.qr.QrCodeLoginInstructionsView
|
||||||
android:id="@+id/qrCodeLoginShowQrCodeView"
|
android:id="@+id/qrCodeLoginShowQrCodeInstructionsView"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="24dp"
|
android:layout_marginTop="24dp"
|
||||||
@ -36,7 +36,7 @@
|
|||||||
android:layout_height="240dp"
|
android:layout_height="240dp"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/qrCodeLoginShowQrCodeView"
|
app:layout_constraintTop_toBottomOf="@id/qrCodeLoginShowQrCodeInstructionsView"
|
||||||
app:layout_constraintBottom_toTopOf="@id/qrCodeLoginShowQrCodeCancelButton"/>
|
app:layout_constraintBottom_toTopOf="@id/qrCodeLoginShowQrCodeCancelButton"/>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
@ -96,6 +97,50 @@
|
|||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
tools:visibility="visible" />
|
tools:visibility="visible" />
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:id="@+id/qrCodeLoginConfirmSecurityCodeLayout"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/qrCodeLoginStatusCancelButton"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
tools:visibility="visible">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/qrCodeLoginConfirmSecurityCodeImageView"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:importantForAccessibility="no"
|
||||||
|
android:src="@drawable/ic_info"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/qrCodeLoginConfirmSecurityCodeTextView"
|
||||||
|
style="@style/TextAppearance.Vector.Body"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:includeFontPadding="false"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:text="@string/qr_code_login_confirm_security_code_description"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/qrCodeLoginConfirmSecurityCodeImageView"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/qrCodeLoginConfirmSecurityCodeImageView" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/qrCodeLoginConfirmSecurityCodeButton"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="12dp"
|
||||||
|
android:layout_marginBottom="16dp"
|
||||||
|
android:text="@string/qr_code_login_confirm_security_code"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/qrCodeLoginConfirmSecurityCodeTextView" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/qrCodeLoginStatusCancelButton"
|
android:id="@+id/qrCodeLoginStatusCancelButton"
|
||||||
style="@style/Widget.Vector.Button.Outlined.Login"
|
style="@style/Widget.Vector.Button.Outlined.Login"
|
||||||
|
@ -118,15 +118,6 @@
|
|||||||
android:padding="6dp"
|
android:padding="6dp"
|
||||||
android:text="@string/four"
|
android:text="@string/four"
|
||||||
android:textColor="?colorPrimary" />
|
android:textColor="?colorPrimary" />
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/instruction4TextView"
|
|
||||||
style="@style/TextAppearance.Vector.Body"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center_vertical"
|
|
||||||
android:layout_marginStart="8dp"
|
|
||||||
tools:text="@string/qr_code_login_new_device_instruction_4" />
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</merge>
|
</merge>
|
||||||
|
Reference in New Issue
Block a user