Mavericks 2: continue replacing Rx
This commit is contained in:
parent
0e01c64f69
commit
f72a34ed08
@ -16,7 +16,6 @@
|
||||
|
||||
package im.vector.app.features.home
|
||||
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.airbnb.mvrx.FragmentViewModelContext
|
||||
import com.airbnb.mvrx.MavericksViewModelFactory
|
||||
import com.airbnb.mvrx.ViewModelContext
|
||||
@ -47,6 +46,7 @@ import org.matrix.android.sdk.api.session.room.RoomSortOrder
|
||||
import org.matrix.android.sdk.api.session.room.model.Membership
|
||||
import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams
|
||||
import org.matrix.android.sdk.api.util.toMatrixItem
|
||||
import org.matrix.android.sdk.flow.flow
|
||||
import org.matrix.android.sdk.rx.asObservable
|
||||
import org.matrix.android.sdk.rx.rx
|
||||
import timber.log.Timber
|
||||
@ -95,7 +95,7 @@ class HomeDetailViewModel @AssistedInject constructor(@Assisted initialState: Ho
|
||||
updateShowDialPadTab()
|
||||
observeDataStore()
|
||||
callManager.addProtocolsCheckerListener(this)
|
||||
session.rx().liveUser(session.myUserId).execute {
|
||||
session.flow().liveUser(session.myUserId).execute {
|
||||
copy(
|
||||
myMatrixItem = it.invoke()?.getOrNull()?.toMatrixItem()
|
||||
)
|
||||
|
@ -25,25 +25,25 @@ import com.airbnb.mvrx.Success
|
||||
import com.airbnb.mvrx.Uninitialized
|
||||
import com.airbnb.mvrx.ViewModelContext
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedInject
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import im.vector.app.core.platform.EmptyViewEvents
|
||||
import im.vector.app.core.platform.VectorViewModel
|
||||
import im.vector.app.core.platform.VectorViewModelAction
|
||||
import im.vector.app.features.settings.VectorPreferences
|
||||
import io.reactivex.Observable
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.sample
|
||||
import org.matrix.android.sdk.api.NoOpMatrixCallback
|
||||
import org.matrix.android.sdk.api.extensions.orFalse
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.api.util.MatrixItem
|
||||
import org.matrix.android.sdk.api.util.Optional
|
||||
import org.matrix.android.sdk.api.util.toMatrixItem
|
||||
import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo
|
||||
import org.matrix.android.sdk.flow.flow
|
||||
import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo
|
||||
import org.matrix.android.sdk.internal.crypto.store.PrivateKeysInfo
|
||||
import org.matrix.android.sdk.rx.rx
|
||||
import timber.log.Timber
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
data class UnknownDevicesState(
|
||||
val myMatrixItem: MatrixItem.UserItem? = null,
|
||||
@ -98,31 +98,31 @@ class UnknownDeviceDetectorSharedViewModel @AssistedInject constructor(@Assisted
|
||||
}
|
||||
)
|
||||
|
||||
Observable.combineLatest<List<CryptoDeviceInfo>, List<DeviceInfo>, Optional<PrivateKeysInfo>, List<DeviceDetectionInfo>>(
|
||||
session.rx().liveUserCryptoDevices(session.myUserId),
|
||||
session.rx().liveMyDevicesInfo(),
|
||||
session.rx().liveCrossSigningPrivateKeys(),
|
||||
{ cryptoList, infoList, pInfo ->
|
||||
// Timber.v("## Detector trigger ${cryptoList.map { "${it.deviceId} ${it.trustLevel}" }}")
|
||||
// Timber.v("## Detector trigger canCrossSign ${pInfo.get().selfSigned != null}")
|
||||
infoList
|
||||
.filter { info ->
|
||||
// filter verified session, by checking the crypto device info
|
||||
cryptoList.firstOrNull { info.deviceId == it.deviceId }?.isVerified?.not().orFalse()
|
||||
}
|
||||
// filter out ignored devices
|
||||
.filter { !ignoredDeviceList.contains(it.deviceId) }
|
||||
.sortedByDescending { it.lastSeenTs }
|
||||
.map { deviceInfo ->
|
||||
val deviceKnownSince = cryptoList.firstOrNull { it.deviceId == deviceInfo.deviceId }?.firstTimeSeenLocalTs ?: 0
|
||||
DeviceDetectionInfo(
|
||||
deviceInfo,
|
||||
deviceKnownSince > currentSessionTs + 60_000, // short window to avoid false positive,
|
||||
pInfo.getOrNull()?.selfSigned != null // adding this to pass distinct when cross sign change
|
||||
)
|
||||
}
|
||||
}
|
||||
combine(
|
||||
session.flow().liveUserCryptoDevices(session.myUserId),
|
||||
session.flow().liveMyDevicesInfo(),
|
||||
session.flow().liveCrossSigningPrivateKeys()
|
||||
)
|
||||
{ cryptoList, infoList, pInfo ->
|
||||
// Timber.v("## Detector trigger ${cryptoList.map { "${it.deviceId} ${it.trustLevel}" }}")
|
||||
// Timber.v("## Detector trigger canCrossSign ${pInfo.get().selfSigned != null}")
|
||||
infoList
|
||||
.filter { info ->
|
||||
// filter verified session, by checking the crypto device info
|
||||
cryptoList.firstOrNull { info.deviceId == it.deviceId }?.isVerified?.not().orFalse()
|
||||
}
|
||||
// filter out ignored devices
|
||||
.filter { !ignoredDeviceList.contains(it.deviceId) }
|
||||
.sortedByDescending { it.lastSeenTs }
|
||||
.map { deviceInfo ->
|
||||
val deviceKnownSince = cryptoList.firstOrNull { it.deviceId == deviceInfo.deviceId }?.firstTimeSeenLocalTs ?: 0
|
||||
DeviceDetectionInfo(
|
||||
deviceInfo,
|
||||
deviceKnownSince > currentSessionTs + 60_000, // short window to avoid false positive,
|
||||
pInfo.getOrNull()?.selfSigned != null // adding this to pass distinct when cross sign change
|
||||
)
|
||||
}
|
||||
}
|
||||
.distinctUntilChanged()
|
||||
.execute { async ->
|
||||
// Timber.v("## Detector trigger passed distinct")
|
||||
@ -132,14 +132,14 @@ class UnknownDeviceDetectorSharedViewModel @AssistedInject constructor(@Assisted
|
||||
)
|
||||
}
|
||||
|
||||
session.rx().liveUserCryptoDevices(session.myUserId)
|
||||
session.flow().liveUserCryptoDevices(session.myUserId)
|
||||
.distinctUntilChanged()
|
||||
.throttleLast(5_000, TimeUnit.MILLISECONDS)
|
||||
.subscribe {
|
||||
.sample(5_000)
|
||||
.onEach {
|
||||
// If we have a new crypto device change, we might want to trigger refresh of device info
|
||||
session.cryptoService().fetchDevicesList(NoOpMatrixCallback())
|
||||
}
|
||||
.disposeOnClear()
|
||||
.launchIn(viewModelScope)
|
||||
|
||||
// trigger a refresh of lastSeen / last Ip
|
||||
session.cryptoService().fetchDevicesList(NoOpMatrixCallback())
|
||||
|
@ -28,7 +28,6 @@ import com.airbnb.mvrx.Success
|
||||
import com.airbnb.mvrx.Uninitialized
|
||||
import com.airbnb.mvrx.ViewModelContext
|
||||
import com.jakewharton.rxrelay2.BehaviorRelay
|
||||
import com.jakewharton.rxrelay2.PublishRelay
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
@ -60,11 +59,11 @@ import im.vector.app.features.session.coroutineScope
|
||||
import im.vector.app.features.settings.VectorDataStore
|
||||
import im.vector.app.features.settings.VectorPreferences
|
||||
import im.vector.app.features.voice.VoicePlayerHelper
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.rxkotlin.subscribeBy
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.collect
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.filterIsInstance
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
@ -112,8 +111,6 @@ 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.internal.crypto.model.event.WithHeldCode
|
||||
import org.matrix.android.sdk.rx.rx
|
||||
import org.matrix.android.sdk.rx.unwrap
|
||||
import timber.log.Timber
|
||||
import java.util.concurrent.TimeUnit
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
@ -143,7 +140,7 @@ class RoomDetailViewModel @AssistedInject constructor(
|
||||
private val eventId = initialState.eventId
|
||||
private val invisibleEventsObservable = BehaviorRelay.create<RoomDetailAction.TimelineEventTurnsInvisible>()
|
||||
private val visibleEventsObservable = BehaviorRelay.create<RoomDetailAction.TimelineEventTurnsVisible>()
|
||||
private var timelineEvents = PublishRelay.create<List<TimelineEvent>>()
|
||||
private var timelineEvents = MutableSharedFlow<List<TimelineEvent>>(0)
|
||||
val timeline = timelineFactory.createTimeline(viewModelScope, room, eventId)
|
||||
|
||||
// Same lifecycle than the ViewModel (survive to screen rotation)
|
||||
@ -1533,14 +1530,12 @@ class RoomDetailViewModel @AssistedInject constructor(
|
||||
}
|
||||
|
||||
private fun getUnreadState() {
|
||||
Observable
|
||||
.combineLatest<List<TimelineEvent>, RoomSummary, UnreadState>(
|
||||
timelineEvents.observeOn(Schedulers.computation()),
|
||||
room.rx().liveRoomSummary().unwrap(),
|
||||
{ timelineEvents, roomSummary ->
|
||||
computeUnreadState(timelineEvents, roomSummary)
|
||||
}
|
||||
)
|
||||
combine(
|
||||
timelineEvents,
|
||||
room.flow().liveRoomSummary().unwrap()
|
||||
) { timelineEvents, roomSummary ->
|
||||
computeUnreadState(timelineEvents, roomSummary)
|
||||
}
|
||||
// We don't want live update of unread so we skip when we already had a HasUnread or HasNoUnread
|
||||
.distinctUntilChanged { previous, current ->
|
||||
when {
|
||||
@ -1549,10 +1544,9 @@ class RoomDetailViewModel @AssistedInject constructor(
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
.subscribe {
|
||||
setState { copy(unreadState = it) }
|
||||
.setOnEach {
|
||||
copy(unreadState = it)
|
||||
}
|
||||
.disposeOnClear()
|
||||
}
|
||||
|
||||
private fun computeUnreadState(events: List<TimelineEvent>, roomSummary: RoomSummary): UnreadState {
|
||||
@ -1619,7 +1613,7 @@ class RoomDetailViewModel @AssistedInject constructor(
|
||||
}
|
||||
|
||||
override fun onTimelineUpdated(snapshot: List<TimelineEvent>) {
|
||||
timelineEvents.accept(snapshot)
|
||||
timelineEvents.tryEmit(snapshot)
|
||||
|
||||
// PreviewUrl
|
||||
if (vectorPreferences.showUrlPreviews()) {
|
||||
|
@ -25,20 +25,17 @@ import com.airbnb.mvrx.Success
|
||||
import com.airbnb.mvrx.Uninitialized
|
||||
import com.airbnb.mvrx.ViewModelContext
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedInject
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
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.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.map
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
@ -50,8 +47,6 @@ import org.matrix.android.sdk.api.session.profile.ProfileService
|
||||
import org.matrix.android.sdk.api.session.room.Room
|
||||
import org.matrix.android.sdk.api.session.room.members.roomMemberQueryParams
|
||||
import org.matrix.android.sdk.api.session.room.model.Membership
|
||||
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.model.RoomType
|
||||
import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
|
||||
import org.matrix.android.sdk.api.session.room.powerlevels.Role
|
||||
@ -60,8 +55,6 @@ 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
|
||||
|
||||
class RoomMemberProfileViewModel @AssistedInject constructor(@Assisted private val initialState: RoomMemberProfileViewState,
|
||||
private val stringProvider: StringProvider,
|
||||
@ -114,7 +107,7 @@ class RoomMemberProfileViewModel @AssistedInject constructor(@Assisted private v
|
||||
}
|
||||
}
|
||||
|
||||
session.rx().liveUserCryptoDevices(initialState.userId)
|
||||
session.flow().liveUserCryptoDevices(initialState.userId)
|
||||
.map {
|
||||
Pair(
|
||||
it.fold(true, { prev, dev -> prev && dev.isVerified }),
|
||||
@ -128,14 +121,14 @@ class RoomMemberProfileViewModel @AssistedInject constructor(@Assisted private v
|
||||
)
|
||||
}
|
||||
|
||||
session.rx().liveCrossSigningInfo(initialState.userId)
|
||||
session.flow().liveCrossSigningInfo(initialState.userId)
|
||||
.execute {
|
||||
copy(userMXCrossSigningInfo = it.invoke()?.getOrNull())
|
||||
}
|
||||
}
|
||||
|
||||
private fun observeIgnoredState() {
|
||||
session.rx().liveIgnoredUsers()
|
||||
session.flow().liveIgnoredUsers()
|
||||
.map { ignored ->
|
||||
ignored.find {
|
||||
it.userId == initialState.userId
|
||||
@ -252,7 +245,7 @@ class RoomMemberProfileViewModel @AssistedInject constructor(@Assisted private v
|
||||
val queryParams = roomMemberQueryParams {
|
||||
this.userId = QueryStringValue.Equals(initialState.userId, QueryStringValue.Case.SENSITIVE)
|
||||
}
|
||||
room.rx().liveRoomMembers(queryParams)
|
||||
room.flow().liveRoomMembers(queryParams)
|
||||
.map { it.firstOrNull().toOptional() }
|
||||
.unwrap()
|
||||
.execute {
|
||||
@ -312,7 +305,7 @@ class RoomMemberProfileViewModel @AssistedInject constructor(@Assisted private v
|
||||
roomSummaryLive.execute {
|
||||
copy(isRoomEncrypted = it.invoke()?.isEncrypted == true)
|
||||
}
|
||||
roomSummaryLive.combine(powerLevelsContentLive){roomSummary, powerLevelsContent ->
|
||||
roomSummaryLive.combine(powerLevelsContentLive) { roomSummary, powerLevelsContent ->
|
||||
val roomName = roomSummary.toMatrixItem().getBestName()
|
||||
val powerLevelsHelper = PowerLevelsHelper(powerLevelsContent)
|
||||
when (val userPowerLevel = powerLevelsHelper.getUserRole(initialState.userId)) {
|
||||
|
@ -33,6 +33,7 @@ import org.matrix.android.sdk.api.session.crypto.crosssigning.MXCrossSigningInfo
|
||||
import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod
|
||||
import org.matrix.android.sdk.api.util.MatrixItem
|
||||
import org.matrix.android.sdk.api.util.toMatrixItem
|
||||
import org.matrix.android.sdk.flow.flow
|
||||
import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo
|
||||
import org.matrix.android.sdk.rx.rx
|
||||
|
||||
@ -55,14 +56,14 @@ class DeviceListBottomSheetViewModel @AssistedInject constructor(@Assisted priva
|
||||
}
|
||||
|
||||
init {
|
||||
session.rx().liveUserCryptoDevices(args.userId)
|
||||
session.flow().liveUserCryptoDevices(args.userId)
|
||||
.execute {
|
||||
copy(cryptoDevices = it).also {
|
||||
refreshSelectedId()
|
||||
}
|
||||
}
|
||||
|
||||
session.rx().liveCrossSigningInfo(args.userId)
|
||||
session.flow().liveCrossSigningInfo(args.userId)
|
||||
.execute {
|
||||
copy(memberCrossSigningKey = it.invoke()?.getOrNull())
|
||||
}
|
||||
|
@ -131,7 +131,7 @@ class RoomAliasViewModel @AssistedInject constructor(@Assisted initialState: Roo
|
||||
}
|
||||
|
||||
private fun observeRoomSummary() {
|
||||
room.rx().liveRoomSummary()
|
||||
room.flow().liveRoomSummary()
|
||||
.unwrap()
|
||||
.execute { async ->
|
||||
copy(
|
||||
|
@ -38,6 +38,8 @@ import org.matrix.android.sdk.api.session.room.model.Membership
|
||||
import org.matrix.android.sdk.api.session.room.model.RoomMemberContent
|
||||
import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary
|
||||
import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
|
||||
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
|
||||
|
||||
@ -54,15 +56,14 @@ class RoomBannedMemberListViewModel @AssistedInject constructor(@Assisted initia
|
||||
private val room = session.getRoom(initialState.roomId)!!
|
||||
|
||||
init {
|
||||
val rxRoom = room.rx()
|
||||
|
||||
room.rx().liveRoomSummary()
|
||||
room.flow().liveRoomSummary()
|
||||
.unwrap()
|
||||
.execute { async ->
|
||||
copy(roomSummary = async)
|
||||
}
|
||||
|
||||
rxRoom.liveRoomMembers(roomMemberQueryParams { memberships = listOf(Membership.BAN) })
|
||||
room.flow().liveRoomMembers(roomMemberQueryParams { memberships = listOf(Membership.BAN) })
|
||||
.execute {
|
||||
copy(
|
||||
bannedMemberSummaries = it
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
package im.vector.app.features.roomprofile.members
|
||||
|
||||
import androidx.lifecycle.asFlow
|
||||
import com.airbnb.mvrx.ActivityViewModelContext
|
||||
import com.airbnb.mvrx.FragmentViewModelContext
|
||||
import com.airbnb.mvrx.MavericksViewModelFactory
|
||||
@ -27,10 +28,16 @@ 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.PowerLevelsFlowFactory
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.catch
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.flatMapLatest
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.switchMap
|
||||
import kotlinx.coroutines.launch
|
||||
import org.matrix.android.sdk.api.crypto.RoomEncryptionTrustLevel
|
||||
import org.matrix.android.sdk.api.extensions.orFalse
|
||||
@ -44,10 +51,9 @@ import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent
|
||||
import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary
|
||||
import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
|
||||
import org.matrix.android.sdk.api.session.room.powerlevels.Role
|
||||
import org.matrix.android.sdk.rx.asObservable
|
||||
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
|
||||
import timber.log.Timber
|
||||
|
||||
class RoomMemberListViewModel @AssistedInject constructor(@Assisted initialState: RoomMemberListViewState,
|
||||
@ -87,28 +93,28 @@ class RoomMemberListViewModel @AssistedInject constructor(@Assisted initialState
|
||||
memberships = Membership.activeMemberships()
|
||||
}
|
||||
|
||||
Observable
|
||||
.combineLatest<List<RoomMemberSummary>, PowerLevelsContent, RoomMemberSummaries>(
|
||||
room.rx().liveRoomMembers(roomMemberQueryParams),
|
||||
room.rx()
|
||||
.liveStateEvent(EventType.STATE_ROOM_POWER_LEVELS, QueryStringValue.NoCondition)
|
||||
.mapOptional { it.content.toModel<PowerLevelsContent>() }
|
||||
.unwrap(),
|
||||
{ roomMembers, powerLevelsContent ->
|
||||
buildRoomMemberSummaries(powerLevelsContent, roomMembers)
|
||||
}
|
||||
)
|
||||
combine(
|
||||
room.flow().liveRoomMembers(roomMemberQueryParams),
|
||||
room.flow()
|
||||
.liveStateEvent(EventType.STATE_ROOM_POWER_LEVELS, QueryStringValue.NoCondition)
|
||||
.mapOptional { it.content.toModel<PowerLevelsContent>() }
|
||||
.unwrap()
|
||||
)
|
||||
{ roomMembers, powerLevelsContent ->
|
||||
buildRoomMemberSummaries(powerLevelsContent, roomMembers)
|
||||
}
|
||||
|
||||
.execute { async ->
|
||||
copy(roomMemberSummaries = async)
|
||||
}
|
||||
|
||||
if (room.isEncrypted()) {
|
||||
room.rx().liveRoomMembers(roomMemberQueryParams)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.switchMap { membersSummary ->
|
||||
room.flow().liveRoomMembers(roomMemberQueryParams)
|
||||
.flowOn(Dispatchers.Main)
|
||||
.flatMapLatest { membersSummary ->
|
||||
session.cryptoService().getLiveCryptoDeviceInfo(membersSummary.map { it.userId })
|
||||
.asObservable()
|
||||
.doOnError { Timber.e(it) }
|
||||
.asFlow()
|
||||
.catch { Timber.e(it) }
|
||||
.map { deviceList ->
|
||||
// If any key change, emit the userIds list
|
||||
deviceList.groupBy { it.userId }.mapValues {
|
||||
@ -147,7 +153,7 @@ class RoomMemberListViewModel @AssistedInject constructor(@Assisted initialState
|
||||
}
|
||||
|
||||
private fun observeRoomSummary() {
|
||||
room.rx().liveRoomSummary()
|
||||
room.flow().liveRoomSummary()
|
||||
.unwrap()
|
||||
.execute { async ->
|
||||
copy(roomSummary = async)
|
||||
@ -155,7 +161,7 @@ class RoomMemberListViewModel @AssistedInject constructor(@Assisted initialState
|
||||
}
|
||||
|
||||
private fun observeThirdPartyInvites() {
|
||||
room.rx().liveStateEvents(setOf(EventType.STATE_ROOM_THIRD_PARTY_INVITE))
|
||||
room.flow().liveStateEvents(setOf(EventType.STATE_ROOM_THIRD_PARTY_INVITE))
|
||||
.execute { async ->
|
||||
copy(threePidInvites = async)
|
||||
}
|
||||
|
@ -28,6 +28,8 @@ import im.vector.app.core.platform.VectorViewModel
|
||||
import im.vector.app.features.home.room.list.actions.RoomListQuickActionsBottomSheet
|
||||
import kotlinx.coroutines.launch
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
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
|
||||
|
||||
@ -64,7 +66,7 @@ class RoomNotificationSettingsViewModel @AssistedInject constructor(
|
||||
}
|
||||
|
||||
private fun observeSummary() {
|
||||
room.rx().liveRoomSummary()
|
||||
room.flow().liveRoomSummary()
|
||||
.unwrap()
|
||||
.execute { async ->
|
||||
copy(roomSummary = async)
|
||||
|
@ -16,7 +16,6 @@
|
||||
|
||||
package im.vector.app.features.roomprofile.uploads
|
||||
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.airbnb.mvrx.ActivityViewModelContext
|
||||
import com.airbnb.mvrx.Fail
|
||||
import com.airbnb.mvrx.FragmentViewModelContext
|
||||
@ -25,15 +24,15 @@ import com.airbnb.mvrx.MavericksViewModelFactory
|
||||
import com.airbnb.mvrx.Success
|
||||
import com.airbnb.mvrx.ViewModelContext
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedInject
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import im.vector.app.core.extensions.exhaustive
|
||||
import im.vector.app.core.platform.VectorViewModel
|
||||
import kotlinx.coroutines.launch
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.api.session.room.model.message.MessageType
|
||||
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.unwrap
|
||||
|
||||
class RoomUploadsViewModel @AssistedInject constructor(
|
||||
@Assisted initialState: RoomUploadsViewState,
|
||||
@ -66,7 +65,7 @@ class RoomUploadsViewModel @AssistedInject constructor(
|
||||
}
|
||||
|
||||
private fun observeRoomSummary() {
|
||||
room.rx().liveRoomSummary()
|
||||
room.flow().liveRoomSummary()
|
||||
.unwrap()
|
||||
.execute { async ->
|
||||
copy(roomSummary = async)
|
||||
|
@ -15,7 +15,6 @@
|
||||
*/
|
||||
package im.vector.app.features.settings.crosssigning
|
||||
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.airbnb.mvrx.FragmentViewModelContext
|
||||
import com.airbnb.mvrx.MavericksViewModelFactory
|
||||
import com.airbnb.mvrx.ViewModelContext
|
||||
@ -28,8 +27,8 @@ import im.vector.app.core.platform.VectorViewModel
|
||||
import im.vector.app.core.resources.StringProvider
|
||||
import im.vector.app.features.auth.ReAuthActivity
|
||||
import im.vector.app.features.login.ReAuthHelper
|
||||
import io.reactivex.Observable
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.launch
|
||||
import org.matrix.android.sdk.api.auth.UIABaseAuth
|
||||
import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor
|
||||
@ -38,14 +37,11 @@ import org.matrix.android.sdk.api.auth.data.LoginFlowTypes
|
||||
import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse
|
||||
import org.matrix.android.sdk.api.auth.registration.nextUncompletedStage
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.api.session.crypto.crosssigning.MXCrossSigningInfo
|
||||
import org.matrix.android.sdk.api.util.Optional
|
||||
import org.matrix.android.sdk.flow.flow
|
||||
import org.matrix.android.sdk.internal.crypto.crosssigning.fromBase64
|
||||
import org.matrix.android.sdk.internal.crypto.crosssigning.isVerified
|
||||
import org.matrix.android.sdk.internal.crypto.model.rest.DefaultBaseAuth
|
||||
import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo
|
||||
import org.matrix.android.sdk.internal.util.awaitCallback
|
||||
import org.matrix.android.sdk.rx.rx
|
||||
import timber.log.Timber
|
||||
import kotlin.coroutines.Continuation
|
||||
import kotlin.coroutines.resume
|
||||
@ -59,26 +55,26 @@ class CrossSigningSettingsViewModel @AssistedInject constructor(
|
||||
) : VectorViewModel<CrossSigningSettingsViewState, CrossSigningSettingsAction, CrossSigningSettingsViewEvents>(initialState) {
|
||||
|
||||
init {
|
||||
Observable.combineLatest<List<DeviceInfo>, Optional<MXCrossSigningInfo>, Pair<List<DeviceInfo>, Optional<MXCrossSigningInfo>>>(
|
||||
session.rx().liveMyDevicesInfo(),
|
||||
session.rx().liveCrossSigningInfo(session.myUserId),
|
||||
{ myDevicesInfo, mxCrossSigningInfo ->
|
||||
myDevicesInfo to mxCrossSigningInfo
|
||||
}
|
||||
combine(
|
||||
session.flow().liveMyDevicesInfo(),
|
||||
session.flow().liveCrossSigningInfo(session.myUserId)
|
||||
)
|
||||
.execute { data ->
|
||||
val crossSigningKeys = data.invoke()?.second?.getOrNull()
|
||||
val xSigningIsEnableInAccount = crossSigningKeys != null
|
||||
val xSigningKeysAreTrusted = session.cryptoService().crossSigningService().checkUserTrust(session.myUserId).isVerified()
|
||||
val xSigningKeyCanSign = session.cryptoService().crossSigningService().canCrossSign()
|
||||
{ myDevicesInfo, mxCrossSigningInfo ->
|
||||
myDevicesInfo to mxCrossSigningInfo
|
||||
}
|
||||
.execute { data ->
|
||||
val crossSigningKeys = data.invoke()?.second?.getOrNull()
|
||||
val xSigningIsEnableInAccount = crossSigningKeys != null
|
||||
val xSigningKeysAreTrusted = session.cryptoService().crossSigningService().checkUserTrust(session.myUserId).isVerified()
|
||||
val xSigningKeyCanSign = session.cryptoService().crossSigningService().canCrossSign()
|
||||
|
||||
copy(
|
||||
crossSigningInfo = crossSigningKeys,
|
||||
xSigningIsEnableInAccount = xSigningIsEnableInAccount,
|
||||
xSigningKeysAreTrusted = xSigningKeysAreTrusted,
|
||||
xSigningKeyCanSign = xSigningKeyCanSign
|
||||
)
|
||||
}
|
||||
copy(
|
||||
crossSigningInfo = crossSigningKeys,
|
||||
xSigningIsEnableInAccount = xSigningIsEnableInAccount,
|
||||
xSigningKeysAreTrusted = xSigningKeysAreTrusted,
|
||||
xSigningKeyCanSign = xSigningKeyCanSign
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
var uiaContinuation: Continuation<UIABaseAuth>? = null
|
||||
@ -126,7 +122,7 @@ class CrossSigningSettingsViewModel @AssistedInject constructor(
|
||||
}
|
||||
Unit
|
||||
}
|
||||
is CrossSigningSettingsAction.SsoAuthDone -> {
|
||||
is CrossSigningSettingsAction.SsoAuthDone -> {
|
||||
Timber.d("## UIA - FallBack success")
|
||||
if (pendingAuth != null) {
|
||||
uiaContinuation?.resume(pendingAuth!!)
|
||||
@ -134,7 +130,7 @@ class CrossSigningSettingsViewModel @AssistedInject constructor(
|
||||
uiaContinuation?.resumeWithException(IllegalArgumentException())
|
||||
}
|
||||
}
|
||||
is CrossSigningSettingsAction.PasswordAuthDone -> {
|
||||
is CrossSigningSettingsAction.PasswordAuthDone -> {
|
||||
val decryptedPass = session.loadSecureSecret<String>(action.password.fromBase64().inputStream(), ReAuthActivity.DEFAULT_RESULT_KEYSTORE_ALIAS)
|
||||
uiaContinuation?.resume(
|
||||
UserPasswordAuth(
|
||||
@ -144,7 +140,7 @@ class CrossSigningSettingsViewModel @AssistedInject constructor(
|
||||
)
|
||||
)
|
||||
}
|
||||
CrossSigningSettingsAction.ReAuthCancelled -> {
|
||||
CrossSigningSettingsAction.ReAuthCancelled -> {
|
||||
Timber.d("## UIA - Reauth cancelled")
|
||||
_viewEvents.post(CrossSigningSettingsViewEvents.HideModalWaitingView)
|
||||
uiaContinuation?.resumeWithException(Exception())
|
||||
|
@ -25,7 +25,9 @@ import dagger.assisted.AssistedFactory
|
||||
import im.vector.app.core.platform.EmptyAction
|
||||
import im.vector.app.core.platform.EmptyViewEvents
|
||||
import im.vector.app.core.platform.VectorViewModel
|
||||
import kotlinx.coroutines.flow.map
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.flow.flow
|
||||
import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo
|
||||
import org.matrix.android.sdk.rx.rx
|
||||
|
||||
@ -48,7 +50,7 @@ class DeviceVerificationInfoBottomSheetViewModel @AssistedInject constructor(@As
|
||||
isRecoverySetup = session.sharedSecretStorageService.isRecoverySetup()
|
||||
)
|
||||
}
|
||||
session.rx().liveCrossSigningInfo(session.myUserId)
|
||||
session.flow().liveCrossSigningInfo(session.myUserId)
|
||||
.execute {
|
||||
copy(
|
||||
hasAccountCrossSigning = it.invoke()?.getOrNull() != null,
|
||||
@ -56,7 +58,7 @@ class DeviceVerificationInfoBottomSheetViewModel @AssistedInject constructor(@As
|
||||
)
|
||||
}
|
||||
|
||||
session.rx().liveUserCryptoDevices(session.myUserId)
|
||||
session.flow().liveUserCryptoDevices(session.myUserId)
|
||||
.map { list ->
|
||||
list.firstOrNull { it.deviceId == deviceId }
|
||||
}
|
||||
@ -67,7 +69,7 @@ class DeviceVerificationInfoBottomSheetViewModel @AssistedInject constructor(@As
|
||||
)
|
||||
}
|
||||
|
||||
session.rx().liveUserCryptoDevices(session.myUserId)
|
||||
session.flow().liveUserCryptoDevices(session.myUserId)
|
||||
.map { it.size }
|
||||
.execute {
|
||||
copy(
|
||||
@ -79,7 +81,7 @@ class DeviceVerificationInfoBottomSheetViewModel @AssistedInject constructor(@As
|
||||
copy(deviceInfo = Loading())
|
||||
}
|
||||
|
||||
session.rx().liveMyDevicesInfo()
|
||||
session.flow().liveMyDevicesInfo()
|
||||
.map { devices ->
|
||||
devices.firstOrNull { it.deviceId == deviceId } ?: DeviceInfo(deviceId = deviceId)
|
||||
}
|
||||
|
@ -16,7 +16,6 @@
|
||||
|
||||
package im.vector.app.features.settings.devices
|
||||
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.airbnb.mvrx.Async
|
||||
import com.airbnb.mvrx.Fail
|
||||
import com.airbnb.mvrx.FragmentViewModelContext
|
||||
@ -34,31 +33,36 @@ import im.vector.app.core.platform.VectorViewModel
|
||||
import im.vector.app.core.resources.StringProvider
|
||||
import im.vector.app.features.auth.ReAuthActivity
|
||||
import im.vector.app.features.login.ReAuthHelper
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.subjects.PublishSubject
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.sample
|
||||
import kotlinx.coroutines.launch
|
||||
import org.matrix.android.sdk.api.MatrixCallback
|
||||
import org.matrix.android.sdk.api.NoOpMatrixCallback
|
||||
import org.matrix.android.sdk.api.auth.UIABaseAuth
|
||||
import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor
|
||||
import org.matrix.android.sdk.api.auth.UserPasswordAuth
|
||||
import org.matrix.android.sdk.api.auth.data.LoginFlowTypes
|
||||
import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse
|
||||
import org.matrix.android.sdk.api.auth.registration.nextUncompletedStage
|
||||
import org.matrix.android.sdk.api.failure.Failure
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod
|
||||
import org.matrix.android.sdk.api.session.crypto.verification.VerificationService
|
||||
import org.matrix.android.sdk.api.session.crypto.verification.VerificationTransaction
|
||||
import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxState
|
||||
import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse
|
||||
import org.matrix.android.sdk.api.auth.registration.nextUncompletedStage
|
||||
import org.matrix.android.sdk.flow.flow
|
||||
import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel
|
||||
import org.matrix.android.sdk.internal.crypto.crosssigning.fromBase64
|
||||
import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo
|
||||
import org.matrix.android.sdk.internal.crypto.model.rest.DefaultBaseAuth
|
||||
import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo
|
||||
import org.matrix.android.sdk.api.auth.UIABaseAuth
|
||||
import org.matrix.android.sdk.api.auth.UserPasswordAuth
|
||||
import org.matrix.android.sdk.internal.util.awaitCallback
|
||||
import org.matrix.android.sdk.rx.rx
|
||||
import timber.log.Timber
|
||||
import java.util.concurrent.TimeUnit
|
||||
import javax.net.ssl.HttpsURLConnection
|
||||
@ -118,18 +122,18 @@ class DevicesViewModel @AssistedInject constructor(
|
||||
)
|
||||
}
|
||||
|
||||
Observable.combineLatest<List<CryptoDeviceInfo>, List<DeviceInfo>, List<DeviceFullInfo>>(
|
||||
session.rx().liveUserCryptoDevices(session.myUserId),
|
||||
session.rx().liveMyDevicesInfo(),
|
||||
{ cryptoList, infoList ->
|
||||
infoList
|
||||
.sortedByDescending { it.lastSeenTs }
|
||||
.map { deviceInfo ->
|
||||
val cryptoDeviceInfo = cryptoList.firstOrNull { it.deviceId == deviceInfo.deviceId }
|
||||
DeviceFullInfo(deviceInfo, cryptoDeviceInfo)
|
||||
}
|
||||
}
|
||||
combine(
|
||||
session.flow().liveUserCryptoDevices(session.myUserId),
|
||||
session.flow().liveMyDevicesInfo()
|
||||
)
|
||||
{ cryptoList, infoList ->
|
||||
infoList
|
||||
.sortedByDescending { it.lastSeenTs }
|
||||
.map { deviceInfo ->
|
||||
val cryptoDeviceInfo = cryptoList.firstOrNull { it.deviceId == deviceInfo.deviceId }
|
||||
DeviceFullInfo(deviceInfo, cryptoDeviceInfo)
|
||||
}
|
||||
}
|
||||
.distinctUntilChanged()
|
||||
.execute { async ->
|
||||
copy(
|
||||
@ -137,7 +141,7 @@ class DevicesViewModel @AssistedInject constructor(
|
||||
)
|
||||
}
|
||||
|
||||
session.rx().liveCrossSigningInfo(session.myUserId)
|
||||
session.flow().liveCrossSigningInfo(session.myUserId)
|
||||
.execute {
|
||||
copy(
|
||||
hasAccountCrossSigning = it.invoke()?.getOrNull() != null,
|
||||
@ -146,24 +150,24 @@ class DevicesViewModel @AssistedInject constructor(
|
||||
}
|
||||
session.cryptoService().verificationService().addListener(this)
|
||||
|
||||
// session.rx().liveMyDeviceInfo()
|
||||
// session.flow().liveMyDeviceInfo()
|
||||
// .execute {
|
||||
// copy(
|
||||
// devices = it
|
||||
// )
|
||||
// }
|
||||
|
||||
session.rx().liveUserCryptoDevices(session.myUserId)
|
||||
session.flow().liveUserCryptoDevices(session.myUserId)
|
||||
.map { it.size }
|
||||
.distinctUntilChanged()
|
||||
.throttleLast(5_000, TimeUnit.MILLISECONDS)
|
||||
.subscribe {
|
||||
.sample(5_000)
|
||||
.onEach {
|
||||
// If we have a new crypto device change, we might want to trigger refresh of device info
|
||||
session.cryptoService().fetchDevicesList(NoOpMatrixCallback())
|
||||
}
|
||||
.disposeOnClear()
|
||||
.launchIn(viewModelScope)
|
||||
|
||||
// session.rx().liveUserCryptoDevices(session.myUserId)
|
||||
// session.flow().liveUserCryptoDevices(session.myUserId)
|
||||
// .execute {
|
||||
// copy(
|
||||
// cryptoDevices = it
|
||||
|
@ -16,7 +16,6 @@
|
||||
|
||||
package im.vector.app.features.settings.threepids
|
||||
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.airbnb.mvrx.ActivityViewModelContext
|
||||
import com.airbnb.mvrx.Fail
|
||||
import com.airbnb.mvrx.FragmentViewModelContext
|
||||
@ -33,15 +32,15 @@ import im.vector.app.core.resources.StringProvider
|
||||
import im.vector.app.core.utils.ReadOnceTrue
|
||||
import im.vector.app.features.auth.ReAuthActivity
|
||||
import kotlinx.coroutines.launch
|
||||
import org.matrix.android.sdk.api.auth.UIABaseAuth
|
||||
import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor
|
||||
import org.matrix.android.sdk.api.auth.UserPasswordAuth
|
||||
import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.api.session.identity.ThreePid
|
||||
import org.matrix.android.sdk.flow.flow
|
||||
import org.matrix.android.sdk.internal.crypto.crosssigning.fromBase64
|
||||
import org.matrix.android.sdk.internal.crypto.model.rest.DefaultBaseAuth
|
||||
import org.matrix.android.sdk.api.auth.UIABaseAuth
|
||||
import org.matrix.android.sdk.api.auth.UserPasswordAuth
|
||||
import org.matrix.android.sdk.rx.rx
|
||||
import timber.log.Timber
|
||||
import kotlin.coroutines.Continuation
|
||||
import kotlin.coroutines.resume
|
||||
@ -102,7 +101,7 @@ class ThreePidsSettingsViewModel @AssistedInject constructor(
|
||||
}
|
||||
|
||||
private fun observeThreePids() {
|
||||
session.rx()
|
||||
session.flow()
|
||||
.liveThreePIds(true)
|
||||
.execute {
|
||||
copy(
|
||||
@ -112,7 +111,7 @@ class ThreePidsSettingsViewModel @AssistedInject constructor(
|
||||
}
|
||||
|
||||
private fun observePendingThreePids() {
|
||||
session.rx()
|
||||
session.flow()
|
||||
.livePendingThreePIds()
|
||||
.execute {
|
||||
copy(
|
||||
@ -131,13 +130,13 @@ class ThreePidsSettingsViewModel @AssistedInject constructor(
|
||||
|
||||
override fun handle(action: ThreePidsSettingsAction) {
|
||||
when (action) {
|
||||
is ThreePidsSettingsAction.AddThreePid -> handleAddThreePid(action)
|
||||
is ThreePidsSettingsAction.AddThreePid -> handleAddThreePid(action)
|
||||
is ThreePidsSettingsAction.ContinueThreePid -> handleContinueThreePid(action)
|
||||
is ThreePidsSettingsAction.SubmitCode -> handleSubmitCode(action)
|
||||
is ThreePidsSettingsAction.CancelThreePid -> handleCancelThreePid(action)
|
||||
is ThreePidsSettingsAction.DeleteThreePid -> handleDeleteThreePid(action)
|
||||
is ThreePidsSettingsAction.ChangeUiState -> handleChangeUiState(action)
|
||||
ThreePidsSettingsAction.SsoAuthDone -> {
|
||||
is ThreePidsSettingsAction.SubmitCode -> handleSubmitCode(action)
|
||||
is ThreePidsSettingsAction.CancelThreePid -> handleCancelThreePid(action)
|
||||
is ThreePidsSettingsAction.DeleteThreePid -> handleDeleteThreePid(action)
|
||||
is ThreePidsSettingsAction.ChangeUiState -> handleChangeUiState(action)
|
||||
ThreePidsSettingsAction.SsoAuthDone -> {
|
||||
Timber.d("## UIA - FallBack success")
|
||||
if (pendingAuth != null) {
|
||||
uiaContinuation?.resume(pendingAuth!!)
|
||||
@ -155,7 +154,7 @@ class ThreePidsSettingsViewModel @AssistedInject constructor(
|
||||
)
|
||||
)
|
||||
}
|
||||
ThreePidsSettingsAction.ReAuthCancelled -> {
|
||||
ThreePidsSettingsAction.ReAuthCancelled -> {
|
||||
Timber.d("## UIA - Reauth cancelled")
|
||||
uiaContinuation?.resumeWithException(Exception())
|
||||
uiaContinuation = null
|
||||
|
@ -34,6 +34,7 @@ import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.api.session.content.ContentAttachmentData
|
||||
import org.matrix.android.sdk.api.session.room.model.Membership
|
||||
import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams
|
||||
import org.matrix.android.sdk.flow.flow
|
||||
import org.matrix.android.sdk.rx.rx
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
@ -68,7 +69,7 @@ class IncomingShareViewModel @AssistedInject constructor(
|
||||
memberships = listOf(Membership.JOIN)
|
||||
}
|
||||
session
|
||||
.rx().liveRoomSummaries(queryParams)
|
||||
.flow().liveRoomSummaries(queryParams)
|
||||
.execute {
|
||||
copy(roomSummaries = it)
|
||||
}
|
||||
|
@ -42,6 +42,7 @@ import org.matrix.android.sdk.api.session.room.model.Membership
|
||||
import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
|
||||
import org.matrix.android.sdk.api.session.room.powerlevels.Role
|
||||
import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams
|
||||
import org.matrix.android.sdk.flow.flow
|
||||
import org.matrix.android.sdk.rx.rx
|
||||
import timber.log.Timber
|
||||
|
||||
@ -77,7 +78,7 @@ class SpaceMenuViewModel @AssistedInject constructor(
|
||||
|
||||
session.getRoom(initialState.spaceId)?.let { room ->
|
||||
|
||||
room.rx().liveRoomSummary().subscribe {
|
||||
room.flow().liveRoomSummary().onEach {
|
||||
it.getOrNull()?.let {
|
||||
if (it.membership == Membership.LEAVE) {
|
||||
setState { copy(leavingState = Success(Unit)) }
|
||||
@ -87,7 +88,7 @@ class SpaceMenuViewModel @AssistedInject constructor(
|
||||
}
|
||||
}
|
||||
}
|
||||
}.disposeOnClear()
|
||||
}.launchIn(viewModelScope)
|
||||
|
||||
PowerLevelsFlowFactory(room)
|
||||
.createFlow()
|
||||
|
@ -16,7 +16,6 @@
|
||||
|
||||
package im.vector.app.features.spaces.leave
|
||||
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.airbnb.mvrx.ActivityViewModelContext
|
||||
import com.airbnb.mvrx.Fail
|
||||
import com.airbnb.mvrx.FragmentViewModelContext
|
||||
@ -31,6 +30,8 @@ import dagger.assisted.AssistedInject
|
||||
import im.vector.app.AppStateHandler
|
||||
import im.vector.app.core.platform.EmptyViewEvents
|
||||
import im.vector.app.core.platform.VectorViewModel
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
import okhttp3.internal.toImmutableList
|
||||
import org.matrix.android.sdk.api.query.ActiveSpaceFilter
|
||||
@ -38,7 +39,8 @@ import org.matrix.android.sdk.api.query.RoomCategoryFilter
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.api.session.room.model.Membership
|
||||
import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams
|
||||
import org.matrix.android.sdk.rx.rx
|
||||
import org.matrix.android.sdk.flow.flow
|
||||
import org.matrix.android.sdk.flow.unwrap
|
||||
import timber.log.Timber
|
||||
|
||||
class SpaceLeaveAdvancedViewModel @AssistedInject constructor(
|
||||
@ -95,17 +97,17 @@ class SpaceLeaveAdvancedViewModel @AssistedInject constructor(
|
||||
val spaceSummary = session.getRoomSummary(initialState.spaceId)
|
||||
setState { copy(spaceSummary = spaceSummary) }
|
||||
session.getRoom(initialState.spaceId)?.let { room ->
|
||||
room.rx().liveRoomSummary().subscribe {
|
||||
it.getOrNull()?.let {
|
||||
if (it.membership == Membership.LEAVE) {
|
||||
setState { copy(leaveState = Success(Unit)) }
|
||||
if (appStateHandler.safeActiveSpaceId() == initialState.spaceId) {
|
||||
// switch to home?
|
||||
appStateHandler.setCurrentSpace(null, session)
|
||||
room.flow().liveRoomSummary()
|
||||
.unwrap()
|
||||
.onEach {
|
||||
if (it.membership == Membership.LEAVE) {
|
||||
setState { copy(leaveState = Success(Unit)) }
|
||||
if (appStateHandler.safeActiveSpaceId() == initialState.spaceId) {
|
||||
// switch to home?
|
||||
appStateHandler.setCurrentSpace(null, session)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}.launchIn(viewModelScope)
|
||||
}
|
||||
|
||||
viewModelScope.launch {
|
||||
|
@ -17,7 +17,6 @@
|
||||
package im.vector.app.features.widgets
|
||||
|
||||
import android.net.Uri
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.airbnb.mvrx.ActivityViewModelContext
|
||||
import com.airbnb.mvrx.Fail
|
||||
import com.airbnb.mvrx.FragmentViewModelContext
|
||||
@ -26,11 +25,12 @@ import com.airbnb.mvrx.MavericksViewModelFactory
|
||||
import com.airbnb.mvrx.Success
|
||||
import com.airbnb.mvrx.ViewModelContext
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedInject
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import im.vector.app.core.platform.VectorViewModel
|
||||
import im.vector.app.core.resources.StringProvider
|
||||
import im.vector.app.features.widgets.permissions.WidgetPermissionsHelper
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.launch
|
||||
import org.matrix.android.sdk.api.query.QueryStringValue
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
@ -41,9 +41,10 @@ import org.matrix.android.sdk.api.session.integrationmanager.IntegrationManagerS
|
||||
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.session.widgets.WidgetManagementFailure
|
||||
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
|
||||
import timber.log.Timber
|
||||
import javax.net.ssl.HttpsURLConnection
|
||||
|
||||
@ -118,16 +119,15 @@ class WidgetViewModel @AssistedInject constructor(@Assisted val initialState: Wi
|
||||
if (room == null) {
|
||||
return
|
||||
}
|
||||
room.rx().liveStateEvent(EventType.STATE_ROOM_POWER_LEVELS, QueryStringValue.NoCondition)
|
||||
room.flow().liveStateEvent(EventType.STATE_ROOM_POWER_LEVELS, QueryStringValue.NoCondition)
|
||||
.mapOptional { it.content.toModel<PowerLevelsContent>() }
|
||||
.unwrap()
|
||||
.map {
|
||||
PowerLevelsHelper(it).isUserAllowedToSend(session.myUserId, true, null)
|
||||
}
|
||||
.subscribe {
|
||||
setState { copy(canManageWidgets = it) }
|
||||
.setOnEach {
|
||||
copy(canManageWidgets = it)
|
||||
}
|
||||
.disposeOnClear()
|
||||
}
|
||||
|
||||
private fun observeWidgetIfNeeded() {
|
||||
|
@ -25,27 +25,23 @@ import com.airbnb.mvrx.MavericksViewModelFactory
|
||||
import com.airbnb.mvrx.Uninitialized
|
||||
import com.airbnb.mvrx.ViewModelContext
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedInject
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import im.vector.app.core.platform.EmptyAction
|
||||
import im.vector.app.core.platform.EmptyViewEvents
|
||||
import im.vector.app.core.platform.VectorViewModel
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.functions.Function4
|
||||
import io.reactivex.subjects.PublishSubject
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.sample
|
||||
import org.matrix.android.sdk.api.extensions.orFalse
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.api.session.accountdata.UserAccountDataEvent
|
||||
import org.matrix.android.sdk.api.session.crypto.crosssigning.MASTER_KEY_SSSS_NAME
|
||||
import org.matrix.android.sdk.api.session.crypto.crosssigning.MXCrossSigningInfo
|
||||
import org.matrix.android.sdk.api.session.crypto.crosssigning.SELF_SIGNING_KEY_SSSS_NAME
|
||||
import org.matrix.android.sdk.api.session.crypto.crosssigning.USER_SIGNING_KEY_SSSS_NAME
|
||||
import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupState
|
||||
import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupStateListener
|
||||
import org.matrix.android.sdk.api.util.Optional
|
||||
import org.matrix.android.sdk.internal.crypto.store.PrivateKeysInfo
|
||||
import org.matrix.android.sdk.rx.rx
|
||||
import java.util.concurrent.TimeUnit
|
||||
import org.matrix.android.sdk.flow.flow
|
||||
|
||||
data class ServerBackupStatusViewState(
|
||||
val bannerState: Async<BannerState> = Uninitialized
|
||||
@ -91,43 +87,38 @@ class ServerBackupStatusViewModel @AssistedInject constructor(@Assisted initialS
|
||||
val keysExportedToFile = MutableLiveData<Boolean>()
|
||||
val keysBackupState = MutableLiveData<KeysBackupState>()
|
||||
|
||||
private val keyBackupPublishSubject: PublishSubject<KeysBackupState> = PublishSubject.create()
|
||||
private val keyBackupFlow = MutableSharedFlow<KeysBackupState>(0)
|
||||
|
||||
init {
|
||||
session.cryptoService().keysBackupService().addListener(this)
|
||||
|
||||
keysBackupState.value = session.cryptoService().keysBackupService().state
|
||||
|
||||
Observable.combineLatest<List<UserAccountDataEvent>, Optional<MXCrossSigningInfo>, KeysBackupState, Optional<PrivateKeysInfo>, BannerState>(
|
||||
session.rx().liveUserAccountData(setOf(MASTER_KEY_SSSS_NAME, USER_SIGNING_KEY_SSSS_NAME, SELF_SIGNING_KEY_SSSS_NAME)),
|
||||
session.rx().liveCrossSigningInfo(session.myUserId),
|
||||
keyBackupPublishSubject,
|
||||
session.rx().liveCrossSigningPrivateKeys(),
|
||||
Function4 { _, crossSigningInfo, keyBackupState, pInfo ->
|
||||
// first check if 4S is already setup
|
||||
if (session.sharedSecretStorageService.isRecoverySetup()) {
|
||||
// 4S is already setup sp we should not display anything
|
||||
return@Function4 when (keyBackupState) {
|
||||
KeysBackupState.BackingUp -> BannerState.BackingUp
|
||||
else -> BannerState.Hidden
|
||||
}
|
||||
}
|
||||
|
||||
// So recovery is not setup
|
||||
// Check if cross signing is enabled and local secrets known
|
||||
if (
|
||||
crossSigningInfo.getOrNull() == null
|
||||
|| (crossSigningInfo.getOrNull()?.isTrusted() == true
|
||||
&& pInfo.getOrNull()?.allKnown().orFalse())
|
||||
) {
|
||||
// So 4S is not setup and we have local secrets,
|
||||
return@Function4 BannerState.Setup(numberOfKeys = getNumberOfKeysToBackup())
|
||||
}
|
||||
|
||||
BannerState.Hidden
|
||||
val liveUserAccountData = session.flow().liveUserAccountData(setOf(MASTER_KEY_SSSS_NAME, USER_SIGNING_KEY_SSSS_NAME, SELF_SIGNING_KEY_SSSS_NAME))
|
||||
val liveCrossSigningInfo = session.flow().liveCrossSigningInfo(session.myUserId)
|
||||
val liveCrossSigningPrivateKeys = session.flow().liveCrossSigningPrivateKeys()
|
||||
combine(liveUserAccountData, liveCrossSigningInfo, keyBackupFlow, liveCrossSigningPrivateKeys) { _, crossSigningInfo, keyBackupState, pInfo ->
|
||||
// first check if 4S is already setup
|
||||
if (session.sharedSecretStorageService.isRecoverySetup()) {
|
||||
// 4S is already setup sp we should not display anything
|
||||
return@combine when (keyBackupState) {
|
||||
KeysBackupState.BackingUp -> BannerState.BackingUp
|
||||
else -> BannerState.Hidden
|
||||
}
|
||||
)
|
||||
.throttleLast(1000, TimeUnit.MILLISECONDS) // we don't want to flicker or catch transient states
|
||||
}
|
||||
|
||||
// So recovery is not setup
|
||||
// Check if cross signing is enabled and local secrets known
|
||||
if (
|
||||
crossSigningInfo.getOrNull() == null
|
||||
|| (crossSigningInfo.getOrNull()?.isTrusted() == true
|
||||
&& pInfo.getOrNull()?.allKnown().orFalse())
|
||||
) {
|
||||
// So 4S is not setup and we have local secrets,
|
||||
return@combine BannerState.Setup(numberOfKeys = getNumberOfKeysToBackup())
|
||||
}
|
||||
BannerState.Hidden
|
||||
|
||||
}
|
||||
.sample(1000) // we don't want to flicker or catch transient states
|
||||
.distinctUntilChanged()
|
||||
.execute { async ->
|
||||
copy(
|
||||
@ -135,7 +126,7 @@ class ServerBackupStatusViewModel @AssistedInject constructor(@Assisted initialS
|
||||
)
|
||||
}
|
||||
|
||||
keyBackupPublishSubject.onNext(session.cryptoService().keysBackupService().state)
|
||||
keyBackupFlow.tryEmit(session.cryptoService().keysBackupService().state)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -165,7 +156,7 @@ class ServerBackupStatusViewModel @AssistedInject constructor(@Assisted initialS
|
||||
}
|
||||
|
||||
override fun onStateChange(newState: KeysBackupState) {
|
||||
keyBackupPublishSubject.onNext(session.cryptoService().keysBackupService().state)
|
||||
keyBackupFlow.tryEmit(session.cryptoService().keysBackupService().state)
|
||||
keysBackupState.value = newState
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,6 @@
|
||||
package im.vector.app.features.workers.signout
|
||||
|
||||
import android.net.Uri
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.airbnb.mvrx.ActivityViewModelContext
|
||||
import com.airbnb.mvrx.Async
|
||||
import com.airbnb.mvrx.FragmentViewModelContext
|
||||
@ -35,6 +34,8 @@ import im.vector.app.core.platform.EmptyViewEvents
|
||||
import im.vector.app.core.platform.VectorViewModel
|
||||
import im.vector.app.core.platform.VectorViewModelAction
|
||||
import im.vector.app.features.crypto.keys.KeysExporter
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.launch
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.api.session.crypto.crosssigning.MASTER_KEY_SSSS_NAME
|
||||
@ -42,7 +43,7 @@ import org.matrix.android.sdk.api.session.crypto.crosssigning.SELF_SIGNING_KEY_S
|
||||
import org.matrix.android.sdk.api.session.crypto.crosssigning.USER_SIGNING_KEY_SSSS_NAME
|
||||
import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupState
|
||||
import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupStateListener
|
||||
import org.matrix.android.sdk.rx.rx
|
||||
import org.matrix.android.sdk.flow.flow
|
||||
import timber.log.Timber
|
||||
|
||||
data class SignoutCheckViewState(
|
||||
@ -97,7 +98,7 @@ class SignoutCheckViewModel @AssistedInject constructor(
|
||||
)
|
||||
}
|
||||
|
||||
session.rx().liveUserAccountData(setOf(MASTER_KEY_SSSS_NAME, USER_SIGNING_KEY_SSSS_NAME, SELF_SIGNING_KEY_SSSS_NAME))
|
||||
session.flow().liveUserAccountData(setOf(MASTER_KEY_SSSS_NAME, USER_SIGNING_KEY_SSSS_NAME, SELF_SIGNING_KEY_SSSS_NAME))
|
||||
.map {
|
||||
session.sharedSecretStorageService.isRecoverySetup()
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user