Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sign in with QR code #2793

Merged
merged 67 commits into from
May 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
855647f
QrCode login: enable and navigate to new Node
bmarty Feb 27, 2024
cb0287a
QrCode login: Intro screen with Camera permission
bmarty Feb 27, 2024
188e5e1
QrCode Scanner - WIP
bmarty Feb 27, 2024
8af1d52
to merge if it works.
bmarty Feb 29, 2024
ad608bb
WIP changes:
jmartinesp Apr 10, 2024
6f36885
Add new code confirmation and connection not secure screens
jmartinesp Apr 11, 2024
2a30842
WIP: start integrating Rust SDK APIs.
jmartinesp Apr 12, 2024
253ce12
Set up QR code login flow up to failure at the end
jmartinesp Apr 23, 2024
c9a2e29
Add localized strings
jmartinesp Apr 23, 2024
c83e6c5
Fix multiple `ClientBuilder` instances being created
jmartinesp Apr 23, 2024
92ea84c
Use `checkCodeString` for the check code value instead
jmartinesp Apr 23, 2024
0542be7
Finish the login flow on a successful QR code login
jmartinesp Apr 24, 2024
a3ba41c
WIP changes to try to fix verification state
jmartinesp Apr 24, 2024
4803864
Reuse existing code and simplify the flow
jmartinesp Apr 25, 2024
8f35a7b
Remove unnecessary 'link new device' option
jmartinesp Apr 25, 2024
a580355
Actually cancel the QR code login and do a cleanup of any lingering c…
jmartinesp Apr 25, 2024
2fc6499
Add some tests to onboarding screen
jmartinesp Apr 25, 2024
f4b51f9
Add some tests to QR code intro screen
jmartinesp Apr 25, 2024
d6ef9be
Fix generic error screen not being displayed
jmartinesp Apr 26, 2024
5791d32
More tests
jmartinesp Apr 26, 2024
7b2c4ad
Add minimal tests to `QrCodeLoginFlowNode`.
jmartinesp Apr 26, 2024
dc435f8
Workaround QrCodeErrorView crash
jmartinesp Apr 26, 2024
18a8fd8
Fix QR code login and verification
jmartinesp Apr 26, 2024
def8af2
Fix navigation issues in login flow by actually resetting the state o…
jmartinesp Apr 26, 2024
f3b2aa8
Actually `QrCodeLoginManagerImpl` doesn't need to be a singleton
jmartinesp Apr 26, 2024
14775d5
Add and fix tests
jmartinesp Apr 29, 2024
bf87cfe
Display the 'establishing secure connection' after the QR code is suc…
jmartinesp Apr 29, 2024
1ec15c0
Update strings
jmartinesp Apr 29, 2024
57e7379
Move `OnboardingConfig` to `appconfig` module
jmartinesp Apr 29, 2024
e12c19e
More tests, rename `QrCodeLoginManagerImpl` to `DefaultQrCodeLoginMan…
jmartinesp Apr 29, 2024
6bd9135
Merge remote-tracking branch 'origin/develop' into feature/bma/signIn…
jmartinesp Apr 30, 2024
f01de85
Fix merge issues
jmartinesp Apr 30, 2024
f4a24cc
Fix lint issues, update strings
jmartinesp May 3, 2024
261aef6
Use custom Rust SDK version
jmartinesp May 3, 2024
e8acd32
Merge remote-tracking branch 'origin/develop' into feature/bma/signIn…
jmartinesp May 3, 2024
4141f7a
Adapt to changes in SDK
jmartinesp May 6, 2024
b38ec55
Fix reading several incorrect QR codes breaking previews
jmartinesp May 9, 2024
3b56690
Use SNAPSHOT version for the Rust SDK
jmartinesp May 10, 2024
338f819
Only display the preview view when it's receiving video input
jmartinesp May 10, 2024
fe2e2f3
Add error mapping
jmartinesp May 17, 2024
a503634
Merge remote-tracking branch 'origin/develop' into feature/bma/signIn…
jmartinesp May 17, 2024
c70a890
WIP: mapping errors to error screens
jmartinesp May 17, 2024
fdbcd04
Add error handling (to be tested)
jmartinesp May 20, 2024
ac1e464
Use Zxing-CPP instead of outdated Zxing `v3.3.3`
jmartinesp May 21, 2024
5d474e2
Add new error codes and screens
jmartinesp May 24, 2024
1356778
Create `QrCodeLoginScope` to isolate the feature and make sure `QrCod…
jmartinesp May 24, 2024
91cdb8c
Merge remote-tracking branch 'origin/develop' into feature/bma/signIn…
jmartinesp May 24, 2024
14b21dd
Fix and improve tests and related code
jmartinesp May 24, 2024
43276e3
Fix lint issues
jmartinesp May 24, 2024
c50ec27
Update screenshots
May 24, 2024
f4e8f3b
Bump Matrix Rust SDK to `v0.2.21` and fix conflicts
jmartinesp May 29, 2024
3336a3b
Merge branch 'misc/jme/rust-sdk-0.2.21' into feature/bma/signInWithQr…
jmartinesp May 29, 2024
32e1609
Add QR code login FF enabled only for debug and nightly builds
jmartinesp May 29, 2024
53f5f09
Add new `QrLoginException.OtherDeviceNotSignedIn` and remove `QrLogin…
jmartinesp May 29, 2024
bfd27ed
Bump SDK, fix tests and lint issues
jmartinesp May 29, 2024
13c5007
Merge remote-tracking branch 'origin/develop' into feature/bma/signIn…
jmartinesp May 29, 2024
b81556f
Fix more lint issues
jmartinesp May 29, 2024
fdc1f8f
Update screenshots
May 29, 2024
9f615c4
Use enum for login flow type
jmartinesp May 30, 2024
0688064
Make nodes in qrcode feature use `QrCodeLoginScope` instead of `AppSc…
jmartinesp May 30, 2024
6ff42bc
Add bottom padding to the camera preview in `QrCodeScanView`
jmartinesp May 30, 2024
13c97ca
Update screenshots
May 30, 2024
a2ac07a
Update strings
jmartinesp May 31, 2024
6b5e558
Merge remote-tracking branch 'origin/develop' into feature/bma/signIn…
jmartinesp May 31, 2024
6375be4
Update screenshots
May 31, 2024
eab9676
Fix lint issues
jmartinesp May 31, 2024
7fad1a6
Fix maestro tests
jmartinesp May 31, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .maestro/tests/account/login.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
appId: ${MAESTRO_APP_ID}
---
- tapOn: "Continue"
- tapOn: "Sign in manually"
- runFlow: ../assertions/assertLoginDisplayed.yaml
- takeScreenshot: build/maestro/100-SignIn
- runFlow: changeServer.yaml
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2023 New Vector Ltd
* Copyright (c) 2024 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.
Expand All @@ -14,9 +14,12 @@
* limitations under the License.
*/

