From e8d01becfe89b03d6d527a1b14d45db6340d0c9a Mon Sep 17 00:00:00 2001 From: Valere Date: Tue, 20 Jul 2021 10:36:44 +0200 Subject: [PATCH] Code review --- .../vector/app/features/home/HomeActivity.kt | 50 ++++------ .../home/PromoteRestrictedViewModel.kt | 92 +++++++++++++++++++ .../spaces/RestrictedPromoBottomSheet.kt | 11 +-- ...ottom_sheet_space_advertise_restricted.xml | 2 +- 4 files changed, 117 insertions(+), 38 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/features/home/PromoteRestrictedViewModel.kt diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt index 4bce697073..6786c1d2b0 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt @@ -33,7 +33,6 @@ import com.google.android.material.appbar.MaterialToolbar import com.google.android.material.dialog.MaterialAlertDialogBuilder import im.vector.app.AppStateHandler import im.vector.app.R -import im.vector.app.RoomGroupingMethod import im.vector.app.core.di.ActiveSessionHolder import im.vector.app.core.di.ScreenComponent import im.vector.app.core.extensions.exhaustive @@ -71,13 +70,8 @@ import im.vector.app.features.workers.signout.ServerBackupStatusViewState import im.vector.app.push.fcm.FcmHelper import io.reactivex.android.schedulers.AndroidSchedulers import kotlinx.parcelize.Parcelize -import org.matrix.android.sdk.api.query.QueryStringValue -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.initsync.InitialSyncProgressService import org.matrix.android.sdk.api.session.permalinks.PermalinkService -import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent -import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper import org.matrix.android.sdk.api.util.MatrixItem import org.matrix.android.sdk.internal.session.sync.InitialSyncStrategy import org.matrix.android.sdk.internal.session.sync.initialSyncStrategy @@ -96,6 +90,7 @@ class HomeActivity : UnknownDeviceDetectorSharedViewModel.Factory, ServerBackupStatusViewModel.Factory, UnreadMessagesSharedViewModel.Factory, + PromoteRestrictedViewModel.Factory, NavigationInterceptor, SpaceInviteBottomSheet.InteractionListener { @@ -106,6 +101,8 @@ class HomeActivity : private val serverBackupStatusViewModel: ServerBackupStatusViewModel by viewModel() @Inject lateinit var serverBackupviewModelFactory: ServerBackupStatusViewModel.Factory + @Inject lateinit var promoteRestrictedViewModelFactory: PromoteRestrictedViewModel.Factory + private val promoteRestrictedViewModel: PromoteRestrictedViewModel by viewModel() @Inject lateinit var activeSessionHolder: ActiveSessionHolder @Inject lateinit var vectorUncaughtExceptionHandler: VectorUncaughtExceptionHandler @@ -179,30 +176,6 @@ class HomeActivity : replaceFragment(R.id.homeDetailFragmentContainer, HomeDetailFragment::class.java) replaceFragment(R.id.homeDrawerFragmentContainer, HomeDrawerFragment::class.java) } - if (!vectorPreferences.didPromoteNewRestrictedFeature()) { - appStateHandler.selectedRoomGroupingObservable.subscribe { - (it.orNull() as? RoomGroupingMethod.BySpace)?.spaceSummary?.let { currentSpaceSummary -> - if (!currentSpaceSummary.isPublic && currentSpaceSummary.otherMemberIds.isNotEmpty()) { - val isAdmin = activeSessionHolder - .getSafeActiveSession() - ?.getRoom(currentSpaceSummary.roomId) - ?.getStateEvent(EventType.STATE_ROOM_POWER_LEVELS, QueryStringValue.NoCondition) - ?.content?.toModel() - ?.let { PowerLevelsHelper(it) } - ?.isUserAllowedToSend(activeSessionHolder.getActiveSession().myUserId, true, EventType.STATE_SPACE_CHILD) - ?: false - - // It's a private space with some members show this once - if (isAdmin && !popupAlertManager.hasAlertsToShow()) { - if (!vectorPreferences.didPromoteNewRestrictedFeature()) { - vectorPreferences.setDidPromoteNewRestrictedFeature() - RestrictedPromoBottomSheet().show(supportFragmentManager, "FOO") - } - } - } - } - }.disposeOnDestroy() - } sharedActionViewModel .observe() @@ -270,6 +243,21 @@ class HomeActivity : shortcutsHandler.observeRoomsAndBuildShortcuts() .disposeOnDestroy() + if (!vectorPreferences.didPromoteNewRestrictedFeature()) { + promoteRestrictedViewModel.subscribe(this) { + if (it.activeSpaceSummary != null && !it.activeSpaceSummary.isPublic + && it.activeSpaceSummary.otherMemberIds.isNotEmpty()) { + // It's a private space with some members show this once + if (it.canUserManageSpace && !popupAlertManager.hasAlertsToShow()) { + if (!vectorPreferences.didPromoteNewRestrictedFeature()) { + vectorPreferences.setDidPromoteNewRestrictedFeature() + RestrictedPromoBottomSheet().show(supportFragmentManager, "FOO") + } + } + } + } + } + if (isFirstCreation()) { handleIntent(intent) } @@ -576,4 +564,6 @@ class HomeActivity : private const val ROOM_LINK_PREFIX = "${MATRIX_TO_CUSTOM_SCHEME_URL_BASE}room/" private const val USER_LINK_PREFIX = "${MATRIX_TO_CUSTOM_SCHEME_URL_BASE}user/" } + + override fun create(initialState: ActiveSpaceViewState) = promoteRestrictedViewModelFactory.create(initialState) } diff --git a/vector/src/main/java/im/vector/app/features/home/PromoteRestrictedViewModel.kt b/vector/src/main/java/im/vector/app/features/home/PromoteRestrictedViewModel.kt new file mode 100644 index 0000000000..f332a1fcdb --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/home/PromoteRestrictedViewModel.kt @@ -0,0 +1,92 @@ +/* + * 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.home + +import com.airbnb.mvrx.ActivityViewModelContext +import com.airbnb.mvrx.FragmentViewModelContext +import com.airbnb.mvrx.MvRxState +import com.airbnb.mvrx.MvRxViewModelFactory +import com.airbnb.mvrx.ViewModelContext +import dagger.assisted.Assisted +import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject +import im.vector.app.AppStateHandler +import im.vector.app.RoomGroupingMethod +import im.vector.app.core.di.ActiveSessionHolder +import im.vector.app.core.platform.EmptyAction +import im.vector.app.core.platform.EmptyViewEvents +import im.vector.app.core.platform.VectorViewModel +import org.matrix.android.sdk.api.query.QueryStringValue +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.room.model.PowerLevelsContent +import org.matrix.android.sdk.api.session.room.model.RoomSummary +import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper + +data class ActiveSpaceViewState( + val isInSpaceMode: Boolean = false, + val activeSpaceSummary: RoomSummary? = null, + val canUserManageSpace: Boolean = false +) : MvRxState + +class PromoteRestrictedViewModel @AssistedInject constructor( + @Assisted initialState: ActiveSpaceViewState, + private val activeSessionHolder: ActiveSessionHolder, + private val appStateHandler: AppStateHandler +) : VectorViewModel(initialState) { + + init { + appStateHandler.selectedRoomGroupingObservable.distinctUntilChanged().execute { + val groupingMethod = it.invoke()?.orNull() + val isSpaceMode = groupingMethod is RoomGroupingMethod.BySpace + val currentSpace = (groupingMethod as? RoomGroupingMethod.BySpace)?.spaceSummary + val canManage = currentSpace?.roomId?.let { roomId -> + activeSessionHolder.getSafeActiveSession() + ?.getRoom(currentSpace.roomId) + ?.getStateEvent(EventType.STATE_ROOM_POWER_LEVELS, QueryStringValue.NoCondition) + ?.content?.toModel()?.let { + PowerLevelsHelper(it).isUserAllowedToSend(activeSessionHolder.getActiveSession().myUserId, true, EventType.STATE_SPACE_CHILD) + } ?: false + } ?: false + + copy( + isInSpaceMode = isSpaceMode, + activeSpaceSummary = currentSpace, + canUserManageSpace = canManage + ) + } + } + + @AssistedFactory + interface Factory { + fun create(initialState: ActiveSpaceViewState): PromoteRestrictedViewModel + } + + companion object : MvRxViewModelFactory { + + @JvmStatic + override fun create(viewModelContext: ViewModelContext, state: ActiveSpaceViewState): PromoteRestrictedViewModel? { + 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") + } + } + + override fun handle(action: EmptyAction) {} +} diff --git a/vector/src/main/java/im/vector/app/features/spaces/RestrictedPromoBottomSheet.kt b/vector/src/main/java/im/vector/app/features/spaces/RestrictedPromoBottomSheet.kt index 4412ca96fc..951b131d4b 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/RestrictedPromoBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/RestrictedPromoBottomSheet.kt @@ -32,7 +32,7 @@ class RestrictedPromoBottomSheet : VectorBaseBottomSheetDialogFragment