Implement qr code login failed states.

This commit is contained in:
Onuray Sahin 2022-10-07 19:04:27 +03:00
parent 2527cab73e
commit 2b452d6fe5
6 changed files with 80 additions and 0 deletions

View file

@ -3337,6 +3337,10 @@
<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_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_failed_title">Unsuccessful connection</string>
<string name="qr_code_login_header_failed_device_is_not_supported_description">Linking with this device is not supported.</string>
<string name="qr_code_login_header_failed_timeout_description">The linking wasnt 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_new_device_instruction_1">Open Element on your other device</string>
<string name="qr_code_login_new_device_instruction_2">Go to Settings -> Security &amp; Privacy</string>
<string name="qr_code_login_new_device_instruction_3">Select \'Link a device\'</string>
@ -3347,5 +3351,6 @@
<string name="qr_code_login_connecting_to_device">Connecting to device</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_try_again">Try again</string>
</resources>

View file

@ -20,4 +20,5 @@ sealed class QrCodeLoginConnectionStatus {
object ConnectingToDevice : QrCodeLoginConnectionStatus()
data class Connected(val securityCode: String) : QrCodeLoginConnectionStatus()
object SigningIn : QrCodeLoginConnectionStatus()
data class Failed(val errorType: QrCodeLoginErrorType, val canTryAgain: Boolean) : QrCodeLoginConnectionStatus()
}

View file

@ -0,0 +1,23 @@
/*
* Copyright (c) 2022 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package im.vector.app.features.login.qr
enum class QrCodeLoginErrorType {
DEVICE_IS_NOT_SUPPORTED,
TIMEOUT,
REQUEST_WAS_DENIED,
}

View file

@ -55,17 +55,42 @@ class QrCodeLoginStatusFragment : VectorBaseFragment<FragmentQrCodeLoginStatusBi
is QrCodeLoginConnectionStatus.Connected -> handleConnectionEstablished(it.connectionStatus)
QrCodeLoginConnectionStatus.ConnectingToDevice -> handleConnectingToDevice()
QrCodeLoginConnectionStatus.SigningIn -> handleSigningIn()
is QrCodeLoginConnectionStatus.Failed -> handleFailed(it.connectionStatus)
null -> { /* NOOP */ }
}
}
}
private fun handleFailed(connectionStatus: QrCodeLoginConnectionStatus.Failed) {
views.qrCodeLoginStatusLoadingLayout.isVisible = false
views.qrCodeLoginStatusHeaderView.isVisible = true
views.qrCodeLoginStatusSecurityCode.isVisible = false
views.qrCodeLoginStatusNoMatchLayout.isVisible = false
views.qrCodeLoginStatusCancelButton.isVisible = true
views.qrCodeLoginStatusTryAgainButton.isVisible = connectionStatus.canTryAgain
views.qrCodeLoginStatusHeaderView.setTitle(getString(R.string.qr_code_login_header_failed_title))
views.qrCodeLoginStatusHeaderView.setDescription(getErrorCode(connectionStatus.errorType))
views.qrCodeLoginStatusHeaderView.setImage(
imageResource = R.drawable.ic_qr_code_login_failed,
backgroundTintColor = ThemeUtils.getColor(requireContext(), R.attr.colorError)
)
}
private fun getErrorCode(errorType: QrCodeLoginErrorType): String {
return when (errorType) {
QrCodeLoginErrorType.DEVICE_IS_NOT_SUPPORTED -> getString(R.string.qr_code_login_header_failed_device_is_not_supported_description)
QrCodeLoginErrorType.TIMEOUT -> getString(R.string.qr_code_login_header_failed_timeout_description)
QrCodeLoginErrorType.REQUEST_WAS_DENIED -> getString(R.string.qr_code_login_header_failed_denied_description)
}
}
private fun handleConnectingToDevice() {
views.qrCodeLoginStatusLoadingLayout.isVisible = true
views.qrCodeLoginStatusHeaderView.isVisible = false
views.qrCodeLoginStatusSecurityCode.isVisible = false
views.qrCodeLoginStatusNoMatchLayout.isVisible = false
views.qrCodeLoginStatusCancelButton.isVisible = true
views.qrCodeLoginStatusTryAgainButton.isVisible = false
views.qrCodeLoginStatusLoadingTextView.setText(R.string.qr_code_login_connecting_to_device)
}
@ -75,6 +100,7 @@ class QrCodeLoginStatusFragment : VectorBaseFragment<FragmentQrCodeLoginStatusBi
views.qrCodeLoginStatusSecurityCode.isVisible = false
views.qrCodeLoginStatusNoMatchLayout.isVisible = false
views.qrCodeLoginStatusCancelButton.isVisible = false
views.qrCodeLoginStatusTryAgainButton.isVisible = false
views.qrCodeLoginStatusLoadingTextView.setText(R.string.qr_code_login_signing_in)
}
@ -84,6 +110,7 @@ class QrCodeLoginStatusFragment : VectorBaseFragment<FragmentQrCodeLoginStatusBi
views.qrCodeLoginStatusSecurityCode.isVisible = true
views.qrCodeLoginStatusNoMatchLayout.isVisible = true
views.qrCodeLoginStatusCancelButton.isVisible = true
views.qrCodeLoginStatusTryAgainButton.isVisible = false
views.qrCodeLoginStatusSecurityCode.text = connectionStatus.securityCode
views.qrCodeLoginStatusHeaderView.setTitle(getString(R.string.qr_code_login_header_connected_title))
views.qrCodeLoginStatusHeaderView.setDescription(getString(R.string.qr_code_login_header_connected_description))

View file

@ -70,10 +70,22 @@ class QrCodeLoginViewModel @AssistedInject constructor(
// TODO. UI test purpose. Fixme remove!
viewModelScope.launch {
delay(3000)
onFailed(QrCodeLoginErrorType.TIMEOUT, false)
delay(3000)
onConnectionEstablished("1234-ABCD-5678-EFGH")
delay(3000)
onSigningIn()
delay(3000)
onFailed(QrCodeLoginErrorType.DEVICE_IS_NOT_SUPPORTED, true)
}
}
private fun onFailed(errorType: QrCodeLoginErrorType, canTryAgain: Boolean) {
setState {
copy(
connectionStatus = QrCodeLoginConnectionStatus.Failed(errorType, canTryAgain)
)
}
}

View file

@ -83,6 +83,18 @@
app:drawableTint="@color/alert_default_error_background" />
</FrameLayout>
<Button
android:id="@+id/qrCodeLoginStatusTryAgainButton"
style="@style/Widget.Vector.Button.Login"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="12dp"
android:text="@string/qr_code_login_try_again"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@id/qrCodeLoginStatusNoMatchLayout"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:visibility="visible" />
<Button
android:id="@+id/qrCodeLoginStatusCancelButton"