Iterate on the consent dialog of the identity server - handle the other places.
This commit is contained in:
parent
3d5d9ad154
commit
b66aff457a
|
@ -23,7 +23,7 @@ import android.webkit.WebViewClient
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
import im.vector.app.features.discovery.IdentityServerPolicy
|
import im.vector.app.features.discovery.IdentityServerWithTerms
|
||||||
import me.gujun.android.span.link
|
import me.gujun.android.span.link
|
||||||
import me.gujun.android.span.span
|
import me.gujun.android.span.span
|
||||||
|
|
||||||
|
@ -45,19 +45,18 @@ fun Context.displayInWebView(url: String) {
|
||||||
.show()
|
.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Context.showIdentityServerConsentDialog(configuredIdentityServer: String?,
|
fun Context.showIdentityServerConsentDialog(identityServerWithTerms: IdentityServerWithTerms?,
|
||||||
policies: List<IdentityServerPolicy>?,
|
|
||||||
consentCallBack: (() -> Unit)) {
|
consentCallBack: (() -> Unit)) {
|
||||||
// Build the message
|
// Build the message
|
||||||
val content = span {
|
val content = span {
|
||||||
+getString(R.string.identity_server_consent_dialog_content_3)
|
+getString(R.string.identity_server_consent_dialog_content_3)
|
||||||
+"\n\n"
|
+"\n\n"
|
||||||
if (!policies.isNullOrEmpty()) {
|
if (identityServerWithTerms?.policies?.isNullOrEmpty() == false) {
|
||||||
span {
|
span {
|
||||||
textStyle = "bold"
|
textStyle = "bold"
|
||||||
text = getString(R.string.settings_privacy_policy)
|
text = getString(R.string.settings_privacy_policy)
|
||||||
}
|
}
|
||||||
policies.forEach {
|
identityServerWithTerms.policies.forEach {
|
||||||
+"\n • "
|
+"\n • "
|
||||||
// Use the url as the text too
|
// Use the url as the text too
|
||||||
link(it.url, it.url)
|
link(it.url, it.url)
|
||||||
|
@ -67,7 +66,7 @@ fun Context.showIdentityServerConsentDialog(configuredIdentityServer: String?,
|
||||||
+getString(R.string.identity_server_consent_dialog_content_question)
|
+getString(R.string.identity_server_consent_dialog_content_question)
|
||||||
}
|
}
|
||||||
MaterialAlertDialogBuilder(this)
|
MaterialAlertDialogBuilder(this)
|
||||||
.setTitle(getString(R.string.identity_server_consent_dialog_title_2, configuredIdentityServer.orEmpty()))
|
.setTitle(getString(R.string.identity_server_consent_dialog_title_2, identityServerWithTerms?.serverUrl.orEmpty()))
|
||||||
.setMessage(content)
|
.setMessage(content)
|
||||||
.setPositiveButton(R.string.reactions_agree) { _, _ ->
|
.setPositiveButton(R.string.reactions_agree) { _, _ ->
|
||||||
consentCallBack.invoke()
|
consentCallBack.invoke()
|
||||||
|
|
|
@ -21,5 +21,6 @@ import im.vector.app.core.platform.VectorViewModelAction
|
||||||
sealed class ContactsBookAction : VectorViewModelAction {
|
sealed class ContactsBookAction : VectorViewModelAction {
|
||||||
data class FilterWith(val filter: String) : ContactsBookAction()
|
data class FilterWith(val filter: String) : ContactsBookAction()
|
||||||
data class OnlyBoundContacts(val onlyBoundContacts: Boolean) : ContactsBookAction()
|
data class OnlyBoundContacts(val onlyBoundContacts: Boolean) : ContactsBookAction()
|
||||||
|
object UserConsentRequest : ContactsBookAction()
|
||||||
object UserConsentGranted : ContactsBookAction()
|
object UserConsentGranted : ContactsBookAction()
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ import com.airbnb.mvrx.activityViewModel
|
||||||
import com.airbnb.mvrx.withState
|
import com.airbnb.mvrx.withState
|
||||||
import im.vector.app.core.extensions.cleanup
|
import im.vector.app.core.extensions.cleanup
|
||||||
import im.vector.app.core.extensions.configureWith
|
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.extensions.hideKeyboard
|
||||||
import im.vector.app.core.platform.VectorBaseFragment
|
import im.vector.app.core.platform.VectorBaseFragment
|
||||||
import im.vector.app.core.utils.showIdentityServerConsentDialog
|
import im.vector.app.core.utils.showIdentityServerConsentDialog
|
||||||
|
@ -67,20 +68,27 @@ class ContactsBookFragment @Inject constructor(
|
||||||
setupConsentView()
|
setupConsentView()
|
||||||
setupOnlyBoundContactsView()
|
setupOnlyBoundContactsView()
|
||||||
setupCloseView()
|
setupCloseView()
|
||||||
|
contactsBookViewModel.observeViewEvents {
|
||||||
|
when (it) {
|
||||||
|
is ContactsBookViewEvents.Failure -> showFailure(it.throwable)
|
||||||
|
is ContactsBookViewEvents.OnPoliciesRetrieved -> showConsentDialog(it)
|
||||||
|
}.exhaustive
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupConsentView() {
|
private fun setupConsentView() {
|
||||||
views.phoneBookSearchForMatrixContacts.setOnClickListener {
|
views.phoneBookSearchForMatrixContacts.setOnClickListener {
|
||||||
withState(contactsBookViewModel) { state ->
|
contactsBookViewModel.handle(ContactsBookAction.UserConsentRequest)
|
||||||
requireContext().showIdentityServerConsentDialog(
|
|
||||||
state.identityServerUrl,
|
|
||||||
/* TODO */ emptyList(),
|
|
||||||
consentCallBack = { contactsBookViewModel.handle(ContactsBookAction.UserConsentGranted) }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun showConsentDialog(event: ContactsBookViewEvents.OnPoliciesRetrieved) {
|
||||||
|
requireContext().showIdentityServerConsentDialog(
|
||||||
|
event.identityServerWithTerms,
|
||||||
|
consentCallBack = { contactsBookViewModel.handle(ContactsBookAction.UserConsentGranted) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private fun setupOnlyBoundContactsView() {
|
private fun setupOnlyBoundContactsView() {
|
||||||
views.phoneBookOnlyBoundContacts.checkedChanges()
|
views.phoneBookOnlyBoundContacts.checkedChanges()
|
||||||
.onEach {
|
.onEach {
|
||||||
|
|
|
@ -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()
|
||||||
|
}
|
|
@ -16,20 +16,21 @@
|
||||||
|
|
||||||
package im.vector.app.features.contactsbook
|
package im.vector.app.features.contactsbook
|
||||||
|
|
||||||
import androidx.lifecycle.viewModelScope
|
|
||||||
import com.airbnb.mvrx.Loading
|
import com.airbnb.mvrx.Loading
|
||||||
import com.airbnb.mvrx.MavericksViewModelFactory
|
import com.airbnb.mvrx.MavericksViewModelFactory
|
||||||
import com.airbnb.mvrx.Success
|
import com.airbnb.mvrx.Success
|
||||||
import dagger.assisted.Assisted
|
import dagger.assisted.Assisted
|
||||||
import dagger.assisted.AssistedFactory
|
import dagger.assisted.AssistedFactory
|
||||||
import dagger.assisted.AssistedInject
|
import dagger.assisted.AssistedInject
|
||||||
|
import im.vector.app.R
|
||||||
import im.vector.app.core.contacts.ContactsDataSource
|
import im.vector.app.core.contacts.ContactsDataSource
|
||||||
import im.vector.app.core.contacts.MappedContact
|
import im.vector.app.core.contacts.MappedContact
|
||||||
import im.vector.app.core.di.MavericksAssistedViewModelFactory
|
import im.vector.app.core.di.MavericksAssistedViewModelFactory
|
||||||
import im.vector.app.core.di.hiltMavericksViewModelFactory
|
import im.vector.app.core.di.hiltMavericksViewModelFactory
|
||||||
import im.vector.app.core.extensions.exhaustive
|
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.platform.VectorViewModel
|
||||||
|
import im.vector.app.core.resources.StringProvider
|
||||||
|
import im.vector.app.features.discovery.fetchIdentityServerWithTerms
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.matrix.android.sdk.api.session.Session
|
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 org.matrix.android.sdk.api.session.identity.ThreePid
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
||||||
class ContactsBookViewModel @AssistedInject constructor(@Assisted
|
class ContactsBookViewModel @AssistedInject constructor(
|
||||||
initialState: ContactsBookViewState,
|
@Assisted initialState: ContactsBookViewState,
|
||||||
private val contactsDataSource: ContactsDataSource,
|
private val contactsDataSource: ContactsDataSource,
|
||||||
private val session: Session) :
|
private val stringProvider: StringProvider,
|
||||||
VectorViewModel<ContactsBookViewState, ContactsBookAction, EmptyViewEvents>(initialState) {
|
private val session: Session
|
||||||
|
) : VectorViewModel<ContactsBookViewState, ContactsBookAction, ContactsBookViewEvents>(initialState) {
|
||||||
|
|
||||||
@AssistedFactory
|
@AssistedFactory
|
||||||
interface Factory : MavericksAssistedViewModelFactory<ContactsBookViewModel, ContactsBookViewState> {
|
interface Factory : MavericksAssistedViewModelFactory<ContactsBookViewModel, ContactsBookViewState> {
|
||||||
|
@ -162,9 +164,22 @@ class ContactsBookViewModel @AssistedInject constructor(@Assisted
|
||||||
is ContactsBookAction.FilterWith -> handleFilterWith(action)
|
is ContactsBookAction.FilterWith -> handleFilterWith(action)
|
||||||
is ContactsBookAction.OnlyBoundContacts -> handleOnlyBoundContacts(action)
|
is ContactsBookAction.OnlyBoundContacts -> handleOnlyBoundContacts(action)
|
||||||
ContactsBookAction.UserConsentGranted -> handleUserConsentGranted()
|
ContactsBookAction.UserConsentGranted -> handleUserConsentGranted()
|
||||||
|
ContactsBookAction.UserConsentRequest -> handleUserConsentRequest()
|
||||||
}.exhaustive
|
}.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() {
|
private fun handleUserConsentGranted() {
|
||||||
session.identityService().setUserConsent(true)
|
session.identityService().setUserConsent(true)
|
||||||
|
|
||||||
|
|
|
@ -186,8 +186,7 @@ class DiscoverySettingsFragment @Inject constructor(
|
||||||
if (newValue) {
|
if (newValue) {
|
||||||
withState(viewModel) { state ->
|
withState(viewModel) { state ->
|
||||||
requireContext().showIdentityServerConsentDialog(
|
requireContext().showIdentityServerConsentDialog(
|
||||||
state.identityServer.invoke()?.serverUrl,
|
state.identityServer.invoke(),
|
||||||
state.identityServer.invoke()?.policies,
|
|
||||||
consentCallBack = { viewModel.handle(DiscoverySettingsAction.UpdateUserConsent(true)) }
|
consentCallBack = { viewModel.handle(DiscoverySettingsAction.UpdateUserConsent(true)) }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,6 @@ import im.vector.app.core.di.hiltMavericksViewModelFactory
|
||||||
import im.vector.app.core.extensions.exhaustive
|
import im.vector.app.core.extensions.exhaustive
|
||||||
import im.vector.app.core.platform.VectorViewModel
|
import im.vector.app.core.platform.VectorViewModel
|
||||||
import im.vector.app.core.resources.StringProvider
|
import im.vector.app.core.resources.StringProvider
|
||||||
import im.vector.app.core.utils.ensureProtocol
|
|
||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
import kotlinx.coroutines.launch
|
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.IdentityServiceListener
|
||||||
import org.matrix.android.sdk.api.session.identity.SharedState
|
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.identity.ThreePid
|
||||||
import org.matrix.android.sdk.api.session.terms.TermsService
|
|
||||||
import org.matrix.android.sdk.flow.flow
|
import org.matrix.android.sdk.flow.flow
|
||||||
|
|
||||||
class DiscoverySettingsViewModel @AssistedInject constructor(
|
class DiscoverySettingsViewModel @AssistedInject constructor(
|
||||||
|
@ -56,7 +54,6 @@ class DiscoverySettingsViewModel @AssistedInject constructor(
|
||||||
companion object : MavericksViewModelFactory<DiscoverySettingsViewModel, DiscoverySettingsState> by hiltMavericksViewModelFactory()
|
companion object : MavericksViewModelFactory<DiscoverySettingsViewModel, DiscoverySettingsState> by hiltMavericksViewModelFactory()
|
||||||
|
|
||||||
private val identityService = session.identityService()
|
private val identityService = session.identityService()
|
||||||
private val termsService: TermsService = session
|
|
||||||
|
|
||||||
private val identityServerManagerListener = object : IdentityServiceListener {
|
private val identityServerManagerListener = object : IdentityServiceListener {
|
||||||
override fun onIdentityServerChange() = withState { state ->
|
override fun onIdentityServerChange() = withState { state ->
|
||||||
|
@ -397,7 +394,7 @@ class DiscoverySettingsViewModel @AssistedInject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
runCatching { fetchIdentityServerWithTerms() }.fold(
|
runCatching { session.fetchIdentityServerWithTerms(stringProvider.getString(R.string.resources_language)) }.fold(
|
||||||
onSuccess = { setState { copy(identityServer = Success(it)) } },
|
onSuccess = { setState { copy(identityServer = Success(it)) } },
|
||||||
onFailure = { _viewEvents.post(DiscoverySettingsViewEvents.Failure(it)) }
|
onFailure = { _viewEvents.post(DiscoverySettingsViewEvents.Failure(it)) }
|
||||||
)
|
)
|
||||||
|
@ -405,21 +402,6 @@ class DiscoverySettingsViewModel @AssistedInject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun fetchIdentityServerWithTerms(): IdentityServerWithTerms? {
|
private suspend fun fetchIdentityServerWithTerms(): IdentityServerWithTerms? {
|
||||||
val identityServerUrl = identityService.getCurrentIdentityServerUrl()
|
return session.fetchIdentityServerWithTerms(stringProvider.getString(R.string.resources_language))
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
|
@ -24,6 +24,7 @@ sealed class UserListAction : VectorViewModelAction {
|
||||||
data class AddPendingSelection(val pendingSelection: PendingSelection) : UserListAction()
|
data class AddPendingSelection(val pendingSelection: PendingSelection) : UserListAction()
|
||||||
data class RemovePendingSelection(val pendingSelection: PendingSelection) : UserListAction()
|
data class RemovePendingSelection(val pendingSelection: PendingSelection) : UserListAction()
|
||||||
object ComputeMatrixToLinkForSharing : UserListAction()
|
object ComputeMatrixToLinkForSharing : UserListAction()
|
||||||
|
object UserConsentRequest : UserListAction()
|
||||||
data class UpdateUserConsent(val consent: Boolean) : UserListAction()
|
data class UpdateUserConsent(val consent: Boolean) : UserListAction()
|
||||||
object Resumed : UserListAction()
|
object Resumed : UserListAction()
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,6 +102,8 @@ class UserListFragment @Inject constructor(
|
||||||
extraTitle = getString(R.string.invite_friends_rich_title)
|
extraTitle = getString(R.string.invite_friends_rich_title)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
is UserListViewEvents.Failure -> showFailure(it.throwable)
|
||||||
|
is UserListViewEvents.OnPoliciesRetrieved -> showConsentDialog(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -230,13 +232,14 @@ class UserListFragment @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun giveIdentityServerConsent() {
|
override fun giveIdentityServerConsent() {
|
||||||
withState(viewModel) { state ->
|
viewModel.handle(UserListAction.UserConsentRequest)
|
||||||
requireContext().showIdentityServerConsentDialog(
|
}
|
||||||
state.configuredIdentityServer,
|
|
||||||
/* TODO */ emptyList(),
|
private fun showConsentDialog(event: UserListViewEvents.OnPoliciesRetrieved) {
|
||||||
consentCallBack = { viewModel.handle(UserListAction.UpdateUserConsent(true)) }
|
requireContext().showIdentityServerConsentDialog(
|
||||||
)
|
event.identityServerWithTerms,
|
||||||
}
|
consentCallBack = { viewModel.handle(UserListAction.UpdateUserConsent(true)) }
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onUseQRCode() {
|
override fun onUseQRCode() {
|
||||||
|
|
|
@ -17,10 +17,13 @@
|
||||||
package im.vector.app.features.userdirectory
|
package im.vector.app.features.userdirectory
|
||||||
|
|
||||||
import im.vector.app.core.platform.VectorViewEvents
|
import im.vector.app.core.platform.VectorViewEvents
|
||||||
|
import im.vector.app.features.discovery.IdentityServerWithTerms
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transient events for invite users to room screen
|
* Transient events for invite users to room screen
|
||||||
*/
|
*/
|
||||||
sealed class UserListViewEvents : VectorViewEvents {
|
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()
|
data class OpenShareMatrixToLink(val link: String) : UserListViewEvents()
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,12 +23,15 @@ import com.airbnb.mvrx.Uninitialized
|
||||||
import dagger.assisted.Assisted
|
import dagger.assisted.Assisted
|
||||||
import dagger.assisted.AssistedFactory
|
import dagger.assisted.AssistedFactory
|
||||||
import dagger.assisted.AssistedInject
|
import dagger.assisted.AssistedInject
|
||||||
|
import im.vector.app.R
|
||||||
import im.vector.app.core.di.MavericksAssistedViewModelFactory
|
import im.vector.app.core.di.MavericksAssistedViewModelFactory
|
||||||
import im.vector.app.core.di.hiltMavericksViewModelFactory
|
import im.vector.app.core.di.hiltMavericksViewModelFactory
|
||||||
import im.vector.app.core.extensions.exhaustive
|
import im.vector.app.core.extensions.exhaustive
|
||||||
import im.vector.app.core.extensions.isEmail
|
import im.vector.app.core.extensions.isEmail
|
||||||
import im.vector.app.core.extensions.toggle
|
import im.vector.app.core.extensions.toggle
|
||||||
import im.vector.app.core.platform.VectorViewModel
|
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.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.debounce
|
import kotlinx.coroutines.flow.debounce
|
||||||
import kotlinx.coroutines.flow.filter
|
import kotlinx.coroutines.flow.filter
|
||||||
|
@ -36,6 +39,7 @@ import kotlinx.coroutines.flow.flatMapLatest
|
||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
import kotlinx.coroutines.flow.sample
|
import kotlinx.coroutines.flow.sample
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
import org.matrix.android.sdk.api.MatrixPatterns
|
import org.matrix.android.sdk.api.MatrixPatterns
|
||||||
import org.matrix.android.sdk.api.extensions.tryOrNull
|
import org.matrix.android.sdk.api.extensions.tryOrNull
|
||||||
import org.matrix.android.sdk.api.session.Session
|
import org.matrix.android.sdk.api.session.Session
|
||||||
|
@ -51,9 +55,11 @@ data class ThreePidUser(
|
||||||
val user: User?
|
val user: User?
|
||||||
)
|
)
|
||||||
|
|
||||||
class UserListViewModel @AssistedInject constructor(@Assisted initialState: UserListViewState,
|
class UserListViewModel @AssistedInject constructor(
|
||||||
private val session: Session) :
|
@Assisted initialState: UserListViewState,
|
||||||
VectorViewModel<UserListViewState, UserListAction, UserListViewEvents>(initialState) {
|
private val stringProvider: StringProvider,
|
||||||
|
private val session: Session
|
||||||
|
) : VectorViewModel<UserListViewState, UserListAction, UserListViewEvents>(initialState) {
|
||||||
|
|
||||||
private val knownUsersSearch = MutableStateFlow("")
|
private val knownUsersSearch = MutableStateFlow("")
|
||||||
private val directoryUsersSearch = MutableStateFlow("")
|
private val directoryUsersSearch = MutableStateFlow("")
|
||||||
|
@ -104,11 +110,24 @@ class UserListViewModel @AssistedInject constructor(@Assisted initialState: User
|
||||||
is UserListAction.AddPendingSelection -> handleSelectUser(action)
|
is UserListAction.AddPendingSelection -> handleSelectUser(action)
|
||||||
is UserListAction.RemovePendingSelection -> handleRemoveSelectedUser(action)
|
is UserListAction.RemovePendingSelection -> handleRemoveSelectedUser(action)
|
||||||
UserListAction.ComputeMatrixToLinkForSharing -> handleShareMyMatrixToLink()
|
UserListAction.ComputeMatrixToLinkForSharing -> handleShareMyMatrixToLink()
|
||||||
|
UserListAction.UserConsentRequest -> handleUserConsentRequest()
|
||||||
is UserListAction.UpdateUserConsent -> handleISUpdateConsent(action)
|
is UserListAction.UpdateUserConsent -> handleISUpdateConsent(action)
|
||||||
UserListAction.Resumed -> handleResumed()
|
UserListAction.Resumed -> handleResumed()
|
||||||
}.exhaustive
|
}.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) {
|
private fun handleISUpdateConsent(action: UserListAction.UpdateUserConsent) {
|
||||||
session.identityService().setUserConsent(action.consent)
|
session.identityService().setUserConsent(action.consent)
|
||||||
withState {
|
withState {
|
||||||
|
|
Loading…
Reference in New Issue