Rx : hides subject inside a class

This commit is contained in:
ganfra 2019-02-19 11:16:31 +01:00
parent c467f179e1
commit 5c78991ae1
7 changed files with 64 additions and 54 deletions

View File

@ -0,0 +1,37 @@
/*
* Copyright 2019 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package im.vector.riotredesign.core.utils

import com.jakewharton.rxrelay2.BehaviorRelay
import io.reactivex.Observable

open class RxStore<T>(defaultValue: T? = null) {

private val storeSubject: BehaviorRelay<T> = if (defaultValue == null) {
BehaviorRelay.create<T>()
} else {
BehaviorRelay.createDefault(defaultValue)
}

fun observe(): Observable<T> {
return storeSubject.hide().distinctUntilChanged()
}

fun post(value: T) {
storeSubject.accept(value)
}
}

View File

@ -16,8 +16,8 @@


package im.vector.riotredesign.features.home package im.vector.riotredesign.features.home


import im.vector.riotredesign.features.home.group.SelectedGroupHolder import im.vector.riotredesign.features.home.group.SelectedGroupStore
import im.vector.riotredesign.features.home.room.VisibleRoomHolder import im.vector.riotredesign.features.home.room.VisibleRoomStore
import im.vector.riotredesign.features.home.room.detail.timeline.DefaultItemFactory import im.vector.riotredesign.features.home.room.detail.timeline.DefaultItemFactory
import im.vector.riotredesign.features.home.room.detail.timeline.MessageItemFactory import im.vector.riotredesign.features.home.room.detail.timeline.MessageItemFactory
import im.vector.riotredesign.features.home.room.detail.timeline.RoomMemberItemFactory import im.vector.riotredesign.features.home.room.detail.timeline.RoomMemberItemFactory
@ -80,11 +80,11 @@ class HomeModule {
} }


single { single {
SelectedGroupHolder() SelectedGroupStore()
} }


single { single {
VisibleRoomHolder() VisibleRoomStore()
} }


single { single {

View File

@ -16,6 +16,7 @@


package im.vector.riotredesign.features.home.group package im.vector.riotredesign.features.home.group


import arrow.core.Option
import com.airbnb.mvrx.MvRxViewModelFactory import com.airbnb.mvrx.MvRxViewModelFactory
import com.airbnb.mvrx.ViewModelContext import com.airbnb.mvrx.ViewModelContext
import im.vector.matrix.android.api.Matrix import im.vector.matrix.android.api.Matrix
@ -25,7 +26,7 @@ import im.vector.riotredesign.core.platform.RiotViewModel
import org.koin.android.ext.android.get import org.koin.android.ext.android.get


class GroupListViewModel(initialState: GroupListViewState, class GroupListViewModel(initialState: GroupListViewState,
private val selectedGroupHolder: SelectedGroupHolder, private val selectedGroupHolder: SelectedGroupStore,
private val session: Session private val session: Session
) : RiotViewModel<GroupListViewState>(initialState) { ) : RiotViewModel<GroupListViewState>(initialState) {


@ -34,7 +35,7 @@ class GroupListViewModel(initialState: GroupListViewState,
@JvmStatic @JvmStatic
override fun create(viewModelContext: ViewModelContext, state: GroupListViewState): GroupListViewModel? { override fun create(viewModelContext: ViewModelContext, state: GroupListViewState): GroupListViewModel? {
val currentSession = Matrix.getInstance().currentSession val currentSession = Matrix.getInstance().currentSession
val selectedGroupHolder = viewModelContext.activity.get<SelectedGroupHolder>() val selectedGroupHolder = viewModelContext.activity.get<SelectedGroupStore>()
return GroupListViewModel(state, selectedGroupHolder, currentSession) return GroupListViewModel(state, selectedGroupHolder, currentSession)
} }
} }
@ -46,7 +47,8 @@ class GroupListViewModel(initialState: GroupListViewState,


private fun observeState() { private fun observeState() {
subscribe { subscribe {
selectedGroupHolder.setSelectedGroup(it.selectedGroup) val selectedGroup = Option.fromNullable(it.selectedGroup)
selectedGroupHolder.post(selectedGroup)
} }
} }



View File

@ -17,22 +17,7 @@
package im.vector.riotredesign.features.home.group package im.vector.riotredesign.features.home.group


import arrow.core.Option import arrow.core.Option
import com.jakewharton.rxrelay2.BehaviorRelay
import im.vector.matrix.android.api.session.group.model.GroupSummary import im.vector.matrix.android.api.session.group.model.GroupSummary
import io.reactivex.Observable import im.vector.riotredesign.core.utils.RxStore


class SelectedGroupHolder { class SelectedGroupStore : RxStore<Option<GroupSummary>>(Option.empty())

private val selectedGroupStream = BehaviorRelay.createDefault<Option<GroupSummary>>(Option.empty())

fun setSelectedGroup(group: GroupSummary?) {
val optionValue = Option.fromNullable(group)
selectedGroupStream.accept(optionValue)
}

fun selectedGroup(): Observable<Option<GroupSummary>> {
return selectedGroupStream.hide()
}


}

View File

@ -16,21 +16,6 @@


package im.vector.riotredesign.features.home.room package im.vector.riotredesign.features.home.room


import com.jakewharton.rxrelay2.BehaviorRelay import im.vector.riotredesign.core.utils.RxStore
import io.reactivex.Observable
import io.reactivex.subjects.BehaviorSubject


class VisibleRoomHolder { class VisibleRoomStore : RxStore<String>()

private val visibleRoomStream = BehaviorRelay.create<String>()

fun setVisibleRoom(roomId: String) {
visibleRoomStream.accept(roomId)
}

fun visibleRoom(): Observable<String> {
return visibleRoomStream.hide()
}


}

View File

@ -26,14 +26,14 @@ import im.vector.matrix.android.api.session.events.model.Event
import im.vector.matrix.rx.rx import im.vector.matrix.rx.rx
import im.vector.riotredesign.core.extensions.lastMinBy import im.vector.riotredesign.core.extensions.lastMinBy
import im.vector.riotredesign.core.platform.RiotViewModel import im.vector.riotredesign.core.platform.RiotViewModel
import im.vector.riotredesign.features.home.room.VisibleRoomHolder import im.vector.riotredesign.features.home.room.VisibleRoomStore
import io.reactivex.rxkotlin.subscribeBy import io.reactivex.rxkotlin.subscribeBy
import org.koin.android.ext.android.get import org.koin.android.ext.android.get
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit


class RoomDetailViewModel(initialState: RoomDetailViewState, class RoomDetailViewModel(initialState: RoomDetailViewState,
private val session: Session, private val session: Session,
private val visibleRoomHolder: VisibleRoomHolder private val visibleRoomHolder: VisibleRoomStore
) : RiotViewModel<RoomDetailViewState>(initialState) { ) : RiotViewModel<RoomDetailViewState>(initialState) {


private val room = session.getRoom(initialState.roomId)!! private val room = session.getRoom(initialState.roomId)!!
@ -47,7 +47,7 @@ class RoomDetailViewModel(initialState: RoomDetailViewState,
@JvmStatic @JvmStatic
override fun create(viewModelContext: ViewModelContext, state: RoomDetailViewState): RoomDetailViewModel? { override fun create(viewModelContext: ViewModelContext, state: RoomDetailViewState): RoomDetailViewModel? {
val currentSession = Matrix.getInstance().currentSession val currentSession = Matrix.getInstance().currentSession
val visibleRoomHolder = viewModelContext.activity.get<VisibleRoomHolder>() val visibleRoomHolder = viewModelContext.activity.get<VisibleRoomStore>()
return RoomDetailViewModel(state, currentSession, visibleRoomHolder) return RoomDetailViewModel(state, currentSession, visibleRoomHolder)
} }
} }
@ -78,7 +78,7 @@ class RoomDetailViewModel(initialState: RoomDetailViewState,
} }


private fun handleIsDisplayed() { private fun handleIsDisplayed() {
visibleRoomHolder.setVisibleRoom(roomId) visibleRoomHolder.post(roomId)
} }


private fun observeDisplayedEvents() { private fun observeDisplayedEvents() {

View File

@ -27,8 +27,8 @@ import im.vector.matrix.android.api.session.room.model.RoomSummary
import im.vector.matrix.android.api.session.room.model.tag.RoomTag import im.vector.matrix.android.api.session.room.model.tag.RoomTag
import im.vector.matrix.rx.rx import im.vector.matrix.rx.rx
import im.vector.riotredesign.core.platform.RiotViewModel import im.vector.riotredesign.core.platform.RiotViewModel
import im.vector.riotredesign.features.home.group.SelectedGroupHolder import im.vector.riotredesign.features.home.group.SelectedGroupStore
import im.vector.riotredesign.features.home.room.VisibleRoomHolder import im.vector.riotredesign.features.home.room.VisibleRoomStore
import io.reactivex.Observable import io.reactivex.Observable
import io.reactivex.functions.Function3 import io.reactivex.functions.Function3
import io.reactivex.rxkotlin.subscribeBy import io.reactivex.rxkotlin.subscribeBy
@ -39,8 +39,8 @@ typealias RoomListFilterName = CharSequence


class RoomListViewModel(initialState: RoomListViewState, class RoomListViewModel(initialState: RoomListViewState,
private val session: Session, private val session: Session,
private val selectedGroupHolder: SelectedGroupHolder, private val selectedGroupHolder: SelectedGroupStore,
private val visibleRoomHolder: VisibleRoomHolder, private val visibleRoomHolder: VisibleRoomStore,
private val roomSelectionRepository: RoomSelectionRepository, private val roomSelectionRepository: RoomSelectionRepository,
private val roomSummaryComparator: RoomSummaryComparator) private val roomSummaryComparator: RoomSummaryComparator)
: RiotViewModel<RoomListViewState>(initialState) { : RiotViewModel<RoomListViewState>(initialState) {
@ -51,8 +51,8 @@ class RoomListViewModel(initialState: RoomListViewState,
override fun create(viewModelContext: ViewModelContext, state: RoomListViewState): RoomListViewModel? { override fun create(viewModelContext: ViewModelContext, state: RoomListViewState): RoomListViewModel? {
val currentSession = Matrix.getInstance().currentSession val currentSession = Matrix.getInstance().currentSession
val roomSelectionRepository = viewModelContext.activity.get<RoomSelectionRepository>() val roomSelectionRepository = viewModelContext.activity.get<RoomSelectionRepository>()
val selectedGroupHolder = viewModelContext.activity.get<SelectedGroupHolder>() val selectedGroupHolder = viewModelContext.activity.get<SelectedGroupStore>()
val visibleRoomHolder = viewModelContext.activity.get<VisibleRoomHolder>() val visibleRoomHolder = viewModelContext.activity.get<VisibleRoomStore>()
val roomSummaryComparator = viewModelContext.activity.get<RoomSummaryComparator>() val roomSummaryComparator = viewModelContext.activity.get<RoomSummaryComparator>()
return RoomListViewModel(state, currentSession, selectedGroupHolder, visibleRoomHolder, roomSelectionRepository, roomSummaryComparator) return RoomListViewModel(state, currentSession, selectedGroupHolder, visibleRoomHolder, roomSelectionRepository, roomSummaryComparator)
} }
@ -87,17 +87,18 @@ class RoomListViewModel(initialState: RoomListViewState,
} }


private fun observeVisibleRoom() { private fun observeVisibleRoom() {
visibleRoomHolder.visibleRoom() visibleRoomHolder.observe()
.subscribeBy { .doOnNext {
setState { copy(selectedRoomId = it) } setState { copy(selectedRoomId = it) }
} }
.subscribe()
.disposeOnClear() .disposeOnClear()
} }


private fun observeRoomSummaries() { private fun observeRoomSummaries() {
Observable.combineLatest<List<RoomSummary>, Option<GroupSummary>, Option<RoomListFilterName>, RoomSummaries>( Observable.combineLatest<List<RoomSummary>, Option<GroupSummary>, Option<RoomListFilterName>, RoomSummaries>(
session.rx().liveRoomSummaries().throttleLast(300, TimeUnit.MILLISECONDS), session.rx().liveRoomSummaries().throttleLast(300, TimeUnit.MILLISECONDS),
selectedGroupHolder.selectedGroup(), selectedGroupHolder.observe(),
roomListFilter.throttleLast(300, TimeUnit.MILLISECONDS), roomListFilter.throttleLast(300, TimeUnit.MILLISECONDS),
Function3 { rooms, selectedGroupOption, filterRoomOption -> Function3 { rooms, selectedGroupOption, filterRoomOption ->
val filteredRooms = filterRooms(rooms, filterRoomOption) val filteredRooms = filterRooms(rooms, filterRoomOption)