From 0250f61d10d4a0cb0963d35556d9ae322788d29c Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Tue, 26 Apr 2022 15:48:34 +0200 Subject: [PATCH 01/23] Replaces izPublic with isPublic --- .../home/room/list/RoomSummaryItem.kt | 68 ++++++++++++++----- .../home/room/list/RoomSummaryItemFactory.kt | 2 +- 2 files changed, 51 insertions(+), 19 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt index 70c5846646..e5a4e374c9 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt @@ -45,24 +45,56 @@ import org.matrix.android.sdk.api.util.MatrixItem @EpoxyModelClass(layout = R.layout.item_room) abstract class RoomSummaryItem : VectorEpoxyModel() { - @EpoxyAttribute lateinit var typingMessage: String - @EpoxyAttribute lateinit var avatarRenderer: AvatarRenderer - @EpoxyAttribute lateinit var matrixItem: MatrixItem + @EpoxyAttribute + lateinit var typingMessage: String - @EpoxyAttribute lateinit var lastFormattedEvent: EpoxyCharSequence - @EpoxyAttribute lateinit var lastEventTime: String - @EpoxyAttribute var encryptionTrustLevel: RoomEncryptionTrustLevel? = null - @EpoxyAttribute var userPresence: UserPresence? = null - @EpoxyAttribute var showPresence: Boolean = false - @EpoxyAttribute var izPublic: Boolean = false - @EpoxyAttribute var unreadNotificationCount: Int = 0 - @EpoxyAttribute var hasUnreadMessage: Boolean = false - @EpoxyAttribute var hasDraft: Boolean = false - @EpoxyAttribute var showHighlighted: Boolean = false - @EpoxyAttribute var hasFailedSending: Boolean = false - @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var itemLongClickListener: View.OnLongClickListener? = null - @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var itemClickListener: ClickListener? = null - @EpoxyAttribute var showSelected: Boolean = false + @EpoxyAttribute + lateinit var avatarRenderer: AvatarRenderer + + @EpoxyAttribute + lateinit var matrixItem: MatrixItem + + @EpoxyAttribute + lateinit var lastFormattedEvent: EpoxyCharSequence + + @EpoxyAttribute + lateinit var lastEventTime: String + + @EpoxyAttribute + var encryptionTrustLevel: RoomEncryptionTrustLevel? = null + + @EpoxyAttribute + var userPresence: UserPresence? = null + + @EpoxyAttribute + var showPresence: Boolean = false + + @EpoxyAttribute @JvmField + var isPublic: Boolean = false + + @EpoxyAttribute + var unreadNotificationCount: Int = 0 + + @EpoxyAttribute + var hasUnreadMessage: Boolean = false + + @EpoxyAttribute + var hasDraft: Boolean = false + + @EpoxyAttribute + var showHighlighted: Boolean = false + + @EpoxyAttribute + var hasFailedSending: Boolean = false + + @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) + var itemLongClickListener: View.OnLongClickListener? = null + + @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) + var itemClickListener: ClickListener? = null + + @EpoxyAttribute + var showSelected: Boolean = false override fun bind(holder: Holder) { super.bind(holder) @@ -79,7 +111,7 @@ abstract class RoomSummaryItem : VectorEpoxyModel() { holder.draftView.isVisible = hasDraft avatarRenderer.render(matrixItem, holder.avatarImageView) holder.roomAvatarDecorationImageView.render(encryptionTrustLevel) - holder.roomAvatarPublicDecorationImageView.isVisible = izPublic + holder.roomAvatarPublicDecorationImageView.isVisible = isPublic holder.roomAvatarFailSendingImageView.isVisible = hasFailedSending renderSelection(holder, showSelected) holder.typingView.setTextOrHide(typingMessage) diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt index 6326d9c97a..cd3a8b0890 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt @@ -124,7 +124,7 @@ class RoomSummaryItemFactory @Inject constructor(private val displayableEventFor .avatarRenderer(avatarRenderer) // We do not display shield in the room list anymore // .encryptionTrustLevel(roomSummary.roomEncryptionTrustLevel) - .izPublic(roomSummary.isPublic) + .isPublic(roomSummary.isPublic) .showPresence(roomSummary.isDirect) .userPresence(roomSummary.directUserPresence) .matrixItem(roomSummary.toMatrixItem()) From a3367d4075f54a06f0d7601d3432ad1fef081aea Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Tue, 26 Apr 2022 15:48:49 +0200 Subject: [PATCH 02/23] Replaces else cases in when branches to RoomListDisplayMode.FILTERED --- .../features/home/room/list/RoomListFragment.kt | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt index aaa469f68d..ef7a1012df 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt @@ -204,7 +204,7 @@ class RoomListFragment @Inject constructor( RoomListDisplayMode.NOTIFICATIONS -> views.createChatFabMenu.isVisible = true RoomListDisplayMode.PEOPLE -> views.createChatRoomButton.isVisible = true RoomListDisplayMode.ROOMS -> views.createGroupRoomButton.isVisible = true - else -> Unit // No button in this mode + RoomListDisplayMode.FILTERED -> Unit // No button in this mode } views.createChatRoomButton.debouncedClicks { @@ -230,7 +230,7 @@ class RoomListFragment @Inject constructor( RoomListDisplayMode.NOTIFICATIONS -> views.createChatFabMenu.hide() RoomListDisplayMode.PEOPLE -> views.createChatRoomButton.hide() RoomListDisplayMode.ROOMS -> views.createGroupRoomButton.hide() - else -> Unit + RoomListDisplayMode.FILTERED -> Unit } } } @@ -309,7 +309,7 @@ class RoomListFragment @Inject constructor( ) } } - section.isExpanded.observe(viewLifecycleOwner) { _ -> + section.isExpanded.observe(viewLifecycleOwner) { refreshCollapseStates() } controller.listener = this @@ -330,7 +330,7 @@ class RoomListFragment @Inject constructor( checkEmptyState() } observeItemCount(section, sectionAdapter) - section.isExpanded.observe(viewLifecycleOwner) { _ -> + section.isExpanded.observe(viewLifecycleOwner) { refreshCollapseStates() } controller.listener = this @@ -359,7 +359,7 @@ class RoomListFragment @Inject constructor( ) } } - section.isExpanded.observe(viewLifecycleOwner) { _ -> + section.isExpanded.observe(viewLifecycleOwner) { refreshCollapseStates() } controller.listener = this @@ -395,7 +395,7 @@ class RoomListFragment @Inject constructor( RoomListDisplayMode.NOTIFICATIONS -> views.createChatFabMenu.show() RoomListDisplayMode.PEOPLE -> views.createChatRoomButton.show() RoomListDisplayMode.ROOMS -> views.createGroupRoomButton.show() - else -> Unit + RoomListDisplayMode.FILTERED -> Unit } } } @@ -474,7 +474,8 @@ class RoomListFragment @Inject constructor( StateView.State.Empty( title = getString(R.string.room_list_catchup_empty_title), image = ContextCompat.getDrawable(requireContext(), R.drawable.ic_noun_party_popper), - message = getString(R.string.room_list_catchup_empty_body)) + message = getString(R.string.room_list_catchup_empty_body) + ) } RoomListDisplayMode.PEOPLE -> StateView.State.Empty( @@ -490,7 +491,7 @@ class RoomListFragment @Inject constructor( isBigImage = true, message = getString(R.string.room_list_rooms_empty_body) ) - else -> + RoomListDisplayMode.FILTERED -> // Always display the content in this mode, because if the footer StateView.State.Content } From 9e53e6cc8f1ef6f0507d93c5961c342185d1a07e Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Thu, 28 Apr 2022 10:41:40 +0200 Subject: [PATCH 03/23] Adds space name to rooms in filtered search --- .../relationship/RoomChildRelationInfo.kt | 16 ++-------- .../room/summary/RoomSummaryUpdater.kt | 29 ++++++++----------- .../list/CollapsableTypedEpoxyController.kt | 2 +- .../home/room/list/RoomListFragment.kt | 2 +- .../home/room/list/RoomSummaryItem.kt | 17 ++++++++++- .../home/room/list/RoomSummaryItemFactory.kt | 7 ++++- .../room/list/RoomSummaryListController.kt | 3 +- .../room/list/RoomSummaryPagedController.kt | 6 ++-- .../list/RoomSummaryPagedControllerFactory.kt | 5 ++-- .../features/share/IncomingShareController.kt | 3 +- vector/src/main/res/layout/item_room.xml | 3 +- 11 files changed, 52 insertions(+), 41 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relationship/RoomChildRelationInfo.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relationship/RoomChildRelationInfo.kt index 5bad334afc..fffca96acf 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relationship/RoomChildRelationInfo.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relationship/RoomChildRelationInfo.kt @@ -43,7 +43,6 @@ internal class RoomChildRelationInfo( data class SpaceChildInfo( val roomId: String, val order: String?, -// val autoJoin: Boolean, val viaServers: List ) @@ -60,18 +59,13 @@ internal class RoomChildRelationInfo( fun getDirectChildrenDescriptions(): List { return CurrentStateEventEntity.whereType(realm, roomId, EventType.STATE_SPACE_CHILD) .findAll() -// .also { -// Timber.v("## Space: Found ${it.count()} m.space.child state events for $roomId") -// } .mapNotNull { ContentMapper.map(it.root?.content).toModel()?.let { scc -> -// Timber.v("## Space child desc state event $scc") // Children where via is not present are ignored. scc.via?.let { via -> SpaceChildInfo( roomId = it.stateKey, order = scc.validOrder(), -// autoJoin = scc.autoJoin ?: false, viaServers = via ) } @@ -83,17 +77,13 @@ internal class RoomChildRelationInfo( fun getParentDescriptions(): List { return CurrentStateEventEntity.whereType(realm, roomId, EventType.STATE_SPACE_PARENT) .findAll() -// .also { -// Timber.v("## Space: Found ${it.count()} m.space.parent state events for $roomId") -// } .mapNotNull { - ContentMapper.map(it.root?.content).toModel()?.let { scc -> -// Timber.v("## Space parent desc state event $scc") + ContentMapper.map(it.root?.content).toModel()?.let { spaceParentContent -> // Parent where via is not present are ignored. - scc.via?.let { via -> + spaceParentContent.via?.let { via -> SpaceParentInfo( roomId = it.stateKey, - canonical = scc.canonical ?: false, + canonical = spaceParentContent.canonical ?: false, viaServers = via, stateEventSender = it.root?.sender ?: "" ) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt index 3af579d050..70c1453865 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt @@ -17,6 +17,7 @@ package org.matrix.android.sdk.internal.session.room.summary import io.realm.Realm +import io.realm.RealmList import io.realm.kotlin.createObject import kotlinx.coroutines.runBlocking import org.matrix.android.sdk.api.extensions.orFalse @@ -349,39 +350,34 @@ internal class RoomSummaryUpdater @Inject constructor( } val acyclicGraph = graph.withoutEdges(backEdges) -// Timber.v("## SPACES: acyclicGraph $acyclicGraph") val flattenSpaceParents = acyclicGraph.flattenDestination().map { it.key.name to it.value.map { it.name } }.toMap() -// Timber.v("## SPACES: flattenSpaceParents ${flattenSpaceParents.map { it.key.name to it.value.map { it.name } }.joinToString("\n") { -// it.first + ": [" + it.second.joinToString(",") + "]" -// }}") - -// Timber.v("## SPACES: lookup map ${lookupMap.map { it.key.name to it.value.map { it.name } }.toMap()}") lookupMap.entries .filter { it.key.roomType == RoomType.SPACE && it.key.membership == Membership.JOIN } .forEach { entry -> val parent = RoomSummaryEntity.where(realm, entry.key.roomId).findFirst() if (parent != null) { -// Timber.v("## SPACES: check hierarchy of ${parent.name} id ${parent.roomId}") -// Timber.v("## SPACES: flat known parents of ${parent.name} are ${flattenSpaceParents[parent.roomId]}") val flattenParentsIds = (flattenSpaceParents[parent.roomId] ?: emptyList()) + listOf(parent.roomId) -// Timber.v("## SPACES: flatten known parents of children of ${parent.name} are ${flattenParentsIds}") entry.value.forEach { child -> RoomSummaryEntity.where(realm, child.roomId).findFirst()?.let { childSum -> - -// Timber.w("## SPACES: ${childSum.name} is ${childSum.roomId} fc: ${childSum.flattenParentIds}") -// var allParents = childSum.flattenParentIds ?: "" + // TODO: Revisit + childSum.parents.add(SpaceParentSummaryEntity( + true, + parent.roomId, + parent, + RealmList() + )) if (childSum.flattenParentIds == null) childSum.flattenParentIds = "" flattenParentsIds.forEach { if (childSum.flattenParentIds?.contains(it) != true) { - childSum.flattenParentIds += "|$it" + if (childSum.flattenParentIds?.isEmpty() == false) { + childSum.flattenParentIds += "|" + } + childSum.flattenParentIds += it } } -// childSum.flattenParentIds = "$allParents|" - -// Timber.v("## SPACES: flatten of ${childSum.name} is ${childSum.flattenParentIds}") } } } @@ -411,7 +407,6 @@ internal class RoomSummaryUpdater @Inject constructor( // we keep real m.child/m.parent relations and add the one for common memberships dmRoom.flattenParentIds += "|${flattenRelated.joinToString("|")}|" } -// Timber.v("## SPACES: flatten of ${dmRoom.otherMemberIds.joinToString(",")} is ${dmRoom.flattenParentIds}") } // Maybe a good place to count the number of notifications for spaces? diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/CollapsableTypedEpoxyController.kt b/vector/src/main/java/im/vector/app/features/home/room/list/CollapsableTypedEpoxyController.kt index 8cf7e6bcab..35396d52d5 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/CollapsableTypedEpoxyController.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/CollapsableTypedEpoxyController.kt @@ -68,7 +68,7 @@ abstract class CollapsableTypedEpoxyController : } override fun buildModels() { - check(isBuildingModels()) { + check(isBuildingModels) { ("You cannot call `buildModels` directly. Call `setData` instead to trigger a model " + "refresh with new data.") } diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt index ef7a1012df..cabaf11b75 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt @@ -287,7 +287,7 @@ class RoomListFragment @Inject constructor( val contentAdapter = when { section.livePages != null -> { - pagedControllerFactory.createRoomSummaryPagedController() + pagedControllerFactory.createRoomSummaryPagedController(roomListParams.displayMode) .also { controller -> section.livePages.observe(viewLifecycleOwner) { pl -> controller.submitList(pl) diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt index e5a4e374c9..a869041aa8 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt @@ -36,6 +36,7 @@ import im.vector.app.core.ui.views.PresenceStateImageView import im.vector.app.core.ui.views.ShieldImageView import im.vector.app.features.displayname.getBestName import im.vector.app.features.home.AvatarRenderer +import im.vector.app.features.home.RoomListDisplayMode import im.vector.app.features.themes.ThemeUtils import im.vector.lib.core.utils.epoxy.charsequence.EpoxyCharSequence import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel @@ -54,6 +55,12 @@ abstract class RoomSummaryItem : VectorEpoxyModel() { @EpoxyAttribute lateinit var matrixItem: MatrixItem + @EpoxyAttribute + var displayMode: RoomListDisplayMode = RoomListDisplayMode.PEOPLE + + @EpoxyAttribute + var spaceName: String? = null + @EpoxyAttribute lateinit var lastFormattedEvent: EpoxyCharSequence @@ -105,7 +112,7 @@ abstract class RoomSummaryItem : VectorEpoxyModel() { } holder.titleView.text = matrixItem.getBestName() holder.lastEventTimeView.text = lastEventTime - holder.lastEventView.text = lastFormattedEvent.charSequence + holder.lastEventView.text = getTextForLastEventView() holder.unreadCounterBadgeView.render(UnreadCounterBadgeView.State(unreadNotificationCount, showHighlighted)) holder.unreadIndentIndicator.isVisible = hasUnreadMessage holder.draftView.isVisible = hasDraft @@ -119,6 +126,14 @@ abstract class RoomSummaryItem : VectorEpoxyModel() { holder.roomAvatarPresenceImageView.render(showPresence, userPresence) } + private fun getTextForLastEventView(): CharSequence { + return if (displayMode == RoomListDisplayMode.FILTERED) { + spaceName.orEmpty() // TODO: handle other cases + } else { + lastFormattedEvent.charSequence + } + } + override fun unbind(holder: Holder) { holder.rootView.setOnClickListener(null) holder.rootView.setOnLongClickListener(null) diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt index cd3a8b0890..f11f39e402 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt @@ -26,6 +26,7 @@ import im.vector.app.core.epoxy.VectorEpoxyModel import im.vector.app.core.error.ErrorFormatter import im.vector.app.core.resources.StringProvider import im.vector.app.features.home.AvatarRenderer +import im.vector.app.features.home.RoomListDisplayMode import im.vector.app.features.home.room.detail.timeline.format.DisplayableEventFormatter import im.vector.app.features.home.room.typing.TypingHelper import im.vector.lib.core.utils.epoxy.charsequence.toEpoxyCharSequence @@ -46,13 +47,14 @@ class RoomSummaryItemFactory @Inject constructor(private val displayableEventFor fun create(roomSummary: RoomSummary, roomChangeMembershipStates: Map, selectedRoomIds: Set, + displayMode: RoomListDisplayMode, listener: RoomListListener?): VectorEpoxyModel<*> { return when (roomSummary.membership) { Membership.INVITE -> { val changeMembershipState = roomChangeMembershipStates[roomSummary.roomId] ?: ChangeMembershipState.Unknown createInvitationItem(roomSummary, changeMembershipState, listener) } - else -> createRoomItem(roomSummary, selectedRoomIds, listener?.let { it::onRoomClicked }, listener?.let { it::onRoomLongClicked }) + else -> createRoomItem(roomSummary, selectedRoomIds, displayMode, listener?.let { it::onRoomClicked }, listener?.let { it::onRoomLongClicked }) } } @@ -105,6 +107,7 @@ class RoomSummaryItemFactory @Inject constructor(private val displayableEventFor fun createRoomItem( roomSummary: RoomSummary, selectedRoomIds: Set, + displayMode: RoomListDisplayMode, onClick: ((RoomSummary) -> Unit)?, onLongClick: ((RoomSummary) -> Boolean)? ): VectorEpoxyModel<*> { @@ -124,6 +127,8 @@ class RoomSummaryItemFactory @Inject constructor(private val displayableEventFor .avatarRenderer(avatarRenderer) // We do not display shield in the room list anymore // .encryptionTrustLevel(roomSummary.roomEncryptionTrustLevel) + .displayMode(displayMode) + .spaceName(roomSummary.spaceParents?.firstOrNull()?.roomSummary?.name.orEmpty()) .isPublic(roomSummary.isPublic) .showPresence(roomSummary.isDirect) .userPresence(roomSummary.directUserPresence) diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryListController.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryListController.kt index 75aaee45cb..683263dbbc 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryListController.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryListController.kt @@ -16,6 +16,7 @@ package im.vector.app.features.home.room.list +import im.vector.app.features.home.RoomListDisplayMode import org.matrix.android.sdk.api.session.room.model.RoomSummary class RoomSummaryListController( @@ -26,7 +27,7 @@ class RoomSummaryListController( override fun buildModels(data: List?) { data?.forEach { - add(roomSummaryItemFactory.create(it, emptyMap(), emptySet(), listener)) + add(roomSummaryItemFactory.create(it, emptyMap(), emptySet(), RoomListDisplayMode.ROOMS /* TODO: change */, listener)) } } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryPagedController.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryPagedController.kt index e9cbc69215..445438eec9 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryPagedController.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryPagedController.kt @@ -19,11 +19,13 @@ package im.vector.app.features.home.room.list import com.airbnb.epoxy.EpoxyModel import com.airbnb.epoxy.paging.PagedListEpoxyController import im.vector.app.core.utils.createUIHandler +import im.vector.app.features.home.RoomListDisplayMode import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState import org.matrix.android.sdk.api.session.room.model.RoomSummary class RoomSummaryPagedController( - private val roomSummaryItemFactory: RoomSummaryItemFactory + private val roomSummaryItemFactory: RoomSummaryItemFactory, + private val displayMode: RoomListDisplayMode ) : PagedListEpoxyController( // Important it must match the PageList builder notify Looper modelBuildingHandler = createUIHandler() @@ -57,6 +59,6 @@ class RoomSummaryPagedController( override fun buildItemModel(currentPosition: Int, item: RoomSummary?): EpoxyModel<*> { // for place holder if enabled item ?: return RoomSummaryItemPlaceHolder_().apply { id(currentPosition) } - return roomSummaryItemFactory.create(item, roomChangeMembershipStates.orEmpty(), emptySet(), listener) + return roomSummaryItemFactory.create(item, roomChangeMembershipStates.orEmpty(), emptySet(), displayMode, listener) } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryPagedControllerFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryPagedControllerFactory.kt index c86d8ab243..36f1b5ac90 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryPagedControllerFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryPagedControllerFactory.kt @@ -16,14 +16,15 @@ package im.vector.app.features.home.room.list +import im.vector.app.features.home.RoomListDisplayMode import javax.inject.Inject class RoomSummaryPagedControllerFactory @Inject constructor( private val roomSummaryItemFactory: RoomSummaryItemFactory ) { - fun createRoomSummaryPagedController(): RoomSummaryPagedController { - return RoomSummaryPagedController(roomSummaryItemFactory) + fun createRoomSummaryPagedController(displayMode: RoomListDisplayMode): RoomSummaryPagedController { + return RoomSummaryPagedController(roomSummaryItemFactory, displayMode) } fun createRoomSummaryListController(): RoomSummaryListController { diff --git a/vector/src/main/java/im/vector/app/features/share/IncomingShareController.kt b/vector/src/main/java/im/vector/app/features/share/IncomingShareController.kt index fd35bf11a4..7c82b7aea0 100644 --- a/vector/src/main/java/im/vector/app/features/share/IncomingShareController.kt +++ b/vector/src/main/java/im/vector/app/features/share/IncomingShareController.kt @@ -22,6 +22,7 @@ import im.vector.app.R import im.vector.app.core.epoxy.loadingItem import im.vector.app.core.epoxy.noResultItem import im.vector.app.core.resources.StringProvider +import im.vector.app.features.home.RoomListDisplayMode import im.vector.app.features.home.room.list.RoomSummaryItemFactory import org.matrix.android.sdk.api.session.room.model.RoomSummary import javax.inject.Inject @@ -53,7 +54,7 @@ class IncomingShareController @Inject constructor(private val roomSummaryItemFac } else { roomSummaries.forEach { roomSummary -> roomSummaryItemFactory - .createRoomItem(roomSummary, data.selectedRoomIds, callback?.let { it::onRoomClicked }, callback?.let { it::onRoomLongClicked }) + .createRoomItem(roomSummary, data.selectedRoomIds, RoomListDisplayMode.ROOMS /* TODO: Change */, callback?.let { it::onRoomClicked }, callback?.let { it::onRoomLongClicked }) .addTo(this) } } diff --git a/vector/src/main/res/layout/item_room.xml b/vector/src/main/res/layout/item_room.xml index 2b27cb8efe..3911e8df34 100644 --- a/vector/src/main/res/layout/item_room.xml +++ b/vector/src/main/res/layout/item_room.xml @@ -213,7 +213,8 @@ app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="@id/roomNameView" app:layout_constraintTop_toBottomOf="@id/roomNameView" - tools:text="Alice is typing…" /> + tools:text="Alice is typing…" + tools:visibility="gone" /> Date: Thu, 28 Apr 2022 11:12:47 +0200 Subject: [PATCH 04/23] Adds user id and canonical alias to search result subtitles --- .../app/features/home/room/list/RoomSummaryItem.kt | 10 +++++----- .../home/room/list/RoomSummaryItemFactory.kt | 12 +++++++++++- vector/src/main/res/layout/item_room.xml | 4 ++-- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt index a869041aa8..3c091d0e05 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt @@ -59,7 +59,7 @@ abstract class RoomSummaryItem : VectorEpoxyModel() { var displayMode: RoomListDisplayMode = RoomListDisplayMode.PEOPLE @EpoxyAttribute - var spaceName: String? = null + lateinit var subtitle: String @EpoxyAttribute lateinit var lastFormattedEvent: EpoxyCharSequence @@ -112,7 +112,7 @@ abstract class RoomSummaryItem : VectorEpoxyModel() { } holder.titleView.text = matrixItem.getBestName() holder.lastEventTimeView.text = lastEventTime - holder.lastEventView.text = getTextForLastEventView() + holder.subtitleView.text = getTextForLastEventView() holder.unreadCounterBadgeView.render(UnreadCounterBadgeView.State(unreadNotificationCount, showHighlighted)) holder.unreadIndentIndicator.isVisible = hasUnreadMessage holder.draftView.isVisible = hasDraft @@ -122,13 +122,13 @@ abstract class RoomSummaryItem : VectorEpoxyModel() { holder.roomAvatarFailSendingImageView.isVisible = hasFailedSending renderSelection(holder, showSelected) holder.typingView.setTextOrHide(typingMessage) - holder.lastEventView.isInvisible = holder.typingView.isVisible + holder.subtitleView.isInvisible = holder.typingView.isVisible holder.roomAvatarPresenceImageView.render(showPresence, userPresence) } private fun getTextForLastEventView(): CharSequence { return if (displayMode == RoomListDisplayMode.FILTERED) { - spaceName.orEmpty() // TODO: handle other cases + subtitle } else { lastFormattedEvent.charSequence } @@ -157,7 +157,7 @@ abstract class RoomSummaryItem : VectorEpoxyModel() { val titleView by bind(R.id.roomNameView) val unreadCounterBadgeView by bind(R.id.roomUnreadCounterBadgeView) val unreadIndentIndicator by bind(R.id.roomUnreadIndicator) - val lastEventView by bind(R.id.roomLastEventView) + val subtitleView by bind(R.id.subtitleView) val typingView by bind(R.id.roomTypingView) val draftView by bind(R.id.roomDraftBadge) val lastEventTimeView by bind(R.id.roomLastEventTimeView) diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt index f11f39e402..cc99c0eb6e 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt @@ -111,6 +111,7 @@ class RoomSummaryItemFactory @Inject constructor(private val displayableEventFor onClick: ((RoomSummary) -> Unit)?, onLongClick: ((RoomSummary) -> Boolean)? ): VectorEpoxyModel<*> { + val subtitle = getSearchResultSubtitle(roomSummary) val unreadCount = roomSummary.notificationCount val showHighlighted = roomSummary.highlightCount > 0 val showSelected = selectedRoomIds.contains(roomSummary.roomId) @@ -121,6 +122,7 @@ class RoomSummaryItemFactory @Inject constructor(private val displayableEventFor latestFormattedEvent = displayableEventFormatter.format(latestEvent, roomSummary.isDirect, roomSummary.isDirect.not()) latestEventTime = dateFormatter.format(latestEvent.root.originServerTs, DateFormatKind.ROOM_LIST) } + val typingMessage = typingHelper.getTypingMessage(roomSummary.typingUsers) return RoomSummaryItem_() .id(roomSummary.roomId) @@ -128,7 +130,7 @@ class RoomSummaryItemFactory @Inject constructor(private val displayableEventFor // We do not display shield in the room list anymore // .encryptionTrustLevel(roomSummary.roomEncryptionTrustLevel) .displayMode(displayMode) - .spaceName(roomSummary.spaceParents?.firstOrNull()?.roomSummary?.name.orEmpty()) + .subtitle(subtitle) .isPublic(roomSummary.isPublic) .showPresence(roomSummary.isDirect) .userPresence(roomSummary.directUserPresence) @@ -147,4 +149,12 @@ class RoomSummaryItemFactory @Inject constructor(private val displayableEventFor } .itemClickListener { onClick?.invoke(roomSummary) } } + + private fun getSearchResultSubtitle(roomSummary: RoomSummary): String { + val spaceName = roomSummary.spaceParents?.firstOrNull()?.roomSummary?.name + val userId = roomSummary.directUserId + val canonicalAlias = roomSummary.canonicalAlias + + return (spaceName ?: userId ?: canonicalAlias).orEmpty() + } } diff --git a/vector/src/main/res/layout/item_room.xml b/vector/src/main/res/layout/item_room.xml index 3911e8df34..ab0af18acb 100644 --- a/vector/src/main/res/layout/item_room.xml +++ b/vector/src/main/res/layout/item_room.xml @@ -183,7 +183,7 @@ tools:text="@tools:sample/date/hhmm" /> Date: Thu, 28 Apr 2022 11:46:02 +0200 Subject: [PATCH 05/23] Disables typing indicator in filtered search --- .../app/features/home/room/list/RoomSummaryItem.kt | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt index 3c091d0e05..e0547b87b1 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt @@ -121,9 +121,16 @@ abstract class RoomSummaryItem : VectorEpoxyModel() { holder.roomAvatarPublicDecorationImageView.isVisible = isPublic holder.roomAvatarFailSendingImageView.isVisible = hasFailedSending renderSelection(holder, showSelected) - holder.typingView.setTextOrHide(typingMessage) - holder.subtitleView.isInvisible = holder.typingView.isVisible holder.roomAvatarPresenceImageView.render(showPresence, userPresence) + showTypingViewIfNecessary(holder) + + } + + private fun showTypingViewIfNecessary(holder: Holder) { + if (displayMode != RoomListDisplayMode.FILTERED) { + holder.typingView.setTextOrHide(typingMessage) + holder.subtitleView.isInvisible = holder.typingView.isVisible + } } private fun getTextForLastEventView(): CharSequence { From 33475602f865d339c3119cb7e137c5c02aa4e9c5 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Thu, 28 Apr 2022 11:54:51 +0200 Subject: [PATCH 06/23] Adds canonical named argument to RoomSummaryUpdater --- .../sdk/internal/session/room/summary/RoomSummaryUpdater.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt index 70c1453865..1c1963bfd4 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt @@ -364,7 +364,7 @@ internal class RoomSummaryUpdater @Inject constructor( RoomSummaryEntity.where(realm, child.roomId).findFirst()?.let { childSum -> // TODO: Revisit childSum.parents.add(SpaceParentSummaryEntity( - true, + canonical = true, parent.roomId, parent, RealmList() From b28035807788e1ac40a1586a24b2a9b79046c4c7 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Thu, 28 Apr 2022 11:55:44 +0200 Subject: [PATCH 07/23] Adds more named arguments to RoomSummaryUpdater --- .../sdk/internal/session/room/summary/RoomSummaryUpdater.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt index 1c1963bfd4..81979c6926 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt @@ -365,9 +365,9 @@ internal class RoomSummaryUpdater @Inject constructor( // TODO: Revisit childSum.parents.add(SpaceParentSummaryEntity( canonical = true, - parent.roomId, - parent, - RealmList() + parentRoomId = parent.roomId, + parentSummaryEntity = parent, + viaServers = RealmList() )) if (childSum.flattenParentIds == null) childSum.flattenParentIds = "" flattenParentsIds.forEach { From 4784717b0cecab67d03731daaa4dc32f58ef8e1d Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Thu, 28 Apr 2022 12:02:04 +0200 Subject: [PATCH 08/23] Fixes lint error --- .../im/vector/app/features/home/room/list/RoomSummaryItem.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt index e0547b87b1..aa459afd3b 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt @@ -123,7 +123,6 @@ abstract class RoomSummaryItem : VectorEpoxyModel() { renderSelection(holder, showSelected) holder.roomAvatarPresenceImageView.render(showPresence, userPresence) showTypingViewIfNecessary(holder) - } private fun showTypingViewIfNecessary(holder: Holder) { From 962e9abc6bea1bfd0efa9105fd0db072b6f48a67 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Thu, 28 Apr 2022 12:04:54 +0200 Subject: [PATCH 09/23] Fixes lint error --- .../app/features/home/room/list/RoomSummaryItemFactory.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt index cc99c0eb6e..f9f61f730b 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt @@ -54,7 +54,9 @@ class RoomSummaryItemFactory @Inject constructor(private val displayableEventFor val changeMembershipState = roomChangeMembershipStates[roomSummary.roomId] ?: ChangeMembershipState.Unknown createInvitationItem(roomSummary, changeMembershipState, listener) } - else -> createRoomItem(roomSummary, selectedRoomIds, displayMode, listener?.let { it::onRoomClicked }, listener?.let { it::onRoomLongClicked }) + else -> createRoomItem( + roomSummary, selectedRoomIds, displayMode, listener?.let { it::onRoomClicked }, listener?.let { it::onRoomLongClicked } + ) } } From 7e415e82b099dcb5111caffb05d1577f843fc3f8 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Thu, 28 Apr 2022 12:37:54 +0200 Subject: [PATCH 10/23] Fixes lint error --- .../vector/app/features/share/IncomingShareController.kt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/vector/src/main/java/im/vector/app/features/share/IncomingShareController.kt b/vector/src/main/java/im/vector/app/features/share/IncomingShareController.kt index 7c82b7aea0..6926a54cc4 100644 --- a/vector/src/main/java/im/vector/app/features/share/IncomingShareController.kt +++ b/vector/src/main/java/im/vector/app/features/share/IncomingShareController.kt @@ -54,7 +54,13 @@ class IncomingShareController @Inject constructor(private val roomSummaryItemFac } else { roomSummaries.forEach { roomSummary -> roomSummaryItemFactory - .createRoomItem(roomSummary, data.selectedRoomIds, RoomListDisplayMode.ROOMS /* TODO: Change */, callback?.let { it::onRoomClicked }, callback?.let { it::onRoomLongClicked }) + .createRoomItem( + roomSummary, + data.selectedRoomIds, + RoomListDisplayMode.ROOMS /* TODO: Change */, + callback?.let { it::onRoomClicked }, + callback?.let { it::onRoomLongClicked } + ) .addTo(this) } } From 7cc79fef0faa72b764efdfedc97957e312f2a522 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Fri, 29 Apr 2022 12:37:19 +0200 Subject: [PATCH 11/23] Refactors RoomSummaryItem --- .../home/room/list/RoomSummaryItem.kt | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt index aa459afd3b..4cea812775 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt @@ -105,14 +105,14 @@ abstract class RoomSummaryItem : VectorEpoxyModel() { override fun bind(holder: Holder) { super.bind(holder) + + renderDisplayMode(holder) holder.rootView.onClick(itemClickListener) holder.rootView.setOnLongClickListener { it.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS) itemLongClickListener?.onLongClick(it) ?: false } holder.titleView.text = matrixItem.getBestName() - holder.lastEventTimeView.text = lastEventTime - holder.subtitleView.text = getTextForLastEventView() holder.unreadCounterBadgeView.render(UnreadCounterBadgeView.State(unreadNotificationCount, showHighlighted)) holder.unreadIndentIndicator.isVisible = hasUnreadMessage holder.draftView.isVisible = hasDraft @@ -122,22 +122,24 @@ abstract class RoomSummaryItem : VectorEpoxyModel() { holder.roomAvatarFailSendingImageView.isVisible = hasFailedSending renderSelection(holder, showSelected) holder.roomAvatarPresenceImageView.render(showPresence, userPresence) - showTypingViewIfNecessary(holder) } - private fun showTypingViewIfNecessary(holder: Holder) { - if (displayMode != RoomListDisplayMode.FILTERED) { - holder.typingView.setTextOrHide(typingMessage) - holder.subtitleView.isInvisible = holder.typingView.isVisible - } + private fun renderDisplayMode(holder: Holder) = when (displayMode) { + RoomListDisplayMode.ROOMS, + RoomListDisplayMode.PEOPLE, + RoomListDisplayMode.NOTIFICATIONS -> renderForDefaultDisplayMode(holder) + RoomListDisplayMode.FILTERED -> renderForFilteredDisplayMode(holder) } - private fun getTextForLastEventView(): CharSequence { - return if (displayMode == RoomListDisplayMode.FILTERED) { - subtitle - } else { - lastFormattedEvent.charSequence - } + private fun renderForDefaultDisplayMode(holder: Holder) { + holder.subtitleView.text = lastFormattedEvent.charSequence + holder.lastEventTimeView.text = lastEventTime + } + + private fun renderForFilteredDisplayMode(holder: Holder) { + holder.subtitleView.text = subtitle + holder.typingView.setTextOrHide(typingMessage) + holder.subtitleView.isInvisible = holder.typingView.isVisible } override fun unbind(holder: Holder) { From a355b625e9dd671af000970963eb4406f270faa0 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Fri, 29 Apr 2022 13:05:08 +0200 Subject: [PATCH 12/23] Adds displayMode to RoomSummaryListController --- .../vector/app/features/home/room/list/RoomListFragment.kt | 2 +- .../app/features/home/room/list/RoomSummaryListController.kt | 5 +++-- .../home/room/list/RoomSummaryPagedControllerFactory.kt | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt index cabaf11b75..65055346e6 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt @@ -337,7 +337,7 @@ class RoomListFragment @Inject constructor( } } else -> { - pagedControllerFactory.createRoomSummaryListController() + pagedControllerFactory.createRoomSummaryListController(roomListParams.displayMode) .also { controller -> section.liveList?.observe(viewLifecycleOwner) { list -> controller.setData(list) diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryListController.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryListController.kt index 683263dbbc..2eb8921fd5 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryListController.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryListController.kt @@ -20,14 +20,15 @@ import im.vector.app.features.home.RoomListDisplayMode import org.matrix.android.sdk.api.session.room.model.RoomSummary class RoomSummaryListController( - private val roomSummaryItemFactory: RoomSummaryItemFactory + private val roomSummaryItemFactory: RoomSummaryItemFactory, + private val displayMode: RoomListDisplayMode ) : CollapsableTypedEpoxyController>() { var listener: RoomListListener? = null override fun buildModels(data: List?) { data?.forEach { - add(roomSummaryItemFactory.create(it, emptyMap(), emptySet(), RoomListDisplayMode.ROOMS /* TODO: change */, listener)) + add(roomSummaryItemFactory.create(it, emptyMap(), emptySet(), displayMode, listener)) } } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryPagedControllerFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryPagedControllerFactory.kt index 36f1b5ac90..f72698048d 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryPagedControllerFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryPagedControllerFactory.kt @@ -27,8 +27,8 @@ class RoomSummaryPagedControllerFactory @Inject constructor( return RoomSummaryPagedController(roomSummaryItemFactory, displayMode) } - fun createRoomSummaryListController(): RoomSummaryListController { - return RoomSummaryListController(roomSummaryItemFactory) + fun createRoomSummaryListController(displayMode: RoomListDisplayMode): RoomSummaryListController { + return RoomSummaryListController(roomSummaryItemFactory, displayMode) } fun createSuggestedRoomListController(): SuggestedRoomListController { From f70a24d257f6e28c9c6c3cd5216b52293d1af410 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Fri, 29 Apr 2022 13:18:46 +0200 Subject: [PATCH 13/23] Changes IncomingShareController display mode to FILTERED --- .../im/vector/app/features/share/IncomingShareController.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/java/im/vector/app/features/share/IncomingShareController.kt b/vector/src/main/java/im/vector/app/features/share/IncomingShareController.kt index 6926a54cc4..bf5cedd5da 100644 --- a/vector/src/main/java/im/vector/app/features/share/IncomingShareController.kt +++ b/vector/src/main/java/im/vector/app/features/share/IncomingShareController.kt @@ -57,7 +57,7 @@ class IncomingShareController @Inject constructor(private val roomSummaryItemFac .createRoomItem( roomSummary, data.selectedRoomIds, - RoomListDisplayMode.ROOMS /* TODO: Change */, + RoomListDisplayMode.FILTERED, callback?.let { it::onRoomClicked }, callback?.let { it::onRoomLongClicked } ) From 47493fcfa135ab6464fda974a45d9bd164ee5222 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Mon, 2 May 2022 14:11:17 +0200 Subject: [PATCH 14/23] Replaces method for getting the space parents of rooms --- .../session/room/summary/RoomSummaryDataSource.kt | 13 +++++++++++++ .../session/room/summary/RoomSummaryUpdater.kt | 8 -------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryDataSource.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryDataSource.kt index 18a4f80547..a84f9aa7d6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryDataSource.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryDataSource.kt @@ -37,6 +37,7 @@ 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.model.RoomType +import org.matrix.android.sdk.api.session.room.model.SpaceParentInfo import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams import org.matrix.android.sdk.api.session.room.spaceSummaryQueryParams import org.matrix.android.sdk.api.session.room.summary.RoomAggregateNotificationCount @@ -197,6 +198,18 @@ internal class RoomSummaryDataSource @Inject constructor( } val dataSourceFactory = realmDataSourceFactory.map { roomSummaryMapper.map(it) + }.map { roomSummary -> + val parents = roomSummary.flattenParentIds.mapNotNull { parentId -> + getRoomSummary(parentId)?.let { parentSummary -> + SpaceParentInfo( + parentId = parentSummary.flattenParentIds.firstOrNull(), + roomSummary = parentSummary, + canonical = true, + viaServers = emptyList() + ) + } + } + roomSummary.copy(spaceParents = parents) } val boundaries = MutableLiveData(ResultBoundaries()) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt index 81979c6926..4a9f6c44c9 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt @@ -17,7 +17,6 @@ package org.matrix.android.sdk.internal.session.room.summary import io.realm.Realm -import io.realm.RealmList import io.realm.kotlin.createObject import kotlinx.coroutines.runBlocking import org.matrix.android.sdk.api.extensions.orFalse @@ -362,13 +361,6 @@ internal class RoomSummaryUpdater @Inject constructor( val flattenParentsIds = (flattenSpaceParents[parent.roomId] ?: emptyList()) + listOf(parent.roomId) entry.value.forEach { child -> RoomSummaryEntity.where(realm, child.roomId).findFirst()?.let { childSum -> - // TODO: Revisit - childSum.parents.add(SpaceParentSummaryEntity( - canonical = true, - parentRoomId = parent.roomId, - parentSummaryEntity = parent, - viaServers = RealmList() - )) if (childSum.flattenParentIds == null) childSum.flattenParentIds = "" flattenParentsIds.forEach { if (childSum.flattenParentIds?.contains(it) != true) { From c9b32fec44515b26f4815f41a10dafc738e3c7d6 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Mon, 2 May 2022 14:42:56 +0200 Subject: [PATCH 15/23] Changes ordering of room subtitles used --- .../room/summary/RoomSummaryUpdater.kt | 21 +++++++++++++++---- .../home/room/list/RoomSummaryItemFactory.kt | 4 ++-- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt index 4a9f6c44c9..3af579d050 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt @@ -349,27 +349,39 @@ internal class RoomSummaryUpdater @Inject constructor( } val acyclicGraph = graph.withoutEdges(backEdges) +// Timber.v("## SPACES: acyclicGraph $acyclicGraph") val flattenSpaceParents = acyclicGraph.flattenDestination().map { it.key.name to it.value.map { it.name } }.toMap() +// Timber.v("## SPACES: flattenSpaceParents ${flattenSpaceParents.map { it.key.name to it.value.map { it.name } }.joinToString("\n") { +// it.first + ": [" + it.second.joinToString(",") + "]" +// }}") + +// Timber.v("## SPACES: lookup map ${lookupMap.map { it.key.name to it.value.map { it.name } }.toMap()}") lookupMap.entries .filter { it.key.roomType == RoomType.SPACE && it.key.membership == Membership.JOIN } .forEach { entry -> val parent = RoomSummaryEntity.where(realm, entry.key.roomId).findFirst() if (parent != null) { +// Timber.v("## SPACES: check hierarchy of ${parent.name} id ${parent.roomId}") +// Timber.v("## SPACES: flat known parents of ${parent.name} are ${flattenSpaceParents[parent.roomId]}") val flattenParentsIds = (flattenSpaceParents[parent.roomId] ?: emptyList()) + listOf(parent.roomId) +// Timber.v("## SPACES: flatten known parents of children of ${parent.name} are ${flattenParentsIds}") entry.value.forEach { child -> RoomSummaryEntity.where(realm, child.roomId).findFirst()?.let { childSum -> + +// Timber.w("## SPACES: ${childSum.name} is ${childSum.roomId} fc: ${childSum.flattenParentIds}") +// var allParents = childSum.flattenParentIds ?: "" if (childSum.flattenParentIds == null) childSum.flattenParentIds = "" flattenParentsIds.forEach { if (childSum.flattenParentIds?.contains(it) != true) { - if (childSum.flattenParentIds?.isEmpty() == false) { - childSum.flattenParentIds += "|" - } - childSum.flattenParentIds += it + childSum.flattenParentIds += "|$it" } } +// childSum.flattenParentIds = "$allParents|" + +// Timber.v("## SPACES: flatten of ${childSum.name} is ${childSum.flattenParentIds}") } } } @@ -399,6 +411,7 @@ internal class RoomSummaryUpdater @Inject constructor( // we keep real m.child/m.parent relations and add the one for common memberships dmRoom.flattenParentIds += "|${flattenRelated.joinToString("|")}|" } +// Timber.v("## SPACES: flatten of ${dmRoom.otherMemberIds.joinToString(",")} is ${dmRoom.flattenParentIds}") } // Maybe a good place to count the number of notifications for spaces? diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt index f9f61f730b..05701b908f 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt @@ -153,10 +153,10 @@ class RoomSummaryItemFactory @Inject constructor(private val displayableEventFor } private fun getSearchResultSubtitle(roomSummary: RoomSummary): String { - val spaceName = roomSummary.spaceParents?.firstOrNull()?.roomSummary?.name val userId = roomSummary.directUserId + val spaceName = roomSummary.spaceParents?.firstOrNull()?.roomSummary?.name val canonicalAlias = roomSummary.canonicalAlias - return (spaceName ?: userId ?: canonicalAlias).orEmpty() + return (userId ?: spaceName ?: canonicalAlias).orEmpty() } } From b46794d4df2e863ef1799da1c1ae3e154ce49751 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Mon, 2 May 2022 14:44:23 +0200 Subject: [PATCH 16/23] Adds changelog file --- changelog.d/5860.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/5860.feature diff --git a/changelog.d/5860.feature b/changelog.d/5860.feature new file mode 100644 index 0000000000..6c34fa0905 --- /dev/null +++ b/changelog.d/5860.feature @@ -0,0 +1 @@ +Adds space or user id as a subtitle under rooms in search From 21fe5a23fb5a32ec5204a7be502ffce1c57d822a Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Fri, 13 May 2022 13:07:20 +0200 Subject: [PATCH 17/23] Adds vertical centering of title when no subtitle is present --- .../home/room/list/RoomSummaryItem.kt | 30 ++++++++++++++++--- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt index 4cea812775..0a97518cf1 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt @@ -18,9 +18,10 @@ package im.vector.app.features.home.room.list import android.view.HapticFeedbackConstants import android.view.View -import android.view.ViewGroup import android.widget.ImageView import android.widget.TextView +import androidx.constraintlayout.widget.ConstraintLayout +import androidx.constraintlayout.widget.ConstraintSet import androidx.core.view.isInvisible import androidx.core.view.isVisible import com.airbnb.epoxy.EpoxyAttribute @@ -134,12 +135,33 @@ abstract class RoomSummaryItem : VectorEpoxyModel() { private fun renderForDefaultDisplayMode(holder: Holder) { holder.subtitleView.text = lastFormattedEvent.charSequence holder.lastEventTimeView.text = lastEventTime + holder.typingView.setTextOrHide(typingMessage) + holder.subtitleView.isInvisible = holder.typingView.isVisible } private fun renderForFilteredDisplayMode(holder: Holder) { holder.subtitleView.text = subtitle - holder.typingView.setTextOrHide(typingMessage) - holder.subtitleView.isInvisible = holder.typingView.isVisible + if (subtitle.isEmpty()) { + holder.centerTitleVertically() + } + } + + private fun Holder.centerTitleVertically() { + removeTitleTopMargin() + constrainTitleToParentBottom() + } + + private fun Holder.removeTitleTopMargin() { + val layoutParams = titleView.layoutParams as ConstraintLayout.LayoutParams + layoutParams.topMargin = 0 + titleView.layoutParams = layoutParams + } + + private fun Holder.constrainTitleToParentBottom() { + val constraintSet = ConstraintSet() + constraintSet.clone(rootView) + constraintSet.connect(titleView.id, ConstraintSet.BOTTOM, rootView.id, ConstraintSet.BOTTOM) + constraintSet.applyTo(rootView) } override fun unbind(holder: Holder) { @@ -175,6 +197,6 @@ abstract class RoomSummaryItem : VectorEpoxyModel() { val roomAvatarPublicDecorationImageView by bind(R.id.roomAvatarPublicDecorationImageView) val roomAvatarFailSendingImageView by bind(R.id.roomAvatarFailSendingImageView) val roomAvatarPresenceImageView by bind(R.id.roomAvatarPresenceImageView) - val rootView by bind(R.id.itemRoomLayout) + val rootView by bind(R.id.itemRoomLayout) } } From 50839c206bf14e2783c8953275580f547a990ba2 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Fri, 13 May 2022 20:43:03 +0200 Subject: [PATCH 18/23] Adds flattenParents field to RoomSummary and corresponding mapping --- .../sdk/api/session/room/model/RoomSummary.kt | 1 + .../room/summary/RoomSummaryDataSource.kt | 28 ++++++++++--------- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/RoomSummary.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/RoomSummary.kt index 71c1d8303e..5a265c2b26 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/RoomSummary.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/RoomSummary.kt @@ -62,6 +62,7 @@ data class RoomSummary( val roomType: String? = null, val spaceParents: List? = null, val spaceChildren: List? = null, + val flattenParents: List = emptyList(), val flattenParentIds: List = emptyList(), val roomEncryptionAlgorithm: RoomEncryptionAlgorithm? = null ) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryDataSource.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryDataSource.kt index b165fb3001..752c828710 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryDataSource.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryDataSource.kt @@ -194,19 +194,7 @@ internal class RoomSummaryDataSource @Inject constructor( } val dataSourceFactory = realmDataSourceFactory.map { roomSummaryMapper.map(it) - }.map { roomSummary -> - val parents = roomSummary.flattenParentIds.mapNotNull { parentId -> - getRoomSummary(parentId)?.let { parentSummary -> - SpaceParentInfo( - parentId = parentSummary.flattenParentIds.firstOrNull(), - roomSummary = parentSummary, - canonical = true, - viaServers = emptyList() - ) - } - } - roomSummary.copy(spaceParents = parents) - } + }.map { it.getWithParents()} val boundaries = MutableLiveData(ResultBoundaries()) @@ -245,6 +233,20 @@ internal class RoomSummaryDataSource @Inject constructor( } } + private fun RoomSummary.getWithParents(): RoomSummary { + val parents = flattenParentIds.mapNotNull { parentId -> + getRoomSummary(parentId)?.let { parentSummary -> + SpaceParentInfo( + parentId = parentSummary.flattenParentIds.firstOrNull(), + roomSummary = parentSummary, + canonical = true, + viaServers = emptyList() + ) + } + } + return copy(flattenParents = parents) + } + fun getCountLive(queryParams: RoomSummaryQueryParams): LiveData { val liveRooms = monarchy.findAllManagedWithChanges { roomSummariesQuery(it, queryParams) From 7c1d1c34647e6a860b68adc7913a63a8574159a4 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Mon, 16 May 2022 10:26:28 +0200 Subject: [PATCH 19/23] Adds centering of items with no subtitles --- .../home/room/list/RoomSummaryItem.kt | 25 ++++--------------- vector/src/main/res/layout/item_room.xml | 18 +++++++++++-- 2 files changed, 21 insertions(+), 22 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt index 0a97518cf1..abcfe0d5d8 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt @@ -19,9 +19,9 @@ package im.vector.app.features.home.room.list import android.view.HapticFeedbackConstants import android.view.View import android.widget.ImageView +import android.widget.Space import android.widget.TextView import androidx.constraintlayout.widget.ConstraintLayout -import androidx.constraintlayout.widget.ConstraintSet import androidx.core.view.isInvisible import androidx.core.view.isVisible import com.airbnb.epoxy.EpoxyAttribute @@ -141,27 +141,11 @@ abstract class RoomSummaryItem : VectorEpoxyModel() { private fun renderForFilteredDisplayMode(holder: Holder) { holder.subtitleView.text = subtitle - if (subtitle.isEmpty()) { - holder.centerTitleVertically() - } + holder.centerTitle(shouldCenter = subtitle.isEmpty()) } - private fun Holder.centerTitleVertically() { - removeTitleTopMargin() - constrainTitleToParentBottom() - } - - private fun Holder.removeTitleTopMargin() { - val layoutParams = titleView.layoutParams as ConstraintLayout.LayoutParams - layoutParams.topMargin = 0 - titleView.layoutParams = layoutParams - } - - private fun Holder.constrainTitleToParentBottom() { - val constraintSet = ConstraintSet() - constraintSet.clone(rootView) - constraintSet.connect(titleView.id, ConstraintSet.BOTTOM, rootView.id, ConstraintSet.BOTTOM) - constraintSet.applyTo(rootView) + private fun Holder.centerTitle(shouldCenter: Boolean) { + centerTitleSpace.isVisible = shouldCenter } override fun unbind(holder: Holder) { @@ -198,5 +182,6 @@ abstract class RoomSummaryItem : VectorEpoxyModel() { val roomAvatarFailSendingImageView by bind(R.id.roomAvatarFailSendingImageView) val roomAvatarPresenceImageView by bind(R.id.roomAvatarPresenceImageView) val rootView by bind(R.id.itemRoomLayout) + val centerTitleSpace by bind(R.id.centerTitleSpace) } } diff --git a/vector/src/main/res/layout/item_room.xml b/vector/src/main/res/layout/item_room.xml index ab0af18acb..ac028ccb08 100644 --- a/vector/src/main/res/layout/item_room.xml +++ b/vector/src/main/res/layout/item_room.xml @@ -112,13 +112,27 @@ app:layout_constraintTop_toBottomOf="@id/roomAvatarContainer" tools:layout_marginStart="20dp" /> + + + + Date: Mon, 16 May 2022 10:31:16 +0200 Subject: [PATCH 20/23] Fixes lint error --- .../sdk/internal/session/room/summary/RoomSummaryDataSource.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryDataSource.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryDataSource.kt index 752c828710..f3ad4cbdd3 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryDataSource.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryDataSource.kt @@ -194,7 +194,7 @@ internal class RoomSummaryDataSource @Inject constructor( } val dataSourceFactory = realmDataSourceFactory.map { roomSummaryMapper.map(it) - }.map { it.getWithParents()} + }.map { it.getWithParents() } val boundaries = MutableLiveData(ResultBoundaries()) From 03acf4505acba15f48ae9e8783829aa4087e0c61 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Tue, 17 May 2022 18:03:34 +0200 Subject: [PATCH 21/23] Uses second layout to center room summary item title --- .../home/room/list/RoomSummaryItem.kt | 7 - .../home/room/list/RoomSummaryItemCentered.kt | 134 +++++++++++++++ .../home/room/list/RoomSummaryItemFactory.kt | 91 ++++++++--- vector/src/main/res/layout/item_room.xml | 18 +-- .../main/res/layout/item_room_centered.xml | 152 ++++++++++++++++++ 5 files changed, 355 insertions(+), 47 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemCentered.kt create mode 100644 vector/src/main/res/layout/item_room_centered.xml diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt index abcfe0d5d8..5452b03992 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt @@ -19,7 +19,6 @@ package im.vector.app.features.home.room.list import android.view.HapticFeedbackConstants import android.view.View import android.widget.ImageView -import android.widget.Space import android.widget.TextView import androidx.constraintlayout.widget.ConstraintLayout import androidx.core.view.isInvisible @@ -141,11 +140,6 @@ abstract class RoomSummaryItem : VectorEpoxyModel() { private fun renderForFilteredDisplayMode(holder: Holder) { holder.subtitleView.text = subtitle - holder.centerTitle(shouldCenter = subtitle.isEmpty()) - } - - private fun Holder.centerTitle(shouldCenter: Boolean) { - centerTitleSpace.isVisible = shouldCenter } override fun unbind(holder: Holder) { @@ -182,6 +176,5 @@ abstract class RoomSummaryItem : VectorEpoxyModel() { val roomAvatarFailSendingImageView by bind(R.id.roomAvatarFailSendingImageView) val roomAvatarPresenceImageView by bind(R.id.roomAvatarPresenceImageView) val rootView by bind(R.id.itemRoomLayout) - val centerTitleSpace by bind(R.id.centerTitleSpace) } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemCentered.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemCentered.kt new file mode 100644 index 0000000000..8f2d949178 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemCentered.kt @@ -0,0 +1,134 @@ +/* + * 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.features.home.room.list + +import android.view.HapticFeedbackConstants +import android.view.View +import android.widget.ImageView +import android.widget.TextView +import androidx.constraintlayout.widget.ConstraintLayout +import androidx.core.view.isVisible +import com.airbnb.epoxy.EpoxyAttribute +import com.airbnb.epoxy.EpoxyModelClass +import com.amulyakhare.textdrawable.TextDrawable +import im.vector.app.R +import im.vector.app.core.epoxy.ClickListener +import im.vector.app.core.epoxy.VectorEpoxyHolder +import im.vector.app.core.epoxy.VectorEpoxyModel +import im.vector.app.core.epoxy.onClick +import im.vector.app.core.ui.views.PresenceStateImageView +import im.vector.app.core.ui.views.ShieldImageView +import im.vector.app.features.displayname.getBestName +import im.vector.app.features.home.AvatarRenderer +import im.vector.app.features.home.RoomListDisplayMode +import im.vector.app.features.themes.ThemeUtils +import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel +import org.matrix.android.sdk.api.session.presence.model.UserPresence +import org.matrix.android.sdk.api.util.MatrixItem + +@EpoxyModelClass(layout = R.layout.item_room_centered) +abstract class RoomSummaryItemCentered : VectorEpoxyModel() { + + @EpoxyAttribute + lateinit var avatarRenderer: AvatarRenderer + + @EpoxyAttribute + lateinit var matrixItem: MatrixItem + + @EpoxyAttribute + var displayMode: RoomListDisplayMode = RoomListDisplayMode.PEOPLE + + @EpoxyAttribute + var encryptionTrustLevel: RoomEncryptionTrustLevel? = null + + @EpoxyAttribute + var userPresence: UserPresence? = null + + @EpoxyAttribute + var showPresence: Boolean = false + + @EpoxyAttribute @JvmField + var isPublic: Boolean = false + + @EpoxyAttribute + var unreadNotificationCount: Int = 0 + + @EpoxyAttribute + var hasUnreadMessage: Boolean = false + + @EpoxyAttribute + var hasDraft: Boolean = false + + @EpoxyAttribute + var hasFailedSending: Boolean = false + + @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) + var itemLongClickListener: View.OnLongClickListener? = null + + @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) + var itemClickListener: ClickListener? = null + + @EpoxyAttribute + var showSelected: Boolean = false + + override fun bind(holder: Holder) { + super.bind(holder) + + holder.rootView.onClick(itemClickListener) + holder.rootView.setOnLongClickListener { + it.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS) + itemLongClickListener?.onLongClick(it) ?: false + } + holder.titleView.text = matrixItem.getBestName() + avatarRenderer.render(matrixItem, holder.avatarImageView) + holder.roomAvatarDecorationImageView.render(encryptionTrustLevel) + holder.roomAvatarPublicDecorationImageView.isVisible = isPublic + holder.roomAvatarFailSendingImageView.isVisible = hasFailedSending + renderSelection(holder, showSelected) + holder.roomAvatarPresenceImageView.render(showPresence, userPresence) + } + + override fun unbind(holder: Holder) { + holder.rootView.setOnClickListener(null) + holder.rootView.setOnLongClickListener(null) + avatarRenderer.clear(holder.avatarImageView) + super.unbind(holder) + } + + private fun renderSelection(holder: Holder, isSelected: Boolean) { + if (isSelected) { + holder.avatarCheckedImageView.visibility = View.VISIBLE + val backgroundColor = ThemeUtils.getColor(holder.view.context, R.attr.colorPrimary) + val backgroundDrawable = TextDrawable.builder().buildRound("", backgroundColor) + holder.avatarImageView.setImageDrawable(backgroundDrawable) + } else { + holder.avatarCheckedImageView.visibility = View.GONE + avatarRenderer.render(matrixItem, holder.avatarImageView) + } + } + + class Holder : VectorEpoxyHolder() { + val titleView by bind(R.id.roomNameView) + val avatarCheckedImageView by bind(R.id.roomAvatarCheckedImageView) + val avatarImageView by bind(R.id.roomAvatarImageView) + val roomAvatarDecorationImageView by bind(R.id.roomAvatarDecorationImageView) + val roomAvatarPublicDecorationImageView by bind(R.id.roomAvatarPublicDecorationImageView) + val roomAvatarFailSendingImageView by bind(R.id.roomAvatarFailSendingImageView) + val roomAvatarPresenceImageView by bind(R.id.roomAvatarPresenceImageView) + val rootView by bind(R.id.itemRoomLayout) + } +} diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt index 05701b908f..792303eaf6 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt @@ -126,31 +126,74 @@ class RoomSummaryItemFactory @Inject constructor(private val displayableEventFor } val typingMessage = typingHelper.getTypingMessage(roomSummary.typingUsers) - return RoomSummaryItem_() - .id(roomSummary.roomId) - .avatarRenderer(avatarRenderer) - // We do not display shield in the room list anymore - // .encryptionTrustLevel(roomSummary.roomEncryptionTrustLevel) - .displayMode(displayMode) - .subtitle(subtitle) - .isPublic(roomSummary.isPublic) - .showPresence(roomSummary.isDirect) - .userPresence(roomSummary.directUserPresence) - .matrixItem(roomSummary.toMatrixItem()) - .lastEventTime(latestEventTime) - .typingMessage(typingMessage) - .lastFormattedEvent(latestFormattedEvent.toEpoxyCharSequence()) - .showHighlighted(showHighlighted) - .showSelected(showSelected) - .hasFailedSending(roomSummary.hasFailedSending) - .unreadNotificationCount(unreadCount) - .hasUnreadMessage(roomSummary.hasUnreadMessages) - .hasDraft(roomSummary.userDrafts.isNotEmpty()) - .itemLongClickListener { _ -> - onLongClick?.invoke(roomSummary) ?: false - } - .itemClickListener { onClick?.invoke(roomSummary) } + + return if (subtitle.isBlank() && displayMode == RoomListDisplayMode.FILTERED) { + createCenteredRoomSummaryItem(roomSummary, displayMode, showSelected, unreadCount, onClick, onLongClick) + } else { + createRoomSummaryItem(roomSummary, displayMode, subtitle, latestEventTime, typingMessage, + latestFormattedEvent, showHighlighted, showSelected, unreadCount, onClick, onLongClick) + } } + + private fun createRoomSummaryItem( + roomSummary: RoomSummary, + displayMode: RoomListDisplayMode, + subtitle: String, + latestEventTime: String, + typingMessage: String, + latestFormattedEvent: CharSequence, + showHighlighted: Boolean, + showSelected: Boolean, + unreadCount: Int, + onClick: ((RoomSummary) -> Unit)?, + onLongClick: ((RoomSummary) -> Boolean)? + ) = RoomSummaryItem_() + .id(roomSummary.roomId) + .avatarRenderer(avatarRenderer) + // We do not display shield in the room list anymore + // .encryptionTrustLevel(roomSummary.roomEncryptionTrustLevel) + .displayMode(displayMode) + .subtitle(subtitle) + .isPublic(roomSummary.isPublic) + .showPresence(roomSummary.isDirect) + .userPresence(roomSummary.directUserPresence) + .matrixItem(roomSummary.toMatrixItem()) + .lastEventTime(latestEventTime) + .typingMessage(typingMessage) + .lastFormattedEvent(latestFormattedEvent.toEpoxyCharSequence()) + .showHighlighted(showHighlighted) + .showSelected(showSelected) + .hasFailedSending(roomSummary.hasFailedSending) + .unreadNotificationCount(unreadCount) + .hasUnreadMessage(roomSummary.hasUnreadMessages) + .hasDraft(roomSummary.userDrafts.isNotEmpty()) + .itemLongClickListener { _ -> onLongClick?.invoke(roomSummary) ?: false } + .itemClickListener { onClick?.invoke(roomSummary) } + + private fun createCenteredRoomSummaryItem( + roomSummary: RoomSummary, + displayMode: RoomListDisplayMode, + showSelected: Boolean, + unreadCount: Int, + onClick: ((RoomSummary) -> Unit)?, + onLongClick: ((RoomSummary) -> Boolean)? + ) = RoomSummaryItemCentered_() + .id(roomSummary.roomId) + .avatarRenderer(avatarRenderer) + // We do not display shield in the room list anymore + // .encryptionTrustLevel(roomSummary.roomEncryptionTrustLevel) + .displayMode(displayMode) + .isPublic(roomSummary.isPublic) + .showPresence(roomSummary.isDirect) + .userPresence(roomSummary.directUserPresence) + .matrixItem(roomSummary.toMatrixItem()) + .showSelected(showSelected) + .hasFailedSending(roomSummary.hasFailedSending) + .unreadNotificationCount(unreadCount) + .hasUnreadMessage(roomSummary.hasUnreadMessages) + .hasDraft(roomSummary.userDrafts.isNotEmpty()) + .itemLongClickListener { _ -> onLongClick?.invoke(roomSummary) ?: false } + .itemClickListener { onClick?.invoke(roomSummary) } private fun getSearchResultSubtitle(roomSummary: RoomSummary): String { val userId = roomSummary.directUserId diff --git a/vector/src/main/res/layout/item_room.xml b/vector/src/main/res/layout/item_room.xml index ac028ccb08..ab0af18acb 100644 --- a/vector/src/main/res/layout/item_room.xml +++ b/vector/src/main/res/layout/item_room.xml @@ -112,27 +112,13 @@ app:layout_constraintTop_toBottomOf="@id/roomAvatarContainer" tools:layout_marginStart="20dp" /> - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From d12ab175163fe4f8e58a0c25cc941c042aaf0848 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Wed, 18 May 2022 11:29:23 +0200 Subject: [PATCH 22/23] Fixes lint errors --- .../app/features/home/room/list/RoomSummaryItemFactory.kt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt index 792303eaf6..3f29c1d14c 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt @@ -130,11 +130,13 @@ class RoomSummaryItemFactory @Inject constructor(private val displayableEventFor return if (subtitle.isBlank() && displayMode == RoomListDisplayMode.FILTERED) { createCenteredRoomSummaryItem(roomSummary, displayMode, showSelected, unreadCount, onClick, onLongClick) } else { - createRoomSummaryItem(roomSummary, displayMode, subtitle, latestEventTime, typingMessage, - latestFormattedEvent, showHighlighted, showSelected, unreadCount, onClick, onLongClick) + createRoomSummaryItem( + roomSummary, displayMode, subtitle, latestEventTime, typingMessage, + latestFormattedEvent, showHighlighted, showSelected, unreadCount, onClick, onLongClick + ) } } - + private fun createRoomSummaryItem( roomSummary: RoomSummary, displayMode: RoomListDisplayMode, From a5dc8ec1819b3b5e6c0c83b78414486b3fb34fc3 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Fri, 27 May 2022 15:05:39 +0200 Subject: [PATCH 23/23] Only gets flattenParents if specifically requested --- .../sdk/api/session/room/model/RoomSummary.kt | 2 +- .../internal/session/room/DefaultRoomService.kt | 2 +- .../session/room/summary/RoomSummaryDataSource.kt | 15 ++++----------- .../home/room/list/RoomListSectionBuilderSpace.kt | 4 ++-- 4 files changed, 8 insertions(+), 15 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/RoomSummary.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/RoomSummary.kt index 5a265c2b26..b978feb1e2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/RoomSummary.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/RoomSummary.kt @@ -62,7 +62,7 @@ data class RoomSummary( val roomType: String? = null, val spaceParents: List? = null, val spaceChildren: List? = null, - val flattenParents: List = emptyList(), + val flattenParents: List = emptyList(), val flattenParentIds: List = emptyList(), val roomEncryptionAlgorithm: RoomEncryptionAlgorithm? = null ) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoomService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoomService.kt index 8424ee8a36..29484c4efd 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoomService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoomService.kt @@ -127,7 +127,7 @@ internal class DefaultRoomService @Inject constructor( override fun getFilteredPagedRoomSummariesLive(queryParams: RoomSummaryQueryParams, pagedListConfig: PagedList.Config, sortOrder: RoomSortOrder): UpdatableLivePageResult { - return roomSummaryDataSource.getUpdatablePagedRoomSummariesLive(queryParams, pagedListConfig, sortOrder) + return roomSummaryDataSource.getUpdatablePagedRoomSummariesLive(queryParams, pagedListConfig, sortOrder, getFlattenedParents = true) } override fun getRoomCountLive(queryParams: RoomSummaryQueryParams): LiveData { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryDataSource.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryDataSource.kt index f3ad4cbdd3..cefb4c1bd3 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryDataSource.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryDataSource.kt @@ -36,7 +36,6 @@ 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.model.RoomType -import org.matrix.android.sdk.api.session.room.model.SpaceParentInfo import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams import org.matrix.android.sdk.api.session.room.spaceSummaryQueryParams import org.matrix.android.sdk.api.session.room.summary.RoomAggregateNotificationCount @@ -188,13 +187,14 @@ internal class RoomSummaryDataSource @Inject constructor( fun getUpdatablePagedRoomSummariesLive(queryParams: RoomSummaryQueryParams, pagedListConfig: PagedList.Config, - sortOrder: RoomSortOrder): UpdatableLivePageResult { + sortOrder: RoomSortOrder, + getFlattenedParents: Boolean = false): UpdatableLivePageResult { val realmDataSourceFactory = monarchy.createDataSourceFactory { realm -> roomSummariesQuery(realm, queryParams).process(sortOrder) } val dataSourceFactory = realmDataSourceFactory.map { roomSummaryMapper.map(it) - }.map { it.getWithParents() } + }.map { if (getFlattenedParents) it.getWithParents() else it } val boundaries = MutableLiveData(ResultBoundaries()) @@ -235,14 +235,7 @@ internal class RoomSummaryDataSource @Inject constructor( private fun RoomSummary.getWithParents(): RoomSummary { val parents = flattenParentIds.mapNotNull { parentId -> - getRoomSummary(parentId)?.let { parentSummary -> - SpaceParentInfo( - parentId = parentSummary.flattenParentIds.firstOrNull(), - roomSummary = parentSummary, - canonical = true, - viaServers = emptyList() - ) - } + getRoomSummary(parentId) } return copy(flattenParents = parents) } diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListSectionBuilderSpace.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListSectionBuilderSpace.kt index 59137ec490..c176b1b9a5 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListSectionBuilderSpace.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListSectionBuilderSpace.kt @@ -323,9 +323,9 @@ class RoomListSectionBuilderSpace( { it.memberships = Membership.activeMemberships() }, - { qpm -> + { queryParams -> val name = stringProvider.getString(R.string.bottom_action_rooms) - val updatableFilterLivePageResult = session.roomService().getFilteredPagedRoomSummariesLive(qpm) + val updatableFilterLivePageResult = session.roomService().getFilteredPagedRoomSummariesLive(queryParams) onUpdatable(updatableFilterLivePageResult) val itemCountFlow = updatableFilterLivePageResult.livePagedList.asFlow()