Revert "Revert "Setting for unread badge / room summary event visibility""

This reverts commit 1ff602db3b.

Change-Id: I161a6dcbbee2b2dc517912f6fb1f6b2ec772df0b

Conflicts:
	matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt
This commit is contained in:
SpiritCroc 2020-09-22 10:05:36 +02:00
parent 5ab3e45f10
commit 2fa4518600
15 changed files with 203 additions and 10 deletions

View file

@ -40,10 +40,14 @@ data class RoomSummary constructor(
val joinedMembersCount: Int? = 0,
val invitedMembersCount: Int? = 0,
val latestPreviewableEvent: TimelineEvent? = null,
val latestPreviewableContentEvent: TimelineEvent? = null,
val latestPreviewableOriginalContentEvent: TimelineEvent? = null,
val otherMemberIds: List<String> = emptyList(),
val notificationCount: Int = 0,
val highlightCount: Int = 0,
val hasUnreadMessages: Boolean = false,
val hasUnreadContentMessages: Boolean = false,
val hasUnreadOriginalContentMessages: Boolean = false,
val tags: List<RoomTag> = emptyList(),
val membership: Membership = Membership.NONE,
val versioningState: VersioningState = VersioningState.NONE,
@ -70,7 +74,42 @@ data class RoomSummary constructor(
val canStartCall: Boolean
get() = joinedMembersCount == 2
fun scHasUnreadMessages(preferenceProvider: RoomSummaryPreferenceProvider?): Boolean {
if (preferenceProvider == null) {
// Fallback to default
return hasUnreadMessages
}
return when(preferenceProvider.getUnreadKind()) {
UNREAD_KIND_ORIGINAL_CONTENT -> hasUnreadOriginalContentMessages
UNREAD_KIND_CONTENT -> hasUnreadContentMessages
// UNREAD_KIND_DEFAULT
else -> hasUnreadMessages
}
}
fun scLatestPreviewableEvent(preferenceProvider: RoomSummaryPreferenceProvider?): TimelineEvent? {
if (preferenceProvider == null) {
// Fallback to default
return latestPreviewableEvent
}
return when(preferenceProvider.getUnreadKind()) {
UNREAD_KIND_ORIGINAL_CONTENT -> latestPreviewableOriginalContentEvent
UNREAD_KIND_CONTENT -> latestPreviewableContentEvent
// UNREAD_KIND_DEFAULT
else -> latestPreviewableEvent
}
}
companion object {
const val NOT_IN_BREADCRUMBS = -1
// SC addition
const val UNREAD_KIND_DEFAULT = 0
const val UNREAD_KIND_CONTENT = 1
const val UNREAD_KIND_ORIGINAL_CONTENT = 2
}
// SC addition
interface RoomSummaryPreferenceProvider {
fun getUnreadKind(): Int
}
}

View file

@ -30,4 +30,35 @@ object RoomSummaryConstants {
EventType.STICKER,
EventType.REACTION
)
// SC addition | this is the Element behaviour previous to Element v1.0.7
val PREVIEWABLE_TYPES_ALL = listOf(
// TODO filter message type (KEY_VERIFICATION_READY, etc.)
EventType.MESSAGE,
EventType.STATE_ROOM_NAME,
EventType.STATE_ROOM_TOPIC,
EventType.STATE_ROOM_AVATAR,
EventType.STATE_ROOM_MEMBER,
EventType.STATE_ROOM_HISTORY_VISIBILITY,
EventType.CALL_INVITE,
EventType.CALL_HANGUP,
EventType.CALL_ANSWER,
EventType.ENCRYPTED,
EventType.STATE_ROOM_ENCRYPTION,
EventType.STATE_ROOM_THIRD_PARTY_INVITE,
EventType.STICKER,
EventType.REACTION,
EventType.STATE_ROOM_CREATE
)
// SC addition | no reactions in here
val PREVIEWABLE_ORIGINAL_CONTENT_TYPES = listOf(
// TODO filter message type (KEY_VERIFICATION_READY, etc.)
EventType.MESSAGE,
EventType.CALL_INVITE,
EventType.CALL_HANGUP,
EventType.CALL_ANSWER,
EventType.ENCRYPTED,
EventType.STICKER
)
}

View file

