Skip to content

Commit f72a34e

Browse files
author
ganfra
committed
Mavericks 2: continue replacing Rx
1 parent 0e01c64 commit f72a34e

20 files changed

+234
-241
lines changed

vector/src/main/java/im/vector/app/features/home/HomeDetailViewModel.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
package im.vector.app.features.home
1818

19-
import androidx.lifecycle.viewModelScope
2019
import com.airbnb.mvrx.FragmentViewModelContext
2120
import com.airbnb.mvrx.MavericksViewModelFactory
2221
import com.airbnb.mvrx.ViewModelContext
@@ -47,6 +46,7 @@ import org.matrix.android.sdk.api.session.room.RoomSortOrder
4746
import org.matrix.android.sdk.api.session.room.model.Membership
4847
import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams
4948
import org.matrix.android.sdk.api.util.toMatrixItem
49+
import org.matrix.android.sdk.flow.flow
5050
import org.matrix.android.sdk.rx.asObservable
5151
import org.matrix.android.sdk.rx.rx
5252
import timber.log.Timber
@@ -95,7 +95,7 @@ class HomeDetailViewModel @AssistedInject constructor(@Assisted initialState: Ho
9595
updateShowDialPadTab()
9696
observeDataStore()
9797
callManager.addProtocolsCheckerListener(this)
98-
session.rx().liveUser(session.myUserId).execute {
98+
session.flow().liveUser(session.myUserId).execute {
9999
copy(
100100
myMatrixItem = it.invoke()?.getOrNull()?.toMatrixItem()
101101
)

vector/src/main/java/im/vector/app/features/home/UnknownDeviceDetectorSharedViewModel.kt

+35-35
Original file line numberDiff line numberDiff line change
@@ -25,25 +25,25 @@ import com.airbnb.mvrx.Success
2525
import com.airbnb.mvrx.Uninitialized
2626
import com.airbnb.mvrx.ViewModelContext
2727
import dagger.assisted.Assisted
28-
import dagger.assisted.AssistedInject
2928
import dagger.assisted.AssistedFactory
29+
import dagger.assisted.AssistedInject
3030
import im.vector.app.core.platform.EmptyViewEvents
3131
import im.vector.app.core.platform.VectorViewModel
3232
import im.vector.app.core.platform.VectorViewModelAction
3333
import im.vector.app.features.settings.VectorPreferences
34-
import io.reactivex.Observable
34+
import kotlinx.coroutines.flow.combine
35+
import kotlinx.coroutines.flow.distinctUntilChanged
36+
import kotlinx.coroutines.flow.launchIn
37+
import kotlinx.coroutines.flow.onEach
38+
import kotlinx.coroutines.flow.sample
3539
import org.matrix.android.sdk.api.NoOpMatrixCallback
3640
import org.matrix.android.sdk.api.extensions.orFalse
3741
import org.matrix.android.sdk.api.session.Session
3842
import org.matrix.android.sdk.api.util.MatrixItem
39-
import org.matrix.android.sdk.api.util.Optional
4043
import org.matrix.android.sdk.api.util.toMatrixItem
41-
import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo
44+
import org.matrix.android.sdk.flow.flow
4245
import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo
43-
import org.matrix.android.sdk.internal.crypto.store.PrivateKeysInfo
44-
import org.matrix.android.sdk.rx.rx
4546
import timber.log.Timber
46-
import java.util.concurrent.TimeUnit
4747

4848
data class UnknownDevicesState(
4949
val myMatrixItem: MatrixItem.UserItem? = null,
@@ -98,31 +98,31 @@ class UnknownDeviceDetectorSharedViewModel @AssistedInject constructor(@Assisted
9898
}
9999
)
100100

101-
Observable.combineLatest<List<CryptoDeviceInfo>, List<DeviceInfo>, Optional<PrivateKeysInfo>, List<DeviceDetectionInfo>>(
102-
session.rx().liveUserCryptoDevices(session.myUserId),
103-
session.rx().liveMyDevicesInfo(),
104-
session.rx().liveCrossSigningPrivateKeys(),
105-
{ cryptoList, infoList, pInfo ->
106-
// Timber.v("## Detector trigger ${cryptoList.map { "${it.deviceId} ${it.trustLevel}" }}")
107-
// Timber.v("## Detector trigger canCrossSign ${pInfo.get().selfSigned != null}")
108-
infoList
109-
.filter { info ->
110-
// filter verified session, by checking the crypto device info
111-
cryptoList.firstOrNull { info.deviceId == it.deviceId }?.isVerified?.not().orFalse()
112-
}
113-
// filter out ignored devices
114-
.filter { !ignoredDeviceList.contains(it.deviceId) }
115-
.sortedByDescending { it.lastSeenTs }
116-
.map { deviceInfo ->
117-
val deviceKnownSince = cryptoList.firstOrNull { it.deviceId == deviceInfo.deviceId }?.firstTimeSeenLocalTs ?: 0
118-
DeviceDetectionInfo(
119-
deviceInfo,
120-
deviceKnownSince > currentSessionTs + 60_000, // short window to avoid false positive,
121-
pInfo.getOrNull()?.selfSigned != null // adding this to pass distinct when cross sign change
122-
)
123-
}
124-
}
101+
combine(
102+
session.flow().liveUserCryptoDevices(session.myUserId),
103+
session.flow().liveMyDevicesInfo(),
104+
session.flow().liveCrossSigningPrivateKeys()
125105
)
106+
{ cryptoList, infoList, pInfo ->
107+
// Timber.v("## Detector trigger ${cryptoList.map { "${it.deviceId} ${it.trustLevel}" }}")
108+
// Timber.v("## Detector trigger canCrossSign ${pInfo.get().selfSigned != null}")
109+
infoList
110+
.filter { info ->
111+
// filter verified session, by checking the crypto device info
112+
cryptoList.firstOrNull { info.deviceId == it.deviceId }?.isVerified?.not().orFalse()
113+
}
114+
// filter out ignored devices
115+
.filter { !ignoredDeviceList.contains(it.deviceId) }
116+
.sortedByDescending { it.lastSeenTs }
117+
.map { deviceInfo ->
118+
val deviceKnownSince = cryptoList.firstOrNull { it.deviceId == deviceInfo.deviceId }?.firstTimeSeenLocalTs ?: 0
119+
DeviceDetectionInfo(
120+
deviceInfo,
121+
deviceKnownSince > currentSessionTs + 60_000, // short window to avoid false positive,
122+
pInfo.getOrNull()?.selfSigned != null // adding this to pass distinct when cross sign change
123+
)
124+
}
125+
}
126126
.distinctUntilChanged()
127127
.execute { async ->
128128
// Timber.v("## Detector trigger passed distinct")
@@ -132,14 +132,14 @@ class UnknownDeviceDetectorSharedViewModel @AssistedInject constructor(@Assisted
132132
)
133133
}
134134

135-
session.rx().liveUserCryptoDevices(session.myUserId)
135+
session.flow().liveUserCryptoDevices(session.myUserId)
136136
.distinctUntilChanged()
137-
.throttleLast(5_000, TimeUnit.MILLISECONDS)
138-
.subscribe {
137+
.sample(5_000)
138+
.onEach {
139139
// If we have a new crypto device change, we might want to trigger refresh of device info
140140
session.cryptoService().fetchDevicesList(NoOpMatrixCallback())
141141
}
142-
.disposeOnClear()
142+
.launchIn(viewModelScope)
143143

144144
// trigger a refresh of lastSeen / last Ip
145145
session.cryptoService().fetchDevicesList(NoOpMatrixCallback())

vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt

+12-18
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ import com.airbnb.mvrx.Success
2828
import com.airbnb.mvrx.Uninitialized
2929
import com.airbnb.mvrx.ViewModelContext
3030
import com.jakewharton.rxrelay2.BehaviorRelay
31-
import com.jakewharton.rxrelay2.PublishRelay
3231
import dagger.assisted.Assisted
3332
import dagger.assisted.AssistedFactory
3433
import dagger.assisted.AssistedInject
@@ -60,11 +59,11 @@ import im.vector.app.features.session.coroutineScope
6059
import im.vector.app.features.settings.VectorDataStore
6160
import im.vector.app.features.settings.VectorPreferences
6261
import im.vector.app.features.voice.VoicePlayerHelper
63-
import io.reactivex.Observable
6462
import io.reactivex.rxkotlin.subscribeBy
65-
import io.reactivex.schedulers.Schedulers
6663
import kotlinx.coroutines.Dispatchers
64+
import kotlinx.coroutines.flow.MutableSharedFlow
6765
import kotlinx.coroutines.flow.collect
66+
import kotlinx.coroutines.flow.combine
6867
import kotlinx.coroutines.flow.distinctUntilChanged
6968
import kotlinx.coroutines.flow.filterIsInstance
7069
import kotlinx.coroutines.flow.launchIn
@@ -112,8 +111,6 @@ import org.matrix.android.sdk.api.util.toOptional
112111
import org.matrix.android.sdk.flow.flow
113112
import org.matrix.android.sdk.flow.unwrap
114113
import org.matrix.android.sdk.internal.crypto.model.event.WithHeldCode
115-
import org.matrix.android.sdk.rx.rx
116-
import org.matrix.android.sdk.rx.unwrap
117114
import timber.log.Timber
118115
import java.util.concurrent.TimeUnit
119116
import java.util.concurrent.atomic.AtomicBoolean
@@ -143,7 +140,7 @@ class RoomDetailViewModel @AssistedInject constructor(
143140
private val eventId = initialState.eventId
144141
private val invisibleEventsObservable = BehaviorRelay.create<RoomDetailAction.TimelineEventTurnsInvisible>()
145142
private val visibleEventsObservable = BehaviorRelay.create<RoomDetailAction.TimelineEventTurnsVisible>()
146-
private var timelineEvents = PublishRelay.create<List<TimelineEvent>>()
143+
private var timelineEvents = MutableSharedFlow<List<TimelineEvent>>(0)
147144
val timeline = timelineFactory.createTimeline(viewModelScope, room, eventId)
148145

149146
// Same lifecycle than the ViewModel (survive to screen rotation)
@@ -1533,14 +1530,12 @@ class RoomDetailViewModel @AssistedInject constructor(
15331530
}
15341531

15351532
private fun getUnreadState() {
1536-
Observable
1537-
.combineLatest<List<TimelineEvent>, RoomSummary, UnreadState>(
1538-
timelineEvents.observeOn(Schedulers.computation()),
1539-
room.rx().liveRoomSummary().unwrap(),
1540-
{ timelineEvents, roomSummary ->
1541-
computeUnreadState(timelineEvents, roomSummary)
1542-
}
1543-
)
1533+
combine(
1534+
timelineEvents,
1535+
room.flow().liveRoomSummary().unwrap()
1536+
) { timelineEvents, roomSummary ->
1537+
computeUnreadState(timelineEvents, roomSummary)
1538+
}
15441539
// We don't want live update of unread so we skip when we already had a HasUnread or HasNoUnread
15451540
.distinctUntilChanged { previous, current ->
15461541
when {
@@ -1549,10 +1544,9 @@ class RoomDetailViewModel @AssistedInject constructor(
15491544
else -> false
15501545
}
15511546
}
1552-
.subscribe {
1553-
setState { copy(unreadState = it) }
1547+
.setOnEach {
1548+
copy(unreadState = it)
15541549
}
1555-
.disposeOnClear()
15561550
}
15571551

15581552
private fun computeUnreadState(events: List<TimelineEvent>, roomSummary: RoomSummary): UnreadState {
@@ -1619,7 +1613,7 @@ class RoomDetailViewModel @AssistedInject constructor(
16191613
}
16201614

16211615
override fun onTimelineUpdated(snapshot: List<TimelineEvent>) {
1622-
timelineEvents.accept(snapshot)
1616+
timelineEvents.tryEmit(snapshot)
16231617

16241618
// PreviewUrl
16251619
if (vectorPreferences.showUrlPreviews()) {

vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt

+7-14
Original file line numberDiff line numberDiff line change
@@ -25,20 +25,17 @@ import com.airbnb.mvrx.Success
2525
import com.airbnb.mvrx.Uninitialized
2626
import com.airbnb.mvrx.ViewModelContext
2727
import dagger.assisted.Assisted
28-
import dagger.assisted.AssistedInject
2928
import dagger.assisted.AssistedFactory
29+
import dagger.assisted.AssistedInject
3030
import im.vector.app.R
3131
import im.vector.app.core.mvrx.runCatchingToAsync
3232
import im.vector.app.core.platform.VectorViewModel
3333
import im.vector.app.core.resources.StringProvider
3434
import im.vector.app.features.powerlevel.PowerLevelsFlowFactory
35-
import io.reactivex.Observable
36-
import io.reactivex.functions.BiFunction
3735
import kotlinx.coroutines.Dispatchers
38-
import kotlinx.coroutines.flow.Flow
3936
import kotlinx.coroutines.flow.combine
40-
import kotlinx.coroutines.flow.combineLatest
4137
import kotlinx.coroutines.flow.launchIn
38+
import kotlinx.coroutines.flow.map
4239
import kotlinx.coroutines.flow.onEach
4340
import kotlinx.coroutines.launch
4441
import kotlinx.coroutines.withContext
@@ -50,8 +47,6 @@ import org.matrix.android.sdk.api.session.profile.ProfileService
5047
import org.matrix.android.sdk.api.session.room.Room
5148
import org.matrix.android.sdk.api.session.room.members.roomMemberQueryParams
5249
import org.matrix.android.sdk.api.session.room.model.Membership
53-
import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent
54-
import org.matrix.android.sdk.api.session.room.model.RoomSummary
5550
import org.matrix.android.sdk.api.session.room.model.RoomType
5651
import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
5752
import org.matrix.android.sdk.api.session.room.powerlevels.Role
@@ -60,8 +55,6 @@ import org.matrix.android.sdk.api.util.toMatrixItem
6055
import org.matrix.android.sdk.api.util.toOptional
6156
import org.matrix.android.sdk.flow.flow
6257
import org.matrix.android.sdk.flow.unwrap
63-
import org.matrix.android.sdk.rx.rx
64-
import org.matrix.android.sdk.rx.unwrap
6558

6659
class RoomMemberProfileViewModel @AssistedInject constructor(@Assisted private val initialState: RoomMemberProfileViewState,
6760
private val stringProvider: StringProvider,
@@ -114,7 +107,7 @@ class RoomMemberProfileViewModel @AssistedInject constructor(@Assisted private v
114107
}
115108
}
116109

117-
session.rx().liveUserCryptoDevices(initialState.userId)
110+
session.flow().liveUserCryptoDevices(initialState.userId)
118111
.map {
119112
Pair(
120113
it.fold(true, { prev, dev -> prev && dev.isVerified }),
@@ -128,14 +121,14 @@ class RoomMemberProfileViewModel @AssistedInject constructor(@Assisted private v
128121
)
129122
}
130123

131-
session.rx().liveCrossSigningInfo(initialState.userId)
124+
session.flow().liveCrossSigningInfo(initialState.userId)
132125
.execute {
133126
copy(userMXCrossSigningInfo = it.invoke()?.getOrNull())
134127
}
135128
}
136129

137130
private fun observeIgnoredState() {
138-
session.rx().liveIgnoredUsers()
131+
session.flow().liveIgnoredUsers()
139132
.map { ignored ->
140133
ignored.find {
141134
it.userId == initialState.userId
@@ -252,7 +245,7 @@ class RoomMemberProfileViewModel @AssistedInject constructor(@Assisted private v
252245
val queryParams = roomMemberQueryParams {
253246
this.userId = QueryStringValue.Equals(initialState.userId, QueryStringValue.Case.SENSITIVE)
254247
}
255-
room.rx().liveRoomMembers(queryParams)
248+
room.flow().liveRoomMembers(queryParams)
256249
.map { it.firstOrNull().toOptional() }
257250
.unwrap()
258251
.execute {
@@ -312,7 +305,7 @@ class RoomMemberProfileViewModel @AssistedInject constructor(@Assisted private v
312305
roomSummaryLive.execute {
313306
copy(isRoomEncrypted = it.invoke()?.isEncrypted == true)
314307
}
315-
roomSummaryLive.combine(powerLevelsContentLive){roomSummary, powerLevelsContent ->
308+
roomSummaryLive.combine(powerLevelsContentLive) { roomSummary, powerLevelsContent ->
316309
val roomName = roomSummary.toMatrixItem().getBestName()
317310
val powerLevelsHelper = PowerLevelsHelper(powerLevelsContent)
318311
when (val userPowerLevel = powerLevelsHelper.getUserRole(initialState.userId)) {

vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheetViewModel.kt

+3-2
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import org.matrix.android.sdk.api.session.crypto.crosssigning.MXCrossSigningInfo
3333
import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod
3434
import org.matrix.android.sdk.api.util.MatrixItem
3535
import org.matrix.android.sdk.api.util.toMatrixItem
36+
import org.matrix.android.sdk.flow.flow
3637
import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo
3738
import org.matrix.android.sdk.rx.rx
3839

@@ -55,14 +56,14 @@ class DeviceListBottomSheetViewModel @AssistedInject constructor(@Assisted priva
5556
}
5657

5758
init {
58-
session.rx().liveUserCryptoDevices(args.userId)
59+
session.flow().liveUserCryptoDevices(args.userId)
5960
.execute {
6061
copy(cryptoDevices = it).also {
6162
refreshSelectedId()
6263
}
6364
}
6465

65-
session.rx().liveCrossSigningInfo(args.userId)
66+
session.flow().liveCrossSigningInfo(args.userId)
6667
.execute {
6768
copy(memberCrossSigningKey = it.invoke()?.getOrNull())
6869
}

vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasViewModel.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ class RoomAliasViewModel @AssistedInject constructor(@Assisted initialState: Roo
131131
}
132132

133133
private fun observeRoomSummary() {
134-
room.rx().liveRoomSummary()
134+
room.flow().liveRoomSummary()
135135
.unwrap()
136136
.execute { async ->
137137
copy(

vector/src/main/java/im/vector/app/features/roomprofile/banned/RoomBannedMemberListViewModel.kt

+4-3
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ import org.matrix.android.sdk.api.session.room.model.Membership
3838
import org.matrix.android.sdk.api.session.room.model.RoomMemberContent
3939
import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary
4040
import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
41+
import org.matrix.android.sdk.flow.flow
42+
import org.matrix.android.sdk.flow.unwrap
4143
import org.matrix.android.sdk.rx.rx
4244
import org.matrix.android.sdk.rx.unwrap
4345

@@ -54,15 +56,14 @@ class RoomBannedMemberListViewModel @AssistedInject constructor(@Assisted initia
5456
private val room = session.getRoom(initialState.roomId)!!
5557

5658
init {
57-
val rxRoom = room.rx()
5859

59-
room.rx().liveRoomSummary()
60+
room.flow().liveRoomSummary()
6061
.unwrap()
6162
.execute { async ->
6263
copy(roomSummary = async)
6364
}
6465

65-
rxRoom.liveRoomMembers(roomMemberQueryParams { memberships = listOf(Membership.BAN) })
66+
room.flow().liveRoomMembers(roomMemberQueryParams { memberships = listOf(Membership.BAN) })
6667
.execute {
6768
copy(
6869
bannedMemberSummaries = it

0 commit comments

Comments
 (0)