Better DM filtering + fix space member loading

This commit is contained in:
Valere 2021-04-14 18:16:52 +02:00
parent 7910e84d8e
commit 1deb44f91f
10 changed files with 118 additions and 64 deletions

View File

@ -22,7 +22,6 @@ import com.squareup.moshi.JsonClass
/** /**
* "content": { * "content": {
* "via": ["example.com"], * "via": ["example.com"],
* "present": true,
* "order": "abcd", * "order": "abcd",
* "default": true * "default": true
* } * }

View File

@ -323,6 +323,31 @@ internal class RoomSummaryUpdater @Inject constructor(
// we need also to filter DMs... // we need also to filter DMs...
// it's more annoying as based on if the other members belong the space or not // it's more annoying as based on if the other members belong the space or not
RoomSummaryEntity.where(realm)
.equalTo(RoomSummaryEntityFields.IS_DIRECT, true)
.process(RoomSummaryEntityFields.MEMBERSHIP_STR, Membership.activeMemberships())
.findAll()
.forEach { dmRoom ->
val relatedSpaces = lookupMap.keys
.filter { it.roomType == RoomType.SPACE }
.filter {
dmRoom.otherMemberIds.toList().intersect(it.otherMemberIds.toList()).isNotEmpty()
}
.map { it.roomId }
.distinct()
val flattenRelated = mutableListOf<String>().apply {
addAll(relatedSpaces)
relatedSpaces.map { flattenSpaceParents[it] }.forEach {
if (it != null) addAll(it)
}
}.distinct()
if (flattenRelated.isEmpty()) {
dmRoom.flattenParentIds = null
} else {
dmRoom.flattenParentIds = "|${flattenRelated.joinToString("|")}|"
}
// Timber.v("## SPACES: flatten of ${dmRoom.otherMemberIds.joinToString(",")} is ${dmRoom.flattenParentIds}")
}
// LEGACY GROUPS // LEGACY GROUPS
// lets mark rooms that belongs to groups // lets mark rooms that belongs to groups

View File

@ -20,10 +20,15 @@ import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleObserver import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.OnLifecycleEvent import androidx.lifecycle.OnLifecycleEvent
import arrow.core.Option import arrow.core.Option
import im.vector.app.core.di.ActiveSessionHolder
import im.vector.app.core.utils.BehaviorDataSource import im.vector.app.core.utils.BehaviorDataSource
import im.vector.app.features.spaces.ALL_COMMUNITIES_GROUP_ID
import im.vector.app.features.ui.UiStateRepository import im.vector.app.features.ui.UiStateRepository
import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.CompositeDisposable
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import org.matrix.android.sdk.api.MatrixPatterns import org.matrix.android.sdk.api.MatrixPatterns
import org.matrix.android.sdk.api.extensions.tryOrNull
import org.matrix.android.sdk.api.session.room.model.RoomSummary import org.matrix.android.sdk.api.session.room.model.RoomSummary
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Singleton import javax.inject.Singleton
@ -36,30 +41,51 @@ import javax.inject.Singleton
@Singleton @Singleton
class AppStateHandler @Inject constructor( class AppStateHandler @Inject constructor(
sessionDataSource: ActiveSessionDataSource, sessionDataSource: ActiveSessionDataSource,
private val uiStateRepository: UiStateRepository private val uiStateRepository: UiStateRepository,
private val activeSessionHolder: ActiveSessionHolder
) : LifecycleObserver { ) : LifecycleObserver {
private val compositeDisposable = CompositeDisposable() private val compositeDisposable = CompositeDisposable()
val selectedSpaceDataSource = BehaviorDataSource<Option<RoomSummary>>(Option.empty()) private val selectedSpaceDataSource = BehaviorDataSource<Option<RoomSummary>>(Option.empty())
val selectedSpaceObservable = selectedSpaceDataSource.observe()
fun setCurrentSpace(space: RoomSummary?) {
if (space == selectedSpaceDataSource.currentValue?.orNull()) return
selectedSpaceDataSource.post(space?.let { Option.just(it) } ?: Option.empty())
if (space != null && space.roomId != ALL_COMMUNITIES_GROUP_ID) {
GlobalScope.launch {
tryOrNull {
activeSessionHolder.getSafeActiveSession()?.getRoom(space.roomId)?.loadRoomMembersIfNeeded()
}
}
}
}
init { init {
// restore current space from ui state // restore current space from ui state
sessionDataSource.currentValue?.orNull()?.let { session -> sessionDataSource.currentValue?.orNull()?.let { session ->
uiStateRepository.getSelectedSpace(session.sessionId)?.let { selectedSpaceId -> uiStateRepository.getSelectedSpace(session.sessionId)?.let { selectedSpaceId ->
session.getRoomSummary(selectedSpaceId)?.let { session.getRoomSummary(selectedSpaceId)?.let {
selectedSpaceDataSource.post(Option.just(it)) setCurrentSpace(it)
} }
} }
} }
} }
fun safeActiveSpaceId() : String? { fun safeActiveSpaceId(): String? {
return selectedSpaceDataSource.currentValue?.orNull()?.roomId?.takeIf { return selectedSpaceDataSource.currentValue?.orNull()?.roomId?.takeIf {
MatrixPatterns.isRoomId(it) MatrixPatterns.isRoomId(it)
} }
} }
fun safeActiveSpace(): RoomSummary? {
return selectedSpaceDataSource.currentValue?.orNull()?.takeIf {
MatrixPatterns.isRoomId(it.roomId)
}
}
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME) @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
fun entersForeground() { fun entersForeground() {
} }

View File

@ -149,8 +149,7 @@ class HomeDetailViewModel @AssistedInject constructor(@Assisted initialState: Ho
} }
private fun observeSelectedSpaceStore() { private fun observeSelectedSpaceStore() {
appStateHandler.selectedSpaceDataSource appStateHandler.selectedSpaceObservable
.observe()
.subscribe { .subscribe {
setState { setState {
copy(spaceSummary = it) copy(spaceSummary = it)
@ -160,7 +159,7 @@ class HomeDetailViewModel @AssistedInject constructor(@Assisted initialState: Ho
} }
private fun observeRoomSummaries() { private fun observeRoomSummaries() {
appStateHandler.selectedSpaceDataSource.observe().distinctUntilChanged().switchMap { appStateHandler.selectedSpaceObservable.distinctUntilChanged().switchMap {
session.getPagedRoomSummariesLive( session.getPagedRoomSummariesLive(
roomSummaryQueryParams { roomSummaryQueryParams {
memberships = Membership.activeMemberships() memberships = Membership.activeMemberships()

View File

@ -113,7 +113,9 @@ class GroupRoomListSectionBuilder(
return sections return sections
} }
private fun buildRoomsSections(sections: MutableList<RoomsSection>, activeSpaceAwareQueries: MutableList<UpdatableLivePageResult>, actualGroupId: String?) { private fun buildRoomsSections(sections: MutableList<RoomsSection>,
activeSpaceAwareQueries: MutableList<UpdatableLivePageResult>,
actualGroupId: String?) {
addSection( addSection(
sections, sections,
activeSpaceAwareQueries, activeSpaceAwareQueries,

View File

@ -74,7 +74,7 @@ class RoomListViewModel @Inject constructor(
init { init {
observeMembershipChanges() observeMembershipChanges()
appStateHandler.selectedSpaceDataSource.observe() appStateHandler.selectedSpaceObservable
.distinctUntilChanged() .distinctUntilChanged()
.map { it.orNull() } .map { it.orNull() }
.distinctUntilChanged() .distinctUntilChanged()

View File

@ -40,8 +40,6 @@ import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.session.room.RoomSummaryQueryParams import org.matrix.android.sdk.api.session.room.RoomSummaryQueryParams
import org.matrix.android.sdk.api.session.room.UpdatableLivePageResult import org.matrix.android.sdk.api.session.room.UpdatableLivePageResult
import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.model.Membership
import org.matrix.android.sdk.api.session.room.model.RoomSummary
import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams
import org.matrix.android.sdk.rx.asObservable import org.matrix.android.sdk.rx.asObservable
class SpaceRoomListSectionBuilder( class SpaceRoomListSectionBuilder(
@ -104,7 +102,7 @@ class SpaceRoomListSectionBuilder(
} }
} }
appStateHandler.selectedSpaceDataSource.observe() appStateHandler.selectedSpaceObservable
.distinctUntilChanged() .distinctUntilChanged()
.subscribe { activeSpaceOption -> .subscribe { activeSpaceOption ->
val selectedSpace = activeSpaceOption.orNull() val selectedSpace = activeSpaceOption.orNull()
@ -179,7 +177,7 @@ class SpaceRoomListSectionBuilder(
// add suggested rooms // add suggested rooms
val suggestedRoomsObservable = // MutableLiveData<List<SpaceChildInfo>>() val suggestedRoomsObservable = // MutableLiveData<List<SpaceChildInfo>>()
appStateHandler.selectedSpaceDataSource.observe() appStateHandler.selectedSpaceObservable
.distinctUntilChanged() .distinctUntilChanged()
.switchMap { activeSpaceOption -> .switchMap { activeSpaceOption ->
val selectedSpace = activeSpaceOption.orNull() val selectedSpace = activeSpaceOption.orNull()
@ -243,46 +241,57 @@ class SpaceRoomListSectionBuilder(
it.roomTagQueryFilter = RoomTagQueryFilter(true, null, null) it.roomTagQueryFilter = RoomTagQueryFilter(true, null, null)
} }
// For DMs we still need some post query filter :/ addSection(sections,
// It's probably less important as home is not filtering at all activeSpaceAwareQueries,
val dmList = MutableLiveData<List<RoomSummary>>() R.string.bottom_action_people_x,
Observables.combineLatest( false,
session.getRoomSummariesLive( RoomListViewModel.SpaceFilterStrategy.NOT_IF_ALL
roomSummaryQueryParams { ) {
memberships = listOf(Membership.JOIN) it.memberships = listOf(Membership.JOIN)
roomCategoryFilter = RoomCategoryFilter.ONLY_DM it.roomCategoryFilter = RoomCategoryFilter.ONLY_DM
} it.roomTagQueryFilter = RoomTagQueryFilter(false, null, null)
).asObservable(),
appStateHandler.selectedSpaceDataSource.observe()
) { rooms, currentSpaceOption ->
val currentSpace = currentSpaceOption.orNull()
.takeIf {
// the +ALL trick is annoying, should find a way to fix that at the source!
MatrixPatterns.isRoomId(it?.roomId)
}
if (currentSpace == null) {
rooms
} else {
rooms.filter {
it.otherMemberIds
.intersect(currentSpace.otherMemberIds)
.isNotEmpty()
}
}
}.subscribe {
dmList.postValue(it)
}.also {
onDisposable.invoke(it)
} }
sections.add( // // For DMs we still need some post query filter :/
RoomsSection( // // It's probably less important as home is not filtering at all
sectionName = stringProvider.getString(R.string.bottom_action_people_x), // val dmList = MutableLiveData<List<RoomSummary>>()
liveList = dmList, // Observables.combineLatest(
notifyOfLocalEcho = false // session.getRoomSummariesLive(
) // roomSummaryQueryParams {
) // memberships = listOf(Membership.JOIN)
// roomCategoryFilter = RoomCategoryFilter.ONLY_DM
// }
// ).asObservable(),
// appStateHandler.selectedSpaceDataSource.observe()
//
// ) { rooms, currentSpaceOption ->
// val currentSpace = currentSpaceOption.orNull()
// .takeIf {
// // the +ALL trick is annoying, should find a way to fix that at the source!
// MatrixPatterns.isRoomId(it?.roomId)
// }
// if (currentSpace == null) {
// rooms
// } else {
// rooms.filter {
// it.otherMemberIds
// .intersect(currentSpace.otherMemberIds)
// .isNotEmpty()
// }
// }
// }.subscribe {
// dmList.postValue(it)
// }.also {
// onDisposable.invoke(it)
// }
//
// sections.add(
// RoomsSection(
// sectionName = stringProvider.getString(R.string.bottom_action_people_x),
// liveList = dmList,
// notifyOfLocalEcho = false
// )
// )
} }
private fun addSection(sections: MutableList<RoomsSection>, private fun addSection(sections: MutableList<RoomsSection>,

View File

@ -155,7 +155,7 @@ abstract class BaseAttachmentProvider<Type>(
target.onVideoURLReady(info.uid, data.url) target.onVideoURLReady(info.uid, data.url)
} else { } else {
target.onVideoFileLoading(info.uid) target.onVideoFileLoading(info.uid)
GlobalScope.launch { GlobalScope.launch(Dispatchers.Main) {
val result = runCatching { val result = runCatching {
fileService.downloadFile( fileService.downloadFile(
fileName = data.filename, fileName = data.filename,

View File

@ -29,7 +29,6 @@ import androidx.core.app.ActivityOptionsCompat
import androidx.core.app.TaskStackBuilder import androidx.core.app.TaskStackBuilder
import androidx.core.util.Pair import androidx.core.util.Pair
import androidx.core.view.ViewCompat import androidx.core.view.ViewCompat
import arrow.core.Option
import im.vector.app.AppStateHandler import im.vector.app.AppStateHandler
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.di.ActiveSessionHolder import im.vector.app.core.di.ActiveSessionHolder
@ -114,7 +113,7 @@ class DefaultNavigator @Inject constructor(
sessionHolder.getSafeActiveSession()?.spaceService()?.getSpace(spaceId)?.spaceSummary()?.let { sessionHolder.getSafeActiveSession()?.spaceService()?.getSpace(spaceId)?.spaceSummary()?.let {
Timber.d("## Nav: Switching to space $spaceId / ${it.name}") Timber.d("## Nav: Switching to space $spaceId / ${it.name}")
appStateHandler.selectedSpaceDataSource.post(Option.just(it)) appStateHandler.setCurrentSpace(it)
} ?: kotlin.run { } ?: kotlin.run {
Timber.d("## Nav: Failed to switch to space $spaceId") Timber.d("## Nav: Failed to switch to space $spaceId")
} }
@ -252,7 +251,7 @@ class DefaultNavigator @Inject constructor(
} }
override fun openRoomDirectory(context: Context, initialFilter: String) { override fun openRoomDirectory(context: Context, initialFilter: String) {
val selectedSpace = appStateHandler.selectedSpaceDataSource.currentValue?.orNull()?.let { val selectedSpace = appStateHandler.safeActiveSpace()?.let {
sessionHolder.getSafeActiveSession()?.getRoomSummary(it.roomId) sessionHolder.getSafeActiveSession()?.getRoomSummary(it.roomId)
} }
if (selectedSpace == null) { if (selectedSpace == null) {
@ -276,9 +275,7 @@ class DefaultNavigator @Inject constructor(
} }
override fun openInviteUsersToRoom(context: Context, roomId: String) { override fun openInviteUsersToRoom(context: Context, roomId: String) {
val selectedSpace = appStateHandler.selectedSpaceDataSource.currentValue?.orNull()?.let { val selectedSpace = appStateHandler.safeActiveSpace()
sessionHolder.getSafeActiveSession()?.getRoomSummary(it.roomId)
}
if (vectorPreferences.labSpaces() && selectedSpace != null) { if (vectorPreferences.labSpaces() && selectedSpace != null) {
// let user decides if he does it from space or room // let user decides if he does it from space or room
(context as? AppCompatActivity)?.supportFragmentManager?.let { fm -> (context as? AppCompatActivity)?.supportFragmentManager?.let { fm ->

View File

@ -17,7 +17,6 @@
package im.vector.app.features.spaces package im.vector.app.features.spaces
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import arrow.core.Option
import com.airbnb.mvrx.FragmentViewModelContext import com.airbnb.mvrx.FragmentViewModelContext
import com.airbnb.mvrx.MvRxViewModelFactory import com.airbnb.mvrx.MvRxViewModelFactory
import com.airbnb.mvrx.ViewModelContext import com.airbnb.mvrx.ViewModelContext
@ -68,8 +67,7 @@ class SpacesListViewModel @AssistedInject constructor(@Assisted initialState: Sp
init { init {
observeSpaceSummaries() observeSpaceSummaries()
observeSelectionState() observeSelectionState()
appStateHandler.selectedSpaceDataSource appStateHandler.selectedSpaceObservable
.observe()
.subscribe { .subscribe {
if (currentGroupId != it.orNull()?.roomId) { if (currentGroupId != it.orNull()?.roomId) {
setState { setState {
@ -90,8 +88,7 @@ class SpacesListViewModel @AssistedInject constructor(@Assisted initialState: Sp
currentGroupId = spaceSummary.roomId currentGroupId = spaceSummary.roomId
_viewEvents.post(SpaceListViewEvents.OpenSpace) _viewEvents.post(SpaceListViewEvents.OpenSpace)
} }
val optionGroup = Option.just(spaceSummary) appStateHandler.setCurrentSpace(spaceSummary)
appStateHandler.selectedSpaceDataSource.post(optionGroup)
} else { } else {
// If selected group is null we force to default. It can happens when leaving the selected group. // If selected group is null we force to default. It can happens when leaving the selected group.
setState { setState {