diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomSync.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomSync.kt index e5ac0a39b2..472121269f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomSync.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomSync.kt @@ -47,6 +47,12 @@ data class RoomSync( */ @Json(name = "unread_notifications") val unreadNotifications: RoomSyncUnreadNotifications? = null, + + /** + * The count of threads with unread notifications (not the total # of notifications in all threads) + */ + @Json(name = "org.matrix.msc3773.unread_thread_notifications") val unreadThreadNotifications: Map? = null, + /** * The room summary. */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomSyncUnreadThreadNotifications.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomSyncUnreadThreadNotifications.kt new file mode 100644 index 0000000000..70524d299a --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomSyncUnreadThreadNotifications.kt @@ -0,0 +1,33 @@ +/* + * Copyright 2022 The Matrix.org Foundation C.I.C. + * + * 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 org.matrix.android.sdk.api.session.sync.model + +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass + +@JsonClass(generateAdapter = true) +data class RoomSyncUnreadThreadNotifications( + /** + * The number of threads with unread messages that match the push notification rules. + */ + @Json(name = "notification_count") val notificationCount: Int? = null, + + /** + * The number of threads with highlighted unread messages (subset of notifications). + */ + @Json(name = "highlight_count") val highlightCount: Int? = null +) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/FilterFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/FilterFactory.kt index 676a4f6a38..141144acd8 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/FilterFactory.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/FilterFactory.kt @@ -28,7 +28,8 @@ internal object FilterFactory { limit = numberOfEvents, // senders = listOf(userId), // relationSenders = userId?.let { listOf(it) }, - relationTypes = listOf(RelationType.THREAD) + relationTypes = listOf(RelationType.THREAD), + enableUnreadThreadNotifications = true, ) } @@ -37,7 +38,8 @@ internal object FilterFactory { limit = numberOfEvents, containsUrl = true, types = listOf(EventType.MESSAGE), - lazyLoadMembers = true + lazyLoadMembers = true, + enableUnreadThreadNotifications = true, ) } @@ -62,7 +64,8 @@ internal object FilterFactory { fun createElementRoomFilter(): RoomEventFilter { return RoomEventFilter( - lazyLoadMembers = true + lazyLoadMembers = true, + enableUnreadThreadNotifications = true, // TODO Enable this for optimization // types = (listOfSupportedEventTypes + listOfSupportedStateEventTypes).toMutableList() ) @@ -77,7 +80,8 @@ internal object FilterFactory { private fun createElementStateFilter(): RoomEventFilter { return RoomEventFilter( - lazyLoadMembers = true + lazyLoadMembers = true, + enableUnreadThreadNotifications = true, ) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/RoomEventFilter.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/RoomEventFilter.kt index 220c401137..81d1c04261 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/RoomEventFilter.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/RoomEventFilter.kt @@ -17,6 +17,7 @@ package org.matrix.android.sdk.internal.session.filter import com.squareup.moshi.Json import com.squareup.moshi.JsonClass +import org.matrix.android.sdk.api.session.sync.model.RoomSync import org.matrix.android.sdk.internal.di.MoshiProvider /** @@ -76,7 +77,11 @@ internal data class RoomEventFilter( /** * If true, enables lazy-loading of membership events. See Lazy-loading room members for more information. Defaults to false. */ - @Json(name = "lazy_load_members") val lazyLoadMembers: Boolean? = null + @Json(name = "lazy_load_members") val lazyLoadMembers: Boolean? = null, + /** + * If true, this will opt-in for the server to return unread threads notifications in [RoomSync] + */ + @Json(name = "org.matrix.msc3773.unread_thread_notifications") val enableUnreadThreadNotifications: Boolean? = null, ) { fun toJSONString(): String { @@ -92,6 +97,7 @@ internal data class RoomEventFilter( rooms != null || notRooms != null || containsUrl != null || - lazyLoadMembers != null) + lazyLoadMembers != null || + enableUnreadThreadNotifications != null) } } 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 6979d42827..537483193a 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 @@ -39,6 +39,7 @@ import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper import org.matrix.android.sdk.api.session.room.send.SendState import org.matrix.android.sdk.api.session.sync.model.RoomSyncSummary import org.matrix.android.sdk.api.session.sync.model.RoomSyncUnreadNotifications +import org.matrix.android.sdk.api.session.sync.model.RoomSyncUnreadThreadNotifications import org.matrix.android.sdk.internal.crypto.EventDecryptor import org.matrix.android.sdk.internal.crypto.crosssigning.DefaultCrossSigningService import org.matrix.android.sdk.internal.database.mapper.ContentMapper @@ -91,6 +92,7 @@ internal class RoomSummaryUpdater @Inject constructor( membership: Membership? = null, roomSummary: RoomSyncSummary? = null, unreadNotifications: RoomSyncUnreadNotifications? = null, + unreadThreadNotifications: Map? = null, updateMembers: Boolean = false, inviterId: String? = null, aggregator: SyncResponsePostTreatmentAggregator? = null @@ -111,6 +113,8 @@ internal class RoomSummaryUpdater @Inject constructor( roomSummaryEntity.highlightCount = unreadNotifications?.highlightCount ?: 0 roomSummaryEntity.notificationCount = unreadNotifications?.notificationCount ?: 0 + // TODO: Handle unreadThreadNotifications + if (membership != null) { roomSummaryEntity.membership = membership } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt index a2f2251b70..2825be8291 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt @@ -287,6 +287,7 @@ internal class RoomSyncHandler @Inject constructor( Membership.JOIN, roomSync.summary, roomSync.unreadNotifications, + roomSync.unreadThreadNotifications, updateMembers = hasRoomMember, aggregator = aggregator ) @@ -372,7 +373,8 @@ internal class RoomSyncHandler @Inject constructor( roomEntity.chunks.clearWith { it.deleteOnCascade(deleteStateEvents = true, canDeleteRoot = true) } roomTypingUsersHandler.handle(realm, roomId, null) roomChangeMembershipStateDataSource.setMembershipFromSync(roomId, Membership.LEAVE) - roomSummaryUpdater.update(realm, roomId, membership, roomSync.summary, roomSync.unreadNotifications, aggregator = aggregator) + roomSummaryUpdater.update(realm, roomId, membership, roomSync.summary, + roomSync.unreadNotifications, roomSync.unreadThreadNotifications, aggregator = aggregator) return roomEntity }