Merge pull request #3360 from element-hq/feature/bma/sessionVerificationBannerIsBack
Add banner entry point to set up recovery
This commit is contained in:
commit
9f67c65c2c
20 changed files with 173 additions and 16 deletions
|
|
@ -259,6 +259,10 @@ class LoggedInFlowNode @AssistedInject constructor(
|
||||||
backstack.push(NavTarget.CreateRoom)
|
backstack.push(NavTarget.CreateRoom)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onSetUpRecoveryClick() {
|
||||||
|
backstack.push(NavTarget.SecureBackup(initialElement = SecureBackupEntryPoint.InitialTarget.SetUpRecovery))
|
||||||
|
}
|
||||||
|
|
||||||
override fun onSessionConfirmRecoveryKeyClick() {
|
override fun onSessionConfirmRecoveryKeyClick() {
|
||||||
backstack.push(NavTarget.SecureBackup(initialElement = SecureBackupEntryPoint.InitialTarget.EnterRecoveryKey))
|
backstack.push(NavTarget.SecureBackup(initialElement = SecureBackupEntryPoint.InitialTarget.EnterRecoveryKey))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@ interface RoomListEntryPoint : FeatureEntryPoint {
|
||||||
fun onRoomClick(roomId: RoomId)
|
fun onRoomClick(roomId: RoomId)
|
||||||
fun onCreateRoomClick()
|
fun onCreateRoomClick()
|
||||||
fun onSettingsClick()
|
fun onSettingsClick()
|
||||||
|
fun onSetUpRecoveryClick()
|
||||||
fun onSessionConfirmRecoveryKeyClick()
|
fun onSessionConfirmRecoveryKeyClick()
|
||||||
fun onRoomSettingsClick(roomId: RoomId)
|
fun onRoomSettingsClick(roomId: RoomId)
|
||||||
fun onReportBugClick()
|
fun onReportBugClick()
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,10 @@ class RoomListNode @AssistedInject constructor(
|
||||||
plugins<RoomListEntryPoint.Callback>().forEach { it.onCreateRoomClick() }
|
plugins<RoomListEntryPoint.Callback>().forEach { it.onCreateRoomClick() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun onSetUpRecoveryClick() {
|
||||||
|
plugins<RoomListEntryPoint.Callback>().forEach { it.onSetUpRecoveryClick() }
|
||||||
|
}
|
||||||
|
|
||||||
private fun onSessionConfirmRecoveryKeyClick() {
|
private fun onSessionConfirmRecoveryKeyClick() {
|
||||||
plugins<RoomListEntryPoint.Callback>().forEach { it.onSessionConfirmRecoveryKeyClick() }
|
plugins<RoomListEntryPoint.Callback>().forEach { it.onSessionConfirmRecoveryKeyClick() }
|
||||||
}
|
}
|
||||||
|
|
@ -98,6 +102,7 @@ class RoomListNode @AssistedInject constructor(
|
||||||
onRoomClick = this::onRoomClick,
|
onRoomClick = this::onRoomClick,
|
||||||
onSettingsClick = this::onOpenSettings,
|
onSettingsClick = this::onOpenSettings,
|
||||||
onCreateRoomClick = this::onCreateRoomClick,
|
onCreateRoomClick = this::onCreateRoomClick,
|
||||||
|
onSetUpRecoveryClick = this::onSetUpRecoveryClick,
|
||||||
onConfirmRecoveryKeyClick = this::onSessionConfirmRecoveryKeyClick,
|
onConfirmRecoveryKeyClick = this::onSessionConfirmRecoveryKeyClick,
|
||||||
onRoomSettingsClick = this::onRoomSettingsClick,
|
onRoomSettingsClick = this::onRoomSettingsClick,
|
||||||
onMenuActionClick = { onMenuActionClick(activity, it) },
|
onMenuActionClick = { onMenuActionClick(activity, it) },
|
||||||
|
|
|
||||||
|
|
@ -187,8 +187,15 @@ class RoomListPresenter @Inject constructor(
|
||||||
derivedStateOf {
|
derivedStateOf {
|
||||||
when {
|
when {
|
||||||
currentSecurityBannerDismissed -> SecurityBannerState.None
|
currentSecurityBannerDismissed -> SecurityBannerState.None
|
||||||
recoveryState == RecoveryState.INCOMPLETE &&
|
syncState == SyncState.Running -> {
|
||||||
syncState == SyncState.Running -> SecurityBannerState.RecoveryKeyConfirmation
|
when (recoveryState) {
|
||||||
|
RecoveryState.UNKNOWN,
|
||||||
|
RecoveryState.DISABLED -> SecurityBannerState.SetUpRecovery
|
||||||
|
RecoveryState.INCOMPLETE -> SecurityBannerState.RecoveryKeyConfirmation
|
||||||
|
RecoveryState.WAITING_FOR_SYNC,
|
||||||
|
RecoveryState.ENABLED -> SecurityBannerState.None
|
||||||
|
}
|
||||||
|
}
|
||||||
else -> SecurityBannerState.None
|
else -> SecurityBannerState.None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,7 @@ enum class InvitesState {
|
||||||
|
|
||||||
enum class SecurityBannerState {
|
enum class SecurityBannerState {
|
||||||
None,
|
None,
|
||||||
|
SetUpRecovery,
|
||||||
RecoveryKeyConfirmation,
|
RecoveryKeyConfirmation,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,7 @@ open class RoomListStateProvider : PreviewParameterProvider<RoomListState> {
|
||||||
aRoomListState(contentState = aSkeletonContentState()),
|
aRoomListState(contentState = aSkeletonContentState()),
|
||||||
aRoomListState(matrixUser = MatrixUser(userId = UserId("@id:domain")), contentState = aMigrationContentState()),
|
aRoomListState(matrixUser = MatrixUser(userId = UserId("@id:domain")), contentState = aMigrationContentState()),
|
||||||
aRoomListState(searchState = aRoomListSearchState(isSearchActive = true, query = "Test")),
|
aRoomListState(searchState = aRoomListSearchState(isSearchActive = true, query = "Test")),
|
||||||
|
aRoomListState(contentState = aRoomsContentState(securityBannerState = SecurityBannerState.SetUpRecovery)),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,7 @@ fun RoomListView(
|
||||||
state: RoomListState,
|
state: RoomListState,
|
||||||
onRoomClick: (RoomId) -> Unit,
|
onRoomClick: (RoomId) -> Unit,
|
||||||
onSettingsClick: () -> Unit,
|
onSettingsClick: () -> Unit,
|
||||||
|
onSetUpRecoveryClick: () -> Unit,
|
||||||
onConfirmRecoveryKeyClick: () -> Unit,
|
onConfirmRecoveryKeyClick: () -> Unit,
|
||||||
onCreateRoomClick: () -> Unit,
|
onCreateRoomClick: () -> Unit,
|
||||||
onRoomSettingsClick: (roomId: RoomId) -> Unit,
|
onRoomSettingsClick: (roomId: RoomId) -> Unit,
|
||||||
|
|
@ -78,6 +79,7 @@ fun RoomListView(
|
||||||
|
|
||||||
RoomListScaffold(
|
RoomListScaffold(
|
||||||
state = state,
|
state = state,
|
||||||
|
onSetUpRecoveryClick = onSetUpRecoveryClick,
|
||||||
onConfirmRecoveryKeyClick = onConfirmRecoveryKeyClick,
|
onConfirmRecoveryKeyClick = onConfirmRecoveryKeyClick,
|
||||||
onRoomClick = onRoomClick,
|
onRoomClick = onRoomClick,
|
||||||
onOpenSettings = onSettingsClick,
|
onOpenSettings = onSettingsClick,
|
||||||
|
|
@ -106,6 +108,7 @@ fun RoomListView(
|
||||||
@Composable
|
@Composable
|
||||||
private fun RoomListScaffold(
|
private fun RoomListScaffold(
|
||||||
state: RoomListState,
|
state: RoomListState,
|
||||||
|
onSetUpRecoveryClick: () -> Unit,
|
||||||
onConfirmRecoveryKeyClick: () -> Unit,
|
onConfirmRecoveryKeyClick: () -> Unit,
|
||||||
onRoomClick: (RoomId) -> Unit,
|
onRoomClick: (RoomId) -> Unit,
|
||||||
onOpenSettings: () -> Unit,
|
onOpenSettings: () -> Unit,
|
||||||
|
|
@ -142,6 +145,7 @@ private fun RoomListScaffold(
|
||||||
contentState = state.contentState,
|
contentState = state.contentState,
|
||||||
filtersState = state.filtersState,
|
filtersState = state.filtersState,
|
||||||
eventSink = state.eventSink,
|
eventSink = state.eventSink,
|
||||||
|
onSetUpRecoveryClick = onSetUpRecoveryClick,
|
||||||
onConfirmRecoveryKeyClick = onConfirmRecoveryKeyClick,
|
onConfirmRecoveryKeyClick = onConfirmRecoveryKeyClick,
|
||||||
onRoomClick = ::onRoomClick,
|
onRoomClick = ::onRoomClick,
|
||||||
onCreateRoomClick = onCreateRoomClick,
|
onCreateRoomClick = onCreateRoomClick,
|
||||||
|
|
@ -178,6 +182,7 @@ internal fun RoomListViewPreview(@PreviewParameter(RoomListStateProvider::class)
|
||||||
state = state,
|
state = state,
|
||||||
onRoomClick = {},
|
onRoomClick = {},
|
||||||
onSettingsClick = {},
|
onSettingsClick = {},
|
||||||
|
onSetUpRecoveryClick = {},
|
||||||
onConfirmRecoveryKeyClick = {},
|
onConfirmRecoveryKeyClick = {},
|
||||||
onCreateRoomClick = {},
|
onCreateRoomClick = {},
|
||||||
onRoomSettingsClick = {},
|
onRoomSettingsClick = {},
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,7 @@ fun RoomListContentView(
|
||||||
contentState: RoomListContentState,
|
contentState: RoomListContentState,
|
||||||
filtersState: RoomListFiltersState,
|
filtersState: RoomListFiltersState,
|
||||||
eventSink: (RoomListEvents) -> Unit,
|
eventSink: (RoomListEvents) -> Unit,
|
||||||
|
onSetUpRecoveryClick: () -> Unit,
|
||||||
onConfirmRecoveryKeyClick: () -> Unit,
|
onConfirmRecoveryKeyClick: () -> Unit,
|
||||||
onRoomClick: (RoomListRoomSummary) -> Unit,
|
onRoomClick: (RoomListRoomSummary) -> Unit,
|
||||||
onCreateRoomClick: () -> Unit,
|
onCreateRoomClick: () -> Unit,
|
||||||
|
|
@ -95,6 +96,7 @@ fun RoomListContentView(
|
||||||
state = contentState,
|
state = contentState,
|
||||||
filtersState = filtersState,
|
filtersState = filtersState,
|
||||||
eventSink = eventSink,
|
eventSink = eventSink,
|
||||||
|
onSetUpRecoveryClick = onSetUpRecoveryClick,
|
||||||
onConfirmRecoveryKeyClick = onConfirmRecoveryKeyClick,
|
onConfirmRecoveryKeyClick = onConfirmRecoveryKeyClick,
|
||||||
onRoomClick = onRoomClick,
|
onRoomClick = onRoomClick,
|
||||||
)
|
)
|
||||||
|
|
@ -141,6 +143,7 @@ private fun RoomsView(
|
||||||
state: RoomListContentState.Rooms,
|
state: RoomListContentState.Rooms,
|
||||||
filtersState: RoomListFiltersState,
|
filtersState: RoomListFiltersState,
|
||||||
eventSink: (RoomListEvents) -> Unit,
|
eventSink: (RoomListEvents) -> Unit,
|
||||||
|
onSetUpRecoveryClick: () -> Unit,
|
||||||
onConfirmRecoveryKeyClick: () -> Unit,
|
onConfirmRecoveryKeyClick: () -> Unit,
|
||||||
onRoomClick: (RoomListRoomSummary) -> Unit,
|
onRoomClick: (RoomListRoomSummary) -> Unit,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
|
|
@ -154,6 +157,7 @@ private fun RoomsView(
|
||||||
RoomsViewList(
|
RoomsViewList(
|
||||||
state = state,
|
state = state,
|
||||||
eventSink = eventSink,
|
eventSink = eventSink,
|
||||||
|
onSetUpRecoveryClick = onSetUpRecoveryClick,
|
||||||
onConfirmRecoveryKeyClick = onConfirmRecoveryKeyClick,
|
onConfirmRecoveryKeyClick = onConfirmRecoveryKeyClick,
|
||||||
onRoomClick = onRoomClick,
|
onRoomClick = onRoomClick,
|
||||||
modifier = modifier.fillMaxSize(),
|
modifier = modifier.fillMaxSize(),
|
||||||
|
|
@ -165,6 +169,7 @@ private fun RoomsView(
|
||||||
private fun RoomsViewList(
|
private fun RoomsViewList(
|
||||||
state: RoomListContentState.Rooms,
|
state: RoomListContentState.Rooms,
|
||||||
eventSink: (RoomListEvents) -> Unit,
|
eventSink: (RoomListEvents) -> Unit,
|
||||||
|
onSetUpRecoveryClick: () -> Unit,
|
||||||
onConfirmRecoveryKeyClick: () -> Unit,
|
onConfirmRecoveryKeyClick: () -> Unit,
|
||||||
onRoomClick: (RoomListRoomSummary) -> Unit,
|
onRoomClick: (RoomListRoomSummary) -> Unit,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
|
|
@ -188,21 +193,27 @@ private fun RoomsViewList(
|
||||||
// FAB height is 56dp, bottom padding is 16dp, we add 8dp as extra margin -> 56+16+8 = 80
|
// FAB height is 56dp, bottom padding is 16dp, we add 8dp as extra margin -> 56+16+8 = 80
|
||||||
contentPadding = PaddingValues(bottom = 80.dp)
|
contentPadding = PaddingValues(bottom = 80.dp)
|
||||||
) {
|
) {
|
||||||
if (state.securityBannerState != SecurityBannerState.None) {
|
when (state.securityBannerState) {
|
||||||
when (state.securityBannerState) {
|
SecurityBannerState.SetUpRecovery -> {
|
||||||
SecurityBannerState.RecoveryKeyConfirmation -> {
|
item {
|
||||||
item {
|
SetUpRecoveryKeyBanner(
|
||||||
ConfirmRecoveryKeyBanner(
|
onContinueClick = onSetUpRecoveryClick,
|
||||||
onContinueClick = onConfirmRecoveryKeyClick,
|
onDismissClick = { updatedEventSink(RoomListEvents.DismissRecoveryKeyPrompt) }
|
||||||
onDismissClick = { updatedEventSink(RoomListEvents.DismissRecoveryKeyPrompt) }
|
)
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else -> Unit
|
|
||||||
}
|
}
|
||||||
} else if (state.fullScreenIntentPermissionsState.shouldDisplayBanner) {
|
SecurityBannerState.RecoveryKeyConfirmation -> {
|
||||||
item {
|
item {
|
||||||
FullScreenIntentPermissionBanner(state = state.fullScreenIntentPermissionsState)
|
ConfirmRecoveryKeyBanner(
|
||||||
|
onContinueClick = onConfirmRecoveryKeyClick,
|
||||||
|
onDismissClick = { updatedEventSink(RoomListEvents.DismissRecoveryKeyPrompt) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SecurityBannerState.None -> if (state.fullScreenIntentPermissionsState.shouldDisplayBanner) {
|
||||||
|
item {
|
||||||
|
FullScreenIntentPermissionBanner(state = state.fullScreenIntentPermissionsState)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -276,6 +287,7 @@ internal fun RoomListContentViewPreview(@PreviewParameter(RoomListContentStatePr
|
||||||
filterSelectionStates = RoomListFilter.entries.map { FilterSelectionState(it, isSelected = true) }
|
filterSelectionStates = RoomListFilter.entries.map { FilterSelectionState(it, isSelected = true) }
|
||||||
),
|
),
|
||||||
eventSink = {},
|
eventSink = {},
|
||||||
|
onSetUpRecoveryClick = {},
|
||||||
onConfirmRecoveryKeyClick = {},
|
onConfirmRecoveryKeyClick = {},
|
||||||
onRoomClick = {},
|
onRoomClick = {},
|
||||||
onCreateRoomClick = {},
|
onCreateRoomClick = {},
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* https://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.roomlist.impl.components
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import io.element.android.features.roomlist.impl.R
|
||||||
|
import io.element.android.libraries.designsystem.atomic.molecules.DialogLikeBannerMolecule
|
||||||
|
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||||
|
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
internal fun SetUpRecoveryKeyBanner(
|
||||||
|
onContinueClick: () -> Unit,
|
||||||
|
onDismissClick: () -> Unit,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
) {
|
||||||
|
DialogLikeBannerMolecule(
|
||||||
|
modifier = modifier,
|
||||||
|
title = stringResource(R.string.banner_set_up_recovery_title),
|
||||||
|
content = stringResource(R.string.banner_set_up_recovery_content),
|
||||||
|
onSubmitClick = onContinueClick,
|
||||||
|
onDismissClick = onDismissClick,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@PreviewsDayNight
|
||||||
|
@Composable
|
||||||
|
internal fun SetUpRecoveryKeyBannerPreview() = ElementPreview {
|
||||||
|
SetUpRecoveryKeyBanner(
|
||||||
|
onContinueClick = {},
|
||||||
|
onDismissClick = {},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||||
|
<string name="banner_set_up_recovery_content">"Generate a new recovery key that can be used to restore your encrypted message history in case you lose access to your devices."</string>
|
||||||
|
<string name="banner_set_up_recovery_title">"Set up recovery"</string>
|
||||||
<string name="confirm_recovery_key_banner_message">"Your chat backup is currently out of sync. You need to enter your recovery key to maintain access to your chat backup."</string>
|
<string name="confirm_recovery_key_banner_message">"Your chat backup is currently out of sync. You need to enter your recovery key to maintain access to your chat backup."</string>
|
||||||
<string name="confirm_recovery_key_banner_title">"Enter your recovery key"</string>
|
<string name="confirm_recovery_key_banner_title">"Enter your recovery key"</string>
|
||||||
<string name="full_screen_intent_banner_message">"To ensure you never miss an important call, please change your settings to allow full-screen notifications when your phone is locked."</string>
|
<string name="full_screen_intent_banner_message">"To ensure you never miss an important call, please change your settings to allow full-screen notifications when your phone is locked."</string>
|
||||||
|
|
|
||||||
|
|
@ -264,10 +264,21 @@ class RoomListPresenterTest {
|
||||||
val initialState = consumeItemsUntilPredicate {
|
val initialState = consumeItemsUntilPredicate {
|
||||||
it.contentState is RoomListContentState.Rooms
|
it.contentState is RoomListContentState.Rooms
|
||||||
}.last()
|
}.last()
|
||||||
assertThat(initialState.contentAsRooms().securityBannerState).isEqualTo(SecurityBannerState.None)
|
assertThat(initialState.contentAsRooms().securityBannerState).isEqualTo(SecurityBannerState.SetUpRecovery)
|
||||||
encryptionService.emitRecoveryState(RecoveryState.INCOMPLETE)
|
encryptionService.emitRecoveryState(RecoveryState.INCOMPLETE)
|
||||||
val nextState = awaitItem()
|
val nextState = awaitItem()
|
||||||
assertThat(nextState.contentAsRooms().securityBannerState).isEqualTo(SecurityBannerState.RecoveryKeyConfirmation)
|
assertThat(nextState.contentAsRooms().securityBannerState).isEqualTo(SecurityBannerState.RecoveryKeyConfirmation)
|
||||||
|
// Also check other states
|
||||||
|
encryptionService.emitRecoveryState(RecoveryState.DISABLED)
|
||||||
|
assertThat(awaitItem().contentAsRooms().securityBannerState).isEqualTo(SecurityBannerState.SetUpRecovery)
|
||||||
|
encryptionService.emitRecoveryState(RecoveryState.WAITING_FOR_SYNC)
|
||||||
|
assertThat(awaitItem().contentAsRooms().securityBannerState).isEqualTo(SecurityBannerState.None)
|
||||||
|
encryptionService.emitRecoveryState(RecoveryState.DISABLED)
|
||||||
|
assertThat(awaitItem().contentAsRooms().securityBannerState).isEqualTo(SecurityBannerState.SetUpRecovery)
|
||||||
|
encryptionService.emitRecoveryState(RecoveryState.ENABLED)
|
||||||
|
assertThat(awaitItem().contentAsRooms().securityBannerState).isEqualTo(SecurityBannerState.None)
|
||||||
|
encryptionService.emitRecoveryState(RecoveryState.DISABLED)
|
||||||
|
assertThat(awaitItem().contentAsRooms().securityBannerState).isEqualTo(SecurityBannerState.SetUpRecovery)
|
||||||
nextState.eventSink(RoomListEvents.DismissRecoveryKeyPrompt)
|
nextState.eventSink(RoomListEvents.DismissRecoveryKeyPrompt)
|
||||||
val finalState = awaitItem()
|
val finalState = awaitItem()
|
||||||
assertThat(finalState.contentAsRooms().securityBannerState).isEqualTo(SecurityBannerState.None)
|
assertThat(finalState.contentAsRooms().securityBannerState).isEqualTo(SecurityBannerState.None)
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,24 @@ class RoomListViewTest {
|
||||||
eventsRecorder.assertSingle(RoomListEvents.DismissRecoveryKeyPrompt)
|
eventsRecorder.assertSingle(RoomListEvents.DismissRecoveryKeyPrompt)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `clicking on close setup key banner emits the expected Event`() {
|
||||||
|
val eventsRecorder = EventsRecorder<RoomListEvents>()
|
||||||
|
rule.setRoomListView(
|
||||||
|
state = aRoomListState(
|
||||||
|
contentState = aRoomsContentState(securityBannerState = SecurityBannerState.SetUpRecovery),
|
||||||
|
eventSink = eventsRecorder,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
// Remove automatic initial events
|
||||||
|
eventsRecorder.clear()
|
||||||
|
|
||||||
|
val close = rule.activity.getString(CommonStrings.action_close)
|
||||||
|
rule.onNodeWithContentDescription(close).performClick()
|
||||||
|
eventsRecorder.assertSingle(RoomListEvents.DismissRecoveryKeyPrompt)
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `clicking on continue recovery key banner invokes the expected callback`() {
|
fun `clicking on continue recovery key banner invokes the expected callback`() {
|
||||||
val eventsRecorder = EventsRecorder<RoomListEvents>()
|
val eventsRecorder = EventsRecorder<RoomListEvents>()
|
||||||
|
|
@ -101,6 +119,27 @@ class RoomListViewTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `clicking on continue setup key banner invokes the expected callback`() {
|
||||||
|
val eventsRecorder = EventsRecorder<RoomListEvents>()
|
||||||
|
ensureCalledOnce { callback ->
|
||||||
|
rule.setRoomListView(
|
||||||
|
state = aRoomListState(
|
||||||
|
contentState = aRoomsContentState(securityBannerState = SecurityBannerState.SetUpRecovery),
|
||||||
|
eventSink = eventsRecorder,
|
||||||
|
),
|
||||||
|
onSetUpRecoveryClick = callback,
|
||||||
|
)
|
||||||
|
|
||||||
|
// Remove automatic initial events
|
||||||
|
eventsRecorder.clear()
|
||||||
|
|
||||||
|
rule.clickOn(CommonStrings.action_continue)
|
||||||
|
|
||||||
|
eventsRecorder.assertEmpty()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `clicking on start chat when the session has no room invokes the expected callback`() {
|
fun `clicking on start chat when the session has no room invokes the expected callback`() {
|
||||||
val eventsRecorder = EventsRecorder<RoomListEvents>(expectEvents = false)
|
val eventsRecorder = EventsRecorder<RoomListEvents>(expectEvents = false)
|
||||||
|
|
@ -208,6 +247,7 @@ private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setRoomL
|
||||||
state: RoomListState,
|
state: RoomListState,
|
||||||
onRoomClick: (RoomId) -> Unit = EnsureNeverCalledWithParam(),
|
onRoomClick: (RoomId) -> Unit = EnsureNeverCalledWithParam(),
|
||||||
onSettingsClick: () -> Unit = EnsureNeverCalled(),
|
onSettingsClick: () -> Unit = EnsureNeverCalled(),
|
||||||
|
onSetUpRecoveryClick: () -> Unit = EnsureNeverCalled(),
|
||||||
onConfirmRecoveryKeyClick: () -> Unit = EnsureNeverCalled(),
|
onConfirmRecoveryKeyClick: () -> Unit = EnsureNeverCalled(),
|
||||||
onCreateRoomClick: () -> Unit = EnsureNeverCalled(),
|
onCreateRoomClick: () -> Unit = EnsureNeverCalled(),
|
||||||
onRoomSettingsClick: (RoomId) -> Unit = EnsureNeverCalledWithParam(),
|
onRoomSettingsClick: (RoomId) -> Unit = EnsureNeverCalledWithParam(),
|
||||||
|
|
@ -219,6 +259,7 @@ private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setRoomL
|
||||||
state = state,
|
state = state,
|
||||||
onRoomClick = onRoomClick,
|
onRoomClick = onRoomClick,
|
||||||
onSettingsClick = onSettingsClick,
|
onSettingsClick = onSettingsClick,
|
||||||
|
onSetUpRecoveryClick = onSetUpRecoveryClick,
|
||||||
onConfirmRecoveryKeyClick = onConfirmRecoveryKeyClick,
|
onConfirmRecoveryKeyClick = onConfirmRecoveryKeyClick,
|
||||||
onCreateRoomClick = onCreateRoomClick,
|
onCreateRoomClick = onCreateRoomClick,
|
||||||
onRoomSettingsClick = onRoomSettingsClick,
|
onRoomSettingsClick = onRoomSettingsClick,
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,9 @@ interface SecureBackupEntryPoint : FeatureEntryPoint {
|
||||||
@Parcelize
|
@Parcelize
|
||||||
data object Root : InitialTarget
|
data object Root : InitialTarget
|
||||||
|
|
||||||
|
@Parcelize
|
||||||
|
data object SetUpRecovery : InitialTarget
|
||||||
|
|
||||||
@Parcelize
|
@Parcelize
|
||||||
data object EnterRecoveryKey : InitialTarget
|
data object EnterRecoveryKey : InitialTarget
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@ class SecureBackupFlowNode @AssistedInject constructor(
|
||||||
backstack = BackStack(
|
backstack = BackStack(
|
||||||
initialElement = when (plugins.filterIsInstance<SecureBackupEntryPoint.Params>().first().initialElement) {
|
initialElement = when (plugins.filterIsInstance<SecureBackupEntryPoint.Params>().first().initialElement) {
|
||||||
SecureBackupEntryPoint.InitialTarget.Root -> NavTarget.Root
|
SecureBackupEntryPoint.InitialTarget.Root -> NavTarget.Root
|
||||||
|
SecureBackupEntryPoint.InitialTarget.SetUpRecovery -> NavTarget.Setup
|
||||||
SecureBackupEntryPoint.InitialTarget.EnterRecoveryKey -> NavTarget.EnterRecoveryKey
|
SecureBackupEntryPoint.InitialTarget.EnterRecoveryKey -> NavTarget.EnterRecoveryKey
|
||||||
is SecureBackupEntryPoint.InitialTarget.ResetIdentity -> NavTarget.ResetIdentity
|
is SecureBackupEntryPoint.InitialTarget.ResetIdentity -> NavTarget.ResetIdentity
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -178,6 +178,7 @@ class RoomListScreen(
|
||||||
state = state,
|
state = state,
|
||||||
onRoomClick = ::onRoomClick,
|
onRoomClick = ::onRoomClick,
|
||||||
onSettingsClick = {},
|
onSettingsClick = {},
|
||||||
|
onSetUpRecoveryClick = {},
|
||||||
onConfirmRecoveryKeyClick = {},
|
onConfirmRecoveryKeyClick = {},
|
||||||
onCreateRoomClick = {},
|
onCreateRoomClick = {},
|
||||||
onRoomSettingsClick = {},
|
onRoomSettingsClick = {},
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:eb59f6e1771481bec3e96b89cbc9255685e6ea154412d7bf7e1351130f42173a
|
||||||
|
size 28896
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:413e055704ff0c8dc82321b108c1fa90e7d58af1a781244fbde3daf45d638331
|
||||||
|
size 27829
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:5870fc3df4bb7330972727601016189e75c358f535f31fe6704837eb866866df
|
||||||
|
size 100363
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:d236927f6c4cc81f1e9c9b6d405e27e8e96ceb89f9047493b9ab590165d484b2
|
||||||
|
size 104246
|
||||||
|
|
@ -138,6 +138,7 @@
|
||||||
"screen_roomlist_.*",
|
"screen_roomlist_.*",
|
||||||
"session_verification_banner_.*",
|
"session_verification_banner_.*",
|
||||||
"confirm_recovery_key_banner_.*",
|
"confirm_recovery_key_banner_.*",
|
||||||
|
"banner\\.set_up_recovery\\..*",
|
||||||
"full_screen_intent_banner_.*",
|
"full_screen_intent_banner_.*",
|
||||||
"screen_migration_.*",
|
"screen_migration_.*",
|
||||||
"screen_invites_.*"
|
"screen_invites_.*"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue