mirror of
https://github.com/element-hq/element-android
synced 2024-11-28 05:31:21 +03:00
Better DM filtering + fix space member loading
This commit is contained in:
parent
7910e84d8e
commit
1deb44f91f
10 changed files with 118 additions and 64 deletions
|
@ -22,7 +22,6 @@ import com.squareup.moshi.JsonClass
|
|||
/**
|
||||
* "content": {
|
||||
* "via": ["example.com"],
|
||||
* "present": true,
|
||||
* "order": "abcd",
|
||||
* "default": true
|
||||
* }
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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() {
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -74,7 +74,7 @@ class RoomListViewModel @Inject constructor(
|
|||
init {
|
||||
observeMembershipChanges()
|
||||
|
||||
appStateHandler.selectedSpaceDataSource.observe()
|
||||
appStateHandler.selectedSpaceObservable
|
||||
.distinctUntilChanged()
|
||||
.map { it.orNull() }
|
||||
.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.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>,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 ->
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in a new issue