Unverified Commit 56d0699b authored by Benoît Marty's avatar Benoît Marty Committed by GitHub
Browse files

Merge pull request #3312 from vector-im/feature/bca/spaces_polish

Spaces various fixes and polish
parents bdc3f189 1799dcbd
...@@ -33,7 +33,7 @@ interface Space { ...@@ -33,7 +33,7 @@ interface Space {
fun spaceSummary(): RoomSummary? fun spaceSummary(): RoomSummary?
suspend fun addChildren(roomId: String, suspend fun addChildren(roomId: String,
viaServers: List<String>, viaServers: List<String>?,
order: String?, order: String?,
autoJoin: Boolean = false, autoJoin: Boolean = false,
suggested: Boolean? = false) suggested: Boolean? = false)
......
...@@ -18,19 +18,13 @@ package org.matrix.android.sdk.internal.session.permalinks ...@@ -18,19 +18,13 @@ package org.matrix.android.sdk.internal.session.permalinks
import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.Event
import org.matrix.android.sdk.api.session.permalinks.PermalinkService.Companion.MATRIX_TO_URL_BASE import org.matrix.android.sdk.api.session.permalinks.PermalinkService.Companion.MATRIX_TO_URL_BASE
import org.matrix.android.sdk.api.session.room.members.roomMemberQueryParams
import org.matrix.android.sdk.api.session.room.model.Membership
import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.di.UserId
import org.matrix.android.sdk.internal.session.room.RoomGetter
import java.net.URLEncoder
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Provider
internal class PermalinkFactory @Inject constructor( internal class PermalinkFactory @Inject constructor(
@UserId @UserId
private val userId: String, private val userId: String,
// Use a provider to fix circular Dagger dependency private val viaParameterFinder: ViaParameterFinder
private val roomGetterProvider: Provider<RoomGetter>
) { ) {
fun createPermalink(event: Event): String? { fun createPermalink(event: Event): String? {
...@@ -50,12 +44,12 @@ internal class PermalinkFactory @Inject constructor( ...@@ -50,12 +44,12 @@ internal class PermalinkFactory @Inject constructor(
return if (roomId.isEmpty()) { return if (roomId.isEmpty()) {
null null
} else { } else {
MATRIX_TO_URL_BASE + escape(roomId) + computeViaParams(userId, roomId) MATRIX_TO_URL_BASE + escape(roomId) + viaParameterFinder.computeViaParams(userId, roomId)
} }
} }
fun createPermalink(roomId: String, eventId: String): String { fun createPermalink(roomId: String, eventId: String): String {
return MATRIX_TO_URL_BASE + escape(roomId) + "/" + escape(eventId) + computeViaParams(userId, roomId) return MATRIX_TO_URL_BASE + escape(roomId) + "/" + escape(eventId) + viaParameterFinder.computeViaParams(userId, roomId)
} }
fun getLinkedId(url: String): String? { fun getLinkedId(url: String): String? {
...@@ -66,25 +60,6 @@ internal class PermalinkFactory @Inject constructor( ...@@ -66,25 +60,6 @@ internal class PermalinkFactory @Inject constructor(
} else null } else null
} }
/**
* Compute the via parameters.
* Take up to 3 homeserver domains, taking the most representative one regarding room members and including the
* current user one.
*/
private fun computeViaParams(userId: String, roomId: String): String {
val userHomeserver = userId.substringAfter(":")
return getUserIdsOfJoinedMembers(roomId)
.map { it.substringAfter(":") }
.groupBy { it }
.mapValues { it.value.size }
.toMutableMap()
// Ensure the user homeserver will be included
.apply { this[userHomeserver] = Int.MAX_VALUE }
.let { map -> map.keys.sortedByDescending { map[it] } }
.take(3)
.joinToString(prefix = "?via=", separator = "&via=") { URLEncoder.encode(it, "utf-8") }
}
/** /**
* Escape '/' in id, because it is used as a separator * Escape '/' in id, because it is used as a separator
* *
...@@ -104,15 +79,4 @@ internal class PermalinkFactory @Inject constructor( ...@@ -104,15 +79,4 @@ internal class PermalinkFactory @Inject constructor(
private fun unescape(id: String): String { private fun unescape(id: String): String {
return id.replace("%2F", "/") return id.replace("%2F", "/")
} }
/**
* Get a set of userIds of joined members of a room
*/
private fun getUserIdsOfJoinedMembers(roomId: String): Set<String> {
return roomGetterProvider.get().getRoom(roomId)
?.getRoomMembers(roomMemberQueryParams { memberships = listOf(Membership.JOIN) })
?.map { it.userId }
.orEmpty()
.toSet()
}
} }
/*
* Copyright 2021 The Matrix.org Foundation C.I.C.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.matrix.android.sdk.internal.session.permalinks
import org.matrix.android.sdk.api.session.room.members.roomMemberQueryParams
import org.matrix.android.sdk.api.session.room.model.Membership
import org.matrix.android.sdk.internal.di.UserId
import org.matrix.android.sdk.internal.session.room.RoomGetter
import java.net.URLEncoder
import javax.inject.Inject
import javax.inject.Provider
internal class ViaParameterFinder @Inject constructor(
@UserId private val userId: String,
private val roomGetterProvider: Provider<RoomGetter>
) {
fun computeViaParams(roomId: String, max: Int): List<String> {
return computeViaParams(userId, roomId, max)
}
/**
* Compute the via parameters.
* Take up to 3 homeserver domains, taking the most representative one regarding room members and including the
* current user one.
*/
fun computeViaParams(userId: String, roomId: String): String {
return computeViaParams(userId, roomId, 3)
.joinToString(prefix = "?via=", separator = "&via=") { URLEncoder.encode(it, "utf-8") }
}
fun computeViaParams(userId: String, roomId: String, max: Int): List<String> {
val userHomeserver = userId.substringAfter(":")
return getUserIdsOfJoinedMembers(roomId)
.map { it.substringAfter(":") }
.groupBy { it }
.mapValues { it.value.size }
.toMutableMap()
// Ensure the user homeserver will be included
.apply { this[userHomeserver] = Int.MAX_VALUE }
.let { map -> map.keys.sortedByDescending { map[it] } }
.take(max)
}
/**
* Get a set of userIds of joined members of a room
*/
private fun getUserIdsOfJoinedMembers(roomId: String): Set<String> {
return roomGetterProvider.get().getRoom(roomId)
?.getRoomMembers(roomMemberQueryParams { memberships = listOf(Membership.JOIN) })
?.map { it.userId }
.orEmpty()
.toSet()
}
}
...@@ -40,6 +40,7 @@ import org.matrix.android.sdk.api.session.search.SearchResult ...@@ -40,6 +40,7 @@ import org.matrix.android.sdk.api.session.search.SearchResult
import org.matrix.android.sdk.api.session.space.Space import org.matrix.android.sdk.api.session.space.Space
import org.matrix.android.sdk.api.util.Optional import org.matrix.android.sdk.api.util.Optional
import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM
import org.matrix.android.sdk.internal.session.permalinks.ViaParameterFinder
import org.matrix.android.sdk.internal.session.room.state.SendStateTask import org.matrix.android.sdk.internal.session.room.state.SendStateTask
import org.matrix.android.sdk.internal.session.room.summary.RoomSummaryDataSource import org.matrix.android.sdk.internal.session.room.summary.RoomSummaryDataSource
import org.matrix.android.sdk.internal.session.search.SearchTask import org.matrix.android.sdk.internal.session.search.SearchTask
...@@ -66,6 +67,7 @@ internal class DefaultRoom @Inject constructor(override val roomId: String, ...@@ -66,6 +67,7 @@ internal class DefaultRoom @Inject constructor(override val roomId: String,
private val roomMembersService: MembershipService, private val roomMembersService: MembershipService,
private val roomPushRuleService: RoomPushRuleService, private val roomPushRuleService: RoomPushRuleService,
private val sendStateTask: SendStateTask, private val sendStateTask: SendStateTask,
private val viaParameterFinder: ViaParameterFinder,
private val searchTask: SearchTask) : private val searchTask: SearchTask) :
Room, Room,
TimelineService by timelineService, TimelineService by timelineService,
...@@ -154,6 +156,6 @@ internal class DefaultRoom @Inject constructor(override val roomId: String, ...@@ -154,6 +156,6 @@ internal class DefaultRoom @Inject constructor(override val roomId: String,
override fun asSpace(): Space? { override fun asSpace(): Space? {
if (roomSummary()?.roomType != RoomType.SPACE) return null if (roomSummary()?.roomType != RoomType.SPACE) return null
return DefaultSpace(this, roomSummaryDataSource) return DefaultSpace(this, roomSummaryDataSource, viaParameterFinder)
} }
} }
...@@ -19,6 +19,7 @@ package org.matrix.android.sdk.internal.session.room ...@@ -19,6 +19,7 @@ package org.matrix.android.sdk.internal.session.room
import org.matrix.android.sdk.api.session.crypto.CryptoService import org.matrix.android.sdk.api.session.crypto.CryptoService
import org.matrix.android.sdk.api.session.room.Room import org.matrix.android.sdk.api.session.room.Room
import org.matrix.android.sdk.internal.session.SessionScope import org.matrix.android.sdk.internal.session.SessionScope
import org.matrix.android.sdk.internal.session.permalinks.ViaParameterFinder
import org.matrix.android.sdk.internal.session.room.alias.DefaultAliasService import org.matrix.android.sdk.internal.session.room.alias.DefaultAliasService
import org.matrix.android.sdk.internal.session.room.call.DefaultRoomCallService import org.matrix.android.sdk.internal.session.room.call.DefaultRoomCallService
import org.matrix.android.sdk.internal.session.room.draft.DefaultDraftService import org.matrix.android.sdk.internal.session.room.draft.DefaultDraftService
...@@ -60,6 +61,7 @@ internal class DefaultRoomFactory @Inject constructor(private val cryptoService: ...@@ -60,6 +61,7 @@ internal class DefaultRoomFactory @Inject constructor(private val cryptoService:
private val membershipServiceFactory: DefaultMembershipService.Factory, private val membershipServiceFactory: DefaultMembershipService.Factory,
private val roomPushRuleServiceFactory: DefaultRoomPushRuleService.Factory, private val roomPushRuleServiceFactory: DefaultRoomPushRuleService.Factory,
private val sendStateTask: SendStateTask, private val sendStateTask: SendStateTask,
private val viaParameterFinder: ViaParameterFinder,
private val searchTask: SearchTask) : private val searchTask: SearchTask) :
RoomFactory { RoomFactory {
...@@ -83,7 +85,8 @@ internal class DefaultRoomFactory @Inject constructor(private val cryptoService: ...@@ -83,7 +85,8 @@ internal class DefaultRoomFactory @Inject constructor(private val cryptoService:
roomMembersService = membershipServiceFactory.create(roomId), roomMembersService = membershipServiceFactory.create(roomId),
roomPushRuleService = roomPushRuleServiceFactory.create(roomId), roomPushRuleService = roomPushRuleServiceFactory.create(roomId),
sendStateTask = sendStateTask, sendStateTask = sendStateTask,
searchTask = searchTask searchTask = searchTask,
viaParameterFinder = viaParameterFinder
) )
} }
} }
...@@ -364,6 +364,8 @@ internal class RoomSummaryUpdater @Inject constructor( ...@@ -364,6 +364,8 @@ internal class RoomSummaryUpdater @Inject constructor(
realm.where(RoomSummaryEntity::class.java) realm.where(RoomSummaryEntity::class.java)
.process(RoomSummaryEntityFields.MEMBERSHIP_STR, listOf(Membership.JOIN)) .process(RoomSummaryEntityFields.MEMBERSHIP_STR, listOf(Membership.JOIN))
.notEqualTo(RoomSummaryEntityFields.ROOM_TYPE, RoomType.SPACE) .notEqualTo(RoomSummaryEntityFields.ROOM_TYPE, RoomType.SPACE)
// also we do not count DM in here, because home space will already show them
.equalTo(RoomSummaryEntityFields.IS_DIRECT, false)
.contains(RoomSummaryEntityFields.FLATTEN_PARENT_IDS, space.roomId) .contains(RoomSummaryEntityFields.FLATTEN_PARENT_IDS, space.roomId)
.findAll().forEach { .findAll().forEach {
highlightCount += it.highlightCount highlightCount += it.highlightCount
......
...@@ -24,11 +24,13 @@ import org.matrix.android.sdk.api.session.room.Room ...@@ -24,11 +24,13 @@ import org.matrix.android.sdk.api.session.room.Room
import org.matrix.android.sdk.api.session.room.model.RoomSummary import org.matrix.android.sdk.api.session.room.model.RoomSummary
import org.matrix.android.sdk.api.session.space.Space import org.matrix.android.sdk.api.session.space.Space
import org.matrix.android.sdk.api.session.space.model.SpaceChildContent import org.matrix.android.sdk.api.session.space.model.SpaceChildContent
import org.matrix.android.sdk.internal.session.permalinks.ViaParameterFinder
import org.matrix.android.sdk.internal.session.room.summary.RoomSummaryDataSource import org.matrix.android.sdk.internal.session.room.summary.RoomSummaryDataSource
internal class DefaultSpace( internal class DefaultSpace(
private val room: Room, private val room: Room,
private val spaceSummaryDataSource: RoomSummaryDataSource private val spaceSummaryDataSource: RoomSummaryDataSource,
private val viaParameterFinder: ViaParameterFinder
) : Space { ) : Space {
override fun asRoom(): Room { override fun asRoom(): Room {
...@@ -46,15 +48,17 @@ internal class DefaultSpace( ...@@ -46,15 +48,17 @@ internal class DefaultSpace(
} }
override suspend fun addChildren(roomId: String, override suspend fun addChildren(roomId: String,
viaServers: List<String>, viaServers: List<String>?,
order: String?, order: String?,
autoJoin: Boolean, autoJoin: Boolean,
suggested: Boolean?) { suggested: Boolean?) {
// Find best via
room.sendStateEvent( room.sendStateEvent(
eventType = EventType.STATE_SPACE_CHILD, eventType = EventType.STATE_SPACE_CHILD,
stateKey = roomId, stateKey = roomId,
body = SpaceChildContent( body = SpaceChildContent(
via = viaServers, via = viaServers ?: viaParameterFinder.computeViaParams(roomId, 3),
autoJoin = autoJoin, autoJoin = autoJoin,
order = order, order = order,
suggested = suggested suggested = suggested
......
/*
* Copyright 2019 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package im.vector.app.core.ui.list
import android.content.res.ColorStateList
import android.view.Gravity
import android.widget.ImageView
import android.widget.TextView
import androidx.annotation.DrawableRes
import androidx.core.view.isVisible
import androidx.core.widget.ImageViewCompat
import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass
import im.vector.app.R
import im.vector.app.core.epoxy.VectorEpoxyHolder
import im.vector.app.core.epoxy.VectorEpoxyModel
import im.vector.app.core.extensions.setTextOrHide
import im.vector.app.features.themes.ThemeUtils
/**
* A generic list item with a rounded corner background and an optional icon
*/
@EpoxyModelClass(layout = R.layout.item_generic_pill_footer)
abstract class GenericPillItem : VectorEpoxyModel<GenericPillItem.Holder>() {
@EpoxyAttribute
var text: CharSequence? = null
@EpoxyAttribute
var style: ItemStyle = ItemStyle.NORMAL_TEXT
@EpoxyAttribute
var itemClickAction: GenericItem.Action? = null
@EpoxyAttribute
var centered: Boolean = false
@EpoxyAttribute
@DrawableRes
var imageRes: Int? = null
@EpoxyAttribute
var tintIcon: Boolean = true
override fun bind(holder: Holder) {
super.bind(holder)
holder.textView.setTextOrHide(text)
holder.textView.typeface = style.toTypeFace()
holder.textView.textSize = style.toTextSize()
holder.textView.gravity = if (centered) Gravity.CENTER_HORIZONTAL else Gravity.START
if (imageRes != null) {
holder.imageView.setImageResource(imageRes!!)
holder.imageView.isVisible = true
} else {
holder.imageView.isVisible = false
}
if (tintIcon) {
val iconTintColor = ThemeUtils.getColor(holder.view.context, R.attr.riotx_text_secondary)
ImageViewCompat.setImageTintList(holder.imageView, ColorStateList.valueOf(iconTintColor))
} else {
ImageViewCompat.setImageTintList(holder.imageView, null)
}
holder.view.setOnClickListener {
itemClickAction?.perform?.run()
}
}
class Holder : VectorEpoxyHolder() {
val imageView by bind<ImageView>(R.id.itemGenericPillImage)
val textView by bind<TextView>(R.id.itemGenericPillText)
}
}
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
package im.vector.app.features.grouplist package im.vector.app.features.grouplist
import android.content.res.ColorStateList import android.content.res.ColorStateList
import android.view.View
import android.widget.ImageView import android.widget.ImageView
import android.widget.TextView import android.widget.TextView
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
...@@ -35,8 +36,9 @@ import im.vector.app.features.themes.ThemeUtils ...@@ -35,8 +36,9 @@ import im.vector.app.features.themes.ThemeUtils
abstract class HomeSpaceSummaryItem : VectorEpoxyModel<HomeSpaceSummaryItem.Holder>() { abstract class HomeSpaceSummaryItem : VectorEpoxyModel<HomeSpaceSummaryItem.Holder>() {
@EpoxyAttribute var selected: Boolean = false @EpoxyAttribute var selected: Boolean = false
@EpoxyAttribute var listener: (() -> Unit)? = null @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var listener: (() -> Unit)? = null
@EpoxyAttribute var countState : UnreadCounterBadgeView.State = UnreadCounterBadgeView.State(0, false) @EpoxyAttribute var countState : UnreadCounterBadgeView.State = UnreadCounterBadgeView.State(0, false)
@EpoxyAttribute var showSeparator: Boolean = false
override fun getViewType(): Int { override fun getViewType(): Int {
// mm.. it's reusing the same layout for basic space item // mm.. it's reusing the same layout for basic space item
...@@ -56,6 +58,7 @@ abstract class HomeSpaceSummaryItem : VectorEpoxyModel<HomeSpaceSummaryItem.Hold ...@@ -56,6 +58,7 @@ abstract class HomeSpaceSummaryItem : VectorEpoxyModel<HomeSpaceSummaryItem.Hold
holder.leaveView.isVisible = false holder.leaveView.isVisible = false
holder.counterBadgeView.render(countState) holder.counterBadgeView.render(countState)
holder.bottomSeparator.isVisible = showSeparator
} }
class Holder : VectorEpoxyHolder() { class Holder : VectorEpoxyHolder() {
...@@ -64,5 +67,6 @@ abstract class HomeSpaceSummaryItem : VectorEpoxyModel<HomeSpaceSummaryItem.Hold ...@@ -64,5 +67,6 @@ abstract class HomeSpaceSummaryItem : VectorEpoxyModel<HomeSpaceSummaryItem.Hold
val rootView by bind<CheckableConstraintLayout>(R.id.itemGroupLayout) val rootView by bind<CheckableConstraintLayout>(R.id.itemGroupLayout)
val leaveView by bind<ImageView>(R.id.groupTmpLeave) val leaveView by bind<ImageView>(R.id.groupTmpLeave)
val counterBadgeView by bind<UnreadCounterBadgeView>(R.id.groupCounterBadge) val counterBadgeView by bind<UnreadCounterBadgeView>(R.id.groupCounterBadge)
val bottomSeparator by bind<View>(R.id.groupBottomSeparator)
} }
} }
...@@ -202,7 +202,7 @@ class HomeDetailViewModel @AssistedInject constructor(@Assisted initialState: Ho ...@@ -202,7 +202,7 @@ class HomeDetailViewModel @AssistedInject constructor(@Assisted initialState: Ho
setState { setState {
copy( copy(
notificationCountCatchup = dmRooms.totalCount + otherRooms.totalCount + roomsInvite + dmInvites, notificationCountCatchup = dmRooms.totalCount + otherRooms.totalCount + roomsInvite + dmInvites,
notificationHighlightCatchup = dmRooms.isHighlight || otherRooms.isHighlight, notificationHighlightCatchup = dmRooms.isHighlight || otherRooms.isHighlight || (dmInvites + roomsInvite) > 0,
notificationCountPeople = dmRooms.totalCount + dmInvites, notificationCountPeople = dmRooms.totalCount + dmInvites,
notificationHighlightPeople = dmRooms.isHighlight || dmInvites > 0, notificationHighlightPeople = dmRooms.isHighlight || dmInvites > 0,
notificationCountRooms = otherRooms.totalCount + roomsInvite, notificationCountRooms = otherRooms.totalCount + roomsInvite,
......
...@@ -29,6 +29,7 @@ import im.vector.app.RoomGroupingMethod ...@@ -29,6 +29,7 @@ import im.vector.app.RoomGroupingMethod
import im.vector.app.core.platform.EmptyAction import im.vector.app.core.platform.EmptyAction
import im.vector.app.core.platform.EmptyViewEvents import im.vector.app.core.platform.EmptyViewEvents
import im.vector.app.core.platform.VectorViewModel import im.vector.app.core.platform.VectorViewModel
import im.vector.app.features.settings.VectorPreferences
import io.reactivex.Observable import io.reactivex.Observable
import io.reactivex.schedulers.Schedulers import io.reactivex.schedulers.Schedulers
import org.matrix.android.sdk.api.query.ActiveSpaceFilter import org.matrix.android.sdk.api.query.ActiveSpaceFilter
...@@ -52,6 +53,7 @@ data class CountInfo( ...@@ -52,6 +53,7 @@ data class CountInfo(
class UnreadMessagesSharedViewModel @AssistedInject constructor(@Assisted initialState: UnreadMessagesState, class UnreadMessagesSharedViewModel @AssistedInject constructor(@Assisted initialState: UnreadMessagesState,
session: Session, session: Session,
private val vectorPreferences: VectorPreferences,
appStateHandler: AppStateHandler) appStateHandler: AppStateHandler)
: VectorViewModel<UnreadMessagesState, EmptyAction, EmptyViewEvents>(initialState) { : VectorViewModel<UnreadMessagesState, EmptyAction, EmptyViewEvents>(initialState) {
...@@ -126,12 +128,24 @@ class UnreadMessagesSharedViewModel @AssistedInject constructor(@Assisted initia ...@@ -126,12 +128,24 @@ class UnreadMessagesSharedViewModel @AssistedInject constructor(@Assisted initia
} }
is RoomGroupingMethod.BySpace -> { is RoomGroupingMethod.BySpace -> {
val selectedSpace = appStateHandler.safeActiveSpaceId() val selectedSpace = appStateHandler.safeActiveSpaceId()
val counts = session.getNotificationCountForRooms(
val inviteCount = session.getRoomSummaries(roomSummaryQueryParams {
this.memberships = listOf(Membership.INVITE)
}).size
val totalCount = session.getNotificationCountForRooms(
roomSummaryQueryParams { roomSummaryQueryParams {
this.memberships = listOf(Membership.JOIN) this.memberships = listOf(Membership.JOIN)
this.activeSpaceFilter = ActiveSpaceFilter.ActiveSpace(null) this.activeSpaceFilter = ActiveSpaceFilter.ActiveSpace(null).takeIf {
vectorPreferences.labsSpacesOnlyOrphansInHome()
} ?: ActiveSpaceFilter.None
} }
) )
val counts = RoomAggregateNotificationCount(
totalCount.notificationCount + inviteCount,
totalCount.highlightCount + inviteCount
)
val rootCounts = session.spaceService().getRootSpaceSummaries() val rootCounts = session.spaceService().getRootSpaceSummaries()
.filter { .filter {
// filter out current selection // filter out current selection
......
...@@ -832,7 +832,7 @@ class RoomDetailViewModel @AssistedInject constructor( ...@@ -832,7 +832,7 @@ class RoomDetailViewModel @AssistedInject constructor(
session.spaceService().getSpace(spaceId) session.spaceService().getSpace(spaceId)
?.addChildren( ?.addChildren(
state.roomId,