Move setting to room profile

This commit is contained in:
Valere 2022-10-04 17:17:01 +02:00
parent 8de2fe8917
commit 68d4ac34c7
16 changed files with 173 additions and 124 deletions

View File

@ -1236,7 +1236,7 @@
<string name="encryption_never_send_to_unverified_devices_summary">Never send encrypted messages to unverified sessions from this session.</string> <string name="encryption_never_send_to_unverified_devices_summary">Never send encrypted messages to unverified sessions from this session.</string>
<string name="encryption_never_send_to_unverified_devices_in_room">Never send encrypted messages to unverified sessions in this room.</string> <string name="encryption_never_send_to_unverified_devices_in_room">Never send encrypted messages to unverified sessions in this room.</string>
<string name="some_devices_will_not_be_able_to_decrypt">⚠ There are unverified devices in this room, they wont be able to decrypt messages you send.</string> <string name="some_devices_will_not_be_able_to_decrypt">⚠ There are unverified devices in this room, they wont be able to decrypt messages you send.</string>
<string name="room_settings_global_blacklist_unverified_info_text">🔒 You have enabled encrypt to verified sessions only for all rooms in Security Settings.</string> <string name="room_settings_global_block_unverified_info_text">🔒 You have enabled encrypt to verified sessions only for all rooms in Security Settings.</string>
<plurals name="encryption_import_room_keys_success"> <plurals name="encryption_import_room_keys_success">
<item quantity="one">%1$d/%2$d key imported with success.</item> <item quantity="one">%1$d/%2$d key imported with success.</item>
<item quantity="other">%1$d/%2$d keys imported with success.</item> <item quantity="other">%1$d/%2$d keys imported with success.</item>

View File

