Optimize room list processing

This commit is contained in:
ganfra 2019-11-12 19:53:07 +01:00
parent d2acabddd9
commit 6dc5b126d6
3 changed files with 31 additions and 49 deletions

View File

@ -26,11 +26,13 @@ import im.vector.matrix.rx.rx
import im.vector.riotx.features.home.HomeRoomListDataSource
import im.vector.riotx.features.home.group.ALL_COMMUNITIES_GROUP_ID
import im.vector.riotx.features.home.group.SelectedGroupDataSource
import im.vector.riotx.features.home.room.list.ChronologicalRoomComparator
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.functions.BiFunction
import io.reactivex.rxkotlin.addTo
import java.util.Comparator
import java.util.concurrent.TimeUnit
import javax.inject.Inject
import javax.inject.Singleton
@ -43,7 +45,8 @@ import javax.inject.Singleton
class AppStateHandler @Inject constructor(
private val sessionDataSource: ActiveSessionDataSource,
private val homeRoomListDataSource: HomeRoomListDataSource,
private val selectedGroupDataSource: SelectedGroupDataSource) : LifecycleObserver {
private val selectedGroupDataSource: SelectedGroupDataSource,
private val chronologicalRoomComparator: ChronologicalRoomComparator) : LifecycleObserver {
private val compositeDisposable = CompositeDisposable()
@ -64,31 +67,24 @@ class AppStateHandler @Inject constructor(
.observeOn(AndroidSchedulers.mainThread())
.switchMap {
it.orNull()?.rx()?.liveRoomSummaries()
?: Observable.just(emptyList())
?: Observable.just(emptyList())
}
.throttleLast(300, TimeUnit.MILLISECONDS),
selectedGroupDataSource.observe(),
BiFunction { rooms, selectedGroupOption ->
val selectedGroup = selectedGroupOption.orNull()
val filteredDirectRooms = rooms
.filter { it.isDirect }
.filter {
if (selectedGroup == null || selectedGroup.groupId == ALL_COMMUNITIES_GROUP_ID) {
true
} else {
it.otherMemberIds
.intersect(selectedGroup.userIds)
.isNotEmpty()
}
}
val filteredGroupRooms = rooms
.filter { !it.isDirect }
.filter {
selectedGroup?.groupId == ALL_COMMUNITIES_GROUP_ID
|| selectedGroup?.roomIds?.contains(it.roomId) ?: true
}
filteredDirectRooms + filteredGroupRooms
val filteredRooms = rooms.filter {
if (selectedGroup == null || selectedGroup.groupId == ALL_COMMUNITIES_GROUP_ID) {
true
} else if (it.isDirect) {
it.otherMemberIds
.intersect(selectedGroup.userIds)
.isNotEmpty()
} else {
selectedGroup.roomIds.contains(it.roomId)
}
}
filteredRooms.sortedWith(chronologicalRoomComparator)
}
)
.subscribe {

View File

@ -34,9 +34,7 @@ import javax.inject.Inject
class RoomListViewModel @Inject constructor(initialState: RoomListViewState,
private val session: Session,
private val roomSummariesSource: DataSource<List<RoomSummary>>,
private val alphabeticalRoomComparator: AlphabeticalRoomComparator,
private val chronologicalRoomComparator: ChronologicalRoomComparator)
private val roomSummariesSource: DataSource<List<RoomSummary>>)
: VectorViewModel<RoomListViewState, RoomListAction>(initialState) {
interface Factory {
@ -97,9 +95,6 @@ class RoomListViewModel @Inject constructor(initialState: RoomListViewState,
roomSummariesSource
.observe()
.observeOn(Schedulers.computation())
.map {
it.sortedWith(chronologicalRoomComparator)
}
.execute { asyncRooms ->
copy(asyncRooms = asyncRooms)
}
@ -211,10 +206,11 @@ class RoomListViewModel @Inject constructor(initialState: RoomListViewState,
}
private fun buildRoomSummaries(rooms: List<RoomSummary>): RoomSummaries {
// Set up init size on directChats and groupRooms as they are the biggest ones
val invites = ArrayList<RoomSummary>()
val favourites = ArrayList<RoomSummary>()
val directChats = ArrayList<RoomSummary>()
val groupRooms = ArrayList<RoomSummary>()
val directChats = ArrayList<RoomSummary>(rooms.size)
val groupRooms = ArrayList<RoomSummary>(rooms.size)
val lowPriorities = ArrayList<RoomSummary>()
val serverNotices = ArrayList<RoomSummary>()
@ -232,21 +228,13 @@ class RoomListViewModel @Inject constructor(initialState: RoomListViewState,
}
}
val roomComparator = when (displayMode) {
RoomListDisplayMode.HOME -> chronologicalRoomComparator
RoomListDisplayMode.PEOPLE -> chronologicalRoomComparator
RoomListDisplayMode.ROOMS -> chronologicalRoomComparator
RoomListDisplayMode.FILTERED -> chronologicalRoomComparator
RoomListDisplayMode.SHARE -> chronologicalRoomComparator
}
return RoomSummaries().apply {
put(RoomCategory.INVITE, invites.sortedWith(roomComparator))
put(RoomCategory.FAVOURITE, favourites.sortedWith(roomComparator))
put(RoomCategory.DIRECT, directChats.sortedWith(roomComparator))
put(RoomCategory.GROUP, groupRooms.sortedWith(roomComparator))
put(RoomCategory.LOW_PRIORITY, lowPriorities.sortedWith(roomComparator))
put(RoomCategory.SERVER_NOTICE, serverNotices.sortedWith(roomComparator))
put(RoomCategory.INVITE, invites)
put(RoomCategory.FAVOURITE, favourites)
put(RoomCategory.DIRECT, directChats)
put(RoomCategory.GROUP, groupRooms)
put(RoomCategory.LOW_PRIORITY, lowPriorities)
put(RoomCategory.SERVER_NOTICE, serverNotices)
}
}
}

View File

@ -25,16 +25,14 @@ import javax.inject.Provider
class RoomListViewModelFactory @Inject constructor(private val session: Provider<Session>,
private val homeRoomListDataSource: Provider<HomeRoomListDataSource>,
private val shareRoomListDataSource: Provider<ShareRoomListDataSource>,
private val alphabeticalRoomComparator: Provider<AlphabeticalRoomComparator>,
private val chronologicalRoomComparator: Provider<ChronologicalRoomComparator>) : RoomListViewModel.Factory {
private val shareRoomListDataSource: Provider<ShareRoomListDataSource>)
: RoomListViewModel.Factory {
override fun create(initialState: RoomListViewState): RoomListViewModel {
return RoomListViewModel(
initialState,
session.get(),
if (initialState.displayMode == RoomListDisplayMode.SHARE) shareRoomListDataSource.get() else homeRoomListDataSource.get(),
alphabeticalRoomComparator.get(),
chronologicalRoomComparator.get())
if (initialState.displayMode == RoomListDisplayMode.SHARE) shareRoomListDataSource.get() else homeRoomListDataSource.get()
)
}
}