adding summary notification title and ensuring that it updates without pinging when the counts change

This commit is contained in:
Adam Brown 2022-05-08 12:36:53 +01:00
parent f2be4b8b95
commit 995377343b
2 changed files with 21 additions and 12 deletions

View File

@ -7,8 +7,6 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Build import android.os.Build
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
import app.dapk.st.core.AppLogTag
import app.dapk.st.core.log
import app.dapk.st.imageloader.IconLoader import app.dapk.st.imageloader.IconLoader
import app.dapk.st.matrix.sync.RoomEvent import app.dapk.st.matrix.sync.RoomEvent
import app.dapk.st.matrix.sync.RoomOverview import app.dapk.st.matrix.sync.RoomOverview
@ -22,7 +20,7 @@ class NotificationFactory(
private val context: Context, private val context: Context,
) { ) {
suspend fun createNotifications(events: Map<RoomOverview, List<RoomEvent>>): Notifications { suspend fun createNotifications(events: Map<RoomOverview, List<RoomEvent>>, onlyContainsRemovals: Boolean): Notifications {
val notifications = events.map { (roomOverview, events) -> val notifications = events.map { (roomOverview, events) ->
val messageEvents = events.filterIsInstance<RoomEvent.Message>() val messageEvents = events.filterIsInstance<RoomEvent.Message>()
when (messageEvents.isEmpty()) { when (messageEvents.isEmpty()) {
@ -32,14 +30,14 @@ class NotificationFactory(
} }
val summaryNotification = if (notifications.filterIsInstance<NotificationDelegate.Room>().isNotEmpty()) { val summaryNotification = if (notifications.filterIsInstance<NotificationDelegate.Room>().isNotEmpty()) {
createSummary(notifications) createSummary(notifications, onlyContainsRemovals)
} else { } else {
null null
} }
return Notifications(summaryNotification, notifications) return Notifications(summaryNotification, notifications)
} }
private fun createSummary(notifications: List<NotificationDelegate>): Notification { private fun createSummary(notifications: List<NotificationDelegate>, onlyContainsRemovals: Boolean): Notification {
val summaryInboxStyle = Notification.InboxStyle().also { style -> val summaryInboxStyle = Notification.InboxStyle().also { style ->
notifications.forEach { notifications.forEach {
when (it) { when (it) {
@ -51,8 +49,13 @@ class NotificationFactory(
} }
} }
if (notifications.size > 1) {
summaryInboxStyle.setSummaryText("${notifications.countMessages()} messages from ${notifications.size} chats")
}
return builder() return builder()
.setStyle(summaryInboxStyle) .setStyle(summaryInboxStyle)
.setOnlyAlertOnce(onlyContainsRemovals)
.setSmallIcon(R.drawable.ic_notification_small_icon) .setSmallIcon(R.drawable.ic_notification_small_icon)
.setCategory(Notification.CATEGORY_MESSAGE) .setCategory(Notification.CATEGORY_MESSAGE)
.setGroupSummary(true) .setGroupSummary(true)
@ -60,6 +63,13 @@ class NotificationFactory(
.build() .build()
} }
private fun List<NotificationDelegate>.countMessages() = this.sumOf {
when (it) {
is NotificationDelegate.DismissRoom -> 0
is NotificationDelegate.Room -> it.messageCount
}
}
@RequiresApi(Build.VERSION_CODES.P) @RequiresApi(Build.VERSION_CODES.P)
private suspend fun createMessageStyle(events: List<RoomEvent.Message>, roomOverview: RoomOverview): Notification.MessagingStyle { private suspend fun createMessageStyle(events: List<RoomEvent.Message>, roomOverview: RoomOverview): Notification.MessagingStyle {
val messageStyle = Notification.MessagingStyle( val messageStyle = Notification.MessagingStyle(
@ -131,7 +141,8 @@ class NotificationFactory(
.setAutoCancel(true) .setAutoCancel(true)
.build(), .build(),
roomId = roomOverview.roomId, roomId = roomOverview.roomId,
summary = events.last().content summary = events.last().content,
messageCount = events.size,
) )
} }

View File

@ -21,7 +21,7 @@ class NotificationRenderer(
suspend fun render(result: Map<RoomOverview, List<RoomEvent>>, removedRooms: Set<RoomId>, onlyContainsRemovals: Boolean) { suspend fun render(result: Map<RoomOverview, List<RoomEvent>>, removedRooms: Set<RoomId>, onlyContainsRemovals: Boolean) {
removedRooms.forEach { notificationManager.cancel(it.value, MESSAGE_NOTIFICATION_ID) } removedRooms.forEach { notificationManager.cancel(it.value, MESSAGE_NOTIFICATION_ID) }
val notifications = notificationFactory.createNotifications(result) val notifications = notificationFactory.createNotifications(result, onlyContainsRemovals)
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {
notifications.summaryNotification.ifNull { notifications.summaryNotification.ifNull {
@ -42,17 +42,15 @@ class NotificationRenderer(
} }
notifications.summaryNotification?.let { notifications.summaryNotification?.let {
if (!onlyContainsRemovals) {
log(AppLogTag.NOTIFICATION, "notifying summary") log(AppLogTag.NOTIFICATION, "notifying summary")
notificationManager.notify(SUMMARY_NOTIFICATION_ID, it) notificationManager.notify(SUMMARY_NOTIFICATION_ID, it)
} }
} }
} }
}
} }
sealed interface NotificationDelegate { sealed interface NotificationDelegate {
data class Room(val notification: Notification, val roomId: RoomId, val summary: String) : NotificationDelegate data class Room(val notification: Notification, val roomId: RoomId, val summary: String, val messageCount: Int) : NotificationDelegate
data class DismissRoom(val roomId: RoomId) : NotificationDelegate data class DismissRoom(val roomId: RoomId) : NotificationDelegate
} }