From bc57a03a3939500bdc476ef9817130068a1ca675 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 23 Aug 2023 12:54:22 +0200 Subject: [PATCH] Add setting entry point to manage account (OIDC) --- .../messages/impl/src/main/res/values/localazy.xml | 2 ++ .../preferences/impl/root/PreferencesRootNode.kt | 9 ++++++++- .../impl/root/PreferencesRootPresenter.kt | 13 +++++++++++++ .../preferences/impl/root/PreferencesRootState.kt | 1 + .../impl/root/PreferencesRootStateProvider.kt | 1 + .../preferences/impl/root/PreferencesRootView.kt | 10 ++++++++++ .../impl/root/PreferencesRootPresenterTest.kt | 1 + .../android/libraries/matrix/api/MatrixClient.kt | 1 + .../libraries/matrix/impl/RustMatrixClient.kt | 5 +++++ .../libraries/matrix/test/FakeMatrixClient.kt | 4 ++++ .../ui-strings/src/main/res/values/localazy.xml | 11 +++++++++++ 11 files changed, 57 insertions(+), 1 deletion(-) diff --git a/features/messages/impl/src/main/res/values/localazy.xml b/features/messages/impl/src/main/res/values/localazy.xml index c88beff81a..105cb1fc7b 100644 --- a/features/messages/impl/src/main/res/values/localazy.xml +++ b/features/messages/impl/src/main/res/values/localazy.xml @@ -26,11 +26,13 @@ "You can change it in your %1$s." "global settings" "Default setting" + "Remove custom setting" "An error occurred while loading notification settings." "Failed restoring the default mode, please try again." "Failed setting the mode, please try again." "All messages" "Mentions and Keywords only" + "In this room, notify me for" "Show less" "Show more" "Send again" diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootNode.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootNode.kt index 3f897caf03..e90569b40e 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootNode.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootNode.kt @@ -66,6 +66,12 @@ class PreferencesRootNode @AssistedInject constructor( plugins().forEach { it.onOpenAbout() } } + private fun onManageAccountClicked(activity: Activity, accountManagementUrl: String?) { + accountManagementUrl?.let { + activity.openUrlInChromeCustomTab(null, false, it) + } + } + @Composable override fun View(modifier: Modifier) { val state = presenter.present() @@ -79,7 +85,8 @@ class PreferencesRootNode @AssistedInject constructor( onOpenAbout = this::onOpenAbout, onVerifyClicked = this::onVerifyClicked, onOpenDeveloperSettings = this::onOpenDeveloperSettings, - onSuccessLogout = { onSuccessLogout(activity, it) } + onSuccessLogout = { onSuccessLogout(activity, it) }, + onManageAccountClicked = { onManageAccountClicked(activity, state.accountManagementUrl) }, ) } diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootPresenter.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootPresenter.kt index 0cd2e7f7db..b33940b21e 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootPresenter.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootPresenter.kt @@ -68,6 +68,14 @@ class PreferencesRootPresenter @Inject constructor( derivedStateOf { sessionVerifiedStatus == SessionVerifiedStatus.NotVerified } } + val accountManagementUrl: MutableState = remember { + mutableStateOf(null) + } + + LaunchedEffect(Unit) { + initAccountManagementUrl(accountManagementUrl) + } + val logoutState = logoutPresenter.present() val showDeveloperSettings = buildType != BuildType.RELEASE return PreferencesRootState( @@ -75,6 +83,7 @@ class PreferencesRootPresenter @Inject constructor( myUser = matrixUser.value, version = versionFormatter.get(), showCompleteVerification = sessionIsNotVerified, + accountManagementUrl = accountManagementUrl.value, showAnalyticsSettings = hasAnalyticsProviders, showDeveloperSettings = showDeveloperSettings, snackbarMessage = snackbarMessage, @@ -84,4 +93,8 @@ class PreferencesRootPresenter @Inject constructor( private fun CoroutineScope.initialLoad(matrixUser: MutableState) = launch { matrixUser.value = matrixClient.getCurrentUser() } + + private fun CoroutineScope.initAccountManagementUrl(accountManagementUrl: MutableState) = launch { + accountManagementUrl.value = matrixClient.getAccountManagementUrl().getOrNull() + } } diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootState.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootState.kt index 540c470815..af3a090630 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootState.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootState.kt @@ -25,6 +25,7 @@ data class PreferencesRootState( val myUser: MatrixUser?, val version: String, val showCompleteVerification: Boolean, + val accountManagementUrl: String?, val showAnalyticsSettings: Boolean, val showDeveloperSettings: Boolean, val snackbarMessage: SnackbarMessage?, diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootStateProvider.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootStateProvider.kt index e8c148267f..931a560c1d 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootStateProvider.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootStateProvider.kt @@ -25,6 +25,7 @@ fun aPreferencesRootState() = PreferencesRootState( myUser = null, version = "Version 1.1 (1)", showCompleteVerification = true, + accountManagementUrl = "aUrl", showAnalyticsSettings = true, showDeveloperSettings = true, snackbarMessage = SnackbarMessage(CommonStrings.common_verification_complete), diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootView.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootView.kt index 1cb3a37c77..c24a2ec875 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootView.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootView.kt @@ -23,6 +23,7 @@ import androidx.compose.material.icons.outlined.BugReport import androidx.compose.material.icons.outlined.DeveloperMode import androidx.compose.material.icons.outlined.Help import androidx.compose.material.icons.outlined.InsertChart +import androidx.compose.material.icons.outlined.ManageAccounts import androidx.compose.material.icons.outlined.VerifiedUser import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier @@ -51,6 +52,7 @@ fun PreferencesRootView( state: PreferencesRootState, onBackPressed: () -> Unit, onVerifyClicked: () -> Unit, + onManageAccountClicked: () -> Unit, onOpenAnalytics: () -> Unit, onOpenRageShake: () -> Unit, onOpenAbout: () -> Unit, @@ -76,6 +78,13 @@ fun PreferencesRootView( ) HorizontalDivider() } + if (state.accountManagementUrl != null) { + PreferenceText( + title = stringResource(id = CommonStrings.screen_settings_oidc_account), + icon = Icons.Outlined.ManageAccounts, + onClick = onManageAccountClicked, + ) + } if (state.showAnalyticsSettings) { PreferenceText( title = stringResource(id = CommonStrings.common_analytics), @@ -143,5 +152,6 @@ private fun ContentToPreview(matrixUser: MatrixUser) { onOpenAbout = {}, onVerifyClicked = {}, onSuccessLogout = {}, + onManageAccountClicked = {}, ) } diff --git a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootPresenterTest.kt b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootPresenterTest.kt index 580426fcfa..5d508912a8 100644 --- a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootPresenterTest.kt +++ b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootPresenterTest.kt @@ -64,6 +64,7 @@ class PreferencesRootPresenterTest { ) assertThat(loadedState.showDeveloperSettings).isEqualTo(true) assertThat(loadedState.showAnalyticsSettings).isEqualTo(false) + assertThat(loadedState.accountManagementUrl).isNull() } } } diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt index 705cbbc620..be64a3371f 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt @@ -63,6 +63,7 @@ interface MatrixClient : Closeable { suspend fun logout(): String? suspend fun loadUserDisplayName(): Result suspend fun loadUserAvatarURLString(): Result + suspend fun getAccountManagementUrl(): Result suspend fun uploadMedia(mimeType: String, data: ByteArray, progressCallback: ProgressCallback?): Result fun roomMembershipObserver(): RoomMembershipObserver diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt index e7b1ad4d5e..58d82ec116 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt @@ -311,6 +311,11 @@ class RustMatrixClient constructor( return result } + override suspend fun getAccountManagementUrl(): Result = withContext(sessionDispatcher) { + runCatching { + client.accountUrl() + } + } override suspend fun loadUserDisplayName(): Result = withContext(sessionDispatcher) { runCatching { client.displayName() diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt index 1734aec718..83f7f3ad79 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt @@ -51,6 +51,7 @@ class FakeMatrixClient( private val pushersService: FakePushersService = FakePushersService(), private val notificationService: FakeNotificationService = FakeNotificationService(), private val syncService: FakeSyncService = FakeSyncService(), + private val accountManagementUrlString: Result = Result.success(null), ) : MatrixClient { private var ignoreUserResult: Result = Result.success(Unit) @@ -125,6 +126,9 @@ class FakeMatrixClient( return userAvatarURLString } + override suspend fun getAccountManagementUrl(): Result { + return accountManagementUrlString + } override suspend fun uploadMedia( mimeType: String, data: ByteArray, diff --git a/libraries/ui-strings/src/main/res/values/localazy.xml b/libraries/ui-strings/src/main/res/values/localazy.xml index 3b4c305ffc..e38c4fc6b8 100644 --- a/libraries/ui-strings/src/main/res/values/localazy.xml +++ b/libraries/ui-strings/src/main/res/values/localazy.xml @@ -180,11 +180,21 @@ "Setting up your account." "Additional settings" "Audio and video calls" + "Configuration mismatch" + "We’ve simplified Notifications Settings to make options easier to find. + +Some custom settings you’ve chosen in the past are not shown here, but they’re still active. + +If you proceed, some of your settings may change." "Direct chats" + "Custom setting per chat" "An error occurred while updating the notification setting." + "All messages" + "Mentions and Keywords only" "On direct chats, notify me for" "On group chats, notify me for" "Enable notifications on this device" + "The configuration has not been corrected, please try again." "Group chats" "Mentions" "All" @@ -196,6 +206,7 @@ "System notifications turned off" "Notifications" "Check if you want to hide all current and future messages from this user" + "Account and devices" "Share location" "Share my location" "Open in Apple Maps"