Setting to count unread rooms instead of messages in aggregates

Change-Id: I557741771ba8b83cc2ce7bb6c90501ebc14a7736
This commit is contained in:
SpiritCroc 2021-09-22 18:03:18 +02:00
parent d1273985b8
commit 8d267649eb
12 changed files with 107 additions and 23 deletions

View file

@ -52,6 +52,8 @@ data class RoomSummary(
val hasUnreadOriginalContentMessages: Boolean = false,
val unreadCount: Int? = 0,
val markedUnread: Boolean = false,
val aggregatedUnreadCount: Int = 0,
val aggregatedNotificationCount: Int = 0,
val tags: List<RoomTag> = emptyList(),
val membership: Membership = Membership.NONE,
val versioningState: VersioningState = VersioningState.NONE,
@ -156,6 +158,7 @@ data class RoomSummary(
// SC addition
interface RoomSummaryPreferenceProvider {
fun getUnreadKind(isDirect: Boolean): Int
fun aggregateUnreadRoomCounts(): Boolean
fun getUnreadRoomSummaryField(isDirect: Boolean): String {
return when(getUnreadKind(isDirect)) {
UNREAD_KIND_ORIGINAL_CONTENT -> RoomSummaryEntityFields.HAS_UNREAD_ORIGINAL_CONTENT_MESSAGES

View file

@ -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 = 2L
const val SESSION_STORE_SCHEMA_SC_VERSION = 3L
const val SESSION_STORE_SCHEMA_SC_VERSION_OFFSET = (1L shl 12)
const val SESSION_STORE_SCHEMA_VERSION = 17L +
@ -82,6 +82,7 @@ internal object RealmSessionStoreMigration : RealmMigration {
if (oldScVersion <= 0) migrateToSc1(realm)
if (oldScVersion <= 1) migrateToSc2(realm)
if (oldScVersion <= 2) migrateToSc3(realm)
}
// SC Version 1L added markedUnread
@ -98,6 +99,14 @@ internal object RealmSessionStoreMigration : RealmMigration {
?.addField(RoomSummaryEntityFields.UNREAD_COUNT, Int::class.java)
}
// SC Version 3L added aggregated counts
private fun migrateToSc3(realm: DynamicRealm) {
Timber.d("Step SC 2 -> 3")
realm.schema.get("RoomSummaryEntity")
?.addField(RoomSummaryEntityFields.AGGREGATED_UNREAD_COUNT, Int::class.java)
?.addField(RoomSummaryEntityFields.AGGREGATED_NOTIFICATION_COUNT, Int::class.java)
}
private fun migrateTo1(realm: DynamicRealm) {

View file

@ -63,6 +63,8 @@ internal class RoomSummaryMapper @Inject constructor(private val timelineEventMa
highlightCount = roomSummaryEntity.highlightCount,
notificationCount = roomSummaryEntity.notificationCount,
unreadCount = roomSummaryEntity.unreadCount,
aggregatedUnreadCount = roomSummaryEntity.aggregatedUnreadCount,
aggregatedNotificationCount = roomSummaryEntity.aggregatedNotificationCount,
hasUnreadMessages = roomSummaryEntity.hasUnreadMessages,
hasUnreadContentMessages = roomSummaryEntity.hasUnreadContentMessages,
hasUnreadOriginalContentMessages = roomSummaryEntity.hasUnreadOriginalContentMessages,

View file

@ -119,6 +119,16 @@ internal open class RoomSummaryEntity(
return field
}
var aggregatedUnreadCount: Int = 0
set(value) {
if (value != field) field = value
}
var aggregatedNotificationCount: Int = 0
set(value) {
if (value != field) field = value
}
var readMarkerId: String? = null
set(value) {
if (value != field) field = value

View file

@ -229,21 +229,40 @@ internal class RoomSummaryDataSource @Inject constructor(@SessionDatabase privat
var notificationCount: RoomAggregateNotificationCount? = null
monarchy.doWithRealm { realm ->
val roomSummariesQuery = roomSummariesQuery(realm, queryParams)
val notifCount = roomSummariesQuery.sum(RoomSummaryEntityFields.NOTIFICATION_COUNT).toInt()
val highlightCount = roomSummariesQuery.sum(RoomSummaryEntityFields.HIGHLIGHT_COUNT).toInt()
val unreadCount = max(
// Preferred since MSC 2654
roomSummariesQuery.sum(RoomSummaryEntityFields.UNREAD_COUNT).toInt(),
// TODO-SC-merge: properly use dm/non-dm flag? (note that this will be likely overwritten either way by above field from MSC 2654)
roomSummariesQuery(realm, queryParams).equalTo(preferenceProvider.getUnreadRoomSummaryField(false), true).count().toInt()
)
val markedUnreadCount = roomSummariesQuery(realm, queryParams).equalTo(RoomSummaryEntityFields.MARKED_UNREAD, true).count().toInt()
notificationCount = RoomAggregateNotificationCount(
notifCount,
highlightCount,
unreadCount,
markedUnreadCount
)
notificationCount = if (preferenceProvider.aggregateUnreadRoomCounts()) {
// Count chats
val notifCount = roomSummariesQuery.greaterThan(RoomSummaryEntityFields.NOTIFICATION_COUNT, 0).count().toInt()
val highlightCount = roomSummariesQuery.greaterThan(RoomSummaryEntityFields.HIGHLIGHT_COUNT, 0).count().toInt()
val unreadCount = max(
// Preferred since MSC 2654
roomSummariesQuery.greaterThan(RoomSummaryEntityFields.UNREAD_COUNT, 0).count().toInt(),
// TODO-SC-merge: properly use dm/non-dm flag? (note that this will be likely overwritten either way by above field from MSC 2654)
roomSummariesQuery(realm, queryParams).equalTo(preferenceProvider.getUnreadRoomSummaryField(false), true).count().toInt()
)
RoomAggregateNotificationCount(
notifCount,
highlightCount,
unreadCount,
markedUnreadCount
)
} else {
// Sum unread counts
val notifCount = roomSummariesQuery.sum(RoomSummaryEntityFields.NOTIFICATION_COUNT).toInt()
val highlightCount = roomSummariesQuery.sum(RoomSummaryEntityFields.HIGHLIGHT_COUNT).toInt()
val unreadCount = max(
// Preferred since MSC 2654
roomSummariesQuery.sum(RoomSummaryEntityFields.UNREAD_COUNT).toInt(),
// TODO-SC-merge: properly use dm/non-dm flag? (note that this will be likely overwritten either way by above field from MSC 2654)
roomSummariesQuery(realm, queryParams).equalTo(preferenceProvider.getUnreadRoomSummaryField(false), true).count().toInt()
)
RoomAggregateNotificationCount(
notifCount,
highlightCount,
unreadCount,
markedUnreadCount
)
}
}
return notificationCount!!
}

View file

@ -65,6 +65,7 @@ import org.matrix.android.sdk.internal.session.sync.model.RoomSyncSummary
import org.matrix.android.sdk.internal.session.sync.model.RoomSyncUnreadNotifications
import timber.log.Timber
import javax.inject.Inject
import kotlin.math.min
import kotlin.system.measureTimeMillis
internal class RoomSummaryUpdater @Inject constructor(
@ -99,6 +100,8 @@ internal class RoomSummaryUpdater @Inject constructor(
roomSummaryEntity.highlightCount = unreadNotifications?.highlightCount ?: 0
roomSummaryEntity.notificationCount = unreadNotifications?.notificationCount ?: 0
roomSummaryEntity.unreadCount = unreadCount ?: 0
roomSummaryEntity.aggregatedNotificationCount = roomSummaryEntity.notificationCount
roomSummaryEntity.aggregatedUnreadCount = roomSummaryEntity.unreadCount
if (membership != null) {
roomSummaryEntity.membership = membership
@ -385,6 +388,8 @@ internal class RoomSummaryUpdater @Inject constructor(
var notificationCount = 0
var unreadCount = 0
var markedUnreadCount = 0
var aggregateUnreadCount = 0
var aggregateNotificationCount = 0
realm.where(RoomSummaryEntity::class.java)
.process(RoomSummaryEntityFields.MEMBERSHIP_STR, listOf(Membership.JOIN))
.notEqualTo(RoomSummaryEntityFields.ROOM_TYPE, RoomType.SPACE)
@ -395,12 +400,16 @@ internal class RoomSummaryUpdater @Inject constructor(
highlightCount += it.highlightCount
notificationCount += it.notificationCount
unreadCount += it.unreadCount
aggregateNotificationCount += min(it.highlightCount, 1)
aggregateUnreadCount += min(it.unreadCount, 1)
markedUnreadCount += if (it.markedUnread) 1 else 0
}
space.highlightCount = highlightCount
space.notificationCount = notificationCount + markedUnreadCount
space.unreadCount = unreadCount
space.aggregatedUnreadCount = aggregateUnreadCount
space.aggregatedNotificationCount = aggregateNotificationCount
}
// xxx invites??

View file

@ -86,6 +86,7 @@ class HomeDetailFragment @Inject constructor(
// When this changes, restart the activity for changes to apply
private val shouldShowUnimportantCounterBadge = vectorPreferences.shouldShowUnimportantCounterBadge()
private val useAggregateCounts = vectorPreferences.useAggregateCounts()
private var hasUnreadRooms = false
set(value) {
@ -206,7 +207,8 @@ class HomeDetailFragment @Inject constructor(
override fun onResume() {
super.onResume()
if (vectorPreferences.shouldShowUnimportantCounterBadge() != shouldShowUnimportantCounterBadge) {
if (vectorPreferences.shouldShowUnimportantCounterBadge() != shouldShowUnimportantCounterBadge ||
vectorPreferences.useAggregateCounts() != useAggregateCounts) {
activity?.restart()
return
}

View file

@ -12,4 +12,8 @@ class ScSdkPreferences @Inject constructor(private val vectorPreferences: Vector
override fun getUnreadKind(isDirect: Boolean): Int {
return vectorPreferences?.roomUnreadKind(isDirect) ?: RoomSummary.UNREAD_KIND_FULL
}
override fun aggregateUnreadRoomCounts(): Boolean {
return vectorPreferences?.useAggregateCounts() ?: true
}
}

View file

@ -197,6 +197,7 @@ class VectorPreferences @Inject constructor(private val context: Context) {
private const val SETTINGS_ROOM_UNREAD_KIND_DM = "SETTINGS_ROOM_UNREAD_KIND_DM"
private const val SETTINGS_ROOM_UNREAD_KIND_GROUP = "SETTINGS_ROOM_UNREAD_KIND_GROUP"
const val SETTINGS_UNIMPORTANT_COUNTER_BADGE = "SETTINGS_UNIMPORTANT_COUNTER_BADGE"
const val SETTINGS_AGGREGATE_UNREAD_COUNTS = "SETTINGS_AGGREGATE_UNREAD_COUNTS"
private const val SETTINGS_SIMPLIFIED_MODE = "SETTINGS_SIMPLIFIED_MODE"
private const val SETTINGS_LABS_ALLOW_MARK_UNREAD = "SETTINGS_LABS_ALLOW_MARK_UNREAD"
const val SETTINGS_ALLOW_URL_PREVIEW_IN_ENCRYPTED_ROOM_KEY = "SETTINGS_ALLOW_URL_PREVIEW_IN_ENCRYPTED_ROOM_KEY"
@ -969,6 +970,11 @@ class VectorPreferences @Inject constructor(private val context: Context) {
return defaultPrefs.getBoolean(SETTINGS_UNIMPORTANT_COUNTER_BADGE, true)
}
// SC additions - for spaces/categories: whether to count unread chats, or messages
fun useAggregateCounts(): Boolean {
return defaultPrefs.getBoolean(SETTINGS_AGGREGATE_UNREAD_COUNTS, true)
}
// SC addition
fun simplifiedMode(): Boolean {
return defaultPrefs.getBoolean(SETTINGS_SIMPLIFIED_MODE, false)

View file

@ -28,6 +28,7 @@ import im.vector.app.features.grouplist.homeSpaceSummaryItem
import im.vector.app.features.home.AvatarRenderer
import im.vector.app.features.home.room.ScSdkPreferences
import im.vector.app.features.home.room.list.UnreadCounterBadgeView
import im.vector.app.features.settings.VectorPreferences
import im.vector.app.group
import im.vector.app.space
import org.matrix.android.sdk.api.session.group.model.GroupSummary
@ -40,7 +41,7 @@ import java.util.Locale
import javax.inject.Inject
class SpaceSummaryController @Inject constructor(
private val scSdkPreferences: ScSdkPreferences,
private val vectorPreferences: VectorPreferences,
private val avatarRenderer: AvatarRenderer,
private val colorProvider: ColorProvider,
private val stringProvider: StringProvider) : EpoxyController() {
@ -142,6 +143,8 @@ class SpaceSummaryController @Inject constructor(
listener { host.callback?.onSpaceSelected(null) }
}
val useAggregateCounts = vectorPreferences.useAggregateCounts()
rootSpaces
?.forEach { groupSummary ->
val isSelected = selected is RoomGroupingMethod.BySpace && groupSummary.roomId == selected.space()?.roomId
@ -168,9 +171,9 @@ class SpaceSummaryController @Inject constructor(
toggleExpand { host.callback?.onToggleExpand(groupSummary) }
countState(
UnreadCounterBadgeView.State(
groupSummary.notificationCount,
if (useAggregateCounts) groupSummary.aggregatedNotificationCount else groupSummary.notificationCount,
groupSummary.highlightCount > 0,
groupSummary.safeUnreadCount,
if (useAggregateCounts) groupSummary.aggregatedUnreadCount else groupSummary.safeUnreadCount,
groupSummary.markedUnread
)
)
@ -204,6 +207,8 @@ class SpaceSummaryController @Inject constructor(
val expanded = expandedStates[childSummary.roomId] == true
val isSelected = selected is RoomGroupingMethod.BySpace && childSummary.roomId == selected.space()?.roomId
val useAggregateCounts = vectorPreferences.useAggregateCounts()
subSpaceSummaryItem {
avatarRenderer(host.avatarRenderer)
id(childSummary.roomId)
@ -217,9 +222,9 @@ class SpaceSummaryController @Inject constructor(
indent(currentDepth)
countState(
UnreadCounterBadgeView.State(
childSummary.notificationCount,
if (useAggregateCounts) childSummary.aggregatedNotificationCount else childSummary.notificationCount,
childSummary.highlightCount > 0,
childSummary.safeUnreadCount,
if (useAggregateCounts) childSummary.aggregatedUnreadCount else childSummary.safeUnreadCount,
childSummary.markedUnread
)
)

View file

@ -44,8 +44,11 @@
<string name="bubble_time_location_top">Top</string>
<string name="bubble_time_location_bottom">Bottom</string>
<string name="settings_unread_counter">Unread counter</string>
<string name="settings_unimportant_counter_badge_v2">Count muted messages</string>
<string name="settings_unimportant_counter_badge_summary_v2">Show counts for muted messages in the chat overview</string>
<string name="settings_aggregate_unread_counts">Count chats instead of messages</string>
<string name="settings_aggregate_unread_counts_summary">Whether to count unread chats instead of individual messages in spaces and room categories</string>
<string name="labs_mark_rooms_unread">Mark chats as unread</string>
<string name="labs_mark_rooms_unread_summary">Allow marking chats as unread. Other Matrix clients might not support this yet.</string>

View file

@ -96,11 +96,23 @@
android:summary="%s"
android:title="@string/settings_room_unread_kind_group" />
</im.vector.app.core.preference.VectorPreferenceCategory>
<im.vector.app.core.preference.VectorPreferenceCategory
android:key="SETTINGS_UNREAD_COUNTER"
android:title="@string/settings_unread_counter">
<im.vector.app.core.preference.VectorSwitchPreference
android:defaultValue="true"
android:key="SETTINGS_UNIMPORTANT_COUNTER_BADGE"
android:summary="@string/settings_unimportant_counter_badge_summary_v2"
android:title="@string/settings_unimportant_counter_badge_v2" />
android:title="@string/settings_unimportant_counter_badge_v2"
android:summary="@string/settings_unimportant_counter_badge_summary_v2" />
<im.vector.app.core.preference.VectorSwitchPreference
android:defaultValue="true"
android:key="SETTINGS_AGGREGATE_UNREAD_COUNTS"
android:title="@string/settings_aggregate_unread_counts"
android:summary="@string/settings_aggregate_unread_counts_summary" />
</im.vector.app.core.preference.VectorPreferenceCategory>