mirror of
https://github.com/Novaloop-AG/element-x-android.git
synced 2026-10-31 08:15:02 +00:00
Show account info on the identity confirmation screen
Render an AccountInfoCard with the current user on the "Confirm your digital identity" screen, so the user knows which account needs to be verified. Closes #7898 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -32,6 +32,7 @@ dependencies {
|
||||
implementation(projects.libraries.core)
|
||||
implementation(projects.libraries.architecture)
|
||||
implementation(projects.libraries.matrix.api)
|
||||
implementation(projects.libraries.matrixui)
|
||||
implementation(projects.libraries.designsystem)
|
||||
implementation(projects.libraries.preferences.api)
|
||||
implementation(projects.libraries.uiCommon)
|
||||
|
||||
+4
@@ -20,16 +20,19 @@ import io.element.android.features.logout.api.direct.DirectLogoutState
|
||||
import io.element.android.libraries.architecture.AsyncData
|
||||
import io.element.android.libraries.architecture.Presenter
|
||||
import io.element.android.libraries.core.coroutine.mapState
|
||||
import io.element.android.libraries.matrix.api.MatrixClient
|
||||
import io.element.android.libraries.matrix.api.encryption.EncryptionService
|
||||
import io.element.android.libraries.matrix.api.encryption.RecoveryState
|
||||
|
||||
@Inject
|
||||
class ChooseSelfVerificationModePresenter(
|
||||
private val matrixClient: MatrixClient,
|
||||
private val encryptionService: EncryptionService,
|
||||
private val directLogoutPresenter: Presenter<DirectLogoutState>,
|
||||
) : Presenter<ChooseSelfVerificationModeState> {
|
||||
@Composable
|
||||
override fun present(): ChooseSelfVerificationModeState {
|
||||
val currentUser by matrixClient.userProfile.collectAsState()
|
||||
val hasDevicesToVerifyAgainst by encryptionService.hasDevicesToVerifyAgainst.collectAsState()
|
||||
val canUseRecoveryKey by produceState<AsyncData<Boolean>>(AsyncData.Uninitialized) {
|
||||
encryptionService.recoveryStateStateFlow
|
||||
@@ -72,6 +75,7 @@ class ChooseSelfVerificationModePresenter(
|
||||
}
|
||||
|
||||
return ChooseSelfVerificationModeState(
|
||||
currentUser = currentUser,
|
||||
buttonsState = buttonsState,
|
||||
directLogoutState = directLogoutState,
|
||||
eventSink = ::handleEvent,
|
||||
|
||||
+2
@@ -10,8 +10,10 @@ package io.element.android.features.ftue.impl.sessionverification.choosemode
|
||||
|
||||
import io.element.android.features.logout.api.direct.DirectLogoutState
|
||||
import io.element.android.libraries.architecture.AsyncData
|
||||
import io.element.android.libraries.matrix.api.user.MatrixUser
|
||||
|
||||
data class ChooseSelfVerificationModeState(
|
||||
val currentUser: MatrixUser,
|
||||
val buttonsState: AsyncData<ButtonsState>,
|
||||
val directLogoutState: DirectLogoutState,
|
||||
val eventSink: (ChooseSelfVerificationModeEvent) -> Unit,
|
||||
|
||||
+4
@@ -11,6 +11,8 @@ package io.element.android.features.ftue.impl.sessionverification.choosemode
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
import io.element.android.features.logout.api.direct.aDirectLogoutState
|
||||
import io.element.android.libraries.architecture.AsyncData
|
||||
import io.element.android.libraries.matrix.api.user.MatrixUser
|
||||
import io.element.android.libraries.matrix.ui.components.aMatrixUser
|
||||
|
||||
class ChooseSelfVerificationModeStatePreviewParam :
|
||||
PreviewParameterProvider<ChooseSelfVerificationModeState> {
|
||||
@@ -43,7 +45,9 @@ class ChooseSelfVerificationModeStatePreviewParam :
|
||||
|
||||
fun aChooseSelfVerificationModeState(
|
||||
buttonsState: AsyncData<ChooseSelfVerificationModeState.ButtonsState> = AsyncData.Success(aButtonsState()),
|
||||
currentUser: MatrixUser = aMatrixUser(),
|
||||
) = ChooseSelfVerificationModeState(
|
||||
currentUser = currentUser,
|
||||
buttonsState = buttonsState,
|
||||
directLogoutState = aDirectLogoutState(),
|
||||
eventSink = {},
|
||||
|
||||
+28
-12
@@ -12,6 +12,7 @@ import androidx.activity.compose.BackHandler
|
||||
import androidx.activity.compose.LocalActivity
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
@@ -39,6 +40,9 @@ import io.element.android.libraries.designsystem.theme.components.OutlinedButton
|
||||
import io.element.android.libraries.designsystem.theme.components.Text
|
||||
import io.element.android.libraries.designsystem.theme.components.TextButton
|
||||
import io.element.android.libraries.designsystem.theme.components.TopAppBar
|
||||
import io.element.android.libraries.matrix.ui.components.accountinfo.AccountInfoCard
|
||||
import io.element.android.libraries.matrix.ui.components.accountinfo.AccountInfoCardMode
|
||||
import io.element.android.libraries.matrix.ui.components.accountinfo.AccountInfoCardState
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
|
||||
@Composable
|
||||
@@ -75,6 +79,7 @@ fun ChooseSelfVerificationModeView(
|
||||
subTitle = stringResource(id = R.string.screen_identity_confirmation_subtitle)
|
||||
)
|
||||
},
|
||||
isScrollable = true,
|
||||
footer = {
|
||||
ChooseSelfVerificationModeButtons(
|
||||
state = state,
|
||||
@@ -84,20 +89,31 @@ fun ChooseSelfVerificationModeView(
|
||||
)
|
||||
}
|
||||
) {
|
||||
Row(
|
||||
Column(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.Center,
|
||||
verticalArrangement = Arrangement.spacedBy(24.dp),
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.clickable(onClick = onLearnMore)
|
||||
.padding(vertical = 4.dp, horizontal = 16.dp)
|
||||
.semantics {
|
||||
// Note: there is no Role.Link, so we use Role.Button for better accessibility support
|
||||
role = Role.Button
|
||||
},
|
||||
text = stringResource(CommonStrings.action_learn_more),
|
||||
style = ElementTheme.typography.fontBodyLgMedium
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.Center,
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.clickable(onClick = onLearnMore)
|
||||
.padding(vertical = 4.dp, horizontal = 16.dp)
|
||||
.semantics {
|
||||
// Note: there is no Role.Link, so we use Role.Button for better accessibility support
|
||||
role = Role.Button
|
||||
},
|
||||
text = stringResource(CommonStrings.action_learn_more),
|
||||
style = ElementTheme.typography.fontBodyLgMedium
|
||||
)
|
||||
}
|
||||
AccountInfoCard(
|
||||
state = AccountInfoCardState(
|
||||
matrixUser = state.currentUser,
|
||||
mode = AccountInfoCardMode.Simple,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+28
@@ -14,7 +14,13 @@ import io.element.android.features.logout.api.direct.DirectLogoutState
|
||||
import io.element.android.features.logout.api.direct.aDirectLogoutState
|
||||
import io.element.android.libraries.architecture.AsyncData
|
||||
import io.element.android.libraries.architecture.Presenter
|
||||
import io.element.android.libraries.matrix.api.MatrixClient
|
||||
import io.element.android.libraries.matrix.api.encryption.RecoveryState
|
||||
import io.element.android.libraries.matrix.api.user.MatrixUser
|
||||
import io.element.android.libraries.matrix.test.AN_AVATAR_URL
|
||||
import io.element.android.libraries.matrix.test.A_SESSION_ID
|
||||
import io.element.android.libraries.matrix.test.A_USER_NAME
|
||||
import io.element.android.libraries.matrix.test.FakeMatrixClient
|
||||
import io.element.android.libraries.matrix.test.encryption.FakeEncryptionService
|
||||
import io.element.android.tests.testutils.lambda.lambdaRecorder
|
||||
import io.element.android.tests.testutils.lambda.value
|
||||
@@ -34,6 +40,26 @@ class ChooseSessionVerificationModePresenterTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `present - current user is exposed`() = runTest {
|
||||
val presenter = createPresenter(
|
||||
matrixClient = FakeMatrixClient(
|
||||
sessionId = A_SESSION_ID,
|
||||
userDisplayName = A_USER_NAME,
|
||||
userAvatarUrl = AN_AVATAR_URL,
|
||||
),
|
||||
)
|
||||
presenter.test {
|
||||
assertThat(awaitItem().currentUser).isEqualTo(
|
||||
MatrixUser(
|
||||
userId = A_SESSION_ID,
|
||||
displayName = A_USER_NAME,
|
||||
avatarUrl = AN_AVATAR_URL,
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `present - state is relayed from EncryptionService, order 1`() = runTest {
|
||||
val encryptionService = FakeEncryptionService()
|
||||
@@ -126,9 +152,11 @@ class ChooseSessionVerificationModePresenterTest {
|
||||
}
|
||||
|
||||
private fun createPresenter(
|
||||
matrixClient: MatrixClient = FakeMatrixClient(),
|
||||
encryptionService: FakeEncryptionService = FakeEncryptionService(),
|
||||
directLogoutPresenter: Presenter<DirectLogoutState> = Presenter<DirectLogoutState> { aDirectLogoutState() }
|
||||
) = ChooseSelfVerificationModePresenter(
|
||||
matrixClient = matrixClient,
|
||||
encryptionService = encryptionService,
|
||||
directLogoutPresenter = directLogoutPresenter,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user