Mavericks 2: replacing rx by flow

This commit is contained in:
ganfra 2021-10-01 17:08:09 +02:00
parent bbce37e694
commit d63e1ecfea
13 changed files with 137 additions and 140 deletions

View File

@ -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.factory.TimelineFactory
import im.vector.app.features.home.room.detail.timeline.url.PreviewUrlRetriever 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.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.session.coroutineScope
import im.vector.app.features.settings.VectorDataStore import im.vector.app.features.settings.VectorDataStore
import im.vector.app.features.settings.VectorPreferences import im.vector.app.features.settings.VectorPreferences
@ -66,9 +66,10 @@ import io.reactivex.schedulers.Schedulers
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.filterIsInstance import kotlinx.coroutines.flow.filterIsInstance
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import org.commonmark.parser.Parser import org.commonmark.parser.Parser
@ -238,8 +239,8 @@ class RoomDetailViewModel @AssistedInject constructor(
} }
private fun observePowerLevel() { private fun observePowerLevel() {
PowerLevelsObservableFactory(room).createObservable() PowerLevelsFlowFactory(room).createFlow()
.subscribe { .onEach {
val canSendMessage = PowerLevelsHelper(it).isUserAllowedToSend(session.myUserId, false, EventType.MESSAGE) val canSendMessage = PowerLevelsHelper(it).isUserAllowedToSend(session.myUserId, false, EventType.MESSAGE)
val canInvite = PowerLevelsHelper(it).isUserAbleToInvite(session.myUserId) val canInvite = PowerLevelsHelper(it).isUserAbleToInvite(session.myUserId)
val isAllowedToManageWidgets = session.widgetService().hasPermissionsToHandleWidgets(room.roomId) val isAllowedToManageWidgets = session.widgetService().hasPermissionsToHandleWidgets(room.roomId)
@ -252,8 +253,7 @@ class RoomDetailViewModel @AssistedInject constructor(
isAllowedToStartWebRTCCall = isAllowedToStartWebRTCCall isAllowedToStartWebRTCCall = isAllowedToStartWebRTCCall
) )
} }
} }.launchIn(viewModelScope)
.disposeOnClear()
} }
private fun observeActiveRoomWidgets() { private fun observeActiveRoomWidgets() {

View File

@ -18,7 +18,6 @@ package im.vector.app.features.home.room.detail.timeline.action
import com.airbnb.mvrx.FragmentViewModelContext import com.airbnb.mvrx.FragmentViewModelContext
import com.airbnb.mvrx.MvRxViewModelFactory import com.airbnb.mvrx.MvRxViewModelFactory
import com.airbnb.mvrx.ViewModelContext import com.airbnb.mvrx.ViewModelContext
import com.jakewharton.rxrelay2.BehaviorRelay
import dagger.Lazy import dagger.Lazy
import dagger.assisted.Assisted import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory 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.EventHtmlRenderer
import im.vector.app.features.html.PillsPostProcessor import im.vector.app.features.html.PillsPostProcessor
import im.vector.app.features.html.VectorHtmlCompressor 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.reactions.data.EmojiDataSource
import im.vector.app.features.settings.VectorPreferences import im.vector.app.features.settings.VectorPreferences
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map 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.extensions.orFalse
import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupState 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.api.session.room.timeline.hasBeenEdited
import org.matrix.android.sdk.flow.flow import org.matrix.android.sdk.flow.flow
import org.matrix.android.sdk.flow.unwrap 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. * 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) { if (room == null) {
return return
} }
PowerLevelsObservableFactory(room).createObservable() PowerLevelsFlowFactory(room).createFlow()
.subscribe { .onEach {
val powerLevelsHelper = PowerLevelsHelper(it) val powerLevelsHelper = PowerLevelsHelper(it)
val canReact = powerLevelsHelper.isUserAllowedToSend(session.myUserId, false, EventType.REACTION) val canReact = powerLevelsHelper.isUserAllowedToSend(session.myUserId, false, EventType.REACTION)
val canRedact = powerLevelsHelper.isUserAbleToRedact(session.myUserId) val canRedact = powerLevelsHelper.isUserAbleToRedact(session.myUserId)
@ -135,8 +132,7 @@ class MessageActionsViewModel @AssistedInject constructor(@Assisted
setState { setState {
copy(actionPermissions = permissions) copy(actionPermissions = permissions)
} }
} }.launchIn(viewModelScope)
.disposeOnClear()
} }
private fun observeEvent() { private fun observeEvent() {

View File

@ -16,23 +16,24 @@
package im.vector.app.features.powerlevel package im.vector.app.features.powerlevel
import io.reactivex.Observable import kotlinx.coroutines.Dispatchers
import io.reactivex.schedulers.Schedulers import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOn
import org.matrix.android.sdk.api.query.QueryStringValue 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.EventType
import org.matrix.android.sdk.api.session.events.model.toModel 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.Room
import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent
import org.matrix.android.sdk.rx.mapOptional import org.matrix.android.sdk.flow.flow
import org.matrix.android.sdk.rx.rx import org.matrix.android.sdk.flow.mapOptional
import org.matrix.android.sdk.rx.unwrap import org.matrix.android.sdk.flow.unwrap
class PowerLevelsObservableFactory(private val room: Room) { class PowerLevelsFlowFactory(private val room: Room) {
fun createObservable(): Observable<PowerLevelsContent> { fun createFlow(): Flow<PowerLevelsContent> {
return room.rx() return room.flow()
.liveStateEvent(EventType.STATE_ROOM_POWER_LEVELS, QueryStringValue.NoCondition) .liveStateEvent(EventType.STATE_ROOM_POWER_LEVELS, QueryStringValue.NoCondition)
.observeOn(Schedulers.computation()) .flowOn(Dispatchers.Default)
.mapOptional { it.content.toModel<PowerLevelsContent>() } .mapOptional { it.content.toModel<PowerLevelsContent>() }
.unwrap() .unwrap()
} }

View File

@ -17,7 +17,6 @@
package im.vector.app.features.roommemberprofile package im.vector.app.features.roommemberprofile
import androidx.lifecycle.viewModelScope
import com.airbnb.mvrx.Fail import com.airbnb.mvrx.Fail
import com.airbnb.mvrx.FragmentViewModelContext import com.airbnb.mvrx.FragmentViewModelContext
import com.airbnb.mvrx.Loading 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.mvrx.runCatchingToAsync
import im.vector.app.core.platform.VectorViewModel import im.vector.app.core.platform.VectorViewModel
import im.vector.app.core.resources.StringProvider 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.Observable
import io.reactivex.functions.BiFunction import io.reactivex.functions.BiFunction
import kotlinx.coroutines.Dispatchers 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.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import org.matrix.android.sdk.api.query.QueryStringValue 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.MatrixItem
import org.matrix.android.sdk.api.util.toMatrixItem import org.matrix.android.sdk.api.util.toMatrixItem
import org.matrix.android.sdk.api.util.toOptional 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.rx
import org.matrix.android.sdk.rx.unwrap import org.matrix.android.sdk.rx.unwrap
@ -286,11 +292,11 @@ class RoomMemberProfileViewModel @AssistedInject constructor(@Assisted private v
} }
private fun observeRoomSummaryAndPowerLevels(room: Room) { private fun observeRoomSummaryAndPowerLevels(room: Room) {
val roomSummaryLive = room.rx().liveRoomSummary().unwrap() val roomSummaryLive = room.flow().liveRoomSummary().unwrap()
val powerLevelsContentLive = PowerLevelsObservableFactory(room).createObservable() val powerLevelsContentLive = PowerLevelsFlowFactory(room).createFlow()
powerLevelsContentLive powerLevelsContentLive
.subscribe { .onEach {
val powerLevelsHelper = PowerLevelsHelper(it) val powerLevelsHelper = PowerLevelsHelper(it)
val permissions = ActionPermissions( val permissions = ActionPermissions(
canKick = powerLevelsHelper.isUserAbleToKick(session.myUserId), canKick = powerLevelsHelper.isUserAbleToKick(session.myUserId),
@ -298,30 +304,26 @@ class RoomMemberProfileViewModel @AssistedInject constructor(@Assisted private v
canInvite = powerLevelsHelper.isUserAbleToInvite(session.myUserId), canInvite = powerLevelsHelper.isUserAbleToInvite(session.myUserId),
canEditPowerLevel = powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, EventType.STATE_ROOM_POWER_LEVELS) canEditPowerLevel = powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, EventType.STATE_ROOM_POWER_LEVELS)
) )
setState { copy(powerLevelsContent = it, actionPermissions = permissions) } setState {
} copy(powerLevelsContent = it, actionPermissions = permissions)
.disposeOnClear() }
}.launchIn(viewModelScope)
roomSummaryLive.execute { roomSummaryLive.execute {
copy(isRoomEncrypted = it.invoke()?.isEncrypted == true) copy(isRoomEncrypted = it.invoke()?.isEncrypted == true)
} }
Observable roomSummaryLive.combine(powerLevelsContentLive){roomSummary, powerLevelsContent ->
.combineLatest( val roomName = roomSummary.toMatrixItem().getBestName()
roomSummaryLive, val powerLevelsHelper = PowerLevelsHelper(powerLevelsContent)
powerLevelsContentLive, when (val userPowerLevel = powerLevelsHelper.getUserRole(initialState.userId)) {
BiFunction<RoomSummary, PowerLevelsContent, String> { roomSummary, powerLevelsContent -> Role.Admin -> stringProvider.getString(R.string.room_member_power_level_admin_in, roomName)
val roomName = roomSummary.toMatrixItem().getBestName() Role.Moderator -> stringProvider.getString(R.string.room_member_power_level_moderator_in, roomName)
val powerLevelsHelper = PowerLevelsHelper(powerLevelsContent) Role.Default -> stringProvider.getString(R.string.room_member_power_level_default_in, roomName)
when (val userPowerLevel = powerLevelsHelper.getUserRole(initialState.userId)) { is Role.Custom -> stringProvider.getString(R.string.room_member_power_level_custom_in, userPowerLevel.value, roomName)
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) }.execute {
Role.Default -> stringProvider.getString(R.string.room_member_power_level_default_in, roomName) copy(userPowerLevelString = it)
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 -> private fun handleIgnoreAction() = withState { state ->

View File

@ -17,7 +17,6 @@
package im.vector.app.features.roomprofile package im.vector.app.features.roomprofile
import androidx.lifecycle.viewModelScope
import com.airbnb.mvrx.FragmentViewModelContext import com.airbnb.mvrx.FragmentViewModelContext
import com.airbnb.mvrx.MvRxViewModelFactory import com.airbnb.mvrx.MvRxViewModelFactory
import com.airbnb.mvrx.ViewModelContext 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.platform.VectorViewModel
import im.vector.app.core.resources.StringProvider import im.vector.app.core.resources.StringProvider
import im.vector.app.features.home.ShortcutCreator 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.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.matrix.android.sdk.api.query.QueryStringValue import org.matrix.android.sdk.api.query.QueryStringValue
@ -109,16 +108,15 @@ class RoomProfileViewModel @AssistedInject constructor(
} }
private fun observePermissions() { private fun observePermissions() {
PowerLevelsObservableFactory(room) PowerLevelsFlowFactory(room)
.createObservable() .createFlow()
.subscribe { .setOnEach {
val powerLevelsHelper = PowerLevelsHelper(it) val powerLevelsHelper = PowerLevelsHelper(it)
val permissions = RoomProfileViewState.ActionPermissions( val permissions = RoomProfileViewState.ActionPermissions(
canEnableEncryption = powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, EventType.STATE_ROOM_ENCRYPTION) canEnableEncryption = powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, EventType.STATE_ROOM_ENCRYPTION)
) )
setState { copy(actionPermissions = permissions) } copy(actionPermissions = permissions)
} }
.disposeOnClear()
} }
override fun handle(action: RoomProfileAction) { override fun handle(action: RoomProfileAction) {

View File

@ -16,7 +16,6 @@
package im.vector.app.features.roomprofile.alias package im.vector.app.features.roomprofile.alias
import androidx.lifecycle.viewModelScope
import com.airbnb.mvrx.Fail import com.airbnb.mvrx.Fail
import com.airbnb.mvrx.FragmentViewModelContext import com.airbnb.mvrx.FragmentViewModelContext
import com.airbnb.mvrx.Loading import com.airbnb.mvrx.Loading
@ -29,7 +28,9 @@ import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject import dagger.assisted.AssistedInject
import im.vector.app.core.extensions.exhaustive import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorViewModel 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 kotlinx.coroutines.launch
import org.matrix.android.sdk.api.MatrixPatterns.getDomain import org.matrix.android.sdk.api.MatrixPatterns.getDomain
import org.matrix.android.sdk.api.query.QueryStringValue 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.events.model.toModel
import org.matrix.android.sdk.api.session.room.model.RoomCanonicalAliasContent 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.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.rx
import org.matrix.android.sdk.rx.unwrap import org.matrix.android.sdk.rx.unwrap
@ -138,9 +141,9 @@ class RoomAliasViewModel @AssistedInject constructor(@Assisted initialState: Roo
} }
private fun observePowerLevel() { private fun observePowerLevel() {
PowerLevelsObservableFactory(room) PowerLevelsFlowFactory(room)
.createObservable() .createFlow()
.subscribe { .onEach {
val powerLevelsHelper = PowerLevelsHelper(it) val powerLevelsHelper = PowerLevelsHelper(it)
val permissions = RoomAliasViewState.ActionPermissions( val permissions = RoomAliasViewState.ActionPermissions(
canChangeCanonicalAlias = powerLevelsHelper.isUserAllowedToSend( canChangeCanonicalAlias = powerLevelsHelper.isUserAllowedToSend(
@ -163,27 +166,23 @@ class RoomAliasViewModel @AssistedInject constructor(@Assisted initialState: Roo
publishManuallyState = newPublishManuallyState publishManuallyState = newPublishManuallyState
) )
} }
} }.launchIn(viewModelScope)
.disposeOnClear()
} }
/** /**
* We do not want to use the fallback avatar url, which can be the other user avatar, or the current user avatar. * 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() { private fun observeRoomCanonicalAlias() {
room.rx() room.flow()
.liveStateEvent(EventType.STATE_ROOM_CANONICAL_ALIAS, QueryStringValue.NoCondition) .liveStateEvent(EventType.STATE_ROOM_CANONICAL_ALIAS, QueryStringValue.NoCondition)
.mapOptional { it.content.toModel<RoomCanonicalAliasContent>() } .mapOptional { it.content.toModel<RoomCanonicalAliasContent>() }
.unwrap() .unwrap()
.subscribe { .setOnEach {
setState { copy(
copy( canonicalAlias = it.canonicalAlias,
canonicalAlias = it.canonicalAlias, alternativeAliases = it.alternativeAliases.orEmpty().sorted()
alternativeAliases = it.alternativeAliases.orEmpty().sorted() )
)
}
} }
.disposeOnClear()
} }
override fun handle(action: RoomAliasAction) { override fun handle(action: RoomAliasAction) {

View File

@ -16,7 +16,6 @@
package im.vector.app.features.roomprofile.banned package im.vector.app.features.roomprofile.banned
import androidx.lifecycle.viewModelScope
import com.airbnb.mvrx.FragmentViewModelContext import com.airbnb.mvrx.FragmentViewModelContext
import com.airbnb.mvrx.MvRxViewModelFactory import com.airbnb.mvrx.MvRxViewModelFactory
import com.airbnb.mvrx.ViewModelContext 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.extensions.exhaustive
import im.vector.app.core.platform.VectorViewModel import im.vector.app.core.platform.VectorViewModel
import im.vector.app.core.resources.StringProvider 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.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.matrix.android.sdk.api.query.QueryStringValue 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 powerLevelsContentLive
.subscribe { .setOnEach {
val powerLevelsHelper = PowerLevelsHelper(it) val powerLevelsHelper = PowerLevelsHelper(it)
setState { copy(canUserBan = powerLevelsHelper.isUserAbleToBan(session.myUserId)) } copy(canUserBan = powerLevelsHelper.isUserAbleToBan(session.myUserId))
} }
.disposeOnClear()
} }
companion object : MvRxViewModelFactory<RoomBannedMemberListViewModel, RoomBannedMemberListViewState> { companion object : MvRxViewModelFactory<RoomBannedMemberListViewModel, RoomBannedMemberListViewState> {

View File

@ -16,7 +16,6 @@
package im.vector.app.features.roomprofile.members package im.vector.app.features.roomprofile.members
import androidx.lifecycle.viewModelScope
import com.airbnb.mvrx.ActivityViewModelContext import com.airbnb.mvrx.ActivityViewModelContext
import com.airbnb.mvrx.FragmentViewModelContext import com.airbnb.mvrx.FragmentViewModelContext
import com.airbnb.mvrx.MvRxViewModelFactory 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.extensions.exhaustive
import im.vector.app.core.platform.EmptyViewEvents import im.vector.app.core.platform.EmptyViewEvents
import im.vector.app.core.platform.VectorViewModel 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.Observable
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.matrix.android.sdk.api.crypto.RoomEncryptionTrustLevel import org.matrix.android.sdk.api.crypto.RoomEncryptionTrustLevel
import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.extensions.orFalse
@ -129,8 +130,8 @@ class RoomMemberListViewModel @AssistedInject constructor(@Assisted initialState
} }
private fun observePowerLevel() { private fun observePowerLevel() {
PowerLevelsObservableFactory(room).createObservable() PowerLevelsFlowFactory(room).createFlow()
.subscribe { .onEach {
val permissions = ActionPermissions( val permissions = ActionPermissions(
canInvite = PowerLevelsHelper(it).isUserAbleToInvite(session.myUserId), canInvite = PowerLevelsHelper(it).isUserAbleToInvite(session.myUserId),
canRevokeThreePidInvite = PowerLevelsHelper(it).isUserAllowedToSend( canRevokeThreePidInvite = PowerLevelsHelper(it).isUserAllowedToSend(
@ -142,8 +143,7 @@ class RoomMemberListViewModel @AssistedInject constructor(@Assisted initialState
setState { setState {
copy(actionsPermissions = permissions) copy(actionsPermissions = permissions)
} }
} }.launchIn(viewModelScope)
.disposeOnClear()
} }
private fun observeRoomSummary() { private fun observeRoomSummary() {
@ -192,7 +192,7 @@ class RoomMemberListViewModel @AssistedInject constructor(@Assisted initialState
override fun handle(action: RoomMemberListAction) { override fun handle(action: RoomMemberListAction) {
when (action) { when (action) {
is RoomMemberListAction.RevokeThreePidInvite -> handleRevokeThreePidInvite(action) is RoomMemberListAction.RevokeThreePidInvite -> handleRevokeThreePidInvite(action)
is RoomMemberListAction.FilterMemberList -> handleFilterMemberList(action) is RoomMemberListAction.FilterMemberList -> handleFilterMemberList(action)
}.exhaustive }.exhaustive
} }

View File

@ -25,7 +25,9 @@ import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject import dagger.assisted.AssistedInject
import im.vector.app.core.extensions.exhaustive import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorViewModel 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 kotlinx.coroutines.launch
import org.matrix.android.sdk.api.session.Session 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.EventType
@ -71,9 +73,9 @@ class RoomPermissionsViewModel @AssistedInject constructor(@Assisted initialStat
} }
private fun observePowerLevel() { private fun observePowerLevel() {
PowerLevelsObservableFactory(room) PowerLevelsFlowFactory(room)
.createObservable() .createFlow()
.subscribe { powerLevelContent -> .onEach { powerLevelContent ->
val powerLevelsHelper = PowerLevelsHelper(powerLevelContent) val powerLevelsHelper = PowerLevelsHelper(powerLevelContent)
val permissions = RoomPermissionsViewState.ActionPermissions( val permissions = RoomPermissionsViewState.ActionPermissions(
canChangePowerLevels = powerLevelsHelper.isUserAllowedToSend( canChangePowerLevels = powerLevelsHelper.isUserAllowedToSend(
@ -88,8 +90,7 @@ class RoomPermissionsViewModel @AssistedInject constructor(@Assisted initialStat
currentPowerLevelsContent = Success(powerLevelContent) currentPowerLevelsContent = Success(powerLevelContent)
) )
} }
} }.launchIn(viewModelScope)
.disposeOnClear()
} }
override fun handle(action: RoomPermissionsAction) { override fun handle(action: RoomPermissionsAction) {

View File

@ -26,10 +26,13 @@ import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject import dagger.assisted.AssistedInject
import im.vector.app.core.extensions.exhaustive import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorViewModel 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 im.vector.app.features.settings.VectorPreferences
import io.reactivex.Completable import io.reactivex.Completable
import io.reactivex.Observable 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.extensions.tryOrNull
import org.matrix.android.sdk.api.query.QueryStringValue import org.matrix.android.sdk.api.query.QueryStringValue
import org.matrix.android.sdk.api.session.Session 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.RoomHistoryVisibilityContent
import org.matrix.android.sdk.api.session.room.model.RoomJoinRulesContent 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.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.rx
import org.matrix.android.sdk.rx.unwrap
class RoomSettingsViewModel @AssistedInject constructor(@Assisted initialState: RoomSettingsViewState, class RoomSettingsViewModel @AssistedInject constructor(@Assisted initialState: RoomSettingsViewState,
private val vectorPreferences: VectorPreferences, private val vectorPreferences: VectorPreferences,
@ -123,7 +127,7 @@ class RoomSettingsViewModel @AssistedInject constructor(@Assisted initialState:
} }
private fun observeRoomSummary() { private fun observeRoomSummary() {
room.rx().liveRoomSummary() room.flow().liveRoomSummary()
.unwrap() .unwrap()
.execute { async -> .execute { async ->
val roomSummary = async.invoke() 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 powerLevelsContentLive
.subscribe { .onEach {
val powerLevelsHelper = PowerLevelsHelper(it) val powerLevelsHelper = PowerLevelsHelper(it)
val permissions = RoomSettingsViewState.ActionPermissions( val permissions = RoomSettingsViewState.ActionPermissions(
canChangeAvatar = powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, EventType.STATE_ROOM_AVATAR), 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, canAddChildren = powerLevelsHelper.isUserAllowedToSend(session.myUserId, true,
EventType.STATE_SPACE_CHILD) EventType.STATE_SPACE_CHILD)
) )
setState { copy(actionPermissions = permissions) } setState {
} copy(actionPermissions = permissions)
.disposeOnClear() }
}.launchIn(viewModelScope)
} }
private fun observeRoomHistoryVisibility() { private fun observeRoomHistoryVisibility() {
room.rx() room.flow()
.liveStateEvent(EventType.STATE_ROOM_HISTORY_VISIBILITY, QueryStringValue.NoCondition) .liveStateEvent(EventType.STATE_ROOM_HISTORY_VISIBILITY, QueryStringValue.NoCondition)
.mapOptional { it.content.toModel<RoomHistoryVisibilityContent>() } .mapOptional { it.content.toModel<RoomHistoryVisibilityContent>() }
.unwrap() .unwrap()
.subscribe { .mapNotNull { it.historyVisibility }
it.historyVisibility?.let { .setOnEach {
setState { copy(currentHistoryVisibility = it) } copy(currentHistoryVisibility = it)
}
} }
.disposeOnClear()
} }
private fun observeJoinRule() { private fun observeJoinRule() {
room.rx() room.flow()
.liveStateEvent(EventType.STATE_ROOM_JOIN_RULES, QueryStringValue.NoCondition) .liveStateEvent(EventType.STATE_ROOM_JOIN_RULES, QueryStringValue.NoCondition)
.mapOptional { it.content.toModel<RoomJoinRulesContent>() } .mapOptional { it.content.toModel<RoomJoinRulesContent>() }
.unwrap() .unwrap()
.subscribe { .mapNotNull { it.joinRules }
it.joinRules?.let { .setOnEach {
setState { copy(currentRoomJoinRules = it) } copy(currentRoomJoinRules = it)
}
} }
.disposeOnClear()
} }
private fun observeGuestAccess() { private fun observeGuestAccess() {
room.rx() room.flow()
.liveStateEvent(EventType.STATE_ROOM_GUEST_ACCESS, QueryStringValue.NoCondition) .liveStateEvent(EventType.STATE_ROOM_GUEST_ACCESS, QueryStringValue.NoCondition)
.mapOptional { it.content.toModel<RoomGuestAccessContent>() } .mapOptional { it.content.toModel<RoomGuestAccessContent>() }
.unwrap() .unwrap()
.subscribe { .mapNotNull { it.guestAccess }
it.guestAccess?.let { .setOnEach {
setState { copy(currentGuestAccess = it) } 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. * 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() { private fun observeRoomAvatar() {
room.rx() room.flow()
.liveStateEvent(EventType.STATE_ROOM_AVATAR, QueryStringValue.NoCondition) .liveStateEvent(EventType.STATE_ROOM_AVATAR, QueryStringValue.NoCondition)
.mapOptional { it.content.toModel<RoomAvatarContent>() } .mapOptional { it.content.toModel<RoomAvatarContent>() }
.unwrap() .unwrap()
.subscribe { .setOnEach {
setState { copy(currentRoomAvatarUrl = it.avatarUrl) } copy(currentRoomAvatarUrl = it.avatarUrl)
} }
.disposeOnClear()
} }
override fun handle(action: RoomSettingsAction) { override fun handle(action: RoomSettingsAction) {

View File

@ -30,8 +30,10 @@ import dagger.assisted.AssistedInject
import im.vector.app.AppStateHandler import im.vector.app.AppStateHandler
import im.vector.app.core.platform.EmptyViewEvents import im.vector.app.core.platform.EmptyViewEvents
import im.vector.app.core.platform.VectorViewModel 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 im.vector.app.features.session.coroutineScope
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.matrix.android.sdk.api.query.ActiveSpaceFilter import org.matrix.android.sdk.api.query.ActiveSpaceFilter
import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.Session
@ -87,9 +89,9 @@ class SpaceMenuViewModel @AssistedInject constructor(
} }
}.disposeOnClear() }.disposeOnClear()
PowerLevelsObservableFactory(room) PowerLevelsFlowFactory(room)
.createObservable() .createFlow()
.subscribe { .onEach {
val powerLevelsHelper = PowerLevelsHelper(it) val powerLevelsHelper = PowerLevelsHelper(it)
val canInvite = powerLevelsHelper.isUserAbleToInvite(session.myUserId) val canInvite = powerLevelsHelper.isUserAbleToInvite(session.myUserId)
@ -114,8 +116,7 @@ class SpaceMenuViewModel @AssistedInject constructor(
isLastAdmin = isLastAdmin isLastAdmin = isLastAdmin
) )
} }
} }.launchIn(viewModelScope)
.disposeOnClear()
} }
} }

View File

@ -16,7 +16,6 @@
package im.vector.app.features.spaces.explore package im.vector.app.features.spaces.explore
import androidx.lifecycle.viewModelScope
import com.airbnb.mvrx.ActivityViewModelContext import com.airbnb.mvrx.ActivityViewModelContext
import com.airbnb.mvrx.Fail import com.airbnb.mvrx.Fail
import com.airbnb.mvrx.FragmentViewModelContext import com.airbnb.mvrx.FragmentViewModelContext
@ -29,8 +28,10 @@ import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject import dagger.assisted.AssistedInject
import im.vector.app.core.platform.VectorViewModel 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.Dispatchers
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.matrix.android.sdk.api.session.Session 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.EventType
@ -83,17 +84,17 @@ class SpaceDirectoryViewModel @AssistedInject constructor(
private fun observePermissions() { private fun observePermissions() {
val room = session.getRoom(initialState.spaceId) ?: return val room = session.getRoom(initialState.spaceId) ?: return
val powerLevelsContentLive = PowerLevelsObservableFactory(room).createObservable() val powerLevelsContentLive = PowerLevelsFlowFactory(room).createFlow()
powerLevelsContentLive powerLevelsContentLive
.subscribe { .onEach {
val powerLevelsHelper = PowerLevelsHelper(it) val powerLevelsHelper = PowerLevelsHelper(it)
setState { setState {
copy(canAddRooms = powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, copy(canAddRooms = powerLevelsHelper.isUserAllowedToSend(session.myUserId, true,
EventType.STATE_SPACE_CHILD)) EventType.STATE_SPACE_CHILD))
} }
} }
.disposeOnClear() .launchIn(viewModelScope)
} }
private fun refreshFromApi(rootId: String?) = withState { state -> private fun refreshFromApi(rootId: String?) = withState { state ->

View File

@ -26,7 +26,9 @@ import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject import dagger.assisted.AssistedInject
import im.vector.app.core.platform.VectorViewModel 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.extensions.orFalse
import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
@ -63,9 +65,9 @@ class ShareSpaceViewModel @AssistedInject constructor(
private fun observePowerLevel() { private fun observePowerLevel() {
val room = session.getRoom(initialState.spaceId) ?: return val room = session.getRoom(initialState.spaceId) ?: return
PowerLevelsObservableFactory(room) PowerLevelsFlowFactory(room)
.createObservable() .createFlow()
.subscribe { powerLevelContent -> .onEach { powerLevelContent ->
val powerLevelsHelper = PowerLevelsHelper(powerLevelContent) val powerLevelsHelper = PowerLevelsHelper(powerLevelContent)
setState { setState {
copy( copy(
@ -73,7 +75,7 @@ class ShareSpaceViewModel @AssistedInject constructor(
) )
} }
} }
.disposeOnClear() .launchIn(viewModelScope)
} }
override fun handle(action: ShareSpaceAction) { override fun handle(action: ShareSpaceAction) {