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": {
* "via": ["example.com"],
* "present": true,
* "order": "abcd",
* "default": true
* }

View file

@ -323,6 +323,31 @@ internal class RoomSummaryUpdater @Inject constructor(
// we need also to filter DMs...
// 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
// lets mark rooms that belongs to groups

View file

@ -20,10 +20,15 @@ import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.OnLifecycleEvent
import arrow.core.Option
import im.vector.app.core.di.ActiveSessionHolder
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 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.extensions.tryOrNull
import org.matrix.android.sdk.api.session.room.model.RoomSummary
import javax.inject.Inject
import javax.inject.Singleton
@ -36,30 +41,51 @@ import javax.inject.Singleton
@Singleton
class AppStateHandler @Inject constructor(
sessionDataSource: ActiveSessionDataSource,
private val uiStateRepository: UiStateRepository
private val uiStateRepository: UiStateRepository,
private val activeSessionHolder: ActiveSessionHolder
) : LifecycleObserver {
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 {
// restore current space from ui state
sessionDataSource.currentValue?.orNull()?.let { session ->
uiStateRepository.getSelectedSpace(session.sessionId)?.let { selectedSpaceId ->
session.getRoomSummary(selectedSpaceId)?.let {
selectedSpaceDataSource.post(Option.just(it))
setCurrentSpace(it)
}
}
}
}
fun safeActiveSpaceId() : String? {
fun safeActiveSpaceId(): String? {
return selectedSpaceDataSource.currentValue?.orNull()?.roomId?.takeIf {
MatrixPatterns.isRoomId(it)
}
}
fun safeActiveSpace(): RoomSummary? {
return selectedSpaceDataSource.currentValue?.orNull()?.takeIf {
MatrixPatterns.isRoomId(it.roomId)
}
}
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
fun entersForeground() {
}

View file

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

View file

@ -113,7 +113,9 @@ class GroupRoomListSectionBuilder(
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(
sections,
activeSpaceAwareQueries,

View file

@ -74,7 +74,7 @@ class RoomListViewModel @Inject constructor(
init {
observeMembershipChanges()
appStateHandler.selectedSpaceDataSource.observe()
appStateHandler.selectedSpaceObservable
.distinctUntilChanged()
.map { it.orNull() }
.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.UpdatableLivePageResult
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
class SpaceRoomListSectionBuilder(
@ -104,7 +102,7 @@ class SpaceRoomListSectionBuilder(
}
}
appStateHandler.selectedSpaceDataSource.observe()
appStateHandler.selectedSpaceObservable
.distinctUntilChanged()
.subscribe { activeSpaceOption ->
val selectedSpace = activeSpaceOption.orNull()
@ -179,7 +177,7 @@ class SpaceRoomListSectionBuilder(
// add suggested rooms
val suggestedRoomsObservable = // MutableLiveData<List<SpaceChildInfo>>()
appStateHandler.selectedSpaceDataSource.observe()
appStateHandler.selectedSpaceObservable
.distinctUntilChanged()
.switchMap { activeSpaceOption ->
val selectedSpace = activeSpaceOption.orNull()
@ -243,46 +241,57 @@ class SpaceRoomListSectionBuilder(
it.roomTagQueryFilter = RoomTagQueryFilter(true, null, null)
}
// For DMs we still need some post query filter :/
// It's probably less important as home is not filtering at all
val dmList = MutableLiveData<List<RoomSummary>>()
Observables.combineLatest(
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)
addSection(sections,
activeSpaceAwareQueries,
R.string.bottom_action_people_x,
false,
RoomListViewModel.SpaceFilterStrategy.NOT_IF_ALL
) {
it.memberships = listOf(Membership.JOIN)
it.roomCategoryFilter = RoomCategoryFilter.ONLY_DM
it.roomTagQueryFilter = RoomTagQueryFilter(false, null, null)
}
sections.add(
RoomsSection(
sectionName = stringProvider.getString(R.string.bottom_action_people_x),
liveList = dmList,
notifyOfLocalEcho = false
)
)
// // For DMs we still need some post query filter :/
// // It's probably less important as home is not filtering at all
// val dmList = MutableLiveData<List<RoomSummary>>()
// Observables.combineLatest(
// 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>,

View file

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

View file

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

View file

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