@ -34,6 +34,12 @@ internal class RoomSummaryMapper @Inject constructor(private val timelineEventMa
val latestEvent = roomSummaryEntity.latestPreviewableEvent?.let {
timelineEventMapper.map(it, buildReadReceipts = false)
}
val latestContentEvent = roomSummaryEntity.latestPreviewableContentEvent?.let {
timelineEventMapper.map(it, buildReadReceipts = false)
}
val latestOriginalContentEvent = roomSummaryEntity.latestPreviewableOriginalContentEvent?.let {
timelineEventMapper.map(it, buildReadReceipts = false)
}
// typings are updated through the sync where room summary entity gets updated no matter what, so it's ok get there
val typingUsers = typingUsersTracker.getTypingUsers(roomSummaryEntity.roomId)
@ -45,12 +51,16 @@ internal class RoomSummaryMapper @Inject constructor(private val timelineEventMa
avatarUrl = roomSummaryEntity.avatarUrl ?: "",
isDirect = roomSummaryEntity.isDirect,
latestPreviewableEvent = latestEvent,
latestPreviewableContentEvent = latestContentEvent,
latestPreviewableOriginalContentEvent = latestOriginalContentEvent,
joinedMembersCount = roomSummaryEntity.joinedMembersCount,
invitedMembersCount = roomSummaryEntity.invitedMembersCount,
otherMemberIds = roomSummaryEntity.otherMemberIds.toList(),
highlightCount = roomSummaryEntity.highlightCount,
notificationCount = roomSummaryEntity.notificationCount,
hasUnreadMessages = roomSummaryEntity.hasUnreadMessages,
hasUnreadContentMessages = roomSummaryEntity.hasUnreadContentMessages,
hasUnreadOriginalContentMessages = roomSummaryEntity.hasUnreadOriginalContentMessages,
tags = tags,
typingUsers = typingUsers,
membership = roomSummaryEntity.membership,

View file

@ -32,6 +32,8 @@ internal open class RoomSummaryEntity(
var name: String? = "",
var topic: String? = "",
var latestPreviewableEvent: TimelineEventEntity? = null,
var latestPreviewableContentEvent: TimelineEventEntity? = null,
var latestPreviewableOriginalContentEvent: TimelineEventEntity? = null,
var heroes: RealmList<String> = RealmList(),
var joinedMembersCount: Int? = 0,
var invitedMembersCount: Int? = 0,
@ -42,6 +44,8 @@ internal open class RoomSummaryEntity(
var highlightCount: Int = 0,
var readMarkerId: String? = null,
var hasUnreadMessages: Boolean = false,
var hasUnreadContentMessages: Boolean = false,
var hasUnreadOriginalContentMessages: Boolean = false,
var tags: RealmList<RoomTagEntity> = RealmList(),
var userDrafts: UserDraftsEntity? = null,
var breadcrumbsIndex: Int = RoomSummary.NOT_IN_BREADCRUMBS,

View file

@ -126,6 +126,8 @@ internal class DefaultSetReadMarkersTask @Inject constructor(
roomSummary.notificationCount = 0
roomSummary.highlightCount = 0
roomSummary.hasUnreadMessages = false
roomSummary.hasUnreadContentMessages = false
roomSummary.hasUnreadOriginalContentMessages = false
}
}
}

View file

@ -32,6 +32,24 @@ internal object RoomSummaryEventsHelper {
filterEdits = true
)
// SC addition
private val previewFiltersScAll = TimelineEventFilters(
filterTypes = true,
allowedTypes = RoomSummaryConstants.PREVIEWABLE_TYPES_ALL,
filterUseless = true,
filterRedacted = false,
filterEdits = true
)
// SC addition
private val previewFiltersScOriginalContent = TimelineEventFilters(
filterTypes = true,
allowedTypes = RoomSummaryConstants.PREVIEWABLE_ORIGINAL_CONTENT_TYPES,
filterUseless = true,
filterRedacted = true,
filterEdits = true
)
fun getLatestPreviewableEvent(realm: Realm, roomId: String): TimelineEventEntity? {
return TimelineEventEntity.latestEvent(
realm = realm,
@ -40,4 +58,24 @@ internal object RoomSummaryEventsHelper {
filters = previewFilters
)
}
// SC addition
fun getLatestPreviewableEventScAll(realm: Realm, roomId: String): TimelineEventEntity? {
return TimelineEventEntity.latestEvent(
realm = realm,
roomId = roomId,
includesSending = true,
filters = previewFiltersScAll
)
}
// SC addition
fun getLatestPreviewableEventScOriginalContent(realm: Realm, roomId: String): TimelineEventEntity? {
return TimelineEventEntity.latestEvent(
realm = realm,
roomId = roomId,
includesSending = true,
filters = previewFiltersScOriginalContent
)
}
}

View file

@ -97,17 +97,29 @@ internal class RoomSummaryUpdater @Inject constructor(
.contains(EventEntityFields.CONTENT, "\"algorithm\":\"$MXCRYPTO_ALGORITHM_MEGOLM\"")
.findFirst()
val latestPreviewableEvent = RoomSummaryEventsHelper.getLatestPreviewableEvent(realm, roomId)
val latestPreviewableEvent = RoomSummaryEventsHelper.getLatestPreviewableEventScAll(realm, roomId)
val latestPreviewableContentEvent = RoomSummaryEventsHelper.getLatestPreviewableEvent(realm, roomId)
val latestPreviewableOriginalContentEvent = RoomSummaryEventsHelper.getLatestPreviewableEventScOriginalContent(realm, roomId)
roomSummaryEntity.hasUnreadMessages = roomSummaryEntity.notificationCount > 0
// avoid this call if we are sure there are unread events
|| !isEventRead(realm.configuration, userId, roomId, latestPreviewableEvent?.eventId)
roomSummaryEntity.hasUnreadContentMessages = roomSummaryEntity.notificationCount > 0
// avoid this call if we are sure there are unread events
|| (latestPreviewableContentEvent != null
&& !isEventRead(realm.configuration, userId, roomId, latestPreviewableContentEvent.eventId))
roomSummaryEntity.hasUnreadOriginalContentMessages = roomSummaryEntity.notificationCount > 0
// avoid this call if we are sure there are unread events
|| (latestPreviewableOriginalContentEvent != null
&& !isEventRead(realm.configuration, userId, roomId, latestPreviewableOriginalContentEvent.eventId))
roomSummaryEntity.displayName = roomDisplayNameResolver.resolve(realm, roomId).toString()
roomSummaryEntity.avatarUrl = roomAvatarResolver.resolve(realm, roomId)
roomSummaryEntity.name = ContentMapper.map(lastNameEvent?.content).toModel<RoomNameContent>()?.name
roomSummaryEntity.topic = ContentMapper.map(lastTopicEvent?.content).toModel<RoomTopicContent>()?.topic
roomSummaryEntity.latestPreviewableEvent = latestPreviewableEvent
roomSummaryEntity.latestPreviewableContentEvent = latestPreviewableContentEvent
roomSummaryEntity.latestPreviewableOriginalContentEvent = latestPreviewableOriginalContentEvent
roomSummaryEntity.canonicalAlias = ContentMapper.map(lastCanonicalAliasEvent?.content).toModel<RoomCanonicalAliasContent>()
?.canonicalAlias

View file

@ -0,0 +1,15 @@
package im.vector.app.features.home.room
import android.content.Context
import im.vector.app.features.settings.VectorPreferences
import org.matrix.android.sdk.api.session.room.model.RoomSummary
import javax.inject.Inject
class ScSdkPreferences @Inject constructor(private val vectorPreferences: VectorPreferences?): RoomSummary.RoomSummaryPreferenceProvider {
constructor(context: Context?) : this(vectorPreferences = context?.let { VectorPreferences(it) })
override fun getUnreadKind(): Int {
return vectorPreferences?.roomUnreadKind() ?: RoomSummary.UNREAD_KIND_DEFAULT
}
}

View file

@ -21,11 +21,13 @@ import com.airbnb.epoxy.EpoxyController
import im.vector.app.core.epoxy.zeroItem
import im.vector.app.core.utils.DebouncedClickListener
import im.vector.app.features.home.AvatarRenderer
import im.vector.app.features.home.room.ScSdkPreferences
import org.matrix.android.sdk.api.util.toMatrixItem
import javax.inject.Inject
class BreadcrumbsController @Inject constructor(
private val avatarRenderer: AvatarRenderer
private val avatarRenderer: AvatarRenderer,
private val scSdkPreferences: ScSdkPreferences
) : EpoxyController() {
var listener: Listener? = null
@ -62,7 +64,7 @@ class BreadcrumbsController @Inject constructor(
matrixItem(it.toMatrixItem())
unreadNotificationCount(it.notificationCount)
showHighlighted(it.highlightCount > 0)
hasUnreadMessage(it.hasUnreadMessages)
hasUnreadMessage(it.scHasUnreadMessages(scSdkPreferences))
hasDraft(it.userDrafts.isNotEmpty())
itemClickListener(
DebouncedClickListener(View.OnClickListener { _ ->

View file

@ -120,6 +120,7 @@ import im.vector.app.features.crypto.keysbackup.restore.KeysBackupRestoreActivit
import im.vector.app.features.crypto.util.toImageRes
import im.vector.app.features.crypto.verification.VerificationBottomSheet
import im.vector.app.features.home.AvatarRenderer
import im.vector.app.features.home.room.ScSdkPreferences
import im.vector.app.features.home.room.detail.composer.TextComposerView
import im.vector.app.features.home.room.detail.readreceipts.DisplayReadReceiptsBottomSheet
import im.vector.app.features.home.room.detail.timeline.TimelineEventController
@ -1022,7 +1023,7 @@ class RoomDetailFragment @Inject constructor(
val inviter = state.asyncInviter()
if (summary?.membership == Membership.JOIN) {
jumpToBottomView.count = summary.notificationCount
jumpToBottomView.drawBadge = summary.hasUnreadMessages
jumpToBottomView.drawBadge = summary.scHasUnreadMessages(ScSdkPreferences(context))
scrollOnHighlightedEventCallback.timeline = roomDetailViewModel.timeline
timelineEventController.update(state)
inviteView.visibility = View.GONE

View file

@ -25,6 +25,7 @@ import com.airbnb.mvrx.MvRxState
import com.airbnb.mvrx.Uninitialized
import im.vector.app.R
import im.vector.app.features.home.RoomListDisplayMode
import im.vector.app.features.home.room.ScSdkPreferences
import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState
import org.matrix.android.sdk.api.session.room.model.Membership
import org.matrix.android.sdk.api.session.room.model.RoomSummary
@ -41,7 +42,8 @@ data class RoomListViewState(
val isGroupRoomsExpanded: Boolean = true,
val isCombinedRoomsExpanded: Boolean = true,
val isLowPriorityRoomsExpanded: Boolean = true,
val isServerNoticeRoomsExpanded: Boolean = true
val isServerNoticeRoomsExpanded: Boolean = true,
val scSdkPreferences: ScSdkPreferences? = null
) : MvRxState {
companion object {
@ -57,12 +59,15 @@ data class RoomListViewState(
return ROOM_LIST_ROOM_EXPANDED_LOW_PRIORITY_PREFIX + displayMode.toString()
}
// SC addition
fun initWithContext(context: Context, displayMode: RoomListDisplayMode): RoomListViewState {
val sp = getSharedPreferences(context)
val pref = getRoomListExpandedLowPriorityPref(displayMode)
return copy(isLowPriorityRoomsExpanded = sp.getBoolean(pref, isLowPriorityRoomsExpanded))
val scSdkPreferences = ScSdkPreferences(context)
return copy(isLowPriorityRoomsExpanded = sp.getBoolean(pref, isLowPriorityRoomsExpanded), scSdkPreferences = scSdkPreferences)
}
// SC addition
fun persistWithContext(context: Context, displayMode: RoomListDisplayMode) {
val sp = getSharedPreferences(context)
val pref = getRoomListExpandedLowPriorityPref(displayMode)
@ -97,7 +102,7 @@ data class RoomListViewState(
get() = asyncFilteredRooms.invoke()
?.flatMap { it.value }
?.filter { it.membership == Membership.JOIN }
?.any { it.hasUnreadMessages }
?.any { it.scHasUnreadMessages(scSdkPreferences) }
?: false
}

View file

@ -24,6 +24,7 @@ import im.vector.app.core.epoxy.VectorEpoxyModel
import im.vector.app.core.resources.StringProvider
import im.vector.app.core.utils.DebouncedClickListener
import im.vector.app.features.home.AvatarRenderer
import im.vector.app.features.home.room.ScSdkPreferences
import im.vector.app.features.home.room.detail.timeline.format.DisplayableEventFormatter
import im.vector.app.features.home.room.typing.TypingHelper
import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState
@ -36,7 +37,8 @@ class RoomSummaryItemFactory @Inject constructor(private val displayableEventFor
private val dateFormatter: VectorDateFormatter,
private val stringProvider: StringProvider,
private val typingHelper: TypingHelper,
private val avatarRenderer: AvatarRenderer) {
private val avatarRenderer: AvatarRenderer,
private val scSdkPreferences: ScSdkPreferences) {
fun create(roomSummary: RoomSummary,
roomChangeMembershipStates: Map<String, ChangeMembershipState>,
@ -84,7 +86,7 @@ class RoomSummaryItemFactory @Inject constructor(private val displayableEventFor
val showSelected = selectedRoomIds.contains(roomSummary.roomId)
var latestFormattedEvent: CharSequence = ""
var latestEventTime: CharSequence = ""
val latestEvent = roomSummary.latestPreviewableEvent
val latestEvent = roomSummary.scLatestPreviewableEvent(scSdkPreferences)
if (latestEvent != null) {
latestFormattedEvent = displayableEventFormatter.format(latestEvent, roomSummary.isDirect.not())
latestEventTime = dateFormatter.format(latestEvent.root.originServerTs, DateFormatKind.ROOM_LIST)
@ -103,7 +105,7 @@ class RoomSummaryItemFactory @Inject constructor(private val displayableEventFor
.showSelected(showSelected)
.hasFailedSending(roomSummary.hasFailedSending)
.unreadNotificationCount(unreadCount)
.hasUnreadMessage(roomSummary.hasUnreadMessages)
.hasUnreadMessage(roomSummary.scHasUnreadMessages(scSdkPreferences))
.hasDraft(roomSummary.userDrafts.isNotEmpty())
.itemLongClickListener { _ ->
onLongClick?.invoke(roomSummary) ?: false

View file

@ -29,6 +29,7 @@ import im.vector.app.core.di.DefaultSharedPreferences
import im.vector.app.features.homeserver.ServerUrlsRepository
import im.vector.app.features.themes.ThemeUtils
import org.matrix.android.sdk.api.extensions.tryThis
import org.matrix.android.sdk.api.session.room.model.RoomSummary
import timber.log.Timber
import javax.inject.Inject
@ -177,6 +178,7 @@ class VectorPreferences @Inject constructor(private val context: Context) {
// SC additions
private const val SETTINGS_SINGLE_OVERVIEW = "SETTINGS_SINGLE_OVERVIEW"
private const val SETTINGS_ROOM_UNREAD_KIND = "SETTINGS_ROOM_UNREAD_KIND"
private const val SETTINGS_UNIMPORTANT_COUNTER_BADGE = "SETTINGS_UNIMPORTANT_COUNTER_BADGE"
private const val DID_ASK_TO_ENABLE_SESSION_PUSH = "DID_ASK_TO_ENABLE_SESSION_PUSH"
@ -842,10 +844,21 @@ class VectorPreferences @Inject constructor(private val context: Context) {
return defaultPrefs.getBoolean(SETTINGS_SECURITY_USE_FLAG_SECURE, false)
}
// SC addition
fun singleOverview(): Boolean {
return defaultPrefs.getBoolean(SETTINGS_SINGLE_OVERVIEW, true)
}
// SC addition
fun roomUnreadKind(): Int {
val kind = defaultPrefs.getString(SETTINGS_ROOM_UNREAD_KIND, RoomSummary.UNREAD_KIND_CONTENT.toString())
return try {
Integer.parseInt(kind!!)
} catch (e: Exception) {
RoomSummary.UNREAD_KIND_CONTENT
}
}
// SC addition
fun shouldShowUnimportantCounterBadge(): Boolean {
return defaultPrefs.getBoolean(SETTINGS_UNIMPORTANT_COUNTER_BADGE, true)

View file

@ -12,4 +12,15 @@
<item>both</item>
</string-array>
<string-array name="room_unread_kind_entries" translatable="false">
<item>@string/settings_room_unread_kind_default</item>
<item>@string/settings_room_unread_kind_content</item>
<item>@string/settings_room_unread_kind_original_content</item>
</string-array>
<string-array name="room_unread_kind_values" translatable="false">
<item>0</item>
<item>1</item>
<item>2</item>
</string-array>
</resources>

View file

@ -57,6 +57,14 @@
android:summary="@string/settings_single_overview_summary"
android:title="@string/settings_single_overview" />
<im.vector.app.core.preference.VectorListPreference
android:defaultValue="1"
android:entries="@array/room_unread_kind_entries"
android:entryValues="@array/room_unread_kind_values"
android:key="SETTINGS_ROOM_UNREAD_KIND"
android:summary="%s"
android:title="@string/settings_room_unread_kind" />
<im.vector.app.core.preference.VectorSwitchPreference
android:defaultValue="true"
android:key="SETTINGS_UNIMPORTANT_COUNTER_BADGE"