Merge branch 'feature/fix_issues' into develop

This commit is contained in:
ganfra 2019-07-03 19:46:34 +02:00
commit 9ff24cbf2a
17 changed files with 122 additions and 86 deletions

View File

@ -21,23 +21,24 @@ import im.vector.matrix.android.api.session.room.model.EventAnnotationsSummary
import im.vector.matrix.android.api.session.room.model.RoomSummary import im.vector.matrix.android.api.session.room.model.RoomSummary
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
import io.reactivex.Observable import io.reactivex.Observable
import io.reactivex.schedulers.Schedulers
class RxRoom(private val room: Room) { class RxRoom(private val room: Room) {
fun liveRoomSummary(fetchLastEvent: Boolean): Observable<RoomSummary> { fun liveRoomSummary(fetchLastEvent: Boolean): Observable<RoomSummary> {
return room.liveRoomSummary(fetchLastEvent).asObservable() return room.liveRoomSummary(fetchLastEvent).asObservable().observeOn(Schedulers.computation())
} }
fun liveRoomMemberIds(): Observable<List<String>> { fun liveRoomMemberIds(): Observable<List<String>> {
return room.getRoomMemberIdsLive().asObservable() return room.getRoomMemberIdsLive().asObservable().observeOn(Schedulers.computation())
} }
fun liveAnnotationSummary(eventId: String): Observable<EventAnnotationsSummary> { fun liveAnnotationSummary(eventId: String): Observable<EventAnnotationsSummary> {
return room.getEventSummaryLive(eventId).asObservable() return room.getEventSummaryLive(eventId).asObservable().observeOn(Schedulers.computation())
} }
fun liveTimelineEvent(eventId: String): Observable<TimelineEvent> { fun liveTimelineEvent(eventId: String): Observable<TimelineEvent> {
return room.liveTimeLineEvent(eventId).asObservable() return room.liveTimeLineEvent(eventId).asObservable().observeOn(Schedulers.computation())
} }
} }

View File

@ -22,23 +22,24 @@ import im.vector.matrix.android.api.session.pushers.Pusher
import im.vector.matrix.android.api.session.room.model.RoomSummary import im.vector.matrix.android.api.session.room.model.RoomSummary
import im.vector.matrix.android.api.session.sync.SyncState import im.vector.matrix.android.api.session.sync.SyncState
import io.reactivex.Observable import io.reactivex.Observable
import io.reactivex.schedulers.Schedulers
class RxSession(private val session: Session) { class RxSession(private val session: Session) {
fun liveRoomSummaries(fetchLastEvents: Boolean): Observable<List<RoomSummary>> { fun liveRoomSummaries(fetchLastEvents: Boolean): Observable<List<RoomSummary>> {
return session.liveRoomSummaries(fetchLastEvents).asObservable() return session.liveRoomSummaries(fetchLastEvents).asObservable().observeOn(Schedulers.computation())
} }
fun liveGroupSummaries(): Observable<List<GroupSummary>> { fun liveGroupSummaries(): Observable<List<GroupSummary>> {
return session.liveGroupSummaries().asObservable() return session.liveGroupSummaries().asObservable().observeOn(Schedulers.computation())
} }
fun liveSyncState(): Observable<SyncState> { fun liveSyncState(): Observable<SyncState> {
return session.syncState().asObservable() return session.syncState().asObservable().observeOn(Schedulers.computation())
} }
fun livePushers(): Observable<List<Pusher>> { fun livePushers(): Observable<List<Pusher>> {
return session.livePushers().asObservable() return session.livePushers().asObservable().observeOn(Schedulers.computation())
} }
} }

View File

