From 7ce811c227ffd83c6c72c5ef09c7aa86da82a1f4 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Wed, 6 Oct 2021 16:23:33 +0100 Subject: [PATCH] binding the indentity server policy urls to the discovery page --- .../discovery/DiscoverySettingsController.kt | 39 ++++++++++---- .../discovery/DiscoverySettingsState.kt | 4 +- .../discovery/DiscoverySettingsViewModel.kt | 54 +++++++++++-------- vector/src/main/res/values/strings.xml | 1 + 4 files changed, 65 insertions(+), 33 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsController.kt b/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsController.kt index 8cd787d6ed..502b9c5337 100644 --- a/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsController.kt +++ b/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsController.kt @@ -26,11 +26,14 @@ import im.vector.app.R import im.vector.app.core.epoxy.attributes.ButtonStyle import im.vector.app.core.epoxy.attributes.ButtonType import im.vector.app.core.epoxy.attributes.IconMode +import im.vector.app.core.epoxy.expandableTextItem import im.vector.app.core.epoxy.loadingItem import im.vector.app.core.error.ErrorFormatter import im.vector.app.core.extensions.getFormattedValue import im.vector.app.core.resources.ColorProvider import im.vector.app.core.resources.StringProvider +import im.vector.app.core.utils.EvenBetterLinkMovementMethod +import org.matrix.android.sdk.api.extensions.appendNl import org.matrix.android.sdk.api.failure.Failure import org.matrix.android.sdk.api.session.identity.SharedState import org.matrix.android.sdk.api.session.identity.ThreePid @@ -105,8 +108,9 @@ class DiscoverySettingsController @Inject constructor( } } - private fun buildIdentityServerSection(data: DiscoverySettingsState) { - val identityServer = data.identityServer()?.serverUrl ?: stringProvider.getString(R.string.none) + private fun buildIdentityServerSection(data: DiscoverySettingsState, ) { + val identityServer = data.identityServer() + val identityServerUrl = identityServer?.serverUrl ?: stringProvider.getString(R.string.none) val host = this settingsSectionTitleItem { @@ -116,28 +120,43 @@ class DiscoverySettingsController @Inject constructor( settingsItem { id("idServer") - title(identityServer) + title(identityServerUrl) } - if (data.identityServer() != null && data.termsNotSigned) { + val policyUrls = identityServer?.policyUrls?.joinToString(separator = "\n") { it } + if (policyUrls != null) { + val title = stringProvider.getString(R.string.settings_discovery_identity_server_policies_title) + expandableTextItem { + id("policy-urls") + maxLines(1) + enableScrollBar(false) + content(buildString { + append(title) + appendNl(policyUrls) + }) + movementMethod(EvenBetterLinkMovementMethod()) + } + } + + if (identityServer != null && data.termsNotSigned) { settingsInfoItem { id("idServerFooter") - helperText(host.stringProvider.getString(R.string.settings_agree_to_terms, identityServer)) + helperText(host.stringProvider.getString(R.string.settings_agree_to_terms, identityServerUrl)) showCompoundDrawable(true) itemClickListener { host.listener?.openIdentityServerTerms() } } settingsButtonItem { id("seeTerms") colorProvider(host.colorProvider) - buttonTitle(host.stringProvider.getString(R.string.open_terms_of, identityServer)) + buttonTitle(host.stringProvider.getString(R.string.open_terms_of, identityServerUrl)) buttonClickListener { host.listener?.openIdentityServerTerms() } } } else { settingsInfoItem { id("idServerFooter") showCompoundDrawable(false) - if (data.identityServer() != null) { - helperText(host.stringProvider.getString(R.string.settings_discovery_identity_server_info, identityServer)) + if (identityServer != null) { + helperText(host.stringProvider.getString(R.string.settings_discovery_identity_server_info, identityServerUrl)) } else { helperTextResId(R.string.settings_discovery_identity_server_info_none) } @@ -147,7 +166,7 @@ class DiscoverySettingsController @Inject constructor( settingsButtonItem { id("change") colorProvider(host.colorProvider) - if (data.identityServer() == null) { + if (identityServer == null) { buttonTitleId(R.string.add_identity_server) } else { buttonTitleId(R.string.change_identity_server) @@ -155,7 +174,7 @@ class DiscoverySettingsController @Inject constructor( buttonClickListener { host.listener?.onTapChangeIdentityServer() } } - if (data.identityServer() != null) { + if (identityServer != null) { settingsInfoItem { id("removeInfo") helperTextResId(R.string.settings_discovery_disconnect_identity_server_info) diff --git a/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsState.kt b/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsState.kt index bc56b770f5..360ff4b2b1 100644 --- a/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsState.kt +++ b/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsState.kt @@ -31,6 +31,6 @@ data class DiscoverySettingsState( ) : MvRxState data class IdentityServerWithTerms( - val serverUrl: String?, - val terms: List + val serverUrl: String, + val policyUrls: List ) diff --git a/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsViewModel.kt b/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsViewModel.kt index d703385ca8..9025537c7e 100644 --- a/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsViewModel.kt @@ -67,32 +67,27 @@ class DiscoverySettingsViewModel @AssistedInject constructor( private val identityServerManagerListener = object : IdentityServiceListener { override fun onIdentityServerChange() = withState { state -> viewModelScope.launch { - val identityServer = fetchIdentityServerWithTerms() - val currentIS = state.identityServer() - setState { - copy( - identityServer = Success(identityServer), - userConsent = identityService.getUserConsent() - ) - } - if (currentIS != identityServer) retrieveBinding() + runCatching { fetchIdentityServerWithTerms() }.fold( + onSuccess = { + val currentIS = state.identityServer() + setState { + copy( + identityServer = Success(it), + userConsent = identityService.getUserConsent() + ) + } + if (currentIS != it) retrieveBinding() + }, + onFailure = { _viewEvents.post(DiscoverySettingsViewEvents.Failure(it)) } + ) } } } - private suspend fun fetchIdentityServerWithTerms(): IdentityServerWithTerms { - val identityServerUrl = identityService.getCurrentIdentityServerUrl() - val policies = if (identityServerUrl == null) emptyList() else { - val terms = termsService.getTerms(TermsService.ServiceType.IdentityService, identityServerUrl.ensureProtocol()) - terms.serverResponse.getLocalizedTerms(stringProvider.getString(R.string.resources_language)) - } - return IdentityServerWithTerms(identityServerUrl, policies) - } - init { setState { copy( - identityServer = Success(IdentityServerWithTerms(identityService.getCurrentIdentityServerUrl(), emptyList())), + identityServer = Success(identityService.getCurrentIdentityServerUrl()?.let { IdentityServerWithTerms(it, emptyList()) }), userConsent = identityService.getUserConsent() ) } @@ -116,7 +111,7 @@ class DiscoverySettingsViewModel @AssistedInject constructor( override fun handle(action: DiscoverySettingsAction) { when (action) { - DiscoverySettingsAction.Refresh -> refreshPendingEmailBindings() + DiscoverySettingsAction.Refresh -> fetchContent() DiscoverySettingsAction.RetrieveBinding -> retrieveBinding() DiscoverySettingsAction.DisconnectIdentityServer -> disconnectIdentityServer() is DiscoverySettingsAction.ChangeIdentityServer -> changeIdentityServer(action) @@ -395,12 +390,29 @@ class DiscoverySettingsViewModel @AssistedInject constructor( } } - private fun refreshPendingEmailBindings() = withState { state -> + private fun fetchContent() = withState { state -> state.emailList()?.forEach { info -> when (info.isShared()) { SharedState.BINDING_IN_PROGRESS -> finalizeBind3pid(DiscoverySettingsAction.FinalizeBind3pid(info.threePid), false) else -> Unit } } + viewModelScope.launch { + runCatching { fetchIdentityServerWithTerms() }.fold( + onSuccess = { setState { copy(identityServer = Success(it)) } }, + onFailure = { _viewEvents.post(DiscoverySettingsViewEvents.Failure(it)) } + ) + } + } + + private suspend fun fetchIdentityServerWithTerms(): IdentityServerWithTerms? { + val identityServerUrl = identityService.getCurrentIdentityServerUrl() + return identityServerUrl?.let { + val terms = termsService.getTerms(TermsService.ServiceType.IdentityService, identityServerUrl.ensureProtocol()) + .serverResponse + .getLocalizedTerms(stringProvider.getString(R.string.resources_language)) + val policyUrls = terms.mapNotNull { it.localizedUrl } + IdentityServerWithTerms(identityServerUrl, policyUrls) + } } } diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index bb6f73812f..22cdd98e97 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -2349,6 +2349,7 @@ Configure identity server Open Discovery Settings Change identity server + Identity server policy You are currently using %1$s to discover and be discoverable by existing contacts you know. You are not currently using an identity server. To discover and be discoverable by existing contacts you know, configure one below. Discoverable email addresses