@ -61,7 +61,7 @@ interface CryptoService {
fun isRoomBlacklistUnverifiedDevices(roomId: String?): Boolean fun isRoomBlacklistUnverifiedDevices(roomId: String?): Boolean
fun getLiveBlacklistUnverifiedDevices(roomId: String): LiveData<Boolean> fun getLiveBlockUnverifiedDevices(roomId: String): LiveData<Boolean>
fun setWarnOnUnknownDevices(warn: Boolean) fun setWarnOnUnknownDevices(warn: Boolean)

View File

@ -1177,7 +1177,7 @@ internal class DefaultCryptoService @Inject constructor(
* @return true if the client should encrypt messages only for the verified devices. * @return true if the client should encrypt messages only for the verified devices.
*/ */
override fun isRoomBlacklistUnverifiedDevices(roomId: String?): Boolean { override fun isRoomBlacklistUnverifiedDevices(roomId: String?): Boolean {
return roomId?.let { cryptoStore.getBlacklistUnverifiedDevices(roomId) } return roomId?.let { cryptoStore.getBlockUnverifiedDevices(roomId) }
?: false ?: false
} }
@ -1186,8 +1186,8 @@ internal class DefaultCryptoService @Inject constructor(
* *
* @return Live status * @return Live status
*/ */
override fun getLiveBlacklistUnverifiedDevices(roomId: String): LiveData<Boolean> { override fun getLiveBlockUnverifiedDevices(roomId: String): LiveData<Boolean> {
return cryptoStore.getLiveBlacklistUnverifiedDevices(roomId) return cryptoStore.getLiveBlockUnverifiedDevices(roomId)
} }
/** /**

View File

@ -424,7 +424,7 @@ internal class MXMegolmEncryption(
// an m.new_device. // an m.new_device.
val keys = deviceListManager.downloadKeys(userIds, false) val keys = deviceListManager.downloadKeys(userIds, false)
val encryptToVerifiedDevicesOnly = cryptoStore.getGlobalBlacklistUnverifiedDevices() || val encryptToVerifiedDevicesOnly = cryptoStore.getGlobalBlacklistUnverifiedDevices() ||
cryptoStore.getBlacklistUnverifiedDevices(roomId) cryptoStore.getBlockUnverifiedDevices(roomId)
val devicesInRoom = DeviceInRoomInfo() val devicesInRoom = DeviceInRoomInfo()
val unknownDevices = MXUsersDevicesMap<CryptoDeviceInfo>() val unknownDevices = MXUsersDevicesMap<CryptoDeviceInfo>()

View File

@ -125,14 +125,14 @@ internal interface IMXCryptoStore {
* *
* @return Live status * @return Live status
*/ */
fun getLiveBlacklistUnverifiedDevices(roomId: String): LiveData<Boolean> fun getLiveBlockUnverifiedDevices(roomId: String): LiveData<Boolean>
/** /**
* Tell if unverified devices should be blacklisted when sending keys. * Tell if unverified devices should be blacklisted when sending keys.
* *
* @return true if should not send keys to unverified devices * @return true if should not send keys to unverified devices
*/ */
fun getBlacklistUnverifiedDevices(roomId: String): Boolean fun getBlockUnverifiedDevices(roomId: String): Boolean
/** /**
* Define if encryption keys should be sent to unverified devices in this room. * Define if encryption keys should be sent to unverified devices in this room.

View File

@ -1097,7 +1097,7 @@ internal class RealmCryptoStore @Inject constructor(
} }
} }
override fun getLiveBlacklistUnverifiedDevices(roomId: String): LiveData<Boolean> { override fun getLiveBlockUnverifiedDevices(roomId: String): LiveData<Boolean> {
val liveData = monarchy.findAllMappedWithChanges( val liveData = monarchy.findAllMappedWithChanges(
{ realm: Realm -> { realm: Realm ->
realm.where<CryptoRoomEntity>() realm.where<CryptoRoomEntity>()
@ -1112,7 +1112,7 @@ internal class RealmCryptoStore @Inject constructor(
} }
} }
override fun getBlacklistUnverifiedDevices(roomId: String): Boolean { override fun getBlockUnverifiedDevices(roomId: String): Boolean {
return doWithRealm(realmConfiguration) { realm -> return doWithRealm(realmConfiguration) { realm ->
realm.where<CryptoRoomEntity>() realm.where<CryptoRoomEntity>()
.equalTo(CryptoRoomEntityFields.ROOM_ID, roomId) .equalTo(CryptoRoomEntityFields.ROOM_ID, roomId)

View File

@ -27,4 +27,5 @@ sealed class RoomProfileAction : VectorViewModelAction {
object ShareRoomProfile : RoomProfileAction() object ShareRoomProfile : RoomProfileAction()
object CreateShortcut : RoomProfileAction() object CreateShortcut : RoomProfileAction()
object RestoreEncryptionState : RoomProfileAction() object RestoreEncryptionState : RoomProfileAction()
data class SetEncryptToVerifiedDeviceOnly(val enabled: Boolean) : RoomProfileAction()
} }

View File

@ -27,6 +27,7 @@ import im.vector.app.core.resources.DrawableProvider
import im.vector.app.core.resources.StringProvider import im.vector.app.core.resources.StringProvider
import im.vector.app.core.ui.list.genericFooterItem import im.vector.app.core.ui.list.genericFooterItem
import im.vector.app.core.ui.list.genericPositiveButtonItem import im.vector.app.core.ui.list.genericPositiveButtonItem
import im.vector.app.features.form.formSwitchItem
import im.vector.app.features.home.ShortcutCreator import im.vector.app.features.home.ShortcutCreator
import im.vector.app.features.home.room.detail.timeline.TimelineEventController import im.vector.app.features.home.room.detail.timeline.TimelineEventController
import im.vector.app.features.home.room.detail.timeline.tools.createLinkMovementMethod import im.vector.app.features.home.room.detail.timeline.tools.createLinkMovementMethod
@ -66,6 +67,8 @@ class RoomProfileController @Inject constructor(
fun onUrlInTopicLongClicked(url: String) fun onUrlInTopicLongClicked(url: String)
fun doMigrateToVersion(newVersion: String) fun doMigrateToVersion(newVersion: String)
fun restoreEncryptionState() fun restoreEncryptionState()
fun setEncryptedToVerifiedDevicesOnly(enabled: Boolean)
fun openGlobalBlockSettings()
} }
override fun buildModels(data: RoomProfileViewState?) { override fun buildModels(data: RoomProfileViewState?) {
@ -175,6 +178,53 @@ class RoomProfileController @Inject constructor(
} }
buildEncryptionAction(data.actionPermissions, roomSummary) buildEncryptionAction(data.actionPermissions, roomSummary)
if (roomSummary.isEncrypted && !encryptionMisconfigured) {
data.globalCryptoConfig.invoke()?.let { globalConfig ->
if (globalConfig.globalBlockUnverifiedDevices) {
genericFooterItem {
id("globalConfig")
centered(false)
text(
span {
+host.stringProvider.getString(R.string.room_settings_global_block_unverified_info_text)
apply {
if (data.unverifiedDevicesInTheRoom.invoke() == true) {
+"\n"
+host.stringProvider.getString(R.string.some_devices_will_not_be_able_to_decrypt)
}
}
}.toEpoxyCharSequence()
)
itemClickAction {
host.callback?.openGlobalBlockSettings()
}
}
} else {
// per room setting is available
val shouldBlockUnverified = data.encryptToVerifiedDeviceOnly.invoke()
formSwitchItem {
id("send_to_unverified")
enabled(shouldBlockUnverified != null)
title(host.stringProvider.getString(R.string.encryption_never_send_to_unverified_devices_in_room))
switchChecked(shouldBlockUnverified ?: false)
apply {
if (shouldBlockUnverified == true && data.unverifiedDevicesInTheRoom.invoke() == true) {
summary(
host.stringProvider.getString(R.string.some_devices_will_not_be_able_to_decrypt)
)
} else {
summary(null)
}
}
listener { value ->
host.callback?.setEncryptedToVerifiedDevicesOnly(value)
}
}
}
}
}
// More // More
buildProfileSection(stringProvider.getString(R.string.room_profile_section_more)) buildProfileSection(stringProvider.getString(R.string.room_profile_section_more))
buildProfileAction( buildProfileAction(

View File

@ -53,6 +53,7 @@ import im.vector.app.features.home.room.detail.RoomDetailPendingActionStore
import im.vector.app.features.home.room.detail.upgrade.MigrateRoomBottomSheet import im.vector.app.features.home.room.detail.upgrade.MigrateRoomBottomSheet
import im.vector.app.features.home.room.list.actions.RoomListQuickActionsSharedAction import im.vector.app.features.home.room.list.actions.RoomListQuickActionsSharedAction
import im.vector.app.features.home.room.list.actions.RoomListQuickActionsSharedActionViewModel import im.vector.app.features.home.room.list.actions.RoomListQuickActionsSharedActionViewModel
import im.vector.app.features.navigation.SettingsActivityPayload
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
@ -346,6 +347,14 @@ class RoomProfileFragment :
) )
} }
override fun setEncryptedToVerifiedDevicesOnly(enabled: Boolean) {
roomProfileViewModel.handle(RoomProfileAction.SetEncryptToVerifiedDeviceOnly(enabled))
}
override fun openGlobalBlockSettings() {
navigator.openSettings(requireContext(), SettingsActivityPayload.SecurityPrivacy)
}
private fun onAvatarClicked(view: View) = withState(roomProfileViewModel) { state -> private fun onAvatarClicked(view: View) = withState(roomProfileViewModel) { state ->
state.roomSummary()?.toMatrixItem()?.let { matrixItem -> state.roomSummary()?.toMatrixItem()?.let { matrixItem ->
navigator.openBigImageViewer(requireActivity(), view, matrixItem) navigator.openBigImageViewer(requireActivity(), view, matrixItem)

View File

@ -17,6 +17,7 @@
package im.vector.app.features.roomprofile package im.vector.app.features.roomprofile
import androidx.lifecycle.asFlow
import com.airbnb.mvrx.MavericksViewModelFactory import com.airbnb.mvrx.MavericksViewModelFactory
import dagger.assisted.Assisted import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory import dagger.assisted.AssistedFactory
@ -32,7 +33,11 @@ import im.vector.app.features.home.ShortcutCreator
import im.vector.app.features.powerlevel.PowerLevelsFlowFactory import im.vector.app.features.powerlevel.PowerLevelsFlowFactory
import im.vector.app.features.session.coroutineScope import im.vector.app.features.session.coroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.matrix.android.sdk.api.query.QueryStringValue import org.matrix.android.sdk.api.query.QueryStringValue
@ -76,6 +81,45 @@ class RoomProfileViewModel @AssistedInject constructor(
observeBannedRoomMembers(flowRoom) observeBannedRoomMembers(flowRoom)
observePermissions() observePermissions()
observePowerLevels() observePowerLevels()
observeCryptoSettings(flowRoom)
}
private fun observeCryptoSettings(flowRoom: FlowRoom) {
val perRoomBlockStatus = session.cryptoService().getLiveBlockUnverifiedDevices(initialState.roomId)
.asFlow()
perRoomBlockStatus
.execute {
copy(encryptToVerifiedDeviceOnly = it)
}
val globalBlockStatus = session.cryptoService().getLiveGlobalCryptoConfig()
.asFlow()
globalBlockStatus
.execute {
copy(globalCryptoConfig = it)
}
perRoomBlockStatus.combine(globalBlockStatus) { perRoom, global ->
perRoom || global.globalBlockUnverifiedDevices
}.flatMapLatest {
if (it) {
flowRoom.liveRoomMembers(roomMemberQueryParams { memberships = Membership.activeMemberships() })
.map { it.map { it.userId } }
.flatMapLatest {
session.cryptoService().getLiveCryptoDeviceInfo(it).asFlow()
}
} else {
flowOf(emptyList())
}
}.map {
it.isNotEmpty()
}.execute {
copy(
unverifiedDevicesInTheRoom = it
)
}
} }
private fun observePowerLevels() { private fun observePowerLevels() {
@ -141,6 +185,7 @@ class RoomProfileViewModel @AssistedInject constructor(
is RoomProfileAction.ShareRoomProfile -> handleShareRoomProfile() is RoomProfileAction.ShareRoomProfile -> handleShareRoomProfile()
RoomProfileAction.CreateShortcut -> handleCreateShortcut() RoomProfileAction.CreateShortcut -> handleCreateShortcut()
RoomProfileAction.RestoreEncryptionState -> restoreEncryptionState() RoomProfileAction.RestoreEncryptionState -> restoreEncryptionState()
is RoomProfileAction.SetEncryptToVerifiedDeviceOnly -> setEncryptToVerifiedDeviceOnly(action.enabled)
} }
} }
@ -212,6 +257,12 @@ class RoomProfileViewModel @AssistedInject constructor(
} }
} }
private fun setEncryptToVerifiedDeviceOnly(enabled: Boolean) {
session.coroutineScope.launch {
session.cryptoService().setRoomBlockUnverifiedDevices(room.roomId, enabled)
}
}
private fun restoreEncryptionState() { private fun restoreEncryptionState() {
_viewEvents.post(RoomProfileViewEvents.Loading()) _viewEvents.post(RoomProfileViewEvents.Loading())
session.coroutineScope.launch { session.coroutineScope.launch {

View File

@ -20,6 +20,7 @@ package im.vector.app.features.roomprofile
import com.airbnb.mvrx.Async import com.airbnb.mvrx.Async
import com.airbnb.mvrx.MavericksState import com.airbnb.mvrx.MavericksState
import com.airbnb.mvrx.Uninitialized import com.airbnb.mvrx.Uninitialized
import org.matrix.android.sdk.api.session.crypto.GlobalCryptoConfig
import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary
import org.matrix.android.sdk.api.session.room.model.RoomSummary import org.matrix.android.sdk.api.session.room.model.RoomSummary
import org.matrix.android.sdk.api.session.room.model.create.RoomCreateContent import org.matrix.android.sdk.api.session.room.model.create.RoomCreateContent
@ -36,6 +37,9 @@ data class RoomProfileViewState(
val canUpgradeRoom: Boolean = false, val canUpgradeRoom: Boolean = false,
val isTombstoned: Boolean = false, val isTombstoned: Boolean = false,
val canUpdateRoomState: Boolean = false, val canUpdateRoomState: Boolean = false,
val encryptToVerifiedDeviceOnly: Async<Boolean> = Uninitialized,
val globalCryptoConfig: Async<GlobalCryptoConfig> = Uninitialized,
val unverifiedDevicesInTheRoom: Async<Boolean> = Uninitialized,
) : MavericksState { ) : MavericksState {
constructor(args: RoomProfileArgs) : this(roomId = args.roomId) constructor(args: RoomProfileArgs) : this(roomId = args.roomId)

View File

@ -28,7 +28,6 @@ sealed class RoomSettingsAction : VectorViewModelAction {
data class SetRoomHistoryVisibility(val visibility: RoomHistoryVisibility) : RoomSettingsAction() data class SetRoomHistoryVisibility(val visibility: RoomHistoryVisibility) : RoomSettingsAction()
data class SetRoomJoinRule(val roomJoinRule: RoomJoinRules) : RoomSettingsAction() data class SetRoomJoinRule(val roomJoinRule: RoomJoinRules) : RoomSettingsAction()
data class SetRoomGuestAccess(val guestAccess: GuestAccess) : RoomSettingsAction() data class SetRoomGuestAccess(val guestAccess: GuestAccess) : RoomSettingsAction()
data class SetEncryptToVerifiedDeviceOnly(val enabled: Boolean) : RoomSettingsAction()
object Save : RoomSettingsAction() object Save : RoomSettingsAction()
object Cancel : RoomSettingsAction() object Cancel : RoomSettingsAction()

View File

@ -22,7 +22,6 @@ import im.vector.app.core.epoxy.dividerItem
import im.vector.app.core.epoxy.profiles.buildProfileAction import im.vector.app.core.epoxy.profiles.buildProfileAction
import im.vector.app.core.epoxy.profiles.buildProfileSection import im.vector.app.core.epoxy.profiles.buildProfileSection
import im.vector.app.core.resources.StringProvider import im.vector.app.core.resources.StringProvider
import im.vector.app.core.ui.list.genericFooterItem
import im.vector.app.core.ui.list.verticalMarginItem import im.vector.app.core.ui.list.verticalMarginItem
import im.vector.app.core.utils.DimensionConverter import im.vector.app.core.utils.DimensionConverter
import im.vector.app.features.form.formEditTextItem import im.vector.app.features.form.formEditTextItem
@ -31,8 +30,6 @@ import im.vector.app.features.form.formSwitchItem
import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.AvatarRenderer
import im.vector.app.features.home.room.detail.timeline.format.RoomHistoryVisibilityFormatter import im.vector.app.features.home.room.detail.timeline.format.RoomHistoryVisibilityFormatter
import im.vector.app.features.settings.VectorPreferences import im.vector.app.features.settings.VectorPreferences
import im.vector.lib.core.utils.epoxy.charsequence.toEpoxyCharSequence
import me.gujun.android.span.span
import org.matrix.android.sdk.api.session.room.model.GuestAccess import org.matrix.android.sdk.api.session.room.model.GuestAccess
import org.matrix.android.sdk.api.session.room.model.RoomJoinRules import org.matrix.android.sdk.api.session.room.model.RoomJoinRules
import org.matrix.android.sdk.api.util.toMatrixItem import org.matrix.android.sdk.api.util.toMatrixItem
@ -55,8 +52,6 @@ class RoomSettingsController @Inject constructor(
fun onHistoryVisibilityClicked() fun onHistoryVisibilityClicked()
fun onJoinRuleClicked() fun onJoinRuleClicked()
fun onToggleGuestAccess() fun onToggleGuestAccess()
fun setEncryptedToVerifiedDevicesOnly(enabled: Boolean)
fun openGlobalBlockSettings()
} }
var callback: Callback? = null var callback: Callback? = null
@ -150,54 +145,54 @@ class RoomSettingsController @Inject constructor(
id("guestAccessDivider") id("guestAccessDivider")
} }
} }
//
// // Security
// buildProfileSection(stringProvider.getString(R.string.room_profile_section_security))
// Security // data.globalCryptoConfig.invoke()?.let { globalConfig ->
buildProfileSection(stringProvider.getString(R.string.room_profile_section_security)) // if (globalConfig.globalBlockUnverifiedDevices) {
// genericFooterItem {
data.globalCryptoConfig.invoke()?.let { globalConfig -> // id("globalConfig")
if (globalConfig.globalBlockUnverifiedDevices) { // centered(false)
genericFooterItem { // text(
id("globalConfig") // span {
centered(false) // +host.stringProvider.getString(R.string.room_settings_global_block_unverified_info_text)
text( // apply {
span { // if (data.unverifiedDevicesInTheRoom.invoke() == true) {
+host.stringProvider.getString(R.string.room_settings_global_blacklist_unverified_info_text) // +"\n"
apply { // +host.stringProvider.getString(R.string.some_devices_will_not_be_able_to_decrypt)
if (data.unverifiedDevicesInTheRoom.invoke() == true) { // }
+"\n" // }
+host.stringProvider.getString(R.string.some_devices_will_not_be_able_to_decrypt) // }.toEpoxyCharSequence()
} // )
} // itemClickAction {
}.toEpoxyCharSequence() // host.callback?.openGlobalBlockSettings()
) // }
itemClickAction { // }
host.callback?.openGlobalBlockSettings() // } else {
} // // per room setting is available
} // val shouldBlockUnverified = data.encryptToVerifiedDeviceOnly.invoke()
} else { // formSwitchItem {
// per room setting is available // id("send_to_unverified")
val shouldBlockUnverified = data.encryptToVerifiedDeviceOnly.invoke() // enabled(shouldBlockUnverified != null)
formSwitchItem { // title(host.stringProvider.getString(R.string.encryption_never_send_to_unverified_devices_in_room))
id("send_to_unverified") //
enabled(shouldBlockUnverified != null) // switchChecked(shouldBlockUnverified ?: false)
title(host.stringProvider.getString(R.string.encryption_never_send_to_unverified_devices_in_room)) //
// apply {
switchChecked(shouldBlockUnverified ?: false) // if (shouldBlockUnverified == true && data.unverifiedDevicesInTheRoom.invoke() == true) {
// summary(
apply { // host.stringProvider.getString(R.string.some_devices_will_not_be_able_to_decrypt)
if (shouldBlockUnverified == true && data.unverifiedDevicesInTheRoom.invoke() == true) { // )
summary( // } else {
host.stringProvider.getString(R.string.some_devices_will_not_be_able_to_decrypt) // summary(null)
) // }
} else { // }
summary(null) // listener { value ->
} // host.callback?.setEncryptedToVerifiedDevicesOnly(value)
} // }
listener { value -> // }
host.callback?.setEncryptedToVerifiedDevicesOnly(value) // }
} // }
}
}
}
} }
} }

View File

@ -43,7 +43,6 @@ import im.vector.app.core.utils.toast
import im.vector.app.databinding.FragmentRoomSettingGenericBinding import im.vector.app.databinding.FragmentRoomSettingGenericBinding
import im.vector.app.features.analytics.plan.MobileScreen import im.vector.app.features.analytics.plan.MobileScreen
import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.AvatarRenderer
import im.vector.app.features.navigation.SettingsActivityPayload
import im.vector.app.features.roomprofile.RoomProfileArgs import im.vector.app.features.roomprofile.RoomProfileArgs
import im.vector.app.features.roomprofile.RoomProfileSharedActionViewModel import im.vector.app.features.roomprofile.RoomProfileSharedActionViewModel
import im.vector.app.features.roomprofile.settings.historyvisibility.RoomHistoryVisibilityBottomSheet import im.vector.app.features.roomprofile.settings.historyvisibility.RoomHistoryVisibilityBottomSheet
@ -200,14 +199,6 @@ class RoomSettingsFragment :
viewModel.handle(RoomSettingsAction.SetRoomGuestAccess(toggled)) viewModel.handle(RoomSettingsAction.SetRoomGuestAccess(toggled))
} }
override fun setEncryptedToVerifiedDevicesOnly(enabled: Boolean) {
viewModel.handle(RoomSettingsAction.SetEncryptToVerifiedDeviceOnly(enabled))
}
override fun openGlobalBlockSettings() {
navigator.openSettings(requireContext(), SettingsActivityPayload.SecurityPrivacy)
}
override fun onImageReady(uri: Uri?) { override fun onImageReady(uri: Uri?) {
uri ?: return uri ?: return
viewModel.handle( viewModel.handle(

View File

@ -17,7 +17,6 @@
package im.vector.app.features.roomprofile.settings package im.vector.app.features.roomprofile.settings
import androidx.core.net.toFile import androidx.core.net.toFile
import androidx.lifecycle.asFlow
import com.airbnb.mvrx.MavericksViewModelFactory import com.airbnb.mvrx.MavericksViewModelFactory
import dagger.assisted.Assisted import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory import dagger.assisted.AssistedFactory
@ -26,12 +25,8 @@ 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.platform.VectorViewModel import im.vector.app.core.platform.VectorViewModel
import im.vector.app.features.powerlevel.PowerLevelsFlowFactory import im.vector.app.features.powerlevel.PowerLevelsFlowFactory
import im.vector.app.features.session.coroutineScope
import im.vector.app.features.settings.VectorPreferences import im.vector.app.features.settings.VectorPreferences
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.mapNotNull import kotlinx.coroutines.flow.mapNotNull
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -42,8 +37,6 @@ import org.matrix.android.sdk.api.session.events.model.EventType
import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.events.model.toModel
import org.matrix.android.sdk.api.session.getRoom import org.matrix.android.sdk.api.session.getRoom
import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilities import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilities
import org.matrix.android.sdk.api.session.room.members.roomMemberQueryParams
import org.matrix.android.sdk.api.session.room.model.Membership
import org.matrix.android.sdk.api.session.room.model.RoomAvatarContent import org.matrix.android.sdk.api.session.room.model.RoomAvatarContent
import org.matrix.android.sdk.api.session.room.model.RoomGuestAccessContent import org.matrix.android.sdk.api.session.room.model.RoomGuestAccessContent
import org.matrix.android.sdk.api.session.room.model.RoomHistoryVisibilityContent import org.matrix.android.sdk.api.session.room.model.RoomHistoryVisibilityContent
@ -90,39 +83,6 @@ class RoomSettingsViewModel @AssistedInject constructor(
canUpgradeToRestricted = couldUpgradeToRestricted canUpgradeToRestricted = couldUpgradeToRestricted
) )
} }
session.cryptoService().getLiveBlacklistUnverifiedDevices(initialState.roomId)
.asFlow()
.execute {
copy(encryptToVerifiedDeviceOnly = it)
}
session.cryptoService().getLiveGlobalCryptoConfig()
.asFlow()
.execute {
copy(globalCryptoConfig = it)
}
val flowRoom = room.flow()
session.cryptoService().getLiveBlacklistUnverifiedDevices(initialState.roomId)
.asFlow()
.flatMapLatest {
if (it) {
flowRoom.liveRoomMembers(roomMemberQueryParams { memberships = Membership.activeMemberships() })
.map { it.map { it.userId } }
.flatMapLatest {
session.cryptoService().getLiveCryptoDeviceInfo(it).asFlow()
}
} else {
flowOf(emptyList())
}
}.map {
it.isNotEmpty()
}.execute {
copy(
unverifiedDevicesInTheRoom = it
)
}
} }
private fun observeState() { private fun observeState() {
@ -252,7 +212,6 @@ class RoomSettingsViewModel @AssistedInject constructor(
is RoomSettingsAction.SetRoomGuestAccess -> handleSetGuestAccess(action) is RoomSettingsAction.SetRoomGuestAccess -> handleSetGuestAccess(action)
is RoomSettingsAction.Save -> saveSettings() is RoomSettingsAction.Save -> saveSettings()
is RoomSettingsAction.Cancel -> cancel() is RoomSettingsAction.Cancel -> cancel()
is RoomSettingsAction.SetEncryptToVerifiedDeviceOnly -> setEncryptToVerifiedDeviceOnly(action.enabled)
} }
} }
@ -274,12 +233,6 @@ class RoomSettingsViewModel @AssistedInject constructor(
} }
} }
private fun setEncryptToVerifiedDeviceOnly(enabled: Boolean) {
session.coroutineScope.launch {
session.cryptoService().setRoomBlockUnverifiedDevices(room.roomId, enabled)
}
}
private fun handleSetAvatarAction(action: RoomSettingsAction.SetAvatarAction) { private fun handleSetAvatarAction(action: RoomSettingsAction.SetAvatarAction) {
setState { setState {
deletePendingAvatar(this) deletePendingAvatar(this)

View File

@ -23,7 +23,6 @@ import com.airbnb.mvrx.Uninitialized
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.resources.StringProvider import im.vector.app.core.resources.StringProvider
import im.vector.app.features.roomprofile.RoomProfileArgs import im.vector.app.features.roomprofile.RoomProfileArgs
import org.matrix.android.sdk.api.session.crypto.GlobalCryptoConfig
import org.matrix.android.sdk.api.session.room.model.GuestAccess import org.matrix.android.sdk.api.session.room.model.GuestAccess
import org.matrix.android.sdk.api.session.room.model.RoomHistoryVisibility import org.matrix.android.sdk.api.session.room.model.RoomHistoryVisibility
import org.matrix.android.sdk.api.session.room.model.RoomJoinRules import org.matrix.android.sdk.api.session.room.model.RoomJoinRules
@ -47,9 +46,6 @@ data class RoomSettingsViewState(
val actionPermissions: ActionPermissions = ActionPermissions(), val actionPermissions: ActionPermissions = ActionPermissions(),
val supportsRestricted: Boolean = false, val supportsRestricted: Boolean = false,
val canUpgradeToRestricted: Boolean = false, val canUpgradeToRestricted: Boolean = false,
val encryptToVerifiedDeviceOnly: Async<Boolean> = Uninitialized,
val globalCryptoConfig: Async<GlobalCryptoConfig> = Uninitialized,
val unverifiedDevicesInTheRoom: Async<Boolean> = Uninitialized,
) : MavericksState { ) : MavericksState {
constructor(args: RoomProfileArgs) : this(roomId = args.roomId) constructor(args: RoomProfileArgs) : this(roomId = args.roomId)