99package io.element.android.libraries.push.impl.notifications
1010
1111import android.app.Notification
12- import android.graphics.Typeface
13- import android.text.style.StyleSpan
14- import androidx.core.text.buildSpannedString
15- import androidx.core.text.inSpans
1612import coil3.ImageLoader
1713import dev.zacsweers.metro.AppScope
1814import dev.zacsweers.metro.ContributesBinding
1915import io.element.android.libraries.matrix.api.core.RoomId
2016import io.element.android.libraries.matrix.api.core.SessionId
2117import io.element.android.libraries.matrix.api.core.ThreadId
22- import io.element.android.libraries.push.impl.R
2318import io.element.android.libraries.push.impl.notifications.factories.NotificationAccountParams
2419import io.element.android.libraries.push.impl.notifications.factories.NotificationCreator
2520import io.element.android.libraries.push.impl.notifications.model.FallbackNotifiableEvent
2621import io.element.android.libraries.push.impl.notifications.model.InviteNotifiableEvent
2722import io.element.android.libraries.push.impl.notifications.model.NotifiableMessageEvent
2823import io.element.android.libraries.push.impl.notifications.model.SimpleNotifiableEvent
29- import io.element.android.services.toolbox.api.strings.StringProvider
3024
3125interface NotificationDataFactory {
3226 suspend fun toNotifications (
@@ -51,16 +45,15 @@ interface NotificationDataFactory {
5145
5246 @JvmName(" toNotificationFallbackEvents" )
5347 @Suppress(" INAPPLICABLE_JVM_NAME" )
54- fun toNotifications (
48+ fun toNotification (
5549 fallback : List <FallbackNotifiableEvent >,
5650 notificationAccountParams : NotificationAccountParams ,
57- ): List < OneShotNotification >
51+ ): OneShotNotification ?
5852
5953 fun createSummaryNotification (
6054 roomNotifications : List <RoomNotification >,
6155 invitationNotifications : List <OneShotNotification >,
6256 simpleNotifications : List <OneShotNotification >,
63- fallbackNotifications : List <OneShotNotification >,
6457 notificationAccountParams : NotificationAccountParams ,
6558 ): SummaryNotification
6659}
@@ -71,7 +64,6 @@ class DefaultNotificationDataFactory(
7164 private val roomGroupMessageCreator : RoomGroupMessageCreator ,
7265 private val summaryGroupMessageCreator : SummaryGroupMessageCreator ,
7366 private val activeNotificationsProvider : ActiveNotificationsProvider ,
74- private val stringProvider : StringProvider ,
7567) : NotificationDataFactory {
7668 override suspend fun toNotifications (
7769 messages : List <NotifiableMessageEvent >,
@@ -81,10 +73,7 @@ class DefaultNotificationDataFactory(
8173 val messagesToDisplay = messages.filterNot { it.canNotBeDisplayed() }
8274 .groupBy { it.roomId }
8375 return messagesToDisplay.flatMap { (roomId, events) ->
84- val roomName = events.lastOrNull()?.roomName ? : roomId.value
85- val isDm = events.lastOrNull()?.roomIsDm ? : false
8676 val eventsByThreadId = events.groupBy { it.threadId }
87-
8877 eventsByThreadId.map { (threadId, events) ->
8978 val notification = roomGroupMessageCreator.createRoomMessage(
9079 events = events,
@@ -98,7 +87,6 @@ class DefaultNotificationDataFactory(
9887 notification = notification,
9988 roomId = roomId,
10089 threadId = threadId,
101- summaryLine = createRoomMessagesGroupSummaryLine(events, roomName, isDm),
10290 messageCount = events.size,
10391 latestTimestamp = events.maxOf { it.timestamp },
10492 shouldBing = events.any { it.noisy }
@@ -123,7 +111,6 @@ class DefaultNotificationDataFactory(
123111 OneShotNotification (
124112 tag = event.roomId.value,
125113 notification = notificationCreator.createRoomInvitationNotification(notificationAccountParams, event),
126- summaryLine = event.description,
127114 isNoisy = event.noisy,
128115 timestamp = event.timestamp
129116 )
@@ -140,7 +127,6 @@ class DefaultNotificationDataFactory(
140127 OneShotNotification (
141128 tag = event.eventId.value,
142129 notification = notificationCreator.createSimpleEventNotification(notificationAccountParams, event),
143- summaryLine = event.description,
144130 isNoisy = event.noisy,
145131 timestamp = event.timestamp
146132 )
@@ -149,26 +135,31 @@ class DefaultNotificationDataFactory(
149135
150136 @JvmName(" toNotificationFallbackEvents" )
151137 @Suppress(" INAPPLICABLE_JVM_NAME" )
152- override fun toNotifications (
138+ override fun toNotification (
153139 fallback : List <FallbackNotifiableEvent >,
154140 notificationAccountParams : NotificationAccountParams ,
155- ): List <OneShotNotification > {
156- return fallback.map { event ->
157- OneShotNotification (
158- tag = event.eventId.value,
159- notification = notificationCreator.createFallbackNotification(notificationAccountParams, event),
160- summaryLine = event.description.orEmpty(),
161- isNoisy = false ,
162- timestamp = event.timestamp
163- )
164- }
141+ ): OneShotNotification ? {
142+ if (fallback.isEmpty()) return null
143+ val existingNotification = activeNotificationsProvider
144+ .getFallbackNotification(notificationAccountParams.user.userId)
145+ ?.notification
146+ val notification = notificationCreator.createFallbackNotification(
147+ existingNotification,
148+ notificationAccountParams,
149+ fallback,
150+ )
151+ return OneShotNotification (
152+ tag = " FALLBACK" ,
153+ notification = notification,
154+ isNoisy = false ,
155+ timestamp = fallback.first().timestamp
156+ )
165157 }
166158
167159 override fun createSummaryNotification (
168160 roomNotifications : List <RoomNotification >,
169161 invitationNotifications : List <OneShotNotification >,
170162 simpleNotifications : List <OneShotNotification >,
171- fallbackNotifications : List <OneShotNotification >,
172163 notificationAccountParams : NotificationAccountParams ,
173164 ): SummaryNotification {
174165 return when {
@@ -178,59 +169,17 @@ class DefaultNotificationDataFactory(
178169 roomNotifications = roomNotifications,
179170 invitationNotifications = invitationNotifications,
180171 simpleNotifications = simpleNotifications,
181- fallbackNotifications = fallbackNotifications,
182172 notificationAccountParams = notificationAccountParams,
183173 )
184174 )
185175 }
186176 }
187-
188- private fun createRoomMessagesGroupSummaryLine (events : List <NotifiableMessageEvent >, roomName : String , roomIsDm : Boolean ): CharSequence {
189- return when (events.size) {
190- 1 -> createFirstMessageSummaryLine(events.first(), roomName, roomIsDm)
191- else -> {
192- stringProvider.getQuantityString(
193- R .plurals.notification_compat_summary_line_for_room,
194- events.size,
195- roomName,
196- events.size
197- )
198- }
199- }
200- }
201-
202- private fun createFirstMessageSummaryLine (event : NotifiableMessageEvent , roomName : String , roomIsDm : Boolean ): CharSequence {
203- return if (roomIsDm) {
204- buildSpannedString {
205- event.senderDisambiguatedDisplayName?.let {
206- inSpans(StyleSpan (Typeface .BOLD )) {
207- append(it)
208- append(" : " )
209- }
210- }
211- append(event.description)
212- }
213- } else {
214- buildSpannedString {
215- inSpans(StyleSpan (Typeface .BOLD )) {
216- append(roomName)
217- append(" : " )
218- event.senderDisambiguatedDisplayName?.let {
219- append(it)
220- append(" " )
221- }
222- }
223- append(event.description)
224- }
225- }
226- }
227177}
228178
229179data class RoomNotification (
230180 val notification : Notification ,
231181 val roomId : RoomId ,
232182 val threadId : ThreadId ? ,
233- val summaryLine : CharSequence ,
234183 val messageCount : Int ,
235184 val latestTimestamp : Long ,
236185 val shouldBing : Boolean ,
@@ -239,7 +188,6 @@ data class RoomNotification(
239188 return notification == other.notification &&
240189 roomId == other.roomId &&
241190 threadId == other.threadId &&
242- summaryLine.toString() == other.summaryLine.toString() &&
243191 messageCount == other.messageCount &&
244192 latestTimestamp == other.latestTimestamp &&
245193 shouldBing == other.shouldBing
@@ -249,7 +197,6 @@ data class RoomNotification(
249197data class OneShotNotification (
250198 val notification : Notification ,
251199 val tag : String ,
252- val summaryLine : CharSequence ,
253200 val isNoisy : Boolean ,
254201 val timestamp : Long ,
255202)
0 commit comments