-
Notifications
You must be signed in to change notification settings - Fork 156
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2111 from element-hq/feature/bma/directLogout
Direct logout
- Loading branch information
Showing
19 changed files
with
695 additions
and
58 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Remove extra logout screen. |
22 changes: 22 additions & 0 deletions
22
...t/api/src/main/kotlin/io/element/android/features/logout/api/direct/DirectLogoutEvents.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
/* | ||
* Copyright (c) 2023 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.logout.api.direct | ||
|
||
sealed interface DirectLogoutEvents { | ||
data class Logout(val ignoreSdkError: Boolean) : DirectLogoutEvents | ||
data object CloseDialogs : DirectLogoutEvents | ||
} |
21 changes: 21 additions & 0 deletions
21
...pi/src/main/kotlin/io/element/android/features/logout/api/direct/DirectLogoutPresenter.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
/* | ||
* Copyright (c) 2023 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.logout.api.direct | ||
|
||
import io.element.android.libraries.architecture.Presenter | ||
|
||
interface DirectLogoutPresenter : Presenter<DirectLogoutState> |
26 changes: 26 additions & 0 deletions
26
...ut/api/src/main/kotlin/io/element/android/features/logout/api/direct/DirectLogoutState.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
/* | ||
* Copyright (c) 2023 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.logout.api.direct | ||
|
||
import io.element.android.libraries.architecture.Async | ||
|
||
data class DirectLogoutState( | ||
val canDoDirectSignOut: Boolean, | ||
val showConfirmationDialog: Boolean, | ||
val logoutAction: Async<String?>, | ||
val eventSink: (DirectLogoutEvents) -> Unit, | ||
) |
27 changes: 27 additions & 0 deletions
27
...out/api/src/main/kotlin/io/element/android/features/logout/api/direct/DirectLogoutView.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
/* | ||
* Copyright (c) 2023 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.logout.api.direct | ||
|
||
import androidx.compose.runtime.Composable | ||
|
||
interface DirectLogoutView { | ||
@Composable | ||
fun Render( | ||
state: DirectLogoutState, | ||
onSuccessLogout: (logoutUrlResult: String?) -> Unit | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
113 changes: 113 additions & 0 deletions
113
...ain/kotlin/io/element/android/features/logout/impl/direct/DefaultDirectLogoutPresenter.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
/* | ||
* Copyright (c) 2023 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.logout.impl.direct | ||
|
||
import androidx.compose.runtime.Composable | ||
import androidx.compose.runtime.LaunchedEffect | ||
import androidx.compose.runtime.MutableState | ||
import androidx.compose.runtime.collectAsState | ||
import androidx.compose.runtime.getValue | ||
import androidx.compose.runtime.mutableStateOf | ||
import androidx.compose.runtime.remember | ||
import androidx.compose.runtime.rememberCoroutineScope | ||
import androidx.compose.runtime.setValue | ||
import com.squareup.anvil.annotations.ContributesBinding | ||
import io.element.android.features.logout.api.direct.DirectLogoutEvents | ||
import io.element.android.features.logout.api.direct.DirectLogoutPresenter | ||
import io.element.android.features.logout.api.direct.DirectLogoutState | ||
import io.element.android.features.logout.impl.tools.isBackingUp | ||
import io.element.android.libraries.architecture.Async | ||
import io.element.android.libraries.architecture.runCatchingUpdatingState | ||
import io.element.android.libraries.di.SessionScope | ||
import io.element.android.libraries.featureflag.api.FeatureFlagService | ||
import io.element.android.libraries.featureflag.api.FeatureFlags | ||
import io.element.android.libraries.matrix.api.MatrixClient | ||
import io.element.android.libraries.matrix.api.encryption.BackupUploadState | ||
import io.element.android.libraries.matrix.api.encryption.EncryptionService | ||
import kotlinx.coroutines.CoroutineScope | ||
import kotlinx.coroutines.flow.emptyFlow | ||
import kotlinx.coroutines.flow.flowOf | ||
import kotlinx.coroutines.launch | ||
import javax.inject.Inject | ||
|
||
@ContributesBinding(SessionScope::class) | ||
class DefaultDirectLogoutPresenter @Inject constructor( | ||
private val matrixClient: MatrixClient, | ||
private val encryptionService: EncryptionService, | ||
private val featureFlagService: FeatureFlagService, | ||
) : DirectLogoutPresenter { | ||
@Composable | ||
override fun present(): DirectLogoutState { | ||
val localCoroutineScope = rememberCoroutineScope() | ||
|
||
val logoutAction: MutableState<Async<String?>> = remember { | ||
mutableStateOf(Async.Uninitialized) | ||
} | ||
|
||
val secureStorageFlag by featureFlagService.isFeatureEnabledFlow(FeatureFlags.SecureStorage) | ||
.collectAsState(initial = null) | ||
|
||
val backupUploadState: BackupUploadState by remember(secureStorageFlag) { | ||
when (secureStorageFlag) { | ||
true -> encryptionService.waitForBackupUploadSteadyState() | ||
false -> flowOf(BackupUploadState.Done) | ||
else -> emptyFlow() | ||
} | ||
} | ||
.collectAsState(initial = BackupUploadState.Unknown) | ||
|
||
var showLogoutDialog by remember { mutableStateOf(false) } | ||
var isLastSession by remember { mutableStateOf(false) } | ||
LaunchedEffect(Unit) { | ||
isLastSession = encryptionService.isLastDevice().getOrNull() ?: false | ||
} | ||
|
||
fun handleEvents(event: DirectLogoutEvents) { | ||
when (event) { | ||
is DirectLogoutEvents.Logout -> { | ||
if (showLogoutDialog || event.ignoreSdkError) { | ||
showLogoutDialog = false | ||
localCoroutineScope.logout(logoutAction, event.ignoreSdkError) | ||
} else { | ||
showLogoutDialog = true | ||
} | ||
} | ||
DirectLogoutEvents.CloseDialogs -> { | ||
logoutAction.value = Async.Uninitialized | ||
showLogoutDialog = false | ||
} | ||
} | ||
} | ||
|
||
return DirectLogoutState( | ||
canDoDirectSignOut = !isLastSession && | ||
!backupUploadState.isBackingUp(), | ||
showConfirmationDialog = showLogoutDialog, | ||
logoutAction = logoutAction.value, | ||
eventSink = ::handleEvents | ||
) | ||
} | ||
|
||
private fun CoroutineScope.logout( | ||
logoutAction: MutableState<Async<String?>>, | ||
ignoreSdkError: Boolean, | ||
) = launch { | ||
suspend { | ||
matrixClient.logout(ignoreSdkError) | ||
}.runCatchingUpdatingState(logoutAction) | ||
} | ||
} |
62 changes: 62 additions & 0 deletions
62
...src/main/kotlin/io/element/android/features/logout/impl/direct/DefaultDirectLogoutView.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
/* | ||
* Copyright (c) 2023 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.logout.impl.direct | ||
|
||
import androidx.compose.runtime.Composable | ||
import com.squareup.anvil.annotations.ContributesBinding | ||
import io.element.android.features.logout.api.direct.DirectLogoutEvents | ||
import io.element.android.features.logout.api.direct.DirectLogoutState | ||
import io.element.android.features.logout.api.direct.DirectLogoutView | ||
import io.element.android.features.logout.impl.ui.LogoutActionDialog | ||
import io.element.android.features.logout.impl.ui.LogoutConfirmationDialog | ||
import io.element.android.libraries.di.SessionScope | ||
import javax.inject.Inject | ||
|
||
@ContributesBinding(SessionScope::class) | ||
class DefaultDirectLogoutView @Inject constructor() : DirectLogoutView { | ||
@Composable | ||
override fun Render( | ||
state: DirectLogoutState, | ||
onSuccessLogout: (logoutUrlResult: String?) -> Unit, | ||
) { | ||
val eventSink = state.eventSink | ||
// Log out confirmation dialog | ||
if (state.showConfirmationDialog) { | ||
LogoutConfirmationDialog( | ||
onSubmitClicked = { | ||
eventSink(DirectLogoutEvents.Logout(ignoreSdkError = false)) | ||
}, | ||
onDismiss = { | ||
eventSink(DirectLogoutEvents.CloseDialogs) | ||
} | ||
) | ||
} | ||
|
||
LogoutActionDialog( | ||
state.logoutAction, | ||
onForceLogoutClicked = { | ||
eventSink(DirectLogoutEvents.Logout(ignoreSdkError = true)) | ||
}, | ||
onDismissError = { | ||
eventSink(DirectLogoutEvents.CloseDialogs) | ||
}, | ||
onSuccessLogout = { | ||
onSuccessLogout(it) | ||
}, | ||
) | ||
} | ||
} |
Oops, something went wrong.