package io.element.android.features.onboarding.impl
package io.element.android.appconfig

object OnBoardingConfig {
/** Whether the user can use QR code login. */
const val CAN_LOGIN_WITH_QR_CODE = false

/** Whether the user can create an account using the app. */
const val CAN_CREATE_ACCOUNT = false
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,13 @@ import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import io.element.android.anvilannotations.ContributesNode
import io.element.android.features.login.api.LoginEntryPoint
import io.element.android.features.login.api.LoginFlowType
import io.element.android.features.onboarding.api.OnBoardingEntryPoint
import io.element.android.features.preferences.api.ConfigureTracingEntryPoint
import io.element.android.libraries.architecture.BackstackView
import io.element.android.libraries.architecture.BaseFlowNode
import io.element.android.libraries.designsystem.utils.ForceOrientationInMobileDevices
import io.element.android.libraries.designsystem.utils.ScreenOrientation
import io.element.android.libraries.di.AppScope
import io.element.android.libraries.matrix.ui.media.NotLoggedInImageLoaderFactory
import kotlinx.parcelize.Parcelize
Expand Down Expand Up @@ -73,9 +76,7 @@ class NotLoggedInFlowNode @AssistedInject constructor(
data object OnBoarding : NavTarget

@Parcelize
data class LoginFlow(
val isAccountCreation: Boolean,
) : NavTarget
data class LoginFlow(val type: LoginFlowType) : NavTarget

@Parcelize
data object ConfigureTracing : NavTarget
Expand All @@ -86,11 +87,15 @@ class NotLoggedInFlowNode @AssistedInject constructor(
NavTarget.OnBoarding -> {
val callback = object : OnBoardingEntryPoint.Callback {
override fun onSignUp() {
backstack.push(NavTarget.LoginFlow(isAccountCreation = true))
backstack.push(NavTarget.LoginFlow(type = LoginFlowType.SIGN_UP))
}

override fun onSignIn() {
backstack.push(NavTarget.LoginFlow(isAccountCreation = false))
backstack.push(NavTarget.LoginFlow(type = LoginFlowType.SIGN_IN_MANUAL))
}

override fun onSignInWithQrCode() {
backstack.push(NavTarget.LoginFlow(type = LoginFlowType.SIGN_IN_QR_CODE))
}

override fun onOpenDeveloperSettings() {
Expand All @@ -108,7 +113,7 @@ class NotLoggedInFlowNode @AssistedInject constructor(
}
is NavTarget.LoginFlow -> {
loginEntryPoint.nodeBuilder(this, buildContext)
.params(LoginEntryPoint.Params(isAccountCreation = navTarget.isAccountCreation))
.params(LoginEntryPoint.Params(flowType = navTarget.type))
.build()
}
NavTarget.ConfigureTracing -> {
Expand All @@ -119,6 +124,9 @@ class NotLoggedInFlowNode @AssistedInject constructor(

@Composable
override fun View(modifier: Modifier) {
// The login flow doesn't support landscape mode on mobile devices yet
ForceOrientationInMobileDevices(orientation = ScreenOrientation.PORTRAIT)

BackstackView()
}
}
6 changes: 3 additions & 3 deletions features/ftue/impl/src/main/res/values/localazy.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@
<string name="screen_qr_code_login_connection_note_secure_state_title">"Connection not secure"</string>
<string name="screen_qr_code_login_device_code_subtitle">"You’ll be asked to enter the two digits shown on this device."</string>
<string name="screen_qr_code_login_device_code_title">"Enter the number below on your other device"</string>
<string name="screen_qr_code_login_device_not_signed_in_scan_state_subtitle">"Sign in to your other device and then try again, or use another device that’s already signed in."</string>
<string name="screen_qr_code_login_device_not_signed_in_scan_state_title">"Other device not signed in"</string>
<string name="screen_qr_code_login_device_not_signed_in_scan_state_description">"Sign in to your other device and then try again, or use another device that’s already signed in."</string>
<string name="screen_qr_code_login_device_not_signed_in_scan_state_subtitle">"Other device not signed in"</string>
<string name="screen_qr_code_login_error_cancelled_subtitle">"The sign in was cancelled on the other device."</string>
<string name="screen_qr_code_login_error_cancelled_title">"Sign in request cancelled"</string>
<string name="screen_qr_code_login_error_declined_subtitle">"The request on your other device was not accepted."</string>
<string name="screen_qr_code_login_error_declined_subtitle">"The sign in was declined on the other device."</string>
<string name="screen_qr_code_login_error_declined_title">"Sign in declined"</string>
<string name="screen_qr_code_login_error_expired_subtitle">"Sign in expired. Please try again."</string>
<string name="screen_qr_code_login_error_expired_title">"The sign in was not completed in time"</string>
Expand Down
1 change: 1 addition & 0 deletions features/login/api/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
plugins {
id("io.element.android-library")
id("kotlin-parcelize")
}

android {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,15 @@

package io.element.android.features.login.api

import android.os.Parcelable
import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node
import io.element.android.libraries.architecture.FeatureEntryPoint
import kotlinx.parcelize.Parcelize

interface LoginEntryPoint : FeatureEntryPoint {
data class Params(
val isAccountCreation: Boolean,
val flowType: LoginFlowType

Check warning on line 27 in features/login/api/src/main/kotlin/io/element/android/features/login/api/LoginEntryPoint.kt

View check run for this annotation

Codecov / codecov/patch

features/login/api/src/main/kotlin/io/element/android/features/login/api/LoginEntryPoint.kt#L27

Added line #L27 was not covered by tests
)

fun nodeBuilder(parentNode: Node, buildContext: BuildContext): NodeBuilder
Expand All @@ -32,3 +34,10 @@
fun build(): Node
}
}

@Parcelize
enum class LoginFlowType : Parcelable {
SIGN_IN_MANUAL,
SIGN_IN_QR_CODE,
SIGN_UP

Check warning on line 42 in features/login/api/src/main/kotlin/io/element/android/features/login/api/LoginEntryPoint.kt

View check run for this annotation

Codecov / codecov/patch

features/login/api/src/main/kotlin/io/element/android/features/login/api/LoginEntryPoint.kt#L40-L42

Added lines #L40 - L42 were not covered by tests
}
7 changes: 7 additions & 0 deletions features/login/impl/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ dependencies {
implementation(projects.libraries.designsystem)
implementation(projects.libraries.testtags)
implementation(projects.libraries.uiStrings)
implementation(projects.libraries.permissions.api)
implementation(projects.libraries.qrcode)
implementation(libs.androidx.browser)
implementation(platform(libs.network.retrofit.bom))
implementation(libs.network.retrofit)
Expand All @@ -57,10 +59,15 @@ dependencies {
ksp(libs.showkase.processor)

testImplementation(libs.test.junit)
testImplementation(libs.androidx.compose.ui.test.junit)
testImplementation(libs.androidx.test.ext.junit)
testImplementation(libs.coroutines.test)
testImplementation(libs.molecule.runtime)
testImplementation(libs.test.robolectric)
testImplementation(libs.test.truth)
testImplementation(libs.test.turbine)
testImplementation(projects.libraries.matrix.test)
testImplementation(projects.libraries.permissions.test)
testImplementation(projects.tests.testutils)
testReleaseImplementation(libs.androidx.compose.ui.test.manifest)
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@

return object : LoginEntryPoint.NodeBuilder {
override fun params(params: LoginEntryPoint.Params): LoginEntryPoint.NodeBuilder {
plugins += LoginFlowNode.Inputs(isAccountCreation = params.isAccountCreation)
plugins += LoginFlowNode.Inputs(flowType = params.flowType)

Check warning on line 35 in features/login/impl/src/main/kotlin/io/element/android/features/login/impl/DefaultLoginEntryPoint.kt

View check run for this annotation

Codecov / codecov/patch

features/login/impl/src/main/kotlin/io/element/android/features/login/impl/DefaultLoginEntryPoint.kt#L35

Added line #L35 was not covered by tests
return this
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,14 @@ import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import io.element.android.anvilannotations.ContributesNode
import io.element.android.compound.theme.ElementTheme
import io.element.android.features.login.api.LoginFlowType
import io.element.android.features.login.api.oidc.OidcAction
import io.element.android.features.login.api.oidc.OidcActionFlow
import io.element.android.features.login.impl.accountprovider.AccountProviderDataSource
import io.element.android.features.login.impl.oidc.CustomTabAvailabilityChecker
import io.element.android.features.login.impl.oidc.customtab.CustomTabHandler
import io.element.android.features.login.impl.oidc.webview.OidcNode
import io.element.android.features.login.impl.qrcode.QrCodeLoginFlowNode
import io.element.android.features.login.impl.screens.changeaccountprovider.ChangeAccountProviderNode
import io.element.android.features.login.impl.screens.confirmaccountprovider.ConfirmAccountProviderNode
import io.element.android.features.login.impl.screens.loginpassword.LoginFormState
Expand Down Expand Up @@ -69,7 +71,7 @@ class LoginFlowNode @AssistedInject constructor(
private val oidcActionFlow: OidcActionFlow,
) : BaseFlowNode<LoginFlowNode.NavTarget>(
backstack = BackStack(
initialElement = NavTarget.ConfirmAccountProvider,
initialElement = NavTarget.Root,
savedStateMap = buildContext.savedStateMap,
),
buildContext = buildContext,
Expand All @@ -79,7 +81,7 @@ class LoginFlowNode @AssistedInject constructor(
private var darkTheme: Boolean = false

data class Inputs(
val isAccountCreation: Boolean,
val flowType: LoginFlowType,
) : NodeInputs

private val inputs: Inputs = inputs()
Expand Down Expand Up @@ -107,6 +109,9 @@ class LoginFlowNode @AssistedInject constructor(
}

sealed interface NavTarget : Parcelable {
@Parcelize
data object Root : NavTarget

@Parcelize
data object ConfirmAccountProvider : NavTarget

Expand All @@ -128,9 +133,16 @@ class LoginFlowNode @AssistedInject constructor(

override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node {
return when (navTarget) {
NavTarget.Root -> {
if (inputs.flowType == LoginFlowType.SIGN_IN_QR_CODE) {
createNode<QrCodeLoginFlowNode>(buildContext)
} else {
resolve(NavTarget.ConfirmAccountProvider, buildContext)
}
}
NavTarget.ConfirmAccountProvider -> {
val inputs = ConfirmAccountProviderNode.Inputs(
isAccountCreation = inputs.isAccountCreation
isAccountCreation = inputs.flowType == LoginFlowType.SIGN_UP,
)
val callback = object : ConfirmAccountProviderNode.Callback {
override fun onOidcDetails(oidcDetails: OidcDetails) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright (c) 2024 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 io.element.android.features.login.impl.di

import com.squareup.anvil.annotations.ContributesTo
import io.element.android.features.login.impl.qrcode.QrCodeLoginManager

@ContributesTo(QrCodeLoginScope::class)
interface QrCodeLoginBindings {
fun qrCodeLoginManager(): QrCodeLoginManager
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright (c) 2024 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 io.element.android.features.login.impl.di

import com.squareup.anvil.annotations.ContributesTo
import com.squareup.anvil.annotations.MergeSubcomponent
import dagger.Subcomponent
import io.element.android.libraries.architecture.NodeFactoriesBindings
import io.element.android.libraries.di.AppScope
import io.element.android.libraries.di.SingleIn

@SingleIn(QrCodeLoginScope::class)
@MergeSubcomponent(QrCodeLoginScope::class)
interface QrCodeLoginComponent : NodeFactoriesBindings {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need a separate component and scope for this? This is just to keep the StateFlow<QrCodeLoginStep>?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem here is QrCodeLoginManager had to be shared by several components (QrCodeLofingFlowNode, QrCodeScanPresenter) and for that I needed a singleton if I'm not mistaken. But having a singleton can be troublesome if you aren't super careful with cleaning up its state once you're done working with it, so I created a new component to hold it that will be created when the QR code flow starts and discarded once it's finished.

This should ensure the object is shared but can't be leaked in any way, although it's more complex than I intended it to be.

@Subcomponent.Builder
interface Builder {
fun build(): QrCodeLoginComponent
}

@ContributesTo(AppScope::class)
interface ParentBindings {
fun qrCodeLoginComponentBuilder(): Builder
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* Copyright (c) 2024 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 io.element.android.features.login.impl.di

abstract class QrCodeLoginScope private constructor()

Check warning on line 19 in features/login/impl/src/main/kotlin/io/element/android/features/login/impl/di/QrCodeLoginScope.kt

View check run for this annotation

Codecov / codecov/patch

features/login/impl/src/main/kotlin/io/element/android/features/login/impl/di/QrCodeLoginScope.kt#L19

Added line #L19 was not covered by tests
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,6 @@ fun OidcView(
internal fun OidcViewPreview(@PreviewParameter(OidcStateProvider::class) state: OidcState) = ElementPreview {
OidcView(
state = state,
onNavigateBack = { },
onNavigateBack = {},
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Copyright (c) 2024 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 io.element.android.features.login.impl.qrcode

import com.squareup.anvil.annotations.ContributesBinding
import io.element.android.features.login.impl.di.QrCodeLoginScope
import io.element.android.libraries.di.SingleIn
import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService
import io.element.android.libraries.matrix.api.auth.qrlogin.MatrixQrCodeLoginData
import io.element.android.libraries.matrix.api.auth.qrlogin.QrCodeLoginStep
import io.element.android.libraries.matrix.api.auth.qrlogin.QrLoginException
import io.element.android.libraries.matrix.api.core.SessionId
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import javax.inject.Inject

@SingleIn(QrCodeLoginScope::class)
@ContributesBinding(QrCodeLoginScope::class)
class DefaultQrCodeLoginManager @Inject constructor(
private val authenticationService: MatrixAuthenticationService,
) : QrCodeLoginManager {
private val _currentLoginStep = MutableStateFlow<QrCodeLoginStep>(QrCodeLoginStep.Uninitialized)
override val currentLoginStep: StateFlow<QrCodeLoginStep> = _currentLoginStep

override suspend fun authenticate(qrCodeLoginData: MatrixQrCodeLoginData): Result<SessionId> {
reset()

return authenticationService.loginWithQrCode(qrCodeLoginData) { step ->
_currentLoginStep.value = step
}.onFailure { throwable ->
if (throwable is QrLoginException) {
_currentLoginStep.value = QrCodeLoginStep.Failed(throwable)

Check warning on line 46 in features/login/impl/src/main/kotlin/io/element/android/features/login/impl/qrcode/DefaultQrCodeLoginManager.kt

View check run for this annotation

Codecov / codecov/patch

features/login/impl/src/main/kotlin/io/element/android/features/login/impl/qrcode/DefaultQrCodeLoginManager.kt#L46

Added line #L46 was not covered by tests
}
}
}

override fun reset() {
_currentLoginStep.value = QrCodeLoginStep.Uninitialized
}
}
Loading
Loading