1
0
mirror of https://github.com/vector-im/riotX-android synced 2025-10-06 00:02:48 +02:00

Compare commits

...

1 Commits

Author SHA1 Message Date
ganfra
35d98c2e1e Introduce start/onStart methods on ViewModel, when you want to delay observing db 2020-09-10 22:06:08 +02:00
15 changed files with 59 additions and 27 deletions

View File

@@ -16,6 +16,7 @@
package im.vector.app.core.platform package im.vector.app.core.platform
import androidx.lifecycle.viewModelScope
import com.airbnb.mvrx.Async import com.airbnb.mvrx.Async
import com.airbnb.mvrx.BaseMvRxViewModel import com.airbnb.mvrx.BaseMvRxViewModel
import com.airbnb.mvrx.Fail import com.airbnb.mvrx.Fail
@@ -26,6 +27,9 @@ import im.vector.app.core.utils.DataSource
import im.vector.app.core.utils.PublishDataSource import im.vector.app.core.utils.PublishDataSource
import io.reactivex.Observable import io.reactivex.Observable
import io.reactivex.Single import io.reactivex.Single
import kotlinx.coroutines.launch
import timber.log.Timber
import java.util.concurrent.atomic.AtomicBoolean
abstract class VectorViewModel<S : MvRxState, VA : VectorViewModelAction, VE : VectorViewEvents>(initialState: S) abstract class VectorViewModel<S : MvRxState, VA : VectorViewModelAction, VE : VectorViewEvents>(initialState: S)
: BaseMvRxViewModel<S>(initialState, false) { : BaseMvRxViewModel<S>(initialState, false) {
@@ -37,6 +41,27 @@ abstract class VectorViewModel<S : MvRxState, VA : VectorViewModelAction, VE : V
// Used to post transient events to the View // Used to post transient events to the View
protected val _viewEvents = PublishDataSource<VE>() protected val _viewEvents = PublishDataSource<VE>()
val viewEvents: DataSource<VE> = _viewEvents val viewEvents: DataSource<VE> = _viewEvents
private val isStarted = AtomicBoolean(false)
/**
* Call this method when you are ready to grab data for your ViewModel.
* Mostly to be used at the end of onCreateView from fragment.
* It's safe to be called multiple time.
*/
fun start() {
if (!isStarted.getAndSet(true)) {
Timber.v("Start viewModel ${this.javaClass.name}")
viewModelScope.launch {
onStarted()
}
}
}
/**
* This is the method where you want to start observing rx data, subscribe to state...
* Will be called only once. It's bound the viewModelScope and is launched on Main thread
*/
protected open suspend fun onStarted() = Unit
/** /**
* This method does the same thing as the execute function, but it doesn't subscribe to the stream * This method does the same thing as the execute function, but it doesn't subscribe to the stream

View File

@@ -56,6 +56,7 @@ class GroupListFragment @Inject constructor(
is GroupListViewEvents.OpenGroupSummary -> sharedActionViewModel.post(HomeActivitySharedAction.OpenGroup) is GroupListViewEvents.OpenGroupSummary -> sharedActionViewModel.post(HomeActivitySharedAction.OpenGroup)
}.exhaustive }.exhaustive
} }
viewModel.start()
} }
override fun onDestroyView() { override fun onDestroyView() {

View File

@@ -26,14 +26,14 @@ import com.squareup.inject.assisted.AssistedInject
import im.vector.app.R import im.vector.app.R
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 io.reactivex.Observable
import io.reactivex.functions.BiFunction
import org.matrix.android.sdk.api.NoOpMatrixCallback import org.matrix.android.sdk.api.NoOpMatrixCallback
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
import org.matrix.android.sdk.api.session.group.groupSummaryQueryParams import org.matrix.android.sdk.api.session.group.groupSummaryQueryParams
import org.matrix.android.sdk.api.session.group.model.GroupSummary import org.matrix.android.sdk.api.session.group.model.GroupSummary
import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.model.Membership
import io.reactivex.Observable
import io.reactivex.functions.BiFunction
import org.matrix.android.sdk.rx.rx import org.matrix.android.sdk.rx.rx
const val ALL_COMMUNITIES_GROUP_ID = "+ALL_COMMUNITIES_GROUP_ID" const val ALL_COMMUNITIES_GROUP_ID = "+ALL_COMMUNITIES_GROUP_ID"
@@ -60,7 +60,7 @@ class GroupListViewModel @AssistedInject constructor(@Assisted initialState: Gro
private var currentGroupId = "" private var currentGroupId = ""
init { override suspend fun onStarted() {
observeGroupSummaries() observeGroupSummaries()
observeSelectionState() observeSelectionState()
} }

View File

@@ -53,10 +53,6 @@ import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo
import timber.log.Timber import timber.log.Timber
import javax.inject.Inject import javax.inject.Inject
private const val INDEX_PEOPLE = 0
private const val INDEX_ROOMS = 1
private const val INDEX_CATCHUP = 2
class HomeDetailFragment @Inject constructor( class HomeDetailFragment @Inject constructor(
val homeDetailViewModelFactory: HomeDetailViewModel.Factory, val homeDetailViewModelFactory: HomeDetailViewModel.Factory,
private val serverBackupStatusViewModelFactory: ServerBackupStatusViewModel.Factory, private val serverBackupStatusViewModelFactory: ServerBackupStatusViewModel.Factory,
@@ -123,6 +119,8 @@ class HomeDetailFragment @Inject constructor(
activeCallViewHolder.updateCall(it, webRtcPeerConnectionManager) activeCallViewHolder.updateCall(it, webRtcPeerConnectionManager)
invalidateOptionsMenu() invalidateOptionsMenu()
}) })
viewModel.start()
} }
override fun onResume() { override fun onResume() {

View File

@@ -27,9 +27,9 @@ 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.grouplist.SelectedGroupDataSource import im.vector.app.features.grouplist.SelectedGroupDataSource
import im.vector.app.features.ui.UiStateRepository import im.vector.app.features.ui.UiStateRepository
import io.reactivex.schedulers.Schedulers
import org.matrix.android.sdk.api.session.Session 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.model.Membership
import io.reactivex.schedulers.Schedulers
import org.matrix.android.sdk.rx.rx import org.matrix.android.sdk.rx.rx
/** /**
@@ -65,7 +65,7 @@ class HomeDetailViewModel @AssistedInject constructor(@Assisted initialState: Ho
} }
} }
init { override suspend fun onStarted() {
observeSyncState() observeSyncState()
observeSelectedGroupStore() observeSelectedGroupStore()
observeRoomSummaries() observeRoomSummaries()

View File

@@ -30,6 +30,10 @@ 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.core.platform.VectorViewModelAction import im.vector.app.core.platform.VectorViewModelAction
import im.vector.app.features.settings.VectorPreferences import im.vector.app.features.settings.VectorPreferences
import io.reactivex.Observable
import io.reactivex.functions.Function3
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import org.matrix.android.sdk.api.NoOpMatrixCallback import org.matrix.android.sdk.api.NoOpMatrixCallback
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
@@ -39,8 +43,6 @@ import org.matrix.android.sdk.api.util.toMatrixItem
import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo
import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo
import org.matrix.android.sdk.internal.crypto.store.PrivateKeysInfo import org.matrix.android.sdk.internal.crypto.store.PrivateKeysInfo
import io.reactivex.Observable
import io.reactivex.functions.Function3
import org.matrix.android.sdk.rx.rx import org.matrix.android.sdk.rx.rx
import timber.log.Timber import timber.log.Timber
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
@@ -57,7 +59,7 @@ data class DeviceDetectionInfo(
) )
class UnknownDeviceDetectorSharedViewModel @AssistedInject constructor(@Assisted initialState: UnknownDevicesState, class UnknownDeviceDetectorSharedViewModel @AssistedInject constructor(@Assisted initialState: UnknownDevicesState,
session: Session, private val session: Session,
private val vectorPreferences: VectorPreferences) private val vectorPreferences: VectorPreferences)
: VectorViewModel<UnknownDevicesState, UnknownDeviceDetectorSharedViewModel.Action, EmptyViewEvents>(initialState) { : VectorViewModel<UnknownDevicesState, UnknownDeviceDetectorSharedViewModel.Action, EmptyViewEvents>(initialState) {
@@ -84,12 +86,13 @@ class UnknownDeviceDetectorSharedViewModel @AssistedInject constructor(@Assisted
private val ignoredDeviceList = ArrayList<String>() private val ignoredDeviceList = ArrayList<String>()
init { override suspend fun onStarted() {
val currentSessionTs = withContext(Dispatchers.Default) {
val currentSessionTs = session.cryptoService().getCryptoDeviceInfo(session.myUserId) session.cryptoService().getCryptoDeviceInfo(session.myUserId)
.firstOrNull { it.deviceId == session.sessionParams.deviceId } .firstOrNull { it.deviceId == session.sessionParams.deviceId }
?.firstTimeSeenLocalTs ?.firstTimeSeenLocalTs
?: System.currentTimeMillis() ?: System.currentTimeMillis()
}
Timber.v("## Detector - Current Session first time seen $currentSessionTs") Timber.v("## Detector - Current Session first time seen $currentSessionTs")
ignoredDeviceList.addAll( ignoredDeviceList.addAll(

View File

@@ -43,6 +43,7 @@ class BreadcrumbsFragment @Inject constructor(
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
setupRecyclerView() setupRecyclerView()
sharedActionViewModel = activityViewModelProvider.get(RoomDetailSharedActionViewModel::class.java) sharedActionViewModel = activityViewModelProvider.get(RoomDetailSharedActionViewModel::class.java)
breadcrumbsViewModel.start()
} }
override fun onDestroyView() { override fun onDestroyView() {

View File

@@ -49,7 +49,7 @@ class BreadcrumbsViewModel @AssistedInject constructor(@Assisted initialState: B
} }
} }
init { override suspend fun onStarted() {
observeBreadcrumbs() observeBreadcrumbs()
} }

View File

@@ -365,6 +365,7 @@ class RoomDetailFragment @Inject constructor(
is RoomDetailViewEvents.RequestNativeWidgetPermission -> requestNativeWidgetPermission(it) is RoomDetailViewEvents.RequestNativeWidgetPermission -> requestNativeWidgetPermission(it)
}.exhaustive }.exhaustive
} }
roomDetailViewModel.start()
} }
private fun requestNativeWidgetPermission(it: RoomDetailViewEvents.RequestNativeWidgetPermission) { private fun requestNativeWidgetPermission(it: RoomDetailViewEvents.RequestNativeWidgetPermission) {

View File

@@ -170,7 +170,7 @@ class RoomDetailViewModel @AssistedInject constructor(
} }
} }
init { override suspend fun onStarted() {
timeline.start() timeline.start()
timeline.addListener(this) timeline.addListener(this)
observeRoomSummary() observeRoomSummary()

View File

@@ -116,6 +116,8 @@ class RoomListFragment @Inject constructor(
.observe() .observe()
.subscribe { handleQuickActions(it) } .subscribe { handleQuickActions(it) }
.disposeOnDestroyView() .disposeOnDestroyView()
roomListViewModel.start()
} }
override fun showFailure(throwable: Throwable) { override fun showFailure(throwable: Throwable) {

View File

@@ -55,7 +55,7 @@ class RoomListViewModel @Inject constructor(initialState: RoomListViewState,
private val displayMode = initialState.displayMode private val displayMode = initialState.displayMode
private val roomListDisplayModeFilter = RoomListDisplayModeFilter(displayMode) private val roomListDisplayModeFilter = RoomListDisplayModeFilter(displayMode)
init { override suspend fun onStarted() {
observeRoomSummaries() observeRoomSummaries()
observeMembershipChanges() observeMembershipChanges()
} }

View File

@@ -128,6 +128,7 @@ class WidgetActivity : VectorBaseActivity(), ToolbarConfigurable, WidgetViewMode
viewModel.selectSubscribe(this, WidgetViewState::canManageWidgets) { viewModel.selectSubscribe(this, WidgetViewState::canManageWidgets) {
invalidateOptionsMenu() invalidateOptionsMenu()
} }
viewModel.start()
} }
override fun create(initialState: WidgetViewState): WidgetViewModel { override fun create(initialState: WidgetViewState): WidgetViewModel {

View File

@@ -27,6 +27,10 @@ import com.airbnb.mvrx.Success
import com.airbnb.mvrx.ViewModelContext import com.airbnb.mvrx.ViewModelContext
import com.squareup.inject.assisted.Assisted import com.squareup.inject.assisted.Assisted
import com.squareup.inject.assisted.AssistedInject import com.squareup.inject.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.launch
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
import org.matrix.android.sdk.api.session.events.model.Content import org.matrix.android.sdk.api.session.events.model.Content
@@ -40,10 +44,6 @@ import org.matrix.android.sdk.internal.util.awaitCallback
import org.matrix.android.sdk.rx.mapOptional import org.matrix.android.sdk.rx.mapOptional
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
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.launch
import timber.log.Timber import timber.log.Timber
import javax.net.ssl.HttpsURLConnection import javax.net.ssl.HttpsURLConnection
@@ -82,7 +82,7 @@ class WidgetViewModel @AssistedInject constructor(@Assisted val initialState: Wi
// Flag to avoid infinite loop // Flag to avoid infinite loop
private var canRefreshToken = true private var canRefreshToken = true
init { override suspend fun onStarted() {
integrationManagerService.addListener(this) integrationManagerService.addListener(this)
if (initialState.widgetKind.isAdmin()) { if (initialState.widgetKind.isAdmin()) {
widgetPostAPIHandler = widgetPostAPIHandlerFactory.create(initialState.roomId).apply { widgetPostAPIHandler = widgetPostAPIHandlerFactory.create(initialState.roomId).apply {

View File

@@ -92,7 +92,7 @@ class ServerBackupStatusViewModel @AssistedInject constructor(@Assisted initialS
private val keyBackupPublishSubject: PublishSubject<KeysBackupState> = PublishSubject.create() private val keyBackupPublishSubject: PublishSubject<KeysBackupState> = PublishSubject.create()
init { override suspend fun onStarted() {
session.cryptoService().keysBackupService().addListener(this) session.cryptoService().keysBackupService().addListener(this)
keysBackupState.value = session.cryptoService().keysBackupService().state keysBackupState.value = session.cryptoService().keysBackupService().state