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 3268f6308e..78fa284e0f 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 @@ -50,7 +50,7 @@ data class RoomSummary( val hasUnreadMessages: Boolean = false, val hasUnreadContentMessages: Boolean = false, val hasUnreadOriginalContentMessages: Boolean = false, - val unreadCount: Int? = 0, + val unreadCount: Int? = null, val markedUnread: Boolean = false, val aggregatedUnreadCount: Int = 0, val aggregatedNotificationCount: Int = 0, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt index 13f8efab94..a036c9bd25 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt @@ -49,7 +49,7 @@ internal object RealmSessionStoreMigration : RealmMigration { // SC-specific DB changes on top of Element // 1: added markedUnread field - const val SESSION_STORE_SCHEMA_SC_VERSION = 3L + const val SESSION_STORE_SCHEMA_SC_VERSION = 4L const val SESSION_STORE_SCHEMA_SC_VERSION_OFFSET = (1L shl 12) const val SESSION_STORE_SCHEMA_VERSION = 17L + @@ -83,6 +83,7 @@ internal object RealmSessionStoreMigration : RealmMigration { if (oldScVersion <= 0) migrateToSc1(realm) if (oldScVersion <= 1) migrateToSc2(realm) if (oldScVersion <= 2) migrateToSc3(realm) + if (oldScVersion <= 3) migrateToSc4(realm) } // SC Version 1L added markedUnread @@ -107,6 +108,13 @@ internal object RealmSessionStoreMigration : RealmMigration { ?.addField(RoomSummaryEntityFields.AGGREGATED_NOTIFICATION_COUNT, Int::class.java) } + // SC Version 4L exposes non-reported unread counters to upper layers + private fun migrateToSc4(realm: DynamicRealm) { + Timber.d("Step SC 3 -> 4") + realm.schema.get("RoomSummaryEntity") + ?.setNullable(RoomSummaryEntityFields.UNREAD_COUNT, true) + } + private fun migrateTo1(realm: DynamicRealm) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomSummaryEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomSummaryEntity.kt index b3536ee426..8a7ffea1c9 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomSummaryEntity.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomSummaryEntity.kt @@ -108,16 +108,27 @@ internal open class RoomSummaryEntity( if (value != field) field = value } - var unreadCount: Int = 0 + var unreadCount: Int? = null set(value) { if (value != field) field = value } + /* -> safeUnreadCount get() { if (field == 0 && hasUnreadOriginalContentMessages) { return 1 } return field } + */ + + fun safeUnreadCount(): Int { + val safeUnreadCount = unreadCount + return if (safeUnreadCount == null || safeUnreadCount <= 0) { + if (hasUnreadOriginalContentMessages) 1 else 0 + } else { + safeUnreadCount + } + } var aggregatedUnreadCount: Int = 0 set(value) { 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 1bfc9cc384..98c83acb0f 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 @@ -99,9 +99,9 @@ internal class RoomSummaryUpdater @Inject constructor( } roomSummaryEntity.highlightCount = unreadNotifications?.highlightCount ?: 0 roomSummaryEntity.notificationCount = unreadNotifications?.notificationCount ?: 0 - roomSummaryEntity.unreadCount = unreadCount ?: 0 + roomSummaryEntity.unreadCount = unreadCount roomSummaryEntity.aggregatedNotificationCount = roomSummaryEntity.notificationCount - roomSummaryEntity.aggregatedUnreadCount = roomSummaryEntity.unreadCount + roomSummaryEntity.aggregatedUnreadCount = roomSummaryEntity.safeUnreadCount() if (membership != null) { roomSummaryEntity.membership = membership @@ -399,9 +399,9 @@ internal class RoomSummaryUpdater @Inject constructor( .findAll().forEach { highlightCount += it.highlightCount notificationCount += it.notificationCount - unreadCount += it.unreadCount + unreadCount += it.safeUnreadCount() aggregateNotificationCount += min(it.notificationCount, 1) - aggregateUnreadCount += min(it.unreadCount, 1) + aggregateUnreadCount += min(it.safeUnreadCount(), 1) markedUnreadCount += if (it.markedUnread) 1 else 0 } 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 c986c83913..b8337692d7 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 @@ -57,7 +57,7 @@ abstract class RoomSummaryItem : VectorEpoxyModel() { @EpoxyAttribute var unreadNotificationCount: Int = 0 @EpoxyAttribute var hasUnreadMessage: Boolean = false @EpoxyAttribute var markedUnread: Boolean = false - @EpoxyAttribute var unreadCount: Int = 0 + @EpoxyAttribute var unreadCount: Int? = null @EpoxyAttribute var hasDraft: Boolean = false @EpoxyAttribute var showHighlighted: Boolean = false @EpoxyAttribute var hasFailedSending: Boolean = false @@ -75,7 +75,7 @@ abstract class RoomSummaryItem : VectorEpoxyModel() { holder.titleView.text = matrixItem.getBestName() holder.lastEventTimeView.text = lastEventTime holder.lastEventView.text = lastFormattedEvent - holder.unreadCounterBadgeView.render(UnreadCounterBadgeView.State(unreadNotificationCount, showHighlighted, unreadCount, markedUnread)) + holder.unreadCounterBadgeView.render(UnreadCounterBadgeView.State(unreadNotificationCount, showHighlighted, unreadCount ?: 0, markedUnread)) holder.unreadIndentIndicator.isVisible = hasUnreadMessage holder.draftView.isVisible = hasDraft avatarRenderer.render(matrixItem, holder.avatarImageView) 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 7bd954fba4..c6851f945e 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 @@ -137,7 +137,7 @@ class RoomSummaryItemFactory @Inject constructor(private val displayableEventFor .unreadNotificationCount(unreadCount) .hasUnreadMessage(roomSummary.scIsUnread(scSdkPreferences)) .markedUnread(roomSummary.markedUnread) - .unreadCount(roomSummary.unreadCount ?: 0) + .unreadCount(roomSummary.unreadCount) .hasDraft(roomSummary.userDrafts.isNotEmpty()) .itemLongClickListener { _ -> onLongClick?.invoke(roomSummary) ?: false