diff --git a/changelog.d/4577.feature b/changelog.d/4577.feature new file mode 100644 index 0000000000..56ce827769 --- /dev/null +++ b/changelog.d/4577.feature @@ -0,0 +1 @@ +Iterate on the consent dialog of the identity server. \ No newline at end of file diff --git a/vector/src/main/java/im/vector/app/core/utils/Dialogs.kt b/vector/src/main/java/im/vector/app/core/utils/Dialogs.kt index ad62b0fcb1..ad01546782 100644 --- a/vector/src/main/java/im/vector/app/core/utils/Dialogs.kt +++ b/vector/src/main/java/im/vector/app/core/utils/Dialogs.kt @@ -17,10 +17,15 @@ package im.vector.app.core.utils import android.content.Context +import android.text.method.LinkMovementMethod import android.webkit.WebView import android.webkit.WebViewClient +import android.widget.TextView import com.google.android.material.dialog.MaterialAlertDialogBuilder import im.vector.app.R +import im.vector.app.features.discovery.IdentityServerWithTerms +import me.gujun.android.span.link +import me.gujun.android.span.span /** * Open a web view above the current activity. @@ -40,16 +45,36 @@ fun Context.displayInWebView(url: String) { .show() } -fun Context.showIdentityServerConsentDialog(configuredIdentityServer: String?, policyLinkCallback: () -> Unit, consentCallBack: (() -> Unit)) { +fun Context.showIdentityServerConsentDialog(identityServerWithTerms: IdentityServerWithTerms?, + consentCallBack: (() -> Unit)) { + // Build the message + val content = span { + +getString(R.string.identity_server_consent_dialog_content_3) + +"\n\n" + if (identityServerWithTerms?.policies?.isNullOrEmpty() == false) { + span { + textStyle = "bold" + text = getString(R.string.settings_privacy_policy) + } + identityServerWithTerms.policies.forEach { + +"\n • " + // Use the url as the text too + link(it.url, it.url) + } + +"\n\n" + } + +getString(R.string.identity_server_consent_dialog_content_question) + } MaterialAlertDialogBuilder(this) - .setTitle(getString(R.string.identity_server_consent_dialog_title_2, configuredIdentityServer ?: "")) - .setMessage(R.string.identity_server_consent_dialog_content_2) - .setPositiveButton(R.string.yes) { _, _ -> + .setTitle(getString(R.string.identity_server_consent_dialog_title_2, identityServerWithTerms?.serverUrl.orEmpty())) + .setMessage(content) + .setPositiveButton(R.string.reactions_agree) { _, _ -> consentCallBack.invoke() } - .setNeutralButton(R.string.identity_server_consent_dialog_neutral_policy) { _, _ -> - policyLinkCallback.invoke() - } - .setNegativeButton(R.string.no, null) + .setNegativeButton(R.string.action_not_now, null) .show() + .apply { + // Make the link(s) clickable. Must be called after show() + (findViewById(android.R.id.message) as? TextView)?.movementMethod = LinkMovementMethod.getInstance() + } } diff --git a/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookAction.kt b/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookAction.kt index e380998fd2..6ab8174e0e 100644 --- a/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookAction.kt +++ b/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookAction.kt @@ -21,5 +21,6 @@ import im.vector.app.core.platform.VectorViewModelAction sealed class ContactsBookAction : VectorViewModelAction { data class FilterWith(val filter: String) : ContactsBookAction() data class OnlyBoundContacts(val onlyBoundContacts: Boolean) : ContactsBookAction() + object UserConsentRequest : ContactsBookAction() object UserConsentGranted : ContactsBookAction() } diff --git a/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookFragment.kt b/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookFragment.kt index 95c6105912..c1bccf855d 100644 --- a/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookFragment.kt +++ b/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookFragment.kt @@ -26,11 +26,11 @@ import com.airbnb.mvrx.activityViewModel import com.airbnb.mvrx.withState import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith +import im.vector.app.core.extensions.exhaustive import im.vector.app.core.extensions.hideKeyboard import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.utils.showIdentityServerConsentDialog import im.vector.app.databinding.FragmentContactsBookBinding -import im.vector.app.features.navigation.SettingsActivityPayload import im.vector.app.features.userdirectory.PendingSelection import im.vector.app.features.userdirectory.UserListAction import im.vector.app.features.userdirectory.UserListSharedAction @@ -68,22 +68,27 @@ class ContactsBookFragment @Inject constructor( setupConsentView() setupOnlyBoundContactsView() setupCloseView() + contactsBookViewModel.observeViewEvents { + when (it) { + is ContactsBookViewEvents.Failure -> showFailure(it.throwable) + is ContactsBookViewEvents.OnPoliciesRetrieved -> showConsentDialog(it) + }.exhaustive + } } private fun setupConsentView() { views.phoneBookSearchForMatrixContacts.setOnClickListener { - withState(contactsBookViewModel) { state -> - requireContext().showIdentityServerConsentDialog( - state.identityServerUrl, - policyLinkCallback = { - navigator.openSettings(requireContext(), SettingsActivityPayload.DiscoverySettings(expandIdentityPolicies = true)) - }, - consentCallBack = { contactsBookViewModel.handle(ContactsBookAction.UserConsentGranted) } - ) - } + contactsBookViewModel.handle(ContactsBookAction.UserConsentRequest) } } + private fun showConsentDialog(event: ContactsBookViewEvents.OnPoliciesRetrieved) { + requireContext().showIdentityServerConsentDialog( + event.identityServerWithTerms, + consentCallBack = { contactsBookViewModel.handle(ContactsBookAction.UserConsentGranted) } + ) + } + private fun setupOnlyBoundContactsView() { views.phoneBookOnlyBoundContacts.checkedChanges() .onEach { diff --git a/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookViewEvents.kt b/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookViewEvents.kt new file mode 100644 index 0000000000..c7fd13a62c --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookViewEvents.kt @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2021 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 im.vector.app.features.contactsbook + +import im.vector.app.core.platform.VectorViewEvents +import im.vector.app.features.discovery.IdentityServerWithTerms + +sealed class ContactsBookViewEvents : VectorViewEvents { + data class Failure(val throwable: Throwable) : ContactsBookViewEvents() + data class OnPoliciesRetrieved(val identityServerWithTerms: IdentityServerWithTerms?) : ContactsBookViewEvents() +} diff --git a/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookViewModel.kt b/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookViewModel.kt index 7f0dbcb7b2..5678668b25 100644 --- a/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookViewModel.kt @@ -16,20 +16,21 @@ package im.vector.app.features.contactsbook -import androidx.lifecycle.viewModelScope import com.airbnb.mvrx.Loading import com.airbnb.mvrx.MavericksViewModelFactory import com.airbnb.mvrx.Success import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject +import im.vector.app.R import im.vector.app.core.contacts.ContactsDataSource import im.vector.app.core.contacts.MappedContact import im.vector.app.core.di.MavericksAssistedViewModelFactory import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.extensions.exhaustive -import im.vector.app.core.platform.EmptyViewEvents import im.vector.app.core.platform.VectorViewModel +import im.vector.app.core.resources.StringProvider +import im.vector.app.features.discovery.fetchIdentityServerWithTerms import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import org.matrix.android.sdk.api.session.Session @@ -37,11 +38,12 @@ import org.matrix.android.sdk.api.session.identity.IdentityServiceError import org.matrix.android.sdk.api.session.identity.ThreePid import timber.log.Timber -class ContactsBookViewModel @AssistedInject constructor(@Assisted - initialState: ContactsBookViewState, - private val contactsDataSource: ContactsDataSource, - private val session: Session) : - VectorViewModel(initialState) { +class ContactsBookViewModel @AssistedInject constructor( + @Assisted initialState: ContactsBookViewState, + private val contactsDataSource: ContactsDataSource, + private val stringProvider: StringProvider, + private val session: Session +) : VectorViewModel(initialState) { @AssistedFactory interface Factory : MavericksAssistedViewModelFactory { @@ -162,9 +164,22 @@ class ContactsBookViewModel @AssistedInject constructor(@Assisted is ContactsBookAction.FilterWith -> handleFilterWith(action) is ContactsBookAction.OnlyBoundContacts -> handleOnlyBoundContacts(action) ContactsBookAction.UserConsentGranted -> handleUserConsentGranted() + ContactsBookAction.UserConsentRequest -> handleUserConsentRequest() }.exhaustive } + private fun handleUserConsentRequest() { + viewModelScope.launch { + val event = try { + val result = session.fetchIdentityServerWithTerms(stringProvider.getString(R.string.resources_language)) + ContactsBookViewEvents.OnPoliciesRetrieved(result) + } catch (throwable: Throwable) { + ContactsBookViewEvents.Failure(throwable) + } + _viewEvents.post(event) + } + } + private fun handleUserConsentGranted() { session.identityService().setUserConsent(true) diff --git a/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsFragment.kt b/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsFragment.kt index 7306146027..9c46fc2089 100644 --- a/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsFragment.kt @@ -186,8 +186,7 @@ class DiscoverySettingsFragment @Inject constructor( if (newValue) { withState(viewModel) { state -> requireContext().showIdentityServerConsentDialog( - state.identityServer.invoke()?.serverUrl, - policyLinkCallback = { viewModel.handle(DiscoverySettingsAction.SetPoliciesExpandState(expanded = true)) }, + state.identityServer.invoke(), consentCallBack = { viewModel.handle(DiscoverySettingsAction.UpdateUserConsent(true)) } ) } 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 3f5be60f2e..da8603a437 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 @@ -29,10 +29,3 @@ data class DiscoverySettingsState( val userConsent: Boolean = false, val isIdentityPolicyUrlsExpanded: Boolean = false ) : MavericksState - -data class IdentityServerWithTerms( - val serverUrl: String, - val policies: List -) - -data class IdentityServerPolicy(val name: String, val url: String) 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 b02784dad9..4eb3fada28 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 @@ -30,7 +30,6 @@ import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.VectorViewModel import im.vector.app.core.resources.StringProvider -import im.vector.app.core.utils.ensureProtocol import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch @@ -39,7 +38,6 @@ import org.matrix.android.sdk.api.session.identity.IdentityServiceError import org.matrix.android.sdk.api.session.identity.IdentityServiceListener import org.matrix.android.sdk.api.session.identity.SharedState import org.matrix.android.sdk.api.session.identity.ThreePid -import org.matrix.android.sdk.api.session.terms.TermsService import org.matrix.android.sdk.flow.flow class DiscoverySettingsViewModel @AssistedInject constructor( @@ -56,7 +54,6 @@ class DiscoverySettingsViewModel @AssistedInject constructor( companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() private val identityService = session.identityService() - private val termsService: TermsService = session private val identityServerManagerListener = object : IdentityServiceListener { override fun onIdentityServerChange() = withState { state -> @@ -397,7 +394,7 @@ class DiscoverySettingsViewModel @AssistedInject constructor( } } viewModelScope.launch { - runCatching { fetchIdentityServerWithTerms() }.fold( + runCatching { session.fetchIdentityServerWithTerms(stringProvider.getString(R.string.resources_language)) }.fold( onSuccess = { setState { copy(identityServer = Success(it)) } }, onFailure = { _viewEvents.post(DiscoverySettingsViewEvents.Failure(it)) } ) @@ -405,21 +402,6 @@ class DiscoverySettingsViewModel @AssistedInject constructor( } 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 { - val name = it.localizedName ?: it.policyName - val url = it.localizedUrl - if (name == null || url == null) { - null - } else { - IdentityServerPolicy(name = name, url = url) - } - } - IdentityServerWithTerms(identityServerUrl, policyUrls) - } + return session.fetchIdentityServerWithTerms(stringProvider.getString(R.string.resources_language)) } } diff --git a/vector/src/main/java/im/vector/app/features/discovery/Extensions.kt b/vector/src/main/java/im/vector/app/features/discovery/Extensions.kt new file mode 100644 index 0000000000..bf6bd89938 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/discovery/Extensions.kt @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2021 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 im.vector.app.features.discovery + +import im.vector.app.core.utils.ensureProtocol +import org.matrix.android.sdk.api.session.Session +import org.matrix.android.sdk.api.session.terms.TermsService + +suspend fun Session.fetchIdentityServerWithTerms(userLanguage: String): IdentityServerWithTerms? { + val identityServerUrl = identityService().getCurrentIdentityServerUrl() + return identityServerUrl?.let { + val terms = getTerms(TermsService.ServiceType.IdentityService, identityServerUrl.ensureProtocol()) + .serverResponse + .getLocalizedTerms(userLanguage) + val policyUrls = terms.mapNotNull { + val name = it.localizedName ?: it.policyName + val url = it.localizedUrl + if (name == null || url == null) { + null + } else { + IdentityServerPolicy(name = name, url = url) + } + } + IdentityServerWithTerms(identityServerUrl, policyUrls) + } +} diff --git a/vector/src/main/java/im/vector/app/features/discovery/IdentityServerWithTerms.kt b/vector/src/main/java/im/vector/app/features/discovery/IdentityServerWithTerms.kt new file mode 100644 index 0000000000..36bae0d0c5 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/discovery/IdentityServerWithTerms.kt @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 im.vector.app.features.discovery + +data class IdentityServerWithTerms( + val serverUrl: String, + val policies: List +) + +data class IdentityServerPolicy( + val name: String, + val url: String +) diff --git a/vector/src/main/java/im/vector/app/features/userdirectory/UserListAction.kt b/vector/src/main/java/im/vector/app/features/userdirectory/UserListAction.kt index 86de26ac23..d5b049e328 100644 --- a/vector/src/main/java/im/vector/app/features/userdirectory/UserListAction.kt +++ b/vector/src/main/java/im/vector/app/features/userdirectory/UserListAction.kt @@ -24,6 +24,7 @@ sealed class UserListAction : VectorViewModelAction { data class AddPendingSelection(val pendingSelection: PendingSelection) : UserListAction() data class RemovePendingSelection(val pendingSelection: PendingSelection) : UserListAction() object ComputeMatrixToLinkForSharing : UserListAction() + object UserConsentRequest : UserListAction() data class UpdateUserConsent(val consent: Boolean) : UserListAction() object Resumed : UserListAction() } diff --git a/vector/src/main/java/im/vector/app/features/userdirectory/UserListFragment.kt b/vector/src/main/java/im/vector/app/features/userdirectory/UserListFragment.kt index 2b4d4f6f1e..721bce4af9 100644 --- a/vector/src/main/java/im/vector/app/features/userdirectory/UserListFragment.kt +++ b/vector/src/main/java/im/vector/app/features/userdirectory/UserListFragment.kt @@ -42,7 +42,6 @@ import im.vector.app.core.utils.showIdentityServerConsentDialog import im.vector.app.core.utils.startSharePlainTextIntent import im.vector.app.databinding.FragmentUserListBinding import im.vector.app.features.homeserver.HomeServerCapabilitiesViewModel -import im.vector.app.features.navigation.SettingsActivityPayload import im.vector.app.features.settings.VectorSettingsActivity import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach @@ -103,6 +102,8 @@ class UserListFragment @Inject constructor( extraTitle = getString(R.string.invite_friends_rich_title) ) } + is UserListViewEvents.Failure -> showFailure(it.throwable) + is UserListViewEvents.OnPoliciesRetrieved -> showConsentDialog(it) } } } @@ -231,15 +232,14 @@ class UserListFragment @Inject constructor( } override fun giveIdentityServerConsent() { - withState(viewModel) { state -> - requireContext().showIdentityServerConsentDialog( - state.configuredIdentityServer, - policyLinkCallback = { - navigator.openSettings(requireContext(), SettingsActivityPayload.DiscoverySettings(expandIdentityPolicies = true)) - }, - consentCallBack = { viewModel.handle(UserListAction.UpdateUserConsent(true)) } - ) - } + viewModel.handle(UserListAction.UserConsentRequest) + } + + private fun showConsentDialog(event: UserListViewEvents.OnPoliciesRetrieved) { + requireContext().showIdentityServerConsentDialog( + event.identityServerWithTerms, + consentCallBack = { viewModel.handle(UserListAction.UpdateUserConsent(true)) } + ) } override fun onUseQRCode() { diff --git a/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewEvents.kt b/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewEvents.kt index f5ec044597..ffda0dd505 100644 --- a/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewEvents.kt +++ b/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewEvents.kt @@ -17,10 +17,13 @@ package im.vector.app.features.userdirectory import im.vector.app.core.platform.VectorViewEvents +import im.vector.app.features.discovery.IdentityServerWithTerms /** * Transient events for invite users to room screen */ sealed class UserListViewEvents : VectorViewEvents { + data class Failure(val throwable: Throwable) : UserListViewEvents() + data class OnPoliciesRetrieved(val identityServerWithTerms: IdentityServerWithTerms?) : UserListViewEvents() data class OpenShareMatrixToLink(val link: String) : UserListViewEvents() } diff --git a/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewModel.kt b/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewModel.kt index 0ef56084b7..61f8bc35f3 100644 --- a/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewModel.kt @@ -23,12 +23,15 @@ import com.airbnb.mvrx.Uninitialized import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject +import im.vector.app.R import im.vector.app.core.di.MavericksAssistedViewModelFactory import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.extensions.exhaustive import im.vector.app.core.extensions.isEmail import im.vector.app.core.extensions.toggle import im.vector.app.core.platform.VectorViewModel +import im.vector.app.core.resources.StringProvider +import im.vector.app.features.discovery.fetchIdentityServerWithTerms import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.debounce import kotlinx.coroutines.flow.filter @@ -36,6 +39,7 @@ import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.sample +import kotlinx.coroutines.launch import org.matrix.android.sdk.api.MatrixPatterns import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.session.Session @@ -51,9 +55,11 @@ data class ThreePidUser( val user: User? ) -class UserListViewModel @AssistedInject constructor(@Assisted initialState: UserListViewState, - private val session: Session) : - VectorViewModel(initialState) { +class UserListViewModel @AssistedInject constructor( + @Assisted initialState: UserListViewState, + private val stringProvider: StringProvider, + private val session: Session +) : VectorViewModel(initialState) { private val knownUsersSearch = MutableStateFlow("") private val directoryUsersSearch = MutableStateFlow("") @@ -104,11 +110,24 @@ class UserListViewModel @AssistedInject constructor(@Assisted initialState: User is UserListAction.AddPendingSelection -> handleSelectUser(action) is UserListAction.RemovePendingSelection -> handleRemoveSelectedUser(action) UserListAction.ComputeMatrixToLinkForSharing -> handleShareMyMatrixToLink() + UserListAction.UserConsentRequest -> handleUserConsentRequest() is UserListAction.UpdateUserConsent -> handleISUpdateConsent(action) UserListAction.Resumed -> handleResumed() }.exhaustive } + private fun handleUserConsentRequest() { + viewModelScope.launch { + val event = try { + val result = session.fetchIdentityServerWithTerms(stringProvider.getString(R.string.resources_language)) + UserListViewEvents.OnPoliciesRetrieved(result) + } catch (throwable: Throwable) { + UserListViewEvents.Failure(throwable) + } + _viewEvents.post(event) + } + } + private fun handleISUpdateConsent(action: UserListAction.UpdateUserConsent) { session.identityService().setUserConsent(action.consent) withState { diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index dec9e6e8db..ddb731a5e0 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -456,6 +456,7 @@ Copied to clipboard Disable Return + Not now Confirmation @@ -2193,7 +2194,9 @@ Your rooms will be displayed here. Tap the + bottom right to find existing ones or start some of your own. Reactions + Agree + Like Add Reaction View Reactions @@ -2377,6 +2380,8 @@ Send emails and phone numbers to %s In order to discover existing contacts you know, do you accept to send your contact data (phone numbers and/or emails) to the configured identity server (%1$s)?\n\nFor more privacy, the sent data will be hashed before being sent. To discover existing contacts, you need to send contact info to your identity server.\n\nWe hash your data before sending for privacy. Do you consent to send this info? + To discover existing contacts, you need to send contact info (emails and phone numbers) to your identity server. We hash your data before sending for privacy. + Do you agree to send this info? Policy Enter an identity server URL