From d63e1ecfeacd0f0dc064ad66dc970abe3be93b57 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 1 Oct 2021 17:08:09 +0200 Subject: [PATCH] Mavericks 2: replacing rx by flow --- .../home/room/detail/RoomDetailViewModel.kt | 12 ++-- .../action/MessageActionsViewModel.kt | 16 ++--- ...leFactory.kt => PowerLevelsFlowFactory.kt} | 19 +++--- .../RoomMemberProfileViewModel.kt | 52 ++++++++-------- .../roomprofile/RoomProfileViewModel.kt | 12 ++-- .../roomprofile/alias/RoomAliasViewModel.kt | 33 +++++----- .../banned/RoomBannedMemberListViewModel.kt | 10 ++-- .../members/RoomMemberListViewModel.kt | 14 ++--- .../permissions/RoomPermissionsViewModel.kt | 13 ++-- .../settings/RoomSettingsViewModel.kt | 60 +++++++++---------- .../app/features/spaces/SpaceMenuViewModel.kt | 13 ++-- .../spaces/explore/SpaceDirectoryViewModel.kt | 11 ++-- .../spaces/share/ShareSpaceViewModel.kt | 12 ++-- 13 files changed, 137 insertions(+), 140 deletions(-) rename vector/src/main/java/im/vector/app/features/powerlevel/{PowerLevelsObservableFactory.kt => PowerLevelsFlowFactory.kt} (73%) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt index c64fb89f28..b35e7c2607 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt @@ -55,7 +55,7 @@ import im.vector.app.features.home.room.detail.sticker.StickerPickerActionHandle import im.vector.app.features.home.room.detail.timeline.factory.TimelineFactory import im.vector.app.features.home.room.detail.timeline.url.PreviewUrlRetriever import im.vector.app.features.home.room.typing.TypingHelper -import im.vector.app.features.powerlevel.PowerLevelsObservableFactory +import im.vector.app.features.powerlevel.PowerLevelsFlowFactory import im.vector.app.features.session.coroutineScope import im.vector.app.features.settings.VectorDataStore import im.vector.app.features.settings.VectorPreferences @@ -66,9 +66,10 @@ import io.reactivex.schedulers.Schedulers import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.filterIsInstance +import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import org.commonmark.parser.Parser @@ -238,8 +239,8 @@ class RoomDetailViewModel @AssistedInject constructor( } private fun observePowerLevel() { - PowerLevelsObservableFactory(room).createObservable() - .subscribe { + PowerLevelsFlowFactory(room).createFlow() + .onEach { val canSendMessage = PowerLevelsHelper(it).isUserAllowedToSend(session.myUserId, false, EventType.MESSAGE) val canInvite = PowerLevelsHelper(it).isUserAbleToInvite(session.myUserId) val isAllowedToManageWidgets = session.widgetService().hasPermissionsToHandleWidgets(room.roomId) @@ -252,8 +253,7 @@ class RoomDetailViewModel @AssistedInject constructor( isAllowedToStartWebRTCCall = isAllowedToStartWebRTCCall ) } - } - .disposeOnClear() + }.launchIn(viewModelScope) } private fun observeActiveRoomWidgets() { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsViewModel.kt index fd80a56870..1723e893ad 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsViewModel.kt @@ -18,7 +18,6 @@ package im.vector.app.features.home.room.detail.timeline.action import com.airbnb.mvrx.FragmentViewModelContext import com.airbnb.mvrx.MvRxViewModelFactory import com.airbnb.mvrx.ViewModelContext -import com.jakewharton.rxrelay2.BehaviorRelay import dagger.Lazy import dagger.assisted.Assisted import dagger.assisted.AssistedFactory @@ -33,14 +32,14 @@ import im.vector.app.features.home.room.detail.timeline.format.NoticeEventFormat import im.vector.app.features.html.EventHtmlRenderer import im.vector.app.features.html.PillsPostProcessor import im.vector.app.features.html.VectorHtmlCompressor -import im.vector.app.features.powerlevel.PowerLevelsObservableFactory +import im.vector.app.features.powerlevel.PowerLevelsFlowFactory import im.vector.app.features.reactions.data.EmojiDataSource import im.vector.app.features.settings.VectorPreferences -import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.flatMapLatest +import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map -import kotlinx.coroutines.flow.switchMap +import kotlinx.coroutines.flow.onEach import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupState @@ -61,8 +60,6 @@ import org.matrix.android.sdk.api.session.room.timeline.getLastMessageContent import org.matrix.android.sdk.api.session.room.timeline.hasBeenEdited import org.matrix.android.sdk.flow.flow import org.matrix.android.sdk.flow.unwrap -import org.matrix.android.sdk.rx.rx -import java.util.ArrayList /** * Information related to an event and used to display preview in contextual bottom sheet. @@ -125,8 +122,8 @@ class MessageActionsViewModel @AssistedInject constructor(@Assisted if (room == null) { return } - PowerLevelsObservableFactory(room).createObservable() - .subscribe { + PowerLevelsFlowFactory(room).createFlow() + .onEach { val powerLevelsHelper = PowerLevelsHelper(it) val canReact = powerLevelsHelper.isUserAllowedToSend(session.myUserId, false, EventType.REACTION) val canRedact = powerLevelsHelper.isUserAbleToRedact(session.myUserId) @@ -135,8 +132,7 @@ class MessageActionsViewModel @AssistedInject constructor(@Assisted setState { copy(actionPermissions = permissions) } - } - .disposeOnClear() + }.launchIn(viewModelScope) } private fun observeEvent() { diff --git a/vector/src/main/java/im/vector/app/features/powerlevel/PowerLevelsObservableFactory.kt b/vector/src/main/java/im/vector/app/features/powerlevel/PowerLevelsFlowFactory.kt similarity index 73% rename from vector/src/main/java/im/vector/app/features/powerlevel/PowerLevelsObservableFactory.kt rename to vector/src/main/java/im/vector/app/features/powerlevel/PowerLevelsFlowFactory.kt index a9d4578bf0..767d6f1ba7 100644 --- a/vector/src/main/java/im/vector/app/features/powerlevel/PowerLevelsObservableFactory.kt +++ b/vector/src/main/java/im/vector/app/features/powerlevel/PowerLevelsFlowFactory.kt @@ -16,23 +16,24 @@ package im.vector.app.features.powerlevel -import io.reactivex.Observable -import io.reactivex.schedulers.Schedulers +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flowOn 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.Room import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent -import org.matrix.android.sdk.rx.mapOptional -import org.matrix.android.sdk.rx.rx -import org.matrix.android.sdk.rx.unwrap +import org.matrix.android.sdk.flow.flow +import org.matrix.android.sdk.flow.mapOptional +import org.matrix.android.sdk.flow.unwrap -class PowerLevelsObservableFactory(private val room: Room) { +class PowerLevelsFlowFactory(private val room: Room) { - fun createObservable(): Observable { - return room.rx() + fun createFlow(): Flow { + return room.flow() .liveStateEvent(EventType.STATE_ROOM_POWER_LEVELS, QueryStringValue.NoCondition) - .observeOn(Schedulers.computation()) + .flowOn(Dispatchers.Default) .mapOptional { it.content.toModel() } .unwrap() } diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt index 4b57bdc6aa..ace53c60b7 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt @@ -17,7 +17,6 @@ package im.vector.app.features.roommemberprofile -import androidx.lifecycle.viewModelScope import com.airbnb.mvrx.Fail import com.airbnb.mvrx.FragmentViewModelContext import com.airbnb.mvrx.Loading @@ -32,10 +31,15 @@ import im.vector.app.R import im.vector.app.core.mvrx.runCatchingToAsync import im.vector.app.core.platform.VectorViewModel import im.vector.app.core.resources.StringProvider -import im.vector.app.features.powerlevel.PowerLevelsObservableFactory +import im.vector.app.features.powerlevel.PowerLevelsFlowFactory import io.reactivex.Observable import io.reactivex.functions.BiFunction import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.combineLatest +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import org.matrix.android.sdk.api.query.QueryStringValue @@ -54,6 +58,8 @@ import org.matrix.android.sdk.api.session.room.powerlevels.Role import org.matrix.android.sdk.api.util.MatrixItem import org.matrix.android.sdk.api.util.toMatrixItem import org.matrix.android.sdk.api.util.toOptional +import org.matrix.android.sdk.flow.flow +import org.matrix.android.sdk.flow.unwrap import org.matrix.android.sdk.rx.rx import org.matrix.android.sdk.rx.unwrap @@ -286,11 +292,11 @@ class RoomMemberProfileViewModel @AssistedInject constructor(@Assisted private v } private fun observeRoomSummaryAndPowerLevels(room: Room) { - val roomSummaryLive = room.rx().liveRoomSummary().unwrap() - val powerLevelsContentLive = PowerLevelsObservableFactory(room).createObservable() + val roomSummaryLive = room.flow().liveRoomSummary().unwrap() + val powerLevelsContentLive = PowerLevelsFlowFactory(room).createFlow() powerLevelsContentLive - .subscribe { + .onEach { val powerLevelsHelper = PowerLevelsHelper(it) val permissions = ActionPermissions( canKick = powerLevelsHelper.isUserAbleToKick(session.myUserId), @@ -298,30 +304,26 @@ class RoomMemberProfileViewModel @AssistedInject constructor(@Assisted private v canInvite = powerLevelsHelper.isUserAbleToInvite(session.myUserId), canEditPowerLevel = powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, EventType.STATE_ROOM_POWER_LEVELS) ) - setState { copy(powerLevelsContent = it, actionPermissions = permissions) } - } - .disposeOnClear() + setState { + copy(powerLevelsContent = it, actionPermissions = permissions) + } + }.launchIn(viewModelScope) roomSummaryLive.execute { copy(isRoomEncrypted = it.invoke()?.isEncrypted == true) } - Observable - .combineLatest( - roomSummaryLive, - powerLevelsContentLive, - BiFunction { roomSummary, powerLevelsContent -> - val roomName = roomSummary.toMatrixItem().getBestName() - val powerLevelsHelper = PowerLevelsHelper(powerLevelsContent) - when (val userPowerLevel = powerLevelsHelper.getUserRole(initialState.userId)) { - Role.Admin -> stringProvider.getString(R.string.room_member_power_level_admin_in, roomName) - Role.Moderator -> stringProvider.getString(R.string.room_member_power_level_moderator_in, roomName) - Role.Default -> stringProvider.getString(R.string.room_member_power_level_default_in, roomName) - is Role.Custom -> stringProvider.getString(R.string.room_member_power_level_custom_in, userPowerLevel.value, roomName) - } - } - ).execute { - copy(userPowerLevelString = it) - } + roomSummaryLive.combine(powerLevelsContentLive){roomSummary, powerLevelsContent -> + val roomName = roomSummary.toMatrixItem().getBestName() + val powerLevelsHelper = PowerLevelsHelper(powerLevelsContent) + when (val userPowerLevel = powerLevelsHelper.getUserRole(initialState.userId)) { + Role.Admin -> stringProvider.getString(R.string.room_member_power_level_admin_in, roomName) + Role.Moderator -> stringProvider.getString(R.string.room_member_power_level_moderator_in, roomName) + Role.Default -> stringProvider.getString(R.string.room_member_power_level_default_in, roomName) + is Role.Custom -> stringProvider.getString(R.string.room_member_power_level_custom_in, userPowerLevel.value, roomName) + } + }.execute { + copy(userPowerLevelString = it) + } } private fun handleIgnoreAction() = withState { state -> diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileViewModel.kt index d35e8f3ad5..e6b416bcb6 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileViewModel.kt @@ -17,7 +17,6 @@ package im.vector.app.features.roomprofile -import androidx.lifecycle.viewModelScope import com.airbnb.mvrx.FragmentViewModelContext import com.airbnb.mvrx.MvRxViewModelFactory import com.airbnb.mvrx.ViewModelContext @@ -29,7 +28,7 @@ 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.features.home.ShortcutCreator -import im.vector.app.features.powerlevel.PowerLevelsObservableFactory +import im.vector.app.features.powerlevel.PowerLevelsFlowFactory import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import org.matrix.android.sdk.api.query.QueryStringValue @@ -109,16 +108,15 @@ class RoomProfileViewModel @AssistedInject constructor( } private fun observePermissions() { - PowerLevelsObservableFactory(room) - .createObservable() - .subscribe { + PowerLevelsFlowFactory(room) + .createFlow() + .setOnEach { val powerLevelsHelper = PowerLevelsHelper(it) val permissions = RoomProfileViewState.ActionPermissions( canEnableEncryption = powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, EventType.STATE_ROOM_ENCRYPTION) ) - setState { copy(actionPermissions = permissions) } + copy(actionPermissions = permissions) } - .disposeOnClear() } override fun handle(action: RoomProfileAction) { diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasViewModel.kt index aa9981997c..7ebd82a5c7 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasViewModel.kt @@ -16,7 +16,6 @@ package im.vector.app.features.roomprofile.alias -import androidx.lifecycle.viewModelScope import com.airbnb.mvrx.Fail import com.airbnb.mvrx.FragmentViewModelContext import com.airbnb.mvrx.Loading @@ -29,7 +28,9 @@ import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.VectorViewModel -import im.vector.app.features.powerlevel.PowerLevelsObservableFactory +import im.vector.app.features.powerlevel.PowerLevelsFlowFactory +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import org.matrix.android.sdk.api.MatrixPatterns.getDomain import org.matrix.android.sdk.api.query.QueryStringValue @@ -38,7 +39,9 @@ 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.RoomCanonicalAliasContent import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper -import org.matrix.android.sdk.rx.mapOptional +import org.matrix.android.sdk.flow.flow +import org.matrix.android.sdk.flow.mapOptional +import org.matrix.android.sdk.flow.unwrap import org.matrix.android.sdk.rx.rx import org.matrix.android.sdk.rx.unwrap @@ -138,9 +141,9 @@ class RoomAliasViewModel @AssistedInject constructor(@Assisted initialState: Roo } private fun observePowerLevel() { - PowerLevelsObservableFactory(room) - .createObservable() - .subscribe { + PowerLevelsFlowFactory(room) + .createFlow() + .onEach { val powerLevelsHelper = PowerLevelsHelper(it) val permissions = RoomAliasViewState.ActionPermissions( canChangeCanonicalAlias = powerLevelsHelper.isUserAllowedToSend( @@ -163,27 +166,23 @@ class RoomAliasViewModel @AssistedInject constructor(@Assisted initialState: Roo publishManuallyState = newPublishManuallyState ) } - } - .disposeOnClear() + }.launchIn(viewModelScope) } /** * We do not want to use the fallback avatar url, which can be the other user avatar, or the current user avatar. */ private fun observeRoomCanonicalAlias() { - room.rx() + room.flow() .liveStateEvent(EventType.STATE_ROOM_CANONICAL_ALIAS, QueryStringValue.NoCondition) .mapOptional { it.content.toModel() } .unwrap() - .subscribe { - setState { - copy( - canonicalAlias = it.canonicalAlias, - alternativeAliases = it.alternativeAliases.orEmpty().sorted() - ) - } + .setOnEach { + copy( + canonicalAlias = it.canonicalAlias, + alternativeAliases = it.alternativeAliases.orEmpty().sorted() + ) } - .disposeOnClear() } override fun handle(action: RoomAliasAction) { diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/banned/RoomBannedMemberListViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/banned/RoomBannedMemberListViewModel.kt index 1b64261fcb..450c4ee545 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/banned/RoomBannedMemberListViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/banned/RoomBannedMemberListViewModel.kt @@ -16,7 +16,6 @@ package im.vector.app.features.roomprofile.banned -import androidx.lifecycle.viewModelScope import com.airbnb.mvrx.FragmentViewModelContext import com.airbnb.mvrx.MvRxViewModelFactory import com.airbnb.mvrx.ViewModelContext @@ -27,7 +26,7 @@ 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.features.powerlevel.PowerLevelsObservableFactory +import im.vector.app.features.powerlevel.PowerLevelsFlowFactory import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import org.matrix.android.sdk.api.query.QueryStringValue @@ -70,14 +69,13 @@ class RoomBannedMemberListViewModel @AssistedInject constructor(@Assisted initia ) } - val powerLevelsContentLive = PowerLevelsObservableFactory(room).createObservable() + val powerLevelsContentLive = PowerLevelsFlowFactory(room).createFlow() powerLevelsContentLive - .subscribe { + .setOnEach { val powerLevelsHelper = PowerLevelsHelper(it) - setState { copy(canUserBan = powerLevelsHelper.isUserAbleToBan(session.myUserId)) } + copy(canUserBan = powerLevelsHelper.isUserAbleToBan(session.myUserId)) } - .disposeOnClear() } companion object : MvRxViewModelFactory { diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListViewModel.kt index 5c6ff48403..26f2bc4ebe 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListViewModel.kt @@ -16,7 +16,6 @@ package im.vector.app.features.roomprofile.members -import androidx.lifecycle.viewModelScope import com.airbnb.mvrx.ActivityViewModelContext import com.airbnb.mvrx.FragmentViewModelContext import com.airbnb.mvrx.MvRxViewModelFactory @@ -27,9 +26,11 @@ import dagger.assisted.AssistedInject import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.EmptyViewEvents import im.vector.app.core.platform.VectorViewModel -import im.vector.app.features.powerlevel.PowerLevelsObservableFactory +import im.vector.app.features.powerlevel.PowerLevelsFlowFactory import io.reactivex.Observable import io.reactivex.android.schedulers.AndroidSchedulers +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import org.matrix.android.sdk.api.crypto.RoomEncryptionTrustLevel import org.matrix.android.sdk.api.extensions.orFalse @@ -129,8 +130,8 @@ class RoomMemberListViewModel @AssistedInject constructor(@Assisted initialState } private fun observePowerLevel() { - PowerLevelsObservableFactory(room).createObservable() - .subscribe { + PowerLevelsFlowFactory(room).createFlow() + .onEach { val permissions = ActionPermissions( canInvite = PowerLevelsHelper(it).isUserAbleToInvite(session.myUserId), canRevokeThreePidInvite = PowerLevelsHelper(it).isUserAllowedToSend( @@ -142,8 +143,7 @@ class RoomMemberListViewModel @AssistedInject constructor(@Assisted initialState setState { copy(actionsPermissions = permissions) } - } - .disposeOnClear() + }.launchIn(viewModelScope) } private fun observeRoomSummary() { @@ -192,7 +192,7 @@ class RoomMemberListViewModel @AssistedInject constructor(@Assisted initialState override fun handle(action: RoomMemberListAction) { when (action) { is RoomMemberListAction.RevokeThreePidInvite -> handleRevokeThreePidInvite(action) - is RoomMemberListAction.FilterMemberList -> handleFilterMemberList(action) + is RoomMemberListAction.FilterMemberList -> handleFilterMemberList(action) }.exhaustive } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoomPermissionsViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoomPermissionsViewModel.kt index 56c3940523..92df11ff57 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoomPermissionsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoomPermissionsViewModel.kt @@ -25,7 +25,9 @@ import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.VectorViewModel -import im.vector.app.features.powerlevel.PowerLevelsObservableFactory +import im.vector.app.features.powerlevel.PowerLevelsFlowFactory +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.events.model.EventType @@ -71,9 +73,9 @@ class RoomPermissionsViewModel @AssistedInject constructor(@Assisted initialStat } private fun observePowerLevel() { - PowerLevelsObservableFactory(room) - .createObservable() - .subscribe { powerLevelContent -> + PowerLevelsFlowFactory(room) + .createFlow() + .onEach { powerLevelContent -> val powerLevelsHelper = PowerLevelsHelper(powerLevelContent) val permissions = RoomPermissionsViewState.ActionPermissions( canChangePowerLevels = powerLevelsHelper.isUserAllowedToSend( @@ -88,8 +90,7 @@ class RoomPermissionsViewModel @AssistedInject constructor(@Assisted initialStat currentPowerLevelsContent = Success(powerLevelContent) ) } - } - .disposeOnClear() + }.launchIn(viewModelScope) } override fun handle(action: RoomPermissionsAction) { diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/settings/RoomSettingsViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/settings/RoomSettingsViewModel.kt index e872a04d80..112fe39903 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/settings/RoomSettingsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/settings/RoomSettingsViewModel.kt @@ -26,10 +26,13 @@ import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.VectorViewModel -import im.vector.app.features.powerlevel.PowerLevelsObservableFactory +import im.vector.app.features.powerlevel.PowerLevelsFlowFactory import im.vector.app.features.settings.VectorPreferences import io.reactivex.Completable import io.reactivex.Observable +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.mapNotNull +import kotlinx.coroutines.flow.onEach import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.query.QueryStringValue import org.matrix.android.sdk.api.session.Session @@ -41,9 +44,10 @@ 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.RoomJoinRulesContent import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper -import org.matrix.android.sdk.rx.mapOptional +import org.matrix.android.sdk.flow.flow +import org.matrix.android.sdk.flow.mapOptional +import org.matrix.android.sdk.flow.unwrap import org.matrix.android.sdk.rx.rx -import org.matrix.android.sdk.rx.unwrap class RoomSettingsViewModel @AssistedInject constructor(@Assisted initialState: RoomSettingsViewState, private val vectorPreferences: VectorPreferences, @@ -123,7 +127,7 @@ class RoomSettingsViewModel @AssistedInject constructor(@Assisted initialState: } private fun observeRoomSummary() { - room.rx().liveRoomSummary() + room.flow().liveRoomSummary() .unwrap() .execute { async -> val roomSummary = async.invoke() @@ -134,10 +138,10 @@ class RoomSettingsViewModel @AssistedInject constructor(@Assisted initialState: ) } - val powerLevelsContentLive = PowerLevelsObservableFactory(room).createObservable() + val powerLevelsContentLive = PowerLevelsFlowFactory(room).createFlow() powerLevelsContentLive - .subscribe { + .onEach { val powerLevelsHelper = PowerLevelsHelper(it) val permissions = RoomSettingsViewState.ActionPermissions( canChangeAvatar = powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, EventType.STATE_ROOM_AVATAR), @@ -152,62 +156,56 @@ class RoomSettingsViewModel @AssistedInject constructor(@Assisted initialState: canAddChildren = powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, EventType.STATE_SPACE_CHILD) ) - setState { copy(actionPermissions = permissions) } - } - .disposeOnClear() + setState { + copy(actionPermissions = permissions) + } + }.launchIn(viewModelScope) } private fun observeRoomHistoryVisibility() { - room.rx() + room.flow() .liveStateEvent(EventType.STATE_ROOM_HISTORY_VISIBILITY, QueryStringValue.NoCondition) .mapOptional { it.content.toModel() } .unwrap() - .subscribe { - it.historyVisibility?.let { - setState { copy(currentHistoryVisibility = it) } - } + .mapNotNull { it.historyVisibility } + .setOnEach { + copy(currentHistoryVisibility = it) } - .disposeOnClear() } private fun observeJoinRule() { - room.rx() + room.flow() .liveStateEvent(EventType.STATE_ROOM_JOIN_RULES, QueryStringValue.NoCondition) .mapOptional { it.content.toModel() } .unwrap() - .subscribe { - it.joinRules?.let { - setState { copy(currentRoomJoinRules = it) } - } + .mapNotNull { it.joinRules } + .setOnEach { + copy(currentRoomJoinRules = it) } - .disposeOnClear() } private fun observeGuestAccess() { - room.rx() + room.flow() .liveStateEvent(EventType.STATE_ROOM_GUEST_ACCESS, QueryStringValue.NoCondition) .mapOptional { it.content.toModel() } .unwrap() - .subscribe { - it.guestAccess?.let { - setState { copy(currentGuestAccess = it) } - } + .mapNotNull { it.guestAccess } + .setOnEach { + copy(currentGuestAccess = it) } - .disposeOnClear() } /** * We do not want to use the fallback avatar url, which can be the other user avatar, or the current user avatar. */ private fun observeRoomAvatar() { - room.rx() + room.flow() .liveStateEvent(EventType.STATE_ROOM_AVATAR, QueryStringValue.NoCondition) .mapOptional { it.content.toModel() } .unwrap() - .subscribe { - setState { copy(currentRoomAvatarUrl = it.avatarUrl) } + .setOnEach { + copy(currentRoomAvatarUrl = it.avatarUrl) } - .disposeOnClear() } override fun handle(action: RoomSettingsAction) { diff --git a/vector/src/main/java/im/vector/app/features/spaces/SpaceMenuViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/SpaceMenuViewModel.kt index 24ca218942..1627fdacae 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/SpaceMenuViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/SpaceMenuViewModel.kt @@ -30,8 +30,10 @@ import dagger.assisted.AssistedInject import im.vector.app.AppStateHandler import im.vector.app.core.platform.EmptyViewEvents import im.vector.app.core.platform.VectorViewModel -import im.vector.app.features.powerlevel.PowerLevelsObservableFactory +import im.vector.app.features.powerlevel.PowerLevelsFlowFactory import im.vector.app.features.session.coroutineScope +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import org.matrix.android.sdk.api.query.ActiveSpaceFilter import org.matrix.android.sdk.api.session.Session @@ -87,9 +89,9 @@ class SpaceMenuViewModel @AssistedInject constructor( } }.disposeOnClear() - PowerLevelsObservableFactory(room) - .createObservable() - .subscribe { + PowerLevelsFlowFactory(room) + .createFlow() + .onEach { val powerLevelsHelper = PowerLevelsHelper(it) val canInvite = powerLevelsHelper.isUserAbleToInvite(session.myUserId) @@ -114,8 +116,7 @@ class SpaceMenuViewModel @AssistedInject constructor( isLastAdmin = isLastAdmin ) } - } - .disposeOnClear() + }.launchIn(viewModelScope) } } diff --git a/vector/src/main/java/im/vector/app/features/spaces/explore/SpaceDirectoryViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/explore/SpaceDirectoryViewModel.kt index 1006f5a570..f25241d2dc 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/explore/SpaceDirectoryViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/explore/SpaceDirectoryViewModel.kt @@ -16,7 +16,6 @@ package im.vector.app.features.spaces.explore -import androidx.lifecycle.viewModelScope import com.airbnb.mvrx.ActivityViewModelContext import com.airbnb.mvrx.Fail import com.airbnb.mvrx.FragmentViewModelContext @@ -29,8 +28,10 @@ import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import im.vector.app.core.platform.VectorViewModel -import im.vector.app.features.powerlevel.PowerLevelsObservableFactory +import im.vector.app.features.powerlevel.PowerLevelsFlowFactory import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.events.model.EventType @@ -83,17 +84,17 @@ class SpaceDirectoryViewModel @AssistedInject constructor( private fun observePermissions() { val room = session.getRoom(initialState.spaceId) ?: return - val powerLevelsContentLive = PowerLevelsObservableFactory(room).createObservable() + val powerLevelsContentLive = PowerLevelsFlowFactory(room).createFlow() powerLevelsContentLive - .subscribe { + .onEach { val powerLevelsHelper = PowerLevelsHelper(it) setState { copy(canAddRooms = powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, EventType.STATE_SPACE_CHILD)) } } - .disposeOnClear() + .launchIn(viewModelScope) } private fun refreshFromApi(rootId: String?) = withState { state -> diff --git a/vector/src/main/java/im/vector/app/features/spaces/share/ShareSpaceViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/share/ShareSpaceViewModel.kt index dfce534a7a..2cc4fd388c 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/share/ShareSpaceViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/share/ShareSpaceViewModel.kt @@ -26,7 +26,9 @@ import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import im.vector.app.core.platform.VectorViewModel -import im.vector.app.features.powerlevel.PowerLevelsObservableFactory +import im.vector.app.features.powerlevel.PowerLevelsFlowFactory +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper @@ -63,9 +65,9 @@ class ShareSpaceViewModel @AssistedInject constructor( private fun observePowerLevel() { val room = session.getRoom(initialState.spaceId) ?: return - PowerLevelsObservableFactory(room) - .createObservable() - .subscribe { powerLevelContent -> + PowerLevelsFlowFactory(room) + .createFlow() + .onEach { powerLevelContent -> val powerLevelsHelper = PowerLevelsHelper(powerLevelContent) setState { copy( @@ -73,7 +75,7 @@ class ShareSpaceViewModel @AssistedInject constructor( ) } } - .disposeOnClear() + .launchIn(viewModelScope) } override fun handle(action: ShareSpaceAction) {