From b4a13f95049ccf2d252da0b81f8b3ebf43c8c68d Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 19 Sep 2019 12:42:01 +0200 Subject: [PATCH] Add unread indent on room list --- CHANGES.md | 2 +- .../api/session/room/model/RoomSummary.kt | 3 +- .../database/mapper/RoomSummaryMapper.kt | 18 ++++---- .../database/model/RoomSummaryEntity.kt | 3 +- .../internal/database/query/ReadQueries.kt | 42 +++++++++++++++++++ .../session/room/RoomSummaryUpdater.kt | 17 +++++--- .../session/room/read/DefaultReadService.kt | 19 +-------- .../session/room/read/SetReadMarkersTask.kt | 1 + .../internal/session/sync/RoomSyncHandler.kt | 4 +- .../home/room/detail/RoomDetailViewModel.kt | 2 +- .../room/list/ChronologicalRoomComparator.kt | 8 ++-- .../home/room/list/RoomCategoryItem.kt | 4 +- .../home/room/list/RoomSummaryController.kt | 2 +- .../home/room/list/RoomSummaryItem.kt | 9 +++- .../home/room/list/RoomSummaryItemFactory.kt | 13 +++--- vector/src/main/res/layout/item_room.xml | 12 +++++- 16 files changed, 107 insertions(+), 52 deletions(-) create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/ReadQueries.kt diff --git a/CHANGES.md b/CHANGES.md index cd6db863c5..a5f2a24e12 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,7 +5,7 @@ Features: - Improvements: - - + - Add unread indent on room list (#485) Other changes: - diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/RoomSummary.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/RoomSummary.kt index aae72dd41f..e4bf1bd32b 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/RoomSummary.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/RoomSummary.kt @@ -29,10 +29,11 @@ data class RoomSummary( val topic: String = "", val avatarUrl: String = "", val isDirect: Boolean = false, - val latestEvent: TimelineEvent? = null, + val latestPreviewableEvent: TimelineEvent? = null, val otherMemberIds: List = emptyList(), val notificationCount: Int = 0, val highlightCount: Int = 0, + val hasUnreadMessages: Boolean = false, val tags: List = emptyList(), val membership: Membership = Membership.NONE, val versioningState: VersioningState = VersioningState.NONE diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/RoomSummaryMapper.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/RoomSummaryMapper.kt index 3ec51226af..654b5f8595 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/RoomSummaryMapper.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/RoomSummaryMapper.kt @@ -35,7 +35,7 @@ internal class RoomSummaryMapper @Inject constructor( RoomTag(it.tagName, it.tagOrder) } - val latestEvent = roomSummaryEntity.latestEvent?.let { + val latestEvent = roomSummaryEntity.latestPreviewableEvent?.let { timelineEventMapper.map(it) } if (latestEvent?.root?.isEncrypted() == true && latestEvent.root.mxDecryptionResult == null) { @@ -43,26 +43,28 @@ internal class RoomSummaryMapper @Inject constructor( //for now decrypt sync try { val result = cryptoService.decryptEvent(latestEvent.root, latestEvent.root.roomId + UUID.randomUUID().toString()) - latestEvent.root.mxDecryptionResult = OlmDecryptionResult( - payload = result.clearEvent, - senderKey = result.senderCurve25519Key, - keysClaimed = result.claimedEd25519Key?.let { mapOf("ed25519" to it) }, - forwardingCurve25519KeyChain = result.forwardingCurve25519KeyChain - ) + latestEvent.root.mxDecryptionResult = OlmDecryptionResult( + payload = result.clearEvent, + senderKey = result.senderCurve25519Key, + keysClaimed = result.claimedEd25519Key?.let { mapOf("ed25519" to it) }, + forwardingCurve25519KeyChain = result.forwardingCurve25519KeyChain + ) } catch (e: MXCryptoError) { } } + return RoomSummary( roomId = roomSummaryEntity.roomId, displayName = roomSummaryEntity.displayName ?: "", topic = roomSummaryEntity.topic ?: "", avatarUrl = roomSummaryEntity.avatarUrl ?: "", isDirect = roomSummaryEntity.isDirect, - latestEvent = latestEvent, + latestPreviewableEvent = latestEvent, otherMemberIds = roomSummaryEntity.otherMemberIds.toList(), highlightCount = roomSummaryEntity.highlightCount, notificationCount = roomSummaryEntity.notificationCount, + hasUnreadMessages = roomSummaryEntity.hasUnreadMessages, tags = tags, membership = roomSummaryEntity.membership, versioningState = roomSummaryEntity.versioningState diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/model/RoomSummaryEntity.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/model/RoomSummaryEntity.kt index 6fe81f4cdd..95308d367e 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/model/RoomSummaryEntity.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/model/RoomSummaryEntity.kt @@ -26,7 +26,7 @@ internal open class RoomSummaryEntity(@PrimaryKey var roomId: String = "", var displayName: String? = "", var avatarUrl: String? = "", var topic: String? = "", - var latestEvent: TimelineEventEntity? = null, + var latestPreviewableEvent: TimelineEventEntity? = null, var heroes: RealmList = RealmList(), var joinedMembersCount: Int? = 0, var invitedMembersCount: Int? = 0, @@ -35,6 +35,7 @@ internal open class RoomSummaryEntity(@PrimaryKey var roomId: String = "", var otherMemberIds: RealmList = RealmList(), var notificationCount: Int = 0, var highlightCount: Int = 0, + var hasUnreadMessages: Boolean = false, var tags: RealmList = RealmList() ) : RealmObject() { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/ReadQueries.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/ReadQueries.kt new file mode 100644 index 0000000000..82ab72db26 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/ReadQueries.kt @@ -0,0 +1,42 @@ +/* + * 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.matrix.android.internal.database.query + +import com.zhuinden.monarchy.Monarchy +import im.vector.matrix.android.internal.database.model.ChunkEntity +import im.vector.matrix.android.internal.database.model.ReadReceiptEntity + +internal fun isEventRead(monarchy: Monarchy, + userId: String?, + roomId: String?, + eventId: String?): Boolean { + if (userId.isNullOrBlank() || roomId.isNullOrBlank() || eventId.isNullOrBlank()) { + return false + } + + var isEventRead = false + + monarchy.doWithRealm { realm -> + val readReceipt = ReadReceiptEntity.where(realm, roomId, userId).findFirst() ?: return@doWithRealm + val liveChunk = ChunkEntity.findLastLiveChunkFromRoom(realm, roomId) ?: return@doWithRealm + val readReceiptIndex = liveChunk.timelineEvents.find(readReceipt.eventId)?.root?.displayIndex ?: Int.MIN_VALUE + val eventToCheckIndex = liveChunk.timelineEvents.find(eventId)?.root?.displayIndex ?: Int.MAX_VALUE + + isEventRead = eventToCheckIndex <= readReceiptIndex + } + + return isEventRead +} \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomSummaryUpdater.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomSummaryUpdater.kt index dda8b9322f..a8814771cf 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomSummaryUpdater.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomSummaryUpdater.kt @@ -16,6 +16,7 @@ package im.vector.matrix.android.internal.session.room +import com.zhuinden.monarchy.Monarchy import im.vector.matrix.android.api.auth.data.Credentials import im.vector.matrix.android.api.session.events.model.EventType import im.vector.matrix.android.api.session.events.model.toModel @@ -26,6 +27,7 @@ import im.vector.matrix.android.internal.database.model.EventEntity import im.vector.matrix.android.internal.database.model.EventEntityFields import im.vector.matrix.android.internal.database.model.RoomSummaryEntity import im.vector.matrix.android.internal.database.model.TimelineEventEntity +import im.vector.matrix.android.internal.database.query.isEventRead import im.vector.matrix.android.internal.database.query.latestEvent import im.vector.matrix.android.internal.database.query.prev import im.vector.matrix.android.internal.database.query.where @@ -39,7 +41,8 @@ import javax.inject.Inject internal class RoomSummaryUpdater @Inject constructor(private val credentials: Credentials, private val roomDisplayNameResolver: RoomDisplayNameResolver, - private val roomAvatarResolver: RoomAvatarResolver) { + private val roomAvatarResolver: RoomAvatarResolver, + private val monarchy: Monarchy) { // TODO: maybe allow user of SDK to give that list private val PREVIEWABLE_TYPES = listOf( @@ -63,8 +66,7 @@ internal class RoomSummaryUpdater @Inject constructor(private val credentials: C membership: Membership? = null, roomSummary: RoomSyncSummary? = null, unreadNotifications: RoomSyncUnreadNotifications? = null) { - val roomSummaryEntity = RoomSummaryEntity.where(realm, roomId).findFirst() - ?: realm.createObject(roomId) + val roomSummaryEntity = RoomSummaryEntity.where(realm, roomId).findFirst() ?: realm.createObject(roomId) if (roomSummary != null) { if (roomSummary.heroes.isNotEmpty()) { @@ -85,9 +87,13 @@ internal class RoomSummaryUpdater @Inject constructor(private val credentials: C roomSummaryEntity.membership = membership } - val latestEvent = TimelineEventEntity.latestEvent(realm, roomId, includesSending = true, includedTypes = PREVIEWABLE_TYPES) + val latestPreviewableEvent = TimelineEventEntity.latestEvent(realm, roomId, includesSending = true, includedTypes = PREVIEWABLE_TYPES) val lastTopicEvent = EventEntity.where(realm, roomId, EventType.STATE_ROOM_TOPIC).prev()?.asDomain() + roomSummaryEntity.hasUnreadMessages = roomSummaryEntity.notificationCount > 0 + //avoid this call if we are sure there are unread events + || !isEventRead(monarchy, credentials.userId, roomId, latestPreviewableEvent?.eventId) + val otherRoomMembers = RoomMembers(realm, roomId) .queryRoomMembersEvent() .notEqualTo(EventEntityFields.STATE_KEY, credentials.userId) @@ -98,9 +104,8 @@ internal class RoomSummaryUpdater @Inject constructor(private val credentials: C roomSummaryEntity.displayName = roomDisplayNameResolver.resolve(roomId).toString() roomSummaryEntity.avatarUrl = roomAvatarResolver.resolve(roomId) roomSummaryEntity.topic = lastTopicEvent?.content.toModel()?.topic - roomSummaryEntity.latestEvent = latestEvent + roomSummaryEntity.latestPreviewableEvent = latestPreviewableEvent roomSummaryEntity.otherMemberIds.clear() roomSummaryEntity.otherMemberIds.addAll(otherRoomMembers) - } } \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/read/DefaultReadService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/read/DefaultReadService.kt index 505b958911..11dfee5f81 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/read/DefaultReadService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/read/DefaultReadService.kt @@ -27,11 +27,8 @@ import im.vector.matrix.android.api.session.room.model.ReadReceipt import im.vector.matrix.android.api.session.room.read.ReadService import im.vector.matrix.android.internal.database.RealmLiveData import im.vector.matrix.android.internal.database.mapper.ReadReceiptsSummaryMapper -import im.vector.matrix.android.internal.database.model.ChunkEntity -import im.vector.matrix.android.internal.database.model.ReadReceiptEntity import im.vector.matrix.android.internal.database.model.ReadReceiptsSummaryEntity -import im.vector.matrix.android.internal.database.query.find -import im.vector.matrix.android.internal.database.query.findLastLiveChunkFromRoom +import im.vector.matrix.android.internal.database.query.isEventRead import im.vector.matrix.android.internal.database.query.where import im.vector.matrix.android.internal.task.TaskExecutor import im.vector.matrix.android.internal.task.configureWith @@ -78,19 +75,7 @@ internal class DefaultReadService @AssistedInject constructor(@Assisted private override fun isEventRead(eventId: String): Boolean { - var isEventRead = false - monarchy.doWithRealm { - val readReceipt = ReadReceiptEntity.where(it, roomId, credentials.userId).findFirst() - ?: return@doWithRealm - val liveChunk = ChunkEntity.findLastLiveChunkFromRoom(it, roomId) - ?: return@doWithRealm - val readReceiptIndex = liveChunk.timelineEvents.find(readReceipt.eventId)?.root?.displayIndex - ?: Int.MIN_VALUE - val eventToCheckIndex = liveChunk.timelineEvents.find(eventId)?.root?.displayIndex - ?: Int.MAX_VALUE - isEventRead = eventToCheckIndex <= readReceiptIndex - } - return isEventRead + return isEventRead(monarchy, credentials.userId, roomId, eventId) } override fun getEventReadReceiptsLive(eventId: String): LiveData> { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/read/SetReadMarkersTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/read/SetReadMarkersTask.kt index 41c9cca507..4fa365bb66 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/read/SetReadMarkersTask.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/read/SetReadMarkersTask.kt @@ -101,6 +101,7 @@ internal class DefaultSetReadMarkersTask @Inject constructor(private val roomAPI ?: return@writeAsync roomSummary.notificationCount = 0 roomSummary.highlightCount = 0 + roomSummary.hasUnreadMessages = false } } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/RoomSyncHandler.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/RoomSyncHandler.kt index fccaa9b9b2..8586e6fa0b 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/RoomSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/RoomSyncHandler.kt @@ -113,12 +113,12 @@ internal class RoomSyncHandler @Inject constructor(private val monarchy: Monarch private fun handleJoinedRoom(realm: Realm, roomId: String, roomSync: RoomSync, - isInitalSync: Boolean): RoomEntity { + isInitialSync: Boolean): RoomEntity { Timber.v("Handle join sync for room $roomId") if (roomSync.ephemeral != null && roomSync.ephemeral.events.isNotEmpty()) { - handleEphemeral(realm, roomId, roomSync.ephemeral, isInitalSync) + handleEphemeral(realm, roomId, roomSync.ephemeral, isInitialSync) } if (roomSync.accountData != null && roomSync.accountData.events.isNullOrEmpty().not()) { diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt index 1cd8cc4a41..8ec133c642 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt @@ -658,7 +658,7 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro private fun observeSummaryState() { asyncSubscribe(RoomDetailViewState::asyncRoomSummary) { summary -> if (summary.membership == Membership.INVITE) { - summary.latestEvent?.root?.senderId?.let { senderId -> + summary.latestPreviewableEvent?.root?.senderId?.let { senderId -> session.getUser(senderId) }?.also { setState { copy(asyncInviter = Success(it)) } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/ChronologicalRoomComparator.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/ChronologicalRoomComparator.kt index c4a1633bed..d25198f56a 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/ChronologicalRoomComparator.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/ChronologicalRoomComparator.kt @@ -25,14 +25,14 @@ class ChronologicalRoomComparator @Inject constructor() : Comparator() { @EpoxyAttribute lateinit var title: CharSequence @EpoxyAttribute var expanded: Boolean = false - @EpoxyAttribute var unreadCount: Int = 0 + @EpoxyAttribute var unreadNotificationCount: Int = 0 @EpoxyAttribute var showHighlighted: Boolean = false @EpoxyAttribute var listener: (() -> Unit)? = null @@ -42,7 +42,7 @@ abstract class RoomCategoryItem : VectorEpoxyModel() { val expandedArrowDrawable = ContextCompat.getDrawable(holder.rootView.context, expandedArrowDrawableRes)?.also { DrawableCompat.setTint(it, tintColor) } - holder.unreadCounterBadgeView.render(UnreadCounterBadgeView.State(unreadCount, showHighlighted)) + holder.unreadCounterBadgeView.render(UnreadCounterBadgeView.State(unreadNotificationCount, showHighlighted)) holder.titleView.setCompoundDrawablesWithIntrinsicBounds(expandedArrowDrawable, null, null, null) holder.titleView.text = title holder.rootView.setOnClickListener { listener?.invoke() } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryController.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryController.kt index 03bedbc7b5..42e3a3db85 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryController.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryController.kt @@ -101,7 +101,7 @@ class RoomSummaryController @Inject constructor(private val stringProvider: Stri id(titleRes) title(stringProvider.getString(titleRes).toUpperCase()) expanded(isExpanded) - unreadCount(unreadCount) + unreadNotificationCount(unreadCount) showHighlighted(showHighlighted) listener { mutateExpandedState() diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryItem.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryItem.kt index 72f5b973fb..2ee1f30645 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryItem.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryItem.kt @@ -16,9 +16,11 @@ package im.vector.riotx.features.home.room.list +import android.view.View import android.view.ViewGroup import android.widget.ImageView import android.widget.TextView +import androidx.core.view.isVisible import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyModelClass import im.vector.riotx.R @@ -36,7 +38,8 @@ abstract class RoomSummaryItem : VectorEpoxyModel() { @EpoxyAttribute lateinit var lastFormattedEvent: CharSequence @EpoxyAttribute lateinit var lastEventTime: CharSequence @EpoxyAttribute var avatarUrl: String? = null - @EpoxyAttribute var unreadCount: Int = 0 + @EpoxyAttribute var unreadNotificationCount: Int = 0 + @EpoxyAttribute var hasUnreadMessage: Boolean = false @EpoxyAttribute var showHighlighted: Boolean = false @EpoxyAttribute var listener: (() -> Unit)? = null @@ -47,13 +50,15 @@ abstract class RoomSummaryItem : VectorEpoxyModel() { holder.titleView.text = roomName holder.lastEventTimeView.text = lastEventTime holder.lastEventView.text = lastFormattedEvent - holder.unreadCounterBadgeView.render(UnreadCounterBadgeView.State(unreadCount, showHighlighted)) + holder.unreadCounterBadgeView.render(UnreadCounterBadgeView.State(unreadNotificationCount, showHighlighted)) + holder.unreadIndentIndicator.isVisible = hasUnreadMessage avatarRenderer.render(avatarUrl, roomId, roomName.toString(), holder.avatarImageView) } class Holder : VectorEpoxyHolder() { 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 lastEventTimeView by bind(R.id.roomLastEventTimeView) val avatarImageView by bind(R.id.roomAvatarImageView) diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryItemFactory.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryItemFactory.kt index 38f15974f3..e1d5f2a14e 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryItemFactory.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryItemFactory.kt @@ -16,6 +16,7 @@ package im.vector.riotx.features.home.room.list +import im.vector.matrix.android.api.session.Session import im.vector.matrix.android.api.session.events.model.EventType import im.vector.matrix.android.api.session.events.model.toModel import im.vector.matrix.android.api.session.room.model.Membership @@ -38,7 +39,8 @@ class RoomSummaryItemFactory @Inject constructor(private val noticeEventFormatte private val dateFormatter: VectorDateFormatter, private val colorProvider: ColorProvider, private val stringProvider: StringProvider, - private val avatarRenderer: AvatarRenderer) { + private val avatarRenderer: AvatarRenderer, + private val session: Session) { fun create(roomSummary: RoomSummary, joiningRoomsIds: Set, @@ -59,9 +61,9 @@ class RoomSummaryItemFactory @Inject constructor(private val noticeEventFormatte rejectingErrorRoomsIds: Set, listener: RoomSummaryController.Listener?): VectorEpoxyModel<*> { val secondLine = if (roomSummary.isDirect) { - roomSummary.latestEvent?.root?.senderId + roomSummary.latestPreviewableEvent?.root?.senderId } else { - roomSummary.latestEvent?.root?.senderId?.let { + roomSummary.latestPreviewableEvent?.root?.senderId?.let { stringProvider.getString(R.string.invited_by, it) } } @@ -88,7 +90,7 @@ class RoomSummaryItemFactory @Inject constructor(private val noticeEventFormatte var latestFormattedEvent: CharSequence = "" var latestEventTime: CharSequence = "" - val latestEvent = roomSummary.latestEvent + val latestEvent = roomSummary.latestPreviewableEvent if (latestEvent != null) { val date = latestEvent.root.localDateTime() val currentDate = DateProvider.currentLocalDateTime() @@ -131,7 +133,8 @@ class RoomSummaryItemFactory @Inject constructor(private val noticeEventFormatte .roomName(roomSummary.displayName) .avatarUrl(roomSummary.avatarUrl) .showHighlighted(showHighlighted) - .unreadCount(unreadCount) + .unreadNotificationCount(unreadCount) + .hasUnreadMessage(roomSummary.hasUnreadMessages) .listener { listener?.onRoomSelected(roomSummary) } } diff --git a/vector/src/main/res/layout/item_room.xml b/vector/src/main/res/layout/item_room.xml index b110e20082..7eb2083ecb 100644 --- a/vector/src/main/res/layout/item_room.xml +++ b/vector/src/main/res/layout/item_room.xml @@ -10,12 +10,22 @@ android:focusable="true" android:foreground="?attr/selectableItemBackground"> + +