Better DM filtering + fix space member loading
This commit is contained in:
parent
7910e84d8e
commit
1deb44f91f
|
@ -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
|
||||||
* }
|
* }
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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() {
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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>,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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 ->
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in New Issue