From 3da20aea2907bd928b3ed9a5c202ffdde02f0e67 Mon Sep 17 00:00:00 2001 From: Valere Date: Fri, 9 Jul 2021 14:24:13 +0200 Subject: [PATCH] Cleaning --- .../settings/joinrule/RoomJoinRuleActivity.kt | 11 +- .../joinrule/RoomJoinRuleAdvancedViewModel.kt | 191 ------------------ .../settings/joinrule/RoomJoinRuleFragment.kt | 72 +++---- .../advanced/ChooseRestrictedController.kt | 17 +- .../RoomJoinRuleChooseRestrictedActions.kt | 6 +- .../RoomJoinRuleChooseRestrictedFragment.kt | 10 +- .../RoomJoinRuleChooseRestrictedState.kt | 6 +- .../RoomJoinRuleChooseRestrictedViewModel.kt | 71 +++++-- .../layout/fragment_join_rules_recycler.xml | 2 + 9 files changed, 114 insertions(+), 272 deletions(-) delete mode 100644 vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/RoomJoinRuleAdvancedViewModel.kt diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/RoomJoinRuleActivity.kt b/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/RoomJoinRuleActivity.kt index f152352330..6fb7381349 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/RoomJoinRuleActivity.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/RoomJoinRuleActivity.kt @@ -27,6 +27,7 @@ import im.vector.app.databinding.ActivitySimpleBinding import im.vector.app.features.roomprofile.RoomProfileArgs import im.vector.app.features.roomprofile.settings.joinrule.advanced.RoomJoinRuleChooseRestrictedState import im.vector.app.features.roomprofile.settings.joinrule.advanced.RoomJoinRuleChooseRestrictedViewModel +import javax.inject.Inject class RoomJoinRuleActivity : VectorBaseActivity(), RoomJoinRuleChooseRestrictedViewModel.Factory { @@ -35,13 +36,15 @@ class RoomJoinRuleActivity : VectorBaseActivity(), private lateinit var roomProfileArgs: RoomProfileArgs - private lateinit var allowListViewModelFactory: RoomJoinRuleChooseRestrictedViewModel.Factory + @Inject + lateinit var allowListViewModelFactory: RoomJoinRuleChooseRestrictedViewModel.Factory override fun create(initialState: RoomJoinRuleChooseRestrictedState) = allowListViewModelFactory.create(initialState) override fun injectWith(injector: ScreenComponent) { - injector.inject(this) + injector.inject(this) } + override fun initUiAndData() { roomProfileArgs = intent?.extras?.getParcelable(MvRx.KEY_ARG) ?: return if (isFirstCreation()) { @@ -52,10 +55,6 @@ class RoomJoinRuleActivity : VectorBaseActivity(), ) } } -// -// override fun onBackPressed() { -// super.onBackPressed() -// } companion object { diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/RoomJoinRuleAdvancedViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/RoomJoinRuleAdvancedViewModel.kt deleted file mode 100644 index bf74d4f45e..0000000000 --- a/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/RoomJoinRuleAdvancedViewModel.kt +++ /dev/null @@ -1,191 +0,0 @@ -/* - * 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.roomprofile.settings.joinrule - -import com.airbnb.mvrx.ActivityViewModelContext -import com.airbnb.mvrx.Async -import com.airbnb.mvrx.FragmentViewModelContext -import com.airbnb.mvrx.MvRxState -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.core.platform.VectorViewEvents -import im.vector.app.core.platform.VectorViewModel -import im.vector.app.core.platform.VectorViewModelAction -import im.vector.app.features.roomprofile.RoomProfileArgs -import im.vector.app.features.settings.VectorPreferences -import org.matrix.android.sdk.api.query.QueryStringValue -import org.matrix.android.sdk.api.session.Session -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.homeserver.HomeServerCapabilities -import org.matrix.android.sdk.api.session.room.model.RoomJoinRules -import org.matrix.android.sdk.api.session.room.model.RoomJoinRulesContent -import org.matrix.android.sdk.api.session.room.model.RoomSummary -import org.matrix.android.sdk.api.util.MatrixItem -import org.matrix.android.sdk.api.util.toMatrixItem -import org.matrix.android.sdk.rx.mapOptional -import org.matrix.android.sdk.rx.rx -import org.matrix.android.sdk.rx.unwrap - -data class RoomJoinRuleAdvancedState( - val roomId: String, - val summary: RoomSummary? = null, - val currentRoomJoinRules: RoomJoinRules? = null, - val initialAllowList: List? = null, - val updatedAllowList: List? = null, - val choices: Async> = Uninitialized -) : MvRxState { - constructor(args: RoomProfileArgs) : this(roomId = args.roomId) -} - -sealed class RoomJoinRuleAdvancedAction : VectorViewModelAction { - data class SelectJoinRules(val rules: RoomJoinRules) : RoomJoinRuleAdvancedAction() - data class UpdateAllowList(val roomIds: List) : RoomJoinRuleAdvancedAction() -} - -sealed class RoomJoinRuleAdvancedEvents : VectorViewEvents { - object SelectAllowList : RoomJoinRuleAdvancedEvents() -} - -class RoomJoinRuleAdvancedViewModel @AssistedInject constructor( - @Assisted val initialState: RoomJoinRuleAdvancedState, - private val session: Session, - private val vectorPreferences: VectorPreferences -) : VectorViewModel(initialState) { - - private val room = session.getRoom(initialState.roomId)!! - private val homeServerCapabilities = session.getHomeServerCapabilities() - - @AssistedFactory - interface Factory { - fun create(initialState: RoomJoinRuleAdvancedState): RoomJoinRuleAdvancedViewModel - } - - companion object : MvRxViewModelFactory { - - override fun create(viewModelContext: ViewModelContext, state: RoomJoinRuleAdvancedState): RoomJoinRuleAdvancedViewModel? { - val factory = when (viewModelContext) { - is FragmentViewModelContext -> viewModelContext.fragment as? Factory - is ActivityViewModelContext -> viewModelContext.activity as? Factory - } - return factory?.create(state) ?: error("You should let your activity/fragment implements Factory interface") - } - } - - init { - - val initialAllowList = session.getRoom(initialState.roomId)?.getStateEvent(EventType.STATE_ROOM_JOIN_RULES, QueryStringValue.NoCondition) - ?.content - ?.toModel() - ?.allowList - - setState { - val initialAllowItems = initialAllowList.orEmpty().map { - session.getRoomSummary(it.spaceID)?.toMatrixItem() - ?: MatrixItem.RoomItem(it.spaceID, null, null) - } - copy( - summary = session.getRoomSummary(initialState.roomId), - initialAllowList = initialAllowItems, - updatedAllowList = initialAllowItems - ) - } - - // TODO shouldn't be live - room.rx() - .liveStateEvent(EventType.STATE_ROOM_JOIN_RULES, QueryStringValue.NoCondition) - .mapOptional { it.content.toModel() } - .unwrap() - .subscribe { content -> - - content.joinRules?.let { - var safeRule: RoomJoinRules = it - // server is not really checking that, just to be sure let's check - val restrictedSupportedByThisVersion = homeServerCapabilities - .isFeatureSupported(HomeServerCapabilities.ROOM_CAP_RESTRICTED, room.getRoomVersion()) - if (it == RoomJoinRules.RESTRICTED - && !restrictedSupportedByThisVersion) { - safeRule = RoomJoinRules.INVITE - } - val allowList = if (safeRule == RoomJoinRules.RESTRICTED) content.allowList else null - - 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( - currentRoomJoinRules = safeRule, - choices = Success(choices) - ) - } - } - } - .disposeOnClear() - } - - override fun handle(action: RoomJoinRuleAdvancedAction) { - when (action) { - is RoomJoinRuleAdvancedAction.SelectJoinRules -> handleSelectRule(action) - is RoomJoinRuleAdvancedAction.UpdateAllowList -> handleUpdateAllowList(action) - } - } - - fun handleUpdateAllowList(action: RoomJoinRuleAdvancedAction.UpdateAllowList) = withState { state -> - setState { - copy( - updatedAllowList = action.roomIds.map { - session.getRoomSummary(it)?.toMatrixItem() ?: MatrixItem.RoomItem(it, null, null) - } - ) - } - } - - fun handleSelectRule(action: RoomJoinRuleAdvancedAction.SelectJoinRules) = withState { state -> - - if (action.rules == RoomJoinRules.RESTRICTED) { - // open space select? - _viewEvents.post(RoomJoinRuleAdvancedEvents.SelectAllowList) - } - setState { - copy( - currentRoomJoinRules = action.rules - ) - } - } -} diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/RoomJoinRuleFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/RoomJoinRuleFragment.kt index 7ad78eeb9a..3e00c3f564 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/RoomJoinRuleFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/RoomJoinRuleFragment.kt @@ -20,25 +20,26 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.core.view.isVisible import com.airbnb.mvrx.activityViewModel import com.airbnb.mvrx.withState 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 import im.vector.app.databinding.FragmentJoinRulesRecyclerBinding import im.vector.app.features.home.AvatarRenderer +import im.vector.app.features.roomprofile.settings.joinrule.advanced.RoomJoinRuleChooseRestrictedActions import im.vector.app.features.roomprofile.settings.joinrule.advanced.RoomJoinRuleChooseRestrictedViewModel import org.matrix.android.sdk.api.session.room.model.RoomJoinRules import javax.inject.Inject class RoomJoinRuleFragment @Inject constructor( val controller: RoomJoinRuleAdvancedController, -// val viewModelFactory: RoomJoinRuleAdvancedViewModel.Factory, val avatarRenderer: AvatarRenderer ) : VectorBaseFragment(), -// RoomJoinRuleAdvancedViewModel.Factory, OnBackPressed, RoomJoinRuleAdvancedController.InteractionListener { private val viewModel: RoomJoinRuleChooseRestrictedViewModel by activityViewModel() @@ -48,54 +49,55 @@ class RoomJoinRuleFragment @Inject constructor( override fun onBackPressed(toolbarButton: Boolean): Boolean { // TODO - requireActivity().finish() + val hasUnsavedChanges = withState(viewModel) { it.hasUnsavedChanges } + if (!hasUnsavedChanges) { + requireActivity().finish() + } return true } override fun invalidate() = withState(viewModel) { state -> super.invalidate() controller.setData(state) + if (state.hasUnsavedChanges) { + // show discard and save + views.cancelButton.isVisible = true + views.positiveButton.text = getString(R.string.warning_unsaved_change_discard) + views.positiveButton.isVisible = true + views.positiveButton.text = getString(R.string.save) + } else { + views.cancelButton.isVisible = false + views.positiveButton.isVisible = true + views.positiveButton.text = getString(R.string.ok) + views.positiveButton.debouncedClicks { requireActivity().finish() } + } } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) -// roomProfileSharedActionViewModel = activityViewModelProvider.get(RoomProfileSharedActionViewModel::class.java) -// setupRoomHistoryVisibilitySharedActionViewModel() -// setupRoomJoinRuleSharedActionViewModel() -// controller.callback = this views.genericRecyclerView.configureWith(controller, hasFixedSize = true) controller.interactionListener = this -// views.waitingView.waitingStatusText.setText(R.string.please_wait) -// views.waitingView.waitingStatusText.isVisible = true + views.cancelButton.debouncedClicks { requireActivity().finish() } + } -// // Use the Kotlin extension in the fragment-ktx artifact -// setFragmentResultListener("SelectAllowList") { requestKey, bundle -> -// // We use a String here, but any type that can be put in a Bundle is supported -// bundle.getStringArrayList("bundleKey")?.toList()?.let { -// viewModel.handle(RoomJoinRuleAdvancedAction.UpdateAllowList(it)) -// } -// } + override fun onDestroyView() { + views.genericRecyclerView.cleanup() + super.onDestroyView() + } - viewModel.observeViewEvents { - when (it) { - RoomJoinRuleAdvancedEvents.SelectAllowList -> { - 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) - } - } + override fun didSelectRule(rules: RoomJoinRules) { + 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) } } } - - override fun create(initialState: RoomJoinRuleAdvancedState) = viewModelFactory.create(initialState) - - override fun didSelectRule(rules: RoomJoinRules) { - viewModel.handle(RoomJoinRuleAdvancedAction.SelectJoinRules(rules)) - } } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/advanced/ChooseRestrictedController.kt b/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/advanced/ChooseRestrictedController.kt index ed1a5eb2e0..2454307d95 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/advanced/ChooseRestrictedController.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/advanced/ChooseRestrictedController.kt @@ -53,14 +53,17 @@ class ChooseRestrictedController @Inject constructor( is Loading -> loadingItem { id("filter_load") } is Success -> { if (results.invoke().isEmpty()) { - noResultItem { id("empty") } + noResultItem { + id("empty") + text(host.stringProvider.getString(R.string.no_result_placeholder)) + } } else { results.invoke().forEach { matrixItem -> roomSelectionItem { id(matrixItem.id) matrixItem(matrixItem) avatarRenderer(host.avatarRenderer) - selected(data.selectedRoomList.firstOrNull { it == matrixItem.id } != null) + selected(data.updatedAllowList.firstOrNull { it.id == matrixItem.id } != null) itemClickListener { host.listener?.onItemSelected(matrixItem) } } } @@ -77,18 +80,12 @@ class ChooseRestrictedController @Inject constructor( centered(false) } -// val testList = mutableListOf() -// for(i in 0..20) { -// testList.addAll(data.knownSpaceParents) -// } -// testList - data.possibleSpaceCandidate.forEach { matrixItem -> roomSelectionItem { id(matrixItem.id) matrixItem(matrixItem) avatarRenderer(host.avatarRenderer) - selected(data.selectedRoomList.firstOrNull { it == matrixItem.id } != null) + selected(data.updatedAllowList.firstOrNull { it.id == matrixItem.id } != null) itemClickListener { host.listener?.onItemSelected(matrixItem) } } } @@ -105,7 +102,7 @@ class ChooseRestrictedController @Inject constructor( id(matrixItem.id) matrixItem(matrixItem) avatarRenderer(host.avatarRenderer) - selected(data.selectedRoomList.firstOrNull { it == matrixItem.id } != null) + selected(data.updatedAllowList.firstOrNull { it.id == matrixItem.id } != null) itemClickListener { host.listener?.onItemSelected(matrixItem) } } } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/advanced/RoomJoinRuleChooseRestrictedActions.kt b/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/advanced/RoomJoinRuleChooseRestrictedActions.kt index 6f9ecd6b06..909be4654d 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/advanced/RoomJoinRuleChooseRestrictedActions.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/advanced/RoomJoinRuleChooseRestrictedActions.kt @@ -17,9 +17,11 @@ package im.vector.app.features.roomprofile.settings.joinrule.advanced import im.vector.app.core.platform.VectorViewModelAction +import org.matrix.android.sdk.api.session.room.model.RoomJoinRules import org.matrix.android.sdk.api.util.MatrixItem sealed class RoomJoinRuleChooseRestrictedActions : VectorViewModelAction { - data class FilterWith(val filter: String): RoomJoinRuleChooseRestrictedActions() - data class ToggleSelection(val matrixItem: MatrixItem): RoomJoinRuleChooseRestrictedActions() + data class FilterWith(val filter: String) : RoomJoinRuleChooseRestrictedActions() + data class ToggleSelection(val matrixItem: MatrixItem) : RoomJoinRuleChooseRestrictedActions() + data class SelectJoinRules(val rules: RoomJoinRules) : RoomJoinRuleChooseRestrictedActions() } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/advanced/RoomJoinRuleChooseRestrictedFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/advanced/RoomJoinRuleChooseRestrictedFragment.kt index 82cb91fc92..6d5d9c1f30 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/advanced/RoomJoinRuleChooseRestrictedFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/advanced/RoomJoinRuleChooseRestrictedFragment.kt @@ -39,15 +39,11 @@ import javax.inject.Inject class RoomJoinRuleChooseRestrictedFragment @Inject constructor( val controller: ChooseRestrictedController, - // val viewModelFactory: RoomJoinRuleChooseRestrictedViewModel.Factory, val avatarRenderer: AvatarRenderer ) : VectorBaseFragment(), - // RoomJoinRuleChooseRestrictedViewModel.Factory, ChooseRestrictedController.Listener, OnBackPressed { - // override fun create(initialState: RoomJoinRuleChooseRestrictedState) = viewModelFactory.create(initialState) - private val viewModel: RoomJoinRuleChooseRestrictedViewModel by activityViewModel(RoomJoinRuleChooseRestrictedViewModel::class) override fun getBinding(inflater: LayoutInflater, container: ViewGroup?) = @@ -65,11 +61,7 @@ class RoomJoinRuleChooseRestrictedFragment @Inject constructor( .disposeOnDestroyView() views.okButton.debouncedClicks { -// withState(viewModel) { -// // let's return the updated selection list -// setFragmentResult("SelectAllowList", bundleOf("bundleKey" to it.selectedRoomList)) -// parentFragmentManager.popBackStack() -// } + parentFragmentManager.popBackStack() } } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/advanced/RoomJoinRuleChooseRestrictedState.kt b/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/advanced/RoomJoinRuleChooseRestrictedState.kt index 53635f2e4a..0d0b8eeef7 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/advanced/RoomJoinRuleChooseRestrictedState.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/advanced/RoomJoinRuleChooseRestrictedState.kt @@ -32,14 +32,14 @@ data class RoomJoinRuleChooseRestrictedState( val roomSummary: Async = Uninitialized, val initialRoomJoinRules: RoomJoinRules? = null, val currentRoomJoinRules: RoomJoinRules? = null, - val updatedAllowList: List? = null, + val updatedAllowList: List = emptyList(), val choices: List? = null, val initialAllowList: List = emptyList(), - val selectedRoomList: List = emptyList(), val possibleSpaceCandidate: List = emptyList(), val unknownRestricted: List = emptyList(), val filter: String = "", - val filteredResults: Async> = Uninitialized + val filteredResults: Async> = Uninitialized, + val hasUnsavedChanges: Boolean = false ) : MvRxState { constructor(args: RoomProfileArgs) : this(roomId = args.roomId) } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/advanced/RoomJoinRuleChooseRestrictedViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/advanced/RoomJoinRuleChooseRestrictedViewModel.kt index 83d8dcae95..c82bc75fba 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/advanced/RoomJoinRuleChooseRestrictedViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/advanced/RoomJoinRuleChooseRestrictedViewModel.kt @@ -127,7 +127,10 @@ class RoomJoinRuleChooseRestrictedViewModel @AssistedInject constructor( currentRoomJoinRules = safeRule, choices = choices, initialAllowList = initialAllowList.orEmpty(), - selectedRoomList = initialAllowList.orEmpty().map { it.spaceID }, + updatedAllowList = initialAllowList.orEmpty().map { + session.getRoomSummary(it.spaceID)?.toMatrixItem() ?: MatrixItem.RoomItem(it.spaceID, null, null) + }, +// selectedRoomList = initialAllowList.orEmpty().map { it.spaceID }, possibleSpaceCandidate = possibleSpaceCandidate, unknownRestricted = unknownAllowedOrRooms ) @@ -136,6 +139,27 @@ class RoomJoinRuleChooseRestrictedViewModel @AssistedInject constructor( } } + fun checkForChanges() = withState { state -> + if (state.initialRoomJoinRules != state.currentRoomJoinRules) { + setState { + copy(hasUnsavedChanges = true) + } + return@withState + } + + if (state.currentRoomJoinRules == RoomJoinRules.RESTRICTED) { + val allowDidChange = state.initialAllowList.map { it.spaceID } != state.updatedAllowList.map { it.id } + setState { + copy(hasUnsavedChanges = allowDidChange) + } + return@withState + } + + setState { + copy(hasUnsavedChanges = false) + } + } + @AssistedFactory interface Factory { fun create(initialState: RoomJoinRuleChooseRestrictedState): RoomJoinRuleChooseRestrictedViewModel @@ -145,35 +169,50 @@ class RoomJoinRuleChooseRestrictedViewModel @AssistedInject constructor( when (action) { is RoomJoinRuleChooseRestrictedActions.FilterWith -> handleFilter(action) is RoomJoinRuleChooseRestrictedActions.ToggleSelection -> handleToggleSelection(action) + is RoomJoinRuleChooseRestrictedActions.SelectJoinRules -> handleSelectRule(action) }.exhaustive + checkForChanges() + } + + fun handleSelectRule(action: RoomJoinRuleChooseRestrictedActions.SelectJoinRules) = withState { state -> + setState { + copy( + currentRoomJoinRules = action.rules + ) + } } private fun handleToggleSelection(action: RoomJoinRuleChooseRestrictedActions.ToggleSelection) = withState { state -> - val selection = state.selectedRoomList.toMutableList() - if (selection.contains(action.matrixItem.id)) { - selection.remove(action.matrixItem.id) + val selection = state.updatedAllowList.toMutableList() + if (selection.indexOfFirst { action.matrixItem.id == it.id } != -1) { + selection.removeAll { it.id == action.matrixItem.id } } else { - selection.add(action.matrixItem.id) + selection.add(action.matrixItem) } val unknownAllowedOrRooms = mutableListOf() // we would like to keep initial allowed here to show them unchecked // to make it easier for users to spot the changes - state.initialAllowList.map { it.spaceID }.union(selection).sorted().forEach { entry -> - val summary = session.getRoomSummary(entry) + val union = mutableListOf().apply { + addAll( + state.initialAllowList.map { + session.getRoomSummary(it.spaceID)?.toMatrixItem() ?: MatrixItem.RoomItem(it.spaceID, null, null) + } + ) + addAll(selection) + }.distinctBy { it.id }.sortedBy { it.id } + + union.forEach { entry -> + val summary = session.getRoomSummary(entry.id) if (summary == null) { unknownAllowedOrRooms.add( - MatrixItem.RoomItem(entry, null, null) + entry ) } else if (summary.roomType != RoomType.SPACE) { - unknownAllowedOrRooms.add( - summary.toMatrixItem() - ) - } else if (!state.roomSummary.invoke()!!.flattenParentIds.contains(entry)) { + unknownAllowedOrRooms.add(entry) + } else if (!state.roomSummary.invoke()!!.flattenParentIds.contains(entry.id)) { // it's a space but not a direct parent - unknownAllowedOrRooms.add( - summary.toMatrixItem() - ) + unknownAllowedOrRooms.add(entry) } else { // nop } @@ -181,7 +220,7 @@ class RoomJoinRuleChooseRestrictedViewModel @AssistedInject constructor( setState { copy( - selectedRoomList = selection.toList(), + updatedAllowList = selection.toList(), unknownRestricted = unknownAllowedOrRooms ) } diff --git a/vector/src/main/res/layout/fragment_join_rules_recycler.xml b/vector/src/main/res/layout/fragment_join_rules_recycler.xml index 832e292659..22b37274a5 100644 --- a/vector/src/main/res/layout/fragment_join_rules_recycler.xml +++ b/vector/src/main/res/layout/fragment_join_rules_recycler.xml @@ -31,6 +31,7 @@ app:layout_constraintTop_toBottomOf="@id/genericRecyclerView">