handle migration before setting restricted

This commit is contained in:
Valere 2021-07-12 12:02:58 +02:00
parent 2f16a7fff3
commit c9ef08d8a9
11 changed files with 296 additions and 118 deletions

View file

@ -40,10 +40,17 @@ class MigrateRoomBottomSheet :
VectorBaseBottomSheetDialogFragment<BottomSheetRoomUpgradeBinding>(),
MigrateRoomViewModel.Factory {
enum class MigrationReason {
MANUAL,
FOR_RESTRICTED
}
@Parcelize
data class Args(
val roomId: String,
val newVersion: String
val newVersion: String,
val reason: MigrationReason = MigrationReason.MANUAL,
val customDescription: CharSequence? = null
) : Parcelable
@Inject
@ -62,11 +69,22 @@ class MigrateRoomBottomSheet :
override fun invalidate() = withState(viewModel) { state ->
views.headerText.setText(if (state.isPublic) R.string.upgrade_public_room else R.string.upgrade_private_room)
views.upgradeFromTo.text = getString(R.string.upgrade_public_room_from_to, state.currentVersion, state.newVersion)
views.autoInviteSwitch.isVisible = !state.isPublic && state.otherMemberCount > 0
if (state.migrationReason == MigrationReason.MANUAL) {
views.descriptionText.text = getString(R.string.upgrade_room_warning)
views.upgradeFromTo.text = getString(R.string.upgrade_public_room_from_to, state.currentVersion, state.newVersion)
} else if (state.migrationReason == MigrationReason.FOR_RESTRICTED) {
views.descriptionText.setTextOrHide(state.customDescription)
views.upgradeFromTo.text = getString(R.string.upgrade_room_for_restricted_note)
}
views.autoUpdateParent.isVisible = state.knownParents.isNotEmpty()
if (state.autoMigrateMembersAndParents) {
views.autoUpdateParent.isVisible = false
views.autoInviteSwitch.isVisible = false
} else {
views.autoInviteSwitch.isVisible = !state.isPublic && state.otherMemberCount > 0
views.autoUpdateParent.isVisible = state.knownParents.isNotEmpty()
}
when (state.upgradingStatus) {
is Loading -> {
@ -143,9 +161,12 @@ class MigrateRoomBottomSheet :
const val REQUEST_KEY = "MigrateRoomBottomSheetRequest"
const val BUNDLE_KEY_REPLACEMENT_ROOM = "BUNDLE_KEY_REPLACEMENT_ROOM"
fun newInstance(roomId: String, newVersion: String): MigrateRoomBottomSheet {
fun newInstance(roomId: String, newVersion: String,
reason: MigrationReason = MigrationReason.MANUAL,
customDescription: CharSequence? = null
): MigrateRoomBottomSheet {
return MigrateRoomBottomSheet().apply {
setArguments(Args(roomId, newVersion))
setArguments(Args(roomId, newVersion, reason, customDescription))
}
}
}

View file

@ -90,11 +90,23 @@ class MigrateRoomViewModel @AssistedInject constructor(
copy(upgradingStatus = Loading())
}
session.coroutineScope.launch {
val userToInvite = if (state.autoMigrateMembersAndParents) {
summary?.otherMemberIds?.takeIf { !state.isPublic }
} else {
summary?.otherMemberIds?.takeIf { state.shouldIssueInvites }
}.orEmpty()
val parentSpaceToUpdate = if (state.autoMigrateMembersAndParents) {
summary?.flattenParentIds
} else {
summary?.flattenParentIds?.takeIf { state.shouldUpdateKnownParents }
}.orEmpty()
val result = upgradeRoomViewModelTask.execute(UpgradeRoomViewModelTask.Params(
roomId = state.roomId,
newVersion = state.newVersion,
userIdsToAutoInvite = summary?.otherMemberIds?.takeIf { state.shouldIssueInvites } ?: emptyList(),
parentSpaceToUpdate = summary?.flattenParentIds?.takeIf { state.shouldUpdateKnownParents } ?: emptyList(),
userIdsToAutoInvite = userToInvite,
parentSpaceToUpdate = parentSpaceToUpdate,
progressReporter = { indeterminate, progress, total ->
setState {
copy(

View file

@ -23,6 +23,7 @@ import com.airbnb.mvrx.Uninitialized
data class MigrateRoomViewState(
val roomId: String,
val newVersion: String,
val customDescription: CharSequence? = null,
val currentVersion: String? = null,
val isPublic: Boolean = false,
val shouldIssueInvites: Boolean = false,
@ -32,10 +33,15 @@ data class MigrateRoomViewState(
val upgradingStatus: Async<UpgradeRoomViewModelTask.Result> = Uninitialized,
val upgradingProgress: Int = 0,
val upgradingProgressTotal: Int = 0,
val upgradingProgressIndeterminate: Boolean = true
val upgradingProgressIndeterminate: Boolean = true,
val migrationReason: MigrateRoomBottomSheet.MigrationReason = MigrateRoomBottomSheet.MigrationReason.MANUAL,
val autoMigrateMembersAndParents: Boolean = false
) : MvRxState {
constructor(args: MigrateRoomBottomSheet.Args) : this(
roomId = args.roomId,
newVersion = args.newVersion
newVersion = args.newVersion,
migrationReason = args.reason,
autoMigrateMembersAndParents = args.reason == MigrateRoomBottomSheet.MigrationReason.FOR_RESTRICTED,
customDescription = args.customDescription
)
}

View file

@ -26,14 +26,20 @@ import com.airbnb.mvrx.MvRx
import com.airbnb.mvrx.Success
import com.airbnb.mvrx.Uninitialized
import com.airbnb.mvrx.viewModel
import com.airbnb.mvrx.withState
import im.vector.app.R
import im.vector.app.core.di.ScreenComponent
import im.vector.app.core.error.ErrorFormatter
import im.vector.app.core.extensions.addFragment
import im.vector.app.core.extensions.commitTransaction
import im.vector.app.core.extensions.toMvRxBundle
import im.vector.app.core.platform.VectorBaseActivity
import im.vector.app.core.utils.toast
import im.vector.app.databinding.ActivitySimpleBinding
import im.vector.app.features.home.room.detail.upgrade.MigrateRoomBottomSheet
import im.vector.app.features.roomprofile.RoomProfileArgs
import im.vector.app.features.roomprofile.settings.joinrule.advanced.RoomJoinRuleChooseRestrictedActions
import im.vector.app.features.roomprofile.settings.joinrule.advanced.RoomJoinRuleChooseRestrictedEvents
import im.vector.app.features.roomprofile.settings.joinrule.advanced.RoomJoinRuleChooseRestrictedState
import im.vector.app.features.roomprofile.settings.joinrule.advanced.RoomJoinRuleChooseRestrictedViewModel
import javax.inject.Inject
@ -81,7 +87,13 @@ class RoomJoinRuleActivity : VectorBaseActivity<ActivitySimpleBinding>(),
views.simpleActivityWaitingView.isVisible = true
}
is Success -> {
finish()
withState(viewModel) { state ->
if (state.didSwitchToReplacementRoom) {
// we should navigate to new room
navigator.openRoom(this, state.roomId, null, true)
}
finish()
}
}
is Fail -> {
views.simpleActivityWaitingView.isVisible = false
@ -89,6 +101,40 @@ class RoomJoinRuleActivity : VectorBaseActivity<ActivitySimpleBinding>(),
}
}
}
viewModel.observeViewEvents {
when (it) {
RoomJoinRuleChooseRestrictedEvents.NavigateToChooseRestricted -> navigateToChooseRestricted()
is RoomJoinRuleChooseRestrictedEvents.NavigateToUpgradeRoom -> navigateToUpgradeRoom(it)
}
}
supportFragmentManager.setFragmentResultListener(MigrateRoomBottomSheet.REQUEST_KEY, this) { _, bundle ->
bundle.getString(MigrateRoomBottomSheet.BUNDLE_KEY_REPLACEMENT_ROOM)?.let { replacementRoomId ->
viewModel.handle(RoomJoinRuleChooseRestrictedActions.SwitchToRoomAfterMigration(replacementRoomId))
}
}
}
private fun navigateToUpgradeRoom(events: RoomJoinRuleChooseRestrictedEvents.NavigateToUpgradeRoom) {
MigrateRoomBottomSheet.newInstance(
events.roomId,
events.toVersion,
MigrateRoomBottomSheet.MigrationReason.FOR_RESTRICTED,
events.description
).show(supportFragmentManager, "migrate")
}
private fun navigateToChooseRestricted() {
supportFragmentManager.commitTransaction {
setCustomAnimations(R.anim.fade_in, R.anim.fade_out, R.anim.fade_in, R.anim.fade_out)
val tag = RoomJoinRuleChooseRestrictedFragment::class.simpleName
replace(R.id.simpleFragmentContainer,
RoomJoinRuleChooseRestrictedFragment::class.java,
this@RoomJoinRuleActivity.roomProfileArgs.toMvRxBundle(),
tag
).addToBackStack(tag)
}
}
companion object {

View file

@ -27,7 +27,6 @@ import com.airbnb.mvrx.withState
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import im.vector.app.R
import im.vector.app.core.extensions.cleanup
import im.vector.app.core.extensions.commitTransaction
import im.vector.app.core.extensions.configureWith
import im.vector.app.core.platform.OnBackPressed
import im.vector.app.core.platform.VectorBaseFragment
@ -104,18 +103,6 @@ class RoomJoinRuleFragment @Inject constructor(
val isLoading = withState(viewModel) { it.updatingStatus is Loading }
if (isLoading) return
val oldRule = withState(viewModel) { it.currentRoomJoinRules }
viewModel.handle(RoomJoinRuleChooseRestrictedActions.SelectJoinRules(rules))
if (rules == RoomJoinRules.RESTRICTED && oldRule == RoomJoinRules.RESTRICTED) {
parentFragmentManager.commitTransaction {
setCustomAnimations(R.anim.fade_in, R.anim.fade_out, R.anim.fade_in, R.anim.fade_out)
val tag = RoomJoinRuleChooseRestrictedFragment::class.simpleName
replace(R.id.simpleFragmentContainer,
RoomJoinRuleChooseRestrictedFragment::class.java,
this@RoomJoinRuleFragment.arguments,
tag
).addToBackStack(tag)
}
}
}
}

View file

@ -28,6 +28,7 @@ import im.vector.app.core.epoxy.ClickListener
import im.vector.app.core.epoxy.VectorEpoxyHolder
import im.vector.app.core.epoxy.VectorEpoxyModel
import im.vector.app.core.epoxy.onClick
import im.vector.app.core.utils.DebouncedClickListener
import im.vector.app.features.home.AvatarRenderer
import org.matrix.android.sdk.api.util.MatrixItem
@ -53,6 +54,7 @@ abstract class SpaceJoinRuleItem : VectorEpoxyModel<SpaceJoinRuleItem.Holder>()
super.bind(holder)
holder.view.onClick(listener)
holder.upgradeRequiredButton.setOnClickListener(DebouncedClickListener(listener))
if (selected) {
holder.radioImage.setImageDrawable(ContextCompat.getDrawable(holder.view.context, R.drawable.ic_radio_on))
@ -67,19 +69,24 @@ abstract class SpaceJoinRuleItem : VectorEpoxyModel<SpaceJoinRuleItem.Holder>()
val items = listOf(holder.space1, holder.space2, holder.space3, holder.space4, holder.space5)
holder.spaceMore.isVisible = false
if (restrictedList.isEmpty()) {
holder.listTitle.isVisible = false
items.onEach { it.isVisible = false }
} else {
holder.listTitle.isVisible = true
restrictedList.forEachIndexed { index, matrixItem ->
if (index < items.size) {
items[index].isVisible = true
avatarRenderer.render(matrixItem, items[index])
} else if (index == items.size) {
holder.spaceMore.isVisible = true
items.onEach { it.isVisible = false }
if (!needUpgrade) {
if (restrictedList.isEmpty()) {
holder.listTitle.isVisible = false
} else {
holder.listTitle.isVisible = true
restrictedList.forEachIndexed { index, matrixItem ->
if (index < items.size) {
items[index].isVisible = true
avatarRenderer.render(matrixItem, items[index])
} else if (index == items.size) {
holder.spaceMore.isVisible = true
}
}
}
} else {
holder.listTitle.isVisible = false
holder.helperText.isVisible = false
}
}

View file

@ -25,4 +25,5 @@ sealed class RoomJoinRuleChooseRestrictedActions : VectorViewModelAction {
data class ToggleSelection(val matrixItem: MatrixItem) : RoomJoinRuleChooseRestrictedActions()
data class SelectJoinRules(val rules: RoomJoinRules) : RoomJoinRuleChooseRestrictedActions()
object DoUpdateJoinRules : RoomJoinRuleChooseRestrictedActions()
data class SwitchToRoomAfterMigration(val roomId: String) : RoomJoinRuleChooseRestrictedActions()
}

View file

@ -18,4 +18,7 @@ package im.vector.app.features.roomprofile.settings.joinrule.advanced
import im.vector.app.core.platform.VectorViewEvents
sealed class RoomJoinRuleChooseRestrictedEvents : VectorViewEvents
sealed class RoomJoinRuleChooseRestrictedEvents : VectorViewEvents {
object NavigateToChooseRestricted : RoomJoinRuleChooseRestrictedEvents()
data class NavigateToUpgradeRoom(val roomId: String, val toVersion: String, val description: CharSequence) : RoomJoinRuleChooseRestrictedEvents()
}

View file

@ -40,7 +40,11 @@ data class RoomJoinRuleChooseRestrictedState(
val filter: String = "",
val filteredResults: Async<List<MatrixItem>> = Uninitialized,
val hasUnsavedChanges: Boolean = false,
val updatingStatus: Async<Unit> = Uninitialized
val updatingStatus: Async<Unit> = Uninitialized,
val upgradeNeededForRestricted: Boolean = false,
val restrictedSupportedByThisVersion: Boolean = false,
val restrictedVersionNeeded: String? = null,
val didSwitchToReplacementRoom: Boolean = false
) : MvRxState {
constructor(args: RoomProfileArgs) : this(roomId = args.roomId)
}

View file

@ -16,6 +16,8 @@
package im.vector.app.features.roomprofile.settings.joinrule.advanced
import android.graphics.Typeface
import androidx.core.text.toSpannable
import androidx.lifecycle.viewModelScope
import com.airbnb.mvrx.ActivityViewModelContext
import com.airbnb.mvrx.Fail
@ -23,12 +25,16 @@ import com.airbnb.mvrx.FragmentViewModelContext
import com.airbnb.mvrx.Loading
import com.airbnb.mvrx.MvRxViewModelFactory
import com.airbnb.mvrx.Success
import com.airbnb.mvrx.Uninitialized
import com.airbnb.mvrx.ViewModelContext
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import im.vector.app.R
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.styleMatchingText
import im.vector.app.features.roomprofile.settings.joinrule.toOption
import im.vector.app.features.settings.VectorPreferences
import kotlinx.coroutines.launch
@ -46,92 +52,100 @@ import org.matrix.android.sdk.api.util.MatrixItem
import org.matrix.android.sdk.api.util.toMatrixItem
class RoomJoinRuleChooseRestrictedViewModel @AssistedInject constructor(
@Assisted val initialState: RoomJoinRuleChooseRestrictedState,
@Assisted initialState: RoomJoinRuleChooseRestrictedState,
private val session: Session,
private val vectorPreferences: VectorPreferences
private val vectorPreferences: VectorPreferences,
private val stringProvider: StringProvider
) : VectorViewModel<RoomJoinRuleChooseRestrictedState, RoomJoinRuleChooseRestrictedActions, RoomJoinRuleChooseRestrictedEvents>(initialState) {
val room = session.getRoom(initialState.roomId)!!
var room = session.getRoom(initialState.roomId)!!
init {
viewModelScope.launch {
session.getRoomSummary(initialState.roomId)?.let { roomSummary ->
val joinRulesContent = session.getRoom(initialState.roomId)?.getStateEvent(EventType.STATE_ROOM_JOIN_RULES, QueryStringValue.NoCondition)
?.content
?.toModel<RoomJoinRulesContent>()
val initialAllowList = joinRulesContent?.allowList
initializeForRoom(initialState.roomId)
}
}
val knownParentSpacesAllowed = mutableListOf<MatrixItem>()
val unknownAllowedOrRooms = mutableListOf<MatrixItem>()
initialAllowList.orEmpty().forEach { entry ->
val summary = session.getRoomSummary(entry.spaceID)
if (summary == null // it's not known by me
|| summary.roomType != RoomType.SPACE // it's not a space
|| !roomSummary.flattenParentIds.contains(summary.roomId) // it's not a parent space
) {
unknownAllowedOrRooms.add(
summary?.toMatrixItem() ?: MatrixItem.RoomItem(entry.spaceID, null, null)
)
} else {
knownParentSpacesAllowed.add(summary.toMatrixItem())
}
}
private fun initializeForRoom(roomId: String) {
room = session.getRoom(roomId)!!
session.getRoomSummary(roomId)?.let { roomSummary ->
val joinRulesContent = room.getStateEvent(EventType.STATE_ROOM_JOIN_RULES, QueryStringValue.NoCondition)
?.content
?.toModel<RoomJoinRulesContent>()
val initialAllowList = joinRulesContent?.allowList
val possibleSpaceCandidate = knownParentSpacesAllowed.toMutableList()
roomSummary.flattenParentIds.mapNotNull {
session.getRoomSummary(it)?.toMatrixItem()
}.forEach {
if (!possibleSpaceCandidate.contains(it)) {
possibleSpaceCandidate.add(it)
}
}
val homeServerCapabilities = session.getHomeServerCapabilities()
var safeRule: RoomJoinRules = joinRulesContent?.joinRules ?: RoomJoinRules.INVITE
// server is not really checking that, just to be sure let's check
val restrictedSupportedByThisVersion = homeServerCapabilities
.isFeatureSupported(HomeServerCapabilities.ROOM_CAP_RESTRICTED, room.getRoomVersion())
if (safeRule == RoomJoinRules.RESTRICTED
&& !restrictedSupportedByThisVersion) {
safeRule = RoomJoinRules.INVITE
}
val restrictedSupport = homeServerCapabilities.isFeatureSupported(HomeServerCapabilities.ROOM_CAP_RESTRICTED)
val couldUpgradeToRestricted = when (restrictedSupport) {
HomeServerCapabilities.RoomCapabilitySupport.SUPPORTED -> true
HomeServerCapabilities.RoomCapabilitySupport.SUPPORTED_UNSTABLE -> vectorPreferences.labsUseExperimentalRestricted()
else -> false
}
val choices = if (restrictedSupportedByThisVersion || couldUpgradeToRestricted) {
listOf(
RoomJoinRules.INVITE.toOption(false),
RoomJoinRules.RESTRICTED.toOption(!restrictedSupportedByThisVersion),
RoomJoinRules.PUBLIC.toOption(false)
val knownParentSpacesAllowed = mutableListOf<MatrixItem>()
val unknownAllowedOrRooms = mutableListOf<MatrixItem>()
initialAllowList.orEmpty().forEach { entry ->
val summary = session.getRoomSummary(entry.spaceID)
if (summary == null // it's not known by me
|| summary.roomType != RoomType.SPACE // it's not a space
|| !roomSummary.flattenParentIds.contains(summary.roomId) // it's not a parent space
) {
unknownAllowedOrRooms.add(
summary?.toMatrixItem() ?: MatrixItem.RoomItem(entry.spaceID, null, null)
)
} else {
listOf(
RoomJoinRules.INVITE.toOption(false),
RoomJoinRules.PUBLIC.toOption(false)
)
knownParentSpacesAllowed.add(summary.toMatrixItem())
}
}
setState {
copy(
roomSummary = Success(roomSummary),
initialRoomJoinRules = safeRule,
currentRoomJoinRules = safeRule,
choices = choices,
initialAllowList = initialAllowList.orEmpty(),
updatedAllowList = initialAllowList.orEmpty().map {
session.getRoomSummary(it.spaceID)?.toMatrixItem() ?: MatrixItem.RoomItem(it.spaceID, null, null)
},
possibleSpaceCandidate = possibleSpaceCandidate,
unknownRestricted = unknownAllowedOrRooms
)
val possibleSpaceCandidate = knownParentSpacesAllowed.toMutableList()
roomSummary.flattenParentIds.mapNotNull {
session.getRoomSummary(it)?.toMatrixItem()
}.forEach {
if (!possibleSpaceCandidate.contains(it)) {
possibleSpaceCandidate.add(it)
}
}
val homeServerCapabilities = session.getHomeServerCapabilities()
var safeRule: RoomJoinRules = joinRulesContent?.joinRules ?: RoomJoinRules.INVITE
// server is not really checking that, just to be sure let's check
val restrictedSupportedByThisVersion = homeServerCapabilities
.isFeatureSupported(HomeServerCapabilities.ROOM_CAP_RESTRICTED, room.getRoomVersion())
if (safeRule == RoomJoinRules.RESTRICTED
&& !restrictedSupportedByThisVersion) {
safeRule = RoomJoinRules.INVITE
}
val restrictedSupport = homeServerCapabilities.isFeatureSupported(HomeServerCapabilities.ROOM_CAP_RESTRICTED)
val couldUpgradeToRestricted = when (restrictedSupport) {
HomeServerCapabilities.RoomCapabilitySupport.SUPPORTED -> true
HomeServerCapabilities.RoomCapabilitySupport.SUPPORTED_UNSTABLE -> vectorPreferences.labsUseExperimentalRestricted()
else -> false
}
val choices = if (restrictedSupportedByThisVersion || couldUpgradeToRestricted) {
listOf(
RoomJoinRules.INVITE.toOption(false),
RoomJoinRules.RESTRICTED.toOption(!restrictedSupportedByThisVersion),
RoomJoinRules.PUBLIC.toOption(false)
)
} else {
listOf(
RoomJoinRules.INVITE.toOption(false),
RoomJoinRules.PUBLIC.toOption(false)
)
}
setState {
copy(
roomSummary = Success(roomSummary),
initialRoomJoinRules = safeRule,
currentRoomJoinRules = safeRule,
choices = choices,
initialAllowList = initialAllowList.orEmpty(),
updatedAllowList = initialAllowList.orEmpty().map {
session.getRoomSummary(it.spaceID)?.toMatrixItem() ?: MatrixItem.RoomItem(it.spaceID, null, null)
},
possibleSpaceCandidate = possibleSpaceCandidate,
unknownRestricted = unknownAllowedOrRooms,
restrictedSupportedByThisVersion = restrictedSupportedByThisVersion,
upgradeNeededForRestricted = !restrictedSupportedByThisVersion && couldUpgradeToRestricted,
restrictedVersionNeeded = homeServerCapabilities.versionOverrideForFeature(HomeServerCapabilities.ROOM_CAP_RESTRICTED)
)
}
}
}
@ -163,10 +177,11 @@ class RoomJoinRuleChooseRestrictedViewModel @AssistedInject constructor(
override fun handle(action: RoomJoinRuleChooseRestrictedActions) {
when (action) {
is RoomJoinRuleChooseRestrictedActions.FilterWith -> handleFilter(action)
is RoomJoinRuleChooseRestrictedActions.ToggleSelection -> handleToggleSelection(action)
is RoomJoinRuleChooseRestrictedActions.SelectJoinRules -> handleSelectRule(action)
RoomJoinRuleChooseRestrictedActions.DoUpdateJoinRules -> handleSubmit()
is RoomJoinRuleChooseRestrictedActions.FilterWith -> handleFilter(action)
is RoomJoinRuleChooseRestrictedActions.ToggleSelection -> handleToggleSelection(action)
is RoomJoinRuleChooseRestrictedActions.SelectJoinRules -> handleSelectRule(action)
is RoomJoinRuleChooseRestrictedActions.SwitchToRoomAfterMigration -> handleSwitchToRoom(action)
RoomJoinRuleChooseRestrictedActions.DoUpdateJoinRules -> handleSubmit()
}.exhaustive
checkForChanges()
}
@ -193,14 +208,43 @@ class RoomJoinRuleChooseRestrictedViewModel @AssistedInject constructor(
}
fun handleSelectRule(action: RoomJoinRuleChooseRestrictedActions.SelectJoinRules) = withState { state ->
if (action.rules == RoomJoinRules.RESTRICTED && state.currentRoomJoinRules != RoomJoinRules.RESTRICTED) {
val currentRoomJoinRules = state.currentRoomJoinRules
val candidate = session.getRoomSummary(state.roomId)
?.flattenParentIds
?.filter {
session.getRoomSummary(it)?.spaceChildren?.firstOrNull { it.childRoomId == state.roomId } != null
}?.mapNotNull {
session.getRoomSummary(it)?.toMatrixItem()
}?.firstOrNull()
val description = if (candidate != null) {
stringProvider.getString(R.string.upgrade_room_for_restricted, candidate.getBestName()).toSpannable().let {
it.styleMatchingText(candidate.getBestName(), Typeface.BOLD)
}
} else {
stringProvider.getString(R.string.upgrade_room_for_restricted_no_param)
}
if (action.rules == RoomJoinRules.RESTRICTED && state.upgradeNeededForRestricted) {
// let's show the room upgrade bottom sheet
_viewEvents.post(
RoomJoinRuleChooseRestrictedEvents.NavigateToUpgradeRoom(
state.roomId,
state.restrictedVersionNeeded ?: "",
description
)
)
return@withState
}
if (action.rules == RoomJoinRules.RESTRICTED && currentRoomJoinRules != RoomJoinRules.RESTRICTED) {
// switching to restricted
// if allow list is empty, then default to current space parents
if (state.updatedAllowList.isEmpty()) {
val candidates = session.getRoomSummary(initialState.roomId)
val candidates = session.getRoomSummary(state.roomId)
?.flattenParentIds
?.filter {
session.getRoomSummary(it)?.spaceChildren?.firstOrNull { it.childRoomId == initialState.roomId } != null
session.getRoomSummary(it)?.spaceChildren?.firstOrNull { it.childRoomId == state.roomId } != null
}?.mapNotNull {
session.getRoomSummary(it)?.toMatrixItem()
}.orEmpty()
@ -215,6 +259,48 @@ class RoomJoinRuleChooseRestrictedViewModel @AssistedInject constructor(
currentRoomJoinRules = action.rules
)
}
if (action.rules == RoomJoinRules.RESTRICTED && currentRoomJoinRules == RoomJoinRules.RESTRICTED) {
_viewEvents.post(RoomJoinRuleChooseRestrictedEvents.NavigateToChooseRestricted)
}
}
private fun handleSwitchToRoom(action: RoomJoinRuleChooseRestrictedActions.SwitchToRoomAfterMigration) = withState { state ->
viewModelScope.launch {
val oldRoomSummary = session.getRoomSummary(state.roomId)
val replacementRoomSummary = session.getRoomSummary(action.roomId)
setState {
copy(
roomId = action.roomId,
roomSummary = replacementRoomSummary?.let { Success(it) } ?: Uninitialized,
didSwitchToReplacementRoom = true
)
}
initializeForRoom(action.roomId)
// set as restricted now
val candidates = oldRoomSummary
?.flattenParentIds
?.filter {
session.getRoomSummary(it)?.spaceChildren?.firstOrNull { it.childRoomId == state.roomId } != null
}?.mapNotNull {
session.getRoomSummary(it)?.toMatrixItem()
}.orEmpty()
setState {
copy(
currentRoomJoinRules = RoomJoinRules.RESTRICTED,
updatedAllowList = candidates
)
}
setState { copy(updatingStatus = Loading()) }
viewModelScope.launch {
try {
room.setJoinRuleRestricted(candidates.map { it.id })
setState { copy(updatingStatus = Success(Unit)) }
} catch (failure: Throwable) {
setState { copy(updatingStatus = Fail(failure)) }
}
}
}
}
private fun handleToggleSelection(action: RoomJoinRuleChooseRestrictedActions.ToggleSelection) = withState { state ->
@ -261,7 +347,7 @@ class RoomJoinRuleChooseRestrictedViewModel @AssistedInject constructor(
}
}
private fun handleFilter(action: RoomJoinRuleChooseRestrictedActions.FilterWith) {
private fun handleFilter(action: RoomJoinRuleChooseRestrictedActions.FilterWith) = withState { state ->
setState {
copy(filter = action.filter, filteredResults = Loading())
}
@ -283,7 +369,7 @@ class RoomJoinRuleChooseRestrictedViewModel @AssistedInject constructor(
setState {
copy(
filteredResults = Success(
session.getRoomSummary(initialState.roomId)?.flattenParentIds?.mapNotNull {
session.getRoomSummary(state.roomId)?.flattenParentIds?.mapNotNull {
session.getRoomSummary(it)?.toMatrixItem()
}?.filter {
it.displayName?.contains(filter, true) == true

View file

@ -3475,4 +3475,9 @@
<string name="error_voice_message_unable_to_record">Cannot record a voice message</string>
<string name="error_voice_message_cannot_reply_or_edit">Cannot reply or edit while voice message is active</string>
<string name="voice_message_reply_content">Voice Message (%1$s)</string>
<string name="upgrade_room_for_restricted">Anyone in %s will be able to find and join this room - no need to manually invite everyone. Youll be able to change this in room settings anytime.</string>
<string name="upgrade_room_for_restricted_no_param">Anyone in a parent space will be able to find and join this room - no need to manually invite everyone. Youll be able to change this in room settings anytime.</string>
<string name="upgrade_room_for_restricted_note">Please note upgrading will make a new version of the room. All current messages will stay in this archived room.</string>
</resources>