mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2025-03-18 04:08:44 +03:00
handle migration before setting restricted
This commit is contained in:
parent
2f16a7fff3
commit
c9ef08d8a9
11 changed files with 296 additions and 118 deletions
|
@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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
|
||||
)
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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. You’ll 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. You’ll 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>
|
||||
|
|
Loading…
Add table
Reference in a new issue