@ -17,7 +17,10 @@
package im.vector.matrix.android.internal.database package im.vector.matrix.android.internal.database
import com.zhuinden.monarchy.Monarchy import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.internal.util.createBackgroundHandler
import io.realm.OrderedCollectionChangeSet import io.realm.OrderedCollectionChangeSet
import io.realm.Realm
import io.realm.RealmConfiguration
import io.realm.RealmObject import io.realm.RealmObject
import io.realm.RealmResults import io.realm.RealmResults
import java.util.concurrent.atomic.AtomicBoolean import java.util.concurrent.atomic.AtomicBoolean
@ -29,17 +32,24 @@ internal interface LiveEntityObserver {
fun isStarted(): Boolean fun isStarted(): Boolean
} }
internal abstract class RealmLiveEntityObserver<T : RealmObject>(protected val monarchy: Monarchy) internal abstract class RealmLiveEntityObserver<T : RealmObject>(protected val realmConfiguration: RealmConfiguration)
: LiveEntityObserver { : LiveEntityObserver {
private companion object {
val BACKGROUND_HANDLER = createBackgroundHandler("LIVE_ENTITY_BACKGROUND")
}
protected abstract val query: Monarchy.Query<T> protected abstract val query: Monarchy.Query<T>
private val isStarted = AtomicBoolean(false) private val isStarted = AtomicBoolean(false)
private val backgroundRealm = AtomicReference<Realm>()
private lateinit var results: AtomicReference<RealmResults<T>> private lateinit var results: AtomicReference<RealmResults<T>>
override fun start() { override fun start() {
if (isStarted.compareAndSet(false, true)) { if (isStarted.compareAndSet(false, true)) {
monarchy.postToMonarchyThread { BACKGROUND_HANDLER.post {
val queryResults = query.createQuery(it).findAll() val realm = Realm.getInstance(realmConfiguration)
backgroundRealm.set(realm)
val queryResults = query.createQuery(realm).findAll()
queryResults.addChangeListener { t, changeSet -> queryResults.addChangeListener { t, changeSet ->
onChanged(t, changeSet) onChanged(t, changeSet)
} }
@ -50,8 +60,11 @@ internal abstract class RealmLiveEntityObserver<T : RealmObject>(protected val m
override fun dispose() { override fun dispose() {
if (isStarted.compareAndSet(true, false)) { if (isStarted.compareAndSet(true, false)) {
monarchy.postToMonarchyThread { BACKGROUND_HANDLER.post {
results.getAndSet(null).removeAllChangeListeners() results.getAndSet(null).removeAllChangeListeners()
backgroundRealm.getAndSet(null).also {
it.close()
}
} }
} }
} }

View File

@ -23,6 +23,7 @@ import android.os.HandlerThread
import dagger.Module import dagger.Module
import dagger.Provides import dagger.Provides
import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
import im.vector.matrix.android.internal.util.createBackgroundHandler
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.android.asCoroutineDispatcher import kotlinx.coroutines.android.asCoroutineDispatcher
import org.matrix.olm.OlmManager import org.matrix.olm.OlmManager
@ -32,15 +33,12 @@ internal object MatrixModule {
@JvmStatic @JvmStatic
@Provides @Provides
@MatrixScope
fun providesMatrixCoroutineDispatchers(): MatrixCoroutineDispatchers { fun providesMatrixCoroutineDispatchers(): MatrixCoroutineDispatchers {
val THREAD_CRYPTO_NAME = "Crypto_Thread"
val handlerThread = HandlerThread(THREAD_CRYPTO_NAME)
handlerThread.start()
return MatrixCoroutineDispatchers(io = Dispatchers.IO, return MatrixCoroutineDispatchers(io = Dispatchers.IO,
computation = Dispatchers.IO, computation = Dispatchers.IO,
main = Dispatchers.Main, main = Dispatchers.Main,
crypto = Handler(handlerThread.looper).asCoroutineDispatcher("crypto") crypto = createBackgroundHandler("Crypto_Thread").asCoroutineDispatcher()
) )
} }

View File

@ -50,7 +50,6 @@ import javax.inject.Inject
internal class DefaultSession @Inject constructor(override val sessionParams: SessionParams, internal class DefaultSession @Inject constructor(override val sessionParams: SessionParams,
private val context: Context, private val context: Context,
private val liveEntityObservers: Set<@JvmSuppressWildcards LiveEntityObserver>, private val liveEntityObservers: Set<@JvmSuppressWildcards LiveEntityObserver>,
private val monarchy: Monarchy,
private val sessionListeners: SessionListeners, private val sessionListeners: SessionListeners,
private val roomService: RoomService, private val roomService: RoomService,
private val roomDirectoryService: RoomDirectoryService, private val roomDirectoryService: RoomDirectoryService,
@ -66,16 +65,16 @@ internal class DefaultSession @Inject constructor(override val sessionParams: Se
private val contentUrlResolver: ContentUrlResolver, private val contentUrlResolver: ContentUrlResolver,
private val contentUploadProgressTracker: ContentUploadStateTracker) private val contentUploadProgressTracker: ContentUploadStateTracker)
: Session, : Session,
RoomService by roomService, RoomService by roomService,
RoomDirectoryService by roomDirectoryService, RoomDirectoryService by roomDirectoryService,
GroupService by groupService, GroupService by groupService,
UserService by userService, UserService by userService,
CryptoService by cryptoService, CryptoService by cryptoService,
CacheService by cacheService, CacheService by cacheService,
SignOutService by signOutService, SignOutService by signOutService,
FilterService by filterService, FilterService by filterService,
PushRuleService by pushRuleService, PushRuleService by pushRuleService,
PushersService by pushersService { PushersService by pushersService {
private var isOpen = false private var isOpen = false
@ -85,9 +84,6 @@ internal class DefaultSession @Inject constructor(override val sessionParams: Se
assertMainThread() assertMainThread()
assert(!isOpen) assert(!isOpen)
isOpen = true isOpen = true
if (!monarchy.isMonarchyThreadOpen) {
monarchy.openManually()
}
liveEntityObservers.forEach { it.start() } liveEntityObservers.forEach { it.start() }
} }
@ -123,9 +119,6 @@ internal class DefaultSession @Inject constructor(override val sessionParams: Se
stopSync() stopSync()
liveEntityObservers.forEach { it.dispose() } liveEntityObservers.forEach { it.dispose() }
cryptoService.close() cryptoService.close()
if (monarchy.isMonarchyThreadOpen) {
monarchy.closeManually()
}
isOpen = false isOpen = false
} }

View File

@ -27,14 +27,16 @@ import im.vector.matrix.android.api.auth.data.Credentials
import im.vector.matrix.android.internal.database.RealmLiveEntityObserver import im.vector.matrix.android.internal.database.RealmLiveEntityObserver
import im.vector.matrix.android.internal.database.model.GroupEntity import im.vector.matrix.android.internal.database.model.GroupEntity
import im.vector.matrix.android.internal.database.query.where import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.worker.WorkerParamsFactory import im.vector.matrix.android.internal.worker.WorkerParamsFactory
import io.realm.RealmConfiguration
import javax.inject.Inject import javax.inject.Inject
private const val GET_GROUP_DATA_WORKER = "GET_GROUP_DATA_WORKER" private const val GET_GROUP_DATA_WORKER = "GET_GROUP_DATA_WORKER"
internal class GroupSummaryUpdater @Inject constructor(private val context: Context, internal class GroupSummaryUpdater @Inject constructor(private val context: Context,
private val credentials: Credentials, private val credentials: Credentials,
monarchy: Monarchy) : RealmLiveEntityObserver<GroupEntity>(monarchy) { @SessionDatabase realmConfiguration: RealmConfiguration) : RealmLiveEntityObserver<GroupEntity>(realmConfiguration) {
override val query = Monarchy.Query<GroupEntity> { GroupEntity.where(it) } override val query = Monarchy.Query<GroupEntity> { GroupEntity.where(it) }

View File

@ -22,8 +22,10 @@ import im.vector.matrix.android.internal.database.RealmLiveEntityObserver
import im.vector.matrix.android.internal.database.mapper.asDomain import im.vector.matrix.android.internal.database.mapper.asDomain
import im.vector.matrix.android.internal.database.model.EventEntity import im.vector.matrix.android.internal.database.model.EventEntity
import im.vector.matrix.android.internal.database.query.types import im.vector.matrix.android.internal.database.query.types
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.task.TaskExecutor import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.task.configureWith import im.vector.matrix.android.internal.task.configureWith
import io.realm.RealmConfiguration
import timber.log.Timber import timber.log.Timber
import javax.inject.Inject import javax.inject.Inject
@ -33,11 +35,11 @@ import javax.inject.Inject
* The summaries can then be extracted and added (as a decoration) to a TimelineEvent for final display. * The summaries can then be extracted and added (as a decoration) to a TimelineEvent for final display.
*/ */
internal class EventRelationsAggregationUpdater @Inject constructor(monarchy: Monarchy, internal class EventRelationsAggregationUpdater @Inject constructor(@SessionDatabase realmConfiguration: RealmConfiguration,
private val credentials: Credentials, private val credentials: Credentials,
private val task: EventRelationsAggregationTask, private val task: EventRelationsAggregationTask,
private val taskExecutor: TaskExecutor) : private val taskExecutor: TaskExecutor) :
RealmLiveEntityObserver<EventEntity>(monarchy) { RealmLiveEntityObserver<EventEntity>(realmConfiguration) {
override val query = Monarchy.Query<EventEntity> { override val query = Monarchy.Query<EventEntity> {
EventEntity.types(it, listOf( EventEntity.types(it, listOf(

View File

@ -61,9 +61,8 @@ internal class RoomSummaryUpdater @Inject constructor(private val credentials: C
membership: Membership? = null, membership: Membership? = null,
roomSummary: RoomSyncSummary? = null, roomSummary: RoomSyncSummary? = null,
unreadNotifications: RoomSyncUnreadNotifications? = null) { unreadNotifications: RoomSyncUnreadNotifications? = null) {
val roomSummaryEntity = RoomSummaryEntity.where(realm, roomId).findFirst() val roomSummaryEntity = RoomSummaryEntity.where(realm, roomId).findFirst()
?: realm.createObject(roomId) ?: realm.createObject(roomId)
if (roomSummary != null) { if (roomSummary != null) {
if (roomSummary.heroes.isNotEmpty()) { if (roomSummary.heroes.isNotEmpty()) {
@ -77,12 +76,9 @@ internal class RoomSummaryUpdater @Inject constructor(private val credentials: C
roomSummaryEntity.joinedMembersCount = roomSummary.joinedMembersCount roomSummaryEntity.joinedMembersCount = roomSummary.joinedMembersCount
} }
} }
if (unreadNotifications?.highlightCount != null) { roomSummaryEntity.highlightCount = unreadNotifications?.highlightCount ?: 0
roomSummaryEntity.highlightCount = unreadNotifications.highlightCount roomSummaryEntity.notificationCount = unreadNotifications?.notificationCount ?:0
}
if (unreadNotifications?.notificationCount != null) {
roomSummaryEntity.notificationCount = unreadNotifications.notificationCount
}
if (membership != null) { if (membership != null) {
roomSummaryEntity.membership = membership roomSummaryEntity.membership = membership
} }

View File

@ -23,9 +23,11 @@ import im.vector.matrix.android.internal.database.RealmLiveEntityObserver
import im.vector.matrix.android.internal.database.mapper.asDomain import im.vector.matrix.android.internal.database.mapper.asDomain
import im.vector.matrix.android.internal.database.model.EventEntity import im.vector.matrix.android.internal.database.model.EventEntity
import im.vector.matrix.android.internal.database.query.where import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.session.SessionScope import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.task.TaskExecutor import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.task.configureWith import im.vector.matrix.android.internal.task.configureWith
import io.realm.RealmConfiguration
import timber.log.Timber import timber.log.Timber
import javax.inject.Inject import javax.inject.Inject
@ -33,11 +35,11 @@ import javax.inject.Inject
* Listens to the database for the insertion of any redaction event. * Listens to the database for the insertion of any redaction event.
* As it will actually delete the content, it should be called last in the list of listener. * As it will actually delete the content, it should be called last in the list of listener.
*/ */
internal class EventsPruner @Inject constructor(monarchy: Monarchy, internal class EventsPruner @Inject constructor(@SessionDatabase realmConfiguration: RealmConfiguration,
private val credentials: Credentials, private val credentials: Credentials,
private val pruneEventTask: PruneEventTask, private val pruneEventTask: PruneEventTask,
private val taskExecutor: TaskExecutor) : private val taskExecutor: TaskExecutor) :
RealmLiveEntityObserver<EventEntity>(monarchy) { RealmLiveEntityObserver<EventEntity>(realmConfiguration) {
override val query = Monarchy.Query<EventEntity> { EventEntity.where(it, type = EventType.REDACTION) } override val query = Monarchy.Query<EventEntity> { EventEntity.where(it, type = EventType.REDACTION) }

View File

@ -16,9 +16,6 @@
package im.vector.matrix.android.internal.session.room.timeline package im.vector.matrix.android.internal.session.room.timeline
import android.os.Handler
import android.os.HandlerThread
import android.os.Looper
import im.vector.matrix.android.api.MatrixCallback import im.vector.matrix.android.api.MatrixCallback
import im.vector.matrix.android.api.session.crypto.CryptoService import im.vector.matrix.android.api.session.crypto.CryptoService
import im.vector.matrix.android.api.session.events.model.EventType import im.vector.matrix.android.api.session.events.model.EventType
@ -43,6 +40,8 @@ import im.vector.matrix.android.internal.database.query.whereInRoom
import im.vector.matrix.android.internal.task.TaskExecutor import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.task.configureWith import im.vector.matrix.android.internal.task.configureWith
import im.vector.matrix.android.internal.util.Debouncer import im.vector.matrix.android.internal.util.Debouncer
import im.vector.matrix.android.internal.util.createBackgroundHandler
import im.vector.matrix.android.internal.util.createUIHandler
import io.realm.OrderedCollectionChangeSet import io.realm.OrderedCollectionChangeSet
import io.realm.OrderedRealmCollectionChangeListener import io.realm.OrderedRealmCollectionChangeListener
import io.realm.Realm import io.realm.Realm
@ -75,9 +74,7 @@ internal class DefaultTimeline(
) : Timeline { ) : Timeline {
private companion object { private companion object {
val BACKGROUND_HANDLER = Handler( val BACKGROUND_HANDLER = createBackgroundHandler("TIMELINE_DB_THREAD")
HandlerThread("TIMELINE_DB_THREAD").apply { start() }.looper
)
} }
override var listener: Timeline.Listener? = null override var listener: Timeline.Listener? = null
@ -90,7 +87,7 @@ internal class DefaultTimeline(
private val isStarted = AtomicBoolean(false) private val isStarted = AtomicBoolean(false)
private val isReady = AtomicBoolean(false) private val isReady = AtomicBoolean(false)
private val mainHandler = Handler(Looper.getMainLooper()) private val mainHandler = createUIHandler()
private val backgroundRealm = AtomicReference<Realm>() private val backgroundRealm = AtomicReference<Realm>()
private val cancelableBag = CancelableBag() private val cancelableBag = CancelableBag()
private val debouncer = Debouncer(mainHandler) private val debouncer = Debouncer(mainHandler)

View File

@ -22,17 +22,19 @@ import im.vector.matrix.android.internal.database.RealmLiveEntityObserver
import im.vector.matrix.android.internal.database.model.EventEntity import im.vector.matrix.android.internal.database.model.EventEntity
import im.vector.matrix.android.internal.database.model.EventEntityFields import im.vector.matrix.android.internal.database.model.EventEntityFields
import im.vector.matrix.android.internal.database.query.where import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.session.SessionScope import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.task.TaskExecutor import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.task.TaskThread import im.vector.matrix.android.internal.task.TaskThread
import im.vector.matrix.android.internal.task.configureWith import im.vector.matrix.android.internal.task.configureWith
import io.realm.RealmConfiguration
import io.realm.Sort import io.realm.Sort
import javax.inject.Inject import javax.inject.Inject
internal class UserEntityUpdater @Inject constructor(monarchy: Monarchy, internal class UserEntityUpdater @Inject constructor(@SessionDatabase realmConfiguration: RealmConfiguration,
private val updateUserTask: UpdateUserTask, private val updateUserTask: UpdateUserTask,
private val taskExecutor: TaskExecutor) private val taskExecutor: TaskExecutor)
: RealmLiveEntityObserver<EventEntity>(monarchy) { : RealmLiveEntityObserver<EventEntity>(realmConfiguration) {
override val query = Monarchy.Query<EventEntity> { override val query = Monarchy.Query<EventEntity> {
EventEntity EventEntity

View File

@ -0,0 +1,29 @@
/*
* 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.matrix.android.internal.util
import android.os.Handler
import android.os.HandlerThread
import android.os.Looper
fun createBackgroundHandler(name: String): Handler = Handler(
HandlerThread(name).apply { start() }.looper
)
fun createUIHandler(): Handler = Handler(
Looper.getMainLooper()
)

View File

@ -18,6 +18,7 @@ package im.vector.riotx.core.utils
import com.jakewharton.rxrelay2.BehaviorRelay import com.jakewharton.rxrelay2.BehaviorRelay
import io.reactivex.Observable import io.reactivex.Observable
import io.reactivex.schedulers.Schedulers
open class RxStore<T>(defaultValue: T? = null) { open class RxStore<T>(defaultValue: T? = null) {
@ -28,7 +29,7 @@ open class RxStore<T>(defaultValue: T? = null) {
} }
fun observe(): Observable<T> { fun observe(): Observable<T> {
return storeSubject.hide().distinctUntilChanged() return storeSubject.hide().observeOn(Schedulers.computation())
} }
fun post(value: T) { fun post(value: T) {

View File

@ -24,6 +24,7 @@ import com.squareup.inject.assisted.AssistedInject
import im.vector.matrix.android.api.session.Session import im.vector.matrix.android.api.session.Session
import im.vector.matrix.rx.rx import im.vector.matrix.rx.rx
import im.vector.riotx.core.platform.VectorViewModel import im.vector.riotx.core.platform.VectorViewModel
import io.reactivex.schedulers.Schedulers
/** /**
* View model used to update the home bottom bar notification counts * View model used to update the home bottom bar notification counts
@ -68,6 +69,7 @@ class HomeDetailViewModel @AssistedInject constructor(@Assisted initialState: Ho
private fun observeRoomSummaries() { private fun observeRoomSummaries() {
homeRoomListStore homeRoomListStore
.observe() .observe()
.observeOn(Schedulers.computation())
.subscribe { list -> .subscribe { list ->
list.let { summaries -> list.let { summaries ->
val peopleNotifications = summaries val peopleNotifications = summaries

View File

@ -21,18 +21,9 @@ import im.vector.riotx.core.utils.RxStore
import im.vector.riotx.features.home.room.list.RoomListDisplayModeFilter import im.vector.riotx.features.home.room.list.RoomListDisplayModeFilter
import im.vector.riotx.features.home.room.list.RoomListFragment import im.vector.riotx.features.home.room.list.RoomListFragment
import io.reactivex.Observable import io.reactivex.Observable
import io.reactivex.schedulers.Schedulers
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Singleton import javax.inject.Singleton
@Singleton @Singleton
class HomeRoomListObservableStore @Inject constructor() : RxStore<List<RoomSummary>>() { class HomeRoomListObservableStore @Inject constructor() : RxStore<List<RoomSummary>>()
fun observeFilteredBy(displayMode: RoomListFragment.DisplayMode): Observable<List<RoomSummary>> {
return observe()
.flatMapSingle {
Observable.fromIterable(it).filter(RoomListDisplayModeFilter(displayMode)).toList()
}
}
}

View File

@ -23,6 +23,9 @@ import io.reactivex.functions.Predicate
class RoomListDisplayModeFilter(private val displayMode: RoomListFragment.DisplayMode) : Predicate<RoomSummary> { class RoomListDisplayModeFilter(private val displayMode: RoomListFragment.DisplayMode) : Predicate<RoomSummary> {
override fun test(roomSummary: RoomSummary): Boolean { override fun test(roomSummary: RoomSummary): Boolean {
if (roomSummary.membership.isLeft()) {
return false
}
return when (displayMode) { return when (displayMode) {
RoomListFragment.DisplayMode.HOME -> roomSummary.notificationCount > 0 || roomSummary.membership == Membership.INVITE RoomListFragment.DisplayMode.HOME -> roomSummary.notificationCount > 0 || roomSummary.membership == Membership.INVITE
RoomListFragment.DisplayMode.PEOPLE -> roomSummary.isDirect && roomSummary.membership == Membership.JOIN RoomListFragment.DisplayMode.PEOPLE -> roomSummary.isDirect && roomSummary.membership == Membership.JOIN

View File

@ -31,6 +31,7 @@ import im.vector.matrix.android.api.session.room.model.tag.RoomTag
import im.vector.riotx.core.platform.VectorViewModel import im.vector.riotx.core.platform.VectorViewModel
import im.vector.riotx.core.utils.LiveEvent import im.vector.riotx.core.utils.LiveEvent
import im.vector.riotx.features.home.HomeRoomListObservableStore import im.vector.riotx.features.home.HomeRoomListObservableStore
import io.reactivex.schedulers.Schedulers
import timber.log.Timber import timber.log.Timber
class RoomListViewModel @AssistedInject constructor(@Assisted initialState: RoomListViewState, class RoomListViewModel @AssistedInject constructor(@Assisted initialState: RoomListViewState,
@ -55,6 +56,7 @@ class RoomListViewModel @AssistedInject constructor(@Assisted initialState: Room
} }
private val displayMode = initialState.displayMode private val displayMode = initialState.displayMode
private val roomListDisplayModeFilter = RoomListDisplayModeFilter(displayMode)
private val _openRoomLiveData = MutableLiveData<LiveEvent<String>>() private val _openRoomLiveData = MutableLiveData<LiveEvent<String>>()
val openRoomLiveData: LiveData<LiveEvent<String>> val openRoomLiveData: LiveData<LiveEvent<String>>
@ -95,7 +97,9 @@ class RoomListViewModel @AssistedInject constructor(@Assisted initialState: Room
copy(asyncRooms = asyncRooms) copy(asyncRooms = asyncRooms)
} }
homeRoomListObservableSource.observeFilteredBy(displayMode) homeRoomListObservableSource
.observe()
.observeOn(Schedulers.computation())
.map { buildRoomSummaries(it) } .map { buildRoomSummaries(it) }
.execute { async -> .execute { async ->
copy(asyncFilteredRooms = async) copy(asyncFilteredRooms = async)
@ -182,23 +186,24 @@ class RoomListViewModel @AssistedInject constructor(@Assisted initialState: Room
val lowPriorities = ArrayList<RoomSummary>() val lowPriorities = ArrayList<RoomSummary>()
val serverNotices = ArrayList<RoomSummary>() val serverNotices = ArrayList<RoomSummary>()
for (room in rooms) { rooms
if (room.membership.isLeft()) continue .filter { roomListDisplayModeFilter.test(it) }
val tags = room.tags.map { it.name } .forEach { room ->
when { val tags = room.tags.map { it.name }
room.membership == Membership.INVITE -> invites.add(room) when {
tags.contains(RoomTag.ROOM_TAG_SERVER_NOTICE) -> serverNotices.add(room) room.membership == Membership.INVITE -> invites.add(room)
tags.contains(RoomTag.ROOM_TAG_FAVOURITE) -> favourites.add(room) tags.contains(RoomTag.ROOM_TAG_SERVER_NOTICE) -> serverNotices.add(room)
tags.contains(RoomTag.ROOM_TAG_LOW_PRIORITY) -> lowPriorities.add(room) tags.contains(RoomTag.ROOM_TAG_FAVOURITE) -> favourites.add(room)
room.isDirect -> directChats.add(room) tags.contains(RoomTag.ROOM_TAG_LOW_PRIORITY) -> lowPriorities.add(room)
else -> groupRooms.add(room) room.isDirect -> directChats.add(room)
} else -> groupRooms.add(room)
} }
}
val roomComparator = when (displayMode) { val roomComparator = when (displayMode) {
RoomListFragment.DisplayMode.HOME -> chronologicalRoomComparator RoomListFragment.DisplayMode.HOME -> chronologicalRoomComparator
RoomListFragment.DisplayMode.PEOPLE -> chronologicalRoomComparator RoomListFragment.DisplayMode.PEOPLE -> chronologicalRoomComparator
RoomListFragment.DisplayMode.ROOMS -> alphabeticalRoomComparator RoomListFragment.DisplayMode.ROOMS -> chronologicalRoomComparator
} }
return RoomSummaries().apply { return RoomSummaries().apply {
@ -210,6 +215,4 @@ class RoomListViewModel @AssistedInject constructor(@Assisted initialState: Room
put(RoomCategory.SERVER_NOTICE, serverNotices.sortedWith(roomComparator)) put(RoomCategory.SERVER_NOTICE, serverNotices.sortedWith(roomComparator))
} }
} }
} }