Sign out: direct flow if not last session and if not currently backing up keys #2072
Extract some stuff from existing Logout to avoid duplication.
This commit is contained in:
parent
c6f5c0a556
commit
2b983e923e
16 changed files with 477 additions and 52 deletions
|
|
@ -27,16 +27,19 @@ import com.bumble.appyx.core.plugin.plugins
|
|||
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.logout.api.direct.DirectLogoutView
|
||||
import io.element.android.libraries.androidutils.browser.openUrlInChromeCustomTab
|
||||
import io.element.android.libraries.di.SessionScope
|
||||
import io.element.android.libraries.matrix.api.user.MatrixUser
|
||||
import io.element.android.compound.theme.ElementTheme
|
||||
import timber.log.Timber
|
||||
|
||||
@ContributesNode(SessionScope::class)
|
||||
class PreferencesRootNode @AssistedInject constructor(
|
||||
@Assisted buildContext: BuildContext,
|
||||
@Assisted plugins: List<Plugin>,
|
||||
private val presenter: PreferencesRootPresenter,
|
||||
private val directLogoutView: DirectLogoutView,
|
||||
) : Node(buildContext, plugins = plugins) {
|
||||
|
||||
interface Callback : Plugin {
|
||||
|
|
@ -95,6 +98,13 @@ class PreferencesRootNode @AssistedInject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun onSuccessLogout(activity: Activity, url: String?) {
|
||||
Timber.d("Success (direct) logout with result url: $url")
|
||||
url?.let {
|
||||
activity.openUrlInChromeCustomTab(null, false, it)
|
||||
}
|
||||
}
|
||||
|
||||
private fun onOpenNotificationSettings() {
|
||||
plugins<Callback>().forEach { it.onOpenNotificationSettings() }
|
||||
}
|
||||
|
|
@ -133,5 +143,12 @@ class PreferencesRootNode @AssistedInject constructor(
|
|||
onOpenUserProfile = this::onOpenUserProfile,
|
||||
onSignOutClicked = this::onSignOutClicked,
|
||||
)
|
||||
|
||||
directLogoutView.render(
|
||||
state = state.directLogoutState,
|
||||
onSuccessLogout = {
|
||||
onSuccessLogout(activity, it)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import androidx.compose.runtime.getValue
|
|||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import io.element.android.features.logout.api.direct.DirectLogoutPresenter
|
||||
import io.element.android.libraries.architecture.Presenter
|
||||
import io.element.android.libraries.core.meta.BuildType
|
||||
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher
|
||||
|
|
@ -50,6 +51,7 @@ class PreferencesRootPresenter @Inject constructor(
|
|||
private val snackbarDispatcher: SnackbarDispatcher,
|
||||
private val featureFlagService: FeatureFlagService,
|
||||
private val indicatorService: IndicatorService,
|
||||
private val directLogoutPresenter: DirectLogoutPresenter,
|
||||
) : Presenter<PreferencesRootState> {
|
||||
|
||||
@Composable
|
||||
|
|
@ -88,6 +90,8 @@ class PreferencesRootPresenter @Inject constructor(
|
|||
mutableStateOf(null)
|
||||
}
|
||||
|
||||
val directLogoutState = directLogoutPresenter.present()
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
initAccountManagementUrl(accountManagementUrl, devicesManagementUrl)
|
||||
}
|
||||
|
|
@ -105,6 +109,7 @@ class PreferencesRootPresenter @Inject constructor(
|
|||
showDeveloperSettings = showDeveloperSettings,
|
||||
showNotificationSettings = showNotificationSettings.value,
|
||||
showLockScreenSettings = showLockScreenSettings.value,
|
||||
directLogoutState = directLogoutState,
|
||||
snackbarMessage = snackbarMessage,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
package io.element.android.features.preferences.impl.root
|
||||
|
||||
import io.element.android.features.logout.api.direct.DirectLogoutState
|
||||
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarMessage
|
||||
import io.element.android.libraries.matrix.api.user.MatrixUser
|
||||
|
||||
|
|
@ -31,5 +32,6 @@ data class PreferencesRootState(
|
|||
val showDeveloperSettings: Boolean,
|
||||
val showLockScreenSettings: Boolean,
|
||||
val showNotificationSettings: Boolean,
|
||||
val directLogoutState: DirectLogoutState,
|
||||
val snackbarMessage: SnackbarMessage?,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
package io.element.android.features.preferences.impl.root
|
||||
|
||||
import io.element.android.features.logout.api.direct.DirectLogoutState
|
||||
import io.element.android.libraries.architecture.Async
|
||||
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarMessage
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
|
||||
|
|
@ -32,4 +34,12 @@ fun aPreferencesRootState() = PreferencesRootState(
|
|||
showNotificationSettings = true,
|
||||
showLockScreenSettings = true,
|
||||
snackbarMessage = SnackbarMessage(CommonStrings.common_verification_complete),
|
||||
directLogoutState = aDirectLogoutState(),
|
||||
)
|
||||
|
||||
fun aDirectLogoutState() = DirectLogoutState(
|
||||
canDoDirectSignOut = true,
|
||||
showConfirmationDialog = false,
|
||||
logoutAction = Async.Uninitialized,
|
||||
eventSink = {},
|
||||
)
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameter
|
|||
import androidx.compose.ui.unit.dp
|
||||
import io.element.android.compound.theme.ElementTheme
|
||||
import io.element.android.compound.tokens.generated.CompoundIcons
|
||||
import io.element.android.features.logout.api.direct.DirectLogoutEvents
|
||||
import io.element.android.features.preferences.impl.R
|
||||
import io.element.android.features.preferences.impl.user.UserPreferences
|
||||
import io.element.android.libraries.designsystem.components.list.ListItemContent
|
||||
|
|
@ -57,7 +58,7 @@ fun PreferencesRootView(
|
|||
onManageAccountClicked: (url: String) -> Unit,
|
||||
onOpenAnalytics: () -> Unit,
|
||||
onOpenRageShake: () -> Unit,
|
||||
onOpenLockScreenSettings: ()->Unit,
|
||||
onOpenLockScreenSettings: () -> Unit,
|
||||
onOpenAbout: () -> Unit,
|
||||
onOpenDeveloperSettings: () -> Unit,
|
||||
onOpenAdvancedSettings: () -> Unit,
|
||||
|
|
@ -91,7 +92,7 @@ fun PreferencesRootView(
|
|||
if (state.showSecureBackup) {
|
||||
ListItem(
|
||||
headlineContent = { Text(stringResource(id = CommonStrings.common_chat_backup)) },
|
||||
leadingContent = ListItemContent.Icon(IconSource.Resource(CommonDrawables.ic_key_filled),),
|
||||
leadingContent = ListItemContent.Icon(IconSource.Resource(CommonDrawables.ic_key_filled)),
|
||||
trailingContent = ListItemContent.Badge.takeIf { state.showSecureBackupBadge },
|
||||
onClick = onSecureBackupClicked,
|
||||
)
|
||||
|
|
@ -162,7 +163,13 @@ fun PreferencesRootView(
|
|||
headlineContent = { Text(stringResource(id = CommonStrings.action_signout)) },
|
||||
leadingContent = ListItemContent.Icon(IconSource.Resource(CommonDrawables.ic_sign_out)),
|
||||
style = ListItemStyle.Destructive,
|
||||
onClick = onSignOutClicked,
|
||||
onClick = {
|
||||
if (state.directLogoutState.canDoDirectSignOut) {
|
||||
state.directLogoutState.eventSink(DirectLogoutEvents.Logout(ignoreSdkError = false))
|
||||
} else {
|
||||
onSignOutClicked()
|
||||
}
|
||||
},
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier
|
||||
|
|
|
|||
|
|
@ -16,10 +16,14 @@
|
|||
|
||||
package io.element.android.features.preferences.impl.root
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import app.cash.molecule.RecompositionMode
|
||||
import app.cash.molecule.moleculeFlow
|
||||
import app.cash.turbine.test
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import io.element.android.features.logout.api.direct.DirectLogoutPresenter
|
||||
import io.element.android.features.logout.api.direct.DirectLogoutState
|
||||
import io.element.android.libraries.architecture.Async
|
||||
import io.element.android.libraries.core.meta.BuildType
|
||||
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher
|
||||
import io.element.android.libraries.featureflag.test.FakeFeatureFlagService
|
||||
|
|
@ -41,23 +45,34 @@ class PreferencesRootPresenterTest {
|
|||
@get:Rule
|
||||
val warmUpRule = WarmUpRule()
|
||||
|
||||
private val aDirectLogoutState = DirectLogoutState(
|
||||
canDoDirectSignOut = true,
|
||||
showConfirmationDialog = false,
|
||||
logoutAction = Async.Uninitialized,
|
||||
eventSink = {},
|
||||
)
|
||||
|
||||
@Test
|
||||
fun `present - initial state`() = runTest {
|
||||
val matrixClient = FakeMatrixClient()
|
||||
val sessionVerificationService = FakeSessionVerificationService()
|
||||
val presenter = PreferencesRootPresenter(
|
||||
matrixClient,
|
||||
sessionVerificationService,
|
||||
FakeAnalyticsService(),
|
||||
BuildType.DEBUG,
|
||||
FakeVersionFormatter(),
|
||||
SnackbarDispatcher(),
|
||||
FakeFeatureFlagService(),
|
||||
DefaultIndicatorService(
|
||||
matrixClient = matrixClient,
|
||||
sessionVerificationService = sessionVerificationService,
|
||||
analyticsService = FakeAnalyticsService(),
|
||||
buildType = BuildType.DEBUG,
|
||||
versionFormatter = FakeVersionFormatter(),
|
||||
snackbarDispatcher = SnackbarDispatcher(),
|
||||
featureFlagService = FakeFeatureFlagService(),
|
||||
indicatorService = DefaultIndicatorService(
|
||||
sessionVerificationService = sessionVerificationService,
|
||||
encryptionService = FakeEncryptionService(),
|
||||
featureFlagService = FakeFeatureFlagService(),
|
||||
),
|
||||
directLogoutPresenter = object : DirectLogoutPresenter {
|
||||
@Composable
|
||||
override fun present() = aDirectLogoutState
|
||||
}
|
||||
)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
|
|
@ -77,6 +92,7 @@ class PreferencesRootPresenterTest {
|
|||
assertThat(loadedState.showAnalyticsSettings).isFalse()
|
||||
assertThat(loadedState.accountManagementUrl).isNull()
|
||||
assertThat(loadedState.devicesManagementUrl).isNull()
|
||||
assertThat(loadedState.directLogoutState).isEqualTo(aDirectLogoutState)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue