Skip to content

Commit d7cff2d

Browse files
jamesarichclaude
andcommitted
feat(notifications): rebuild the group summary from the child's real MessagingStyle
The summary previously reconstructed each line from EXTRA_TITLE/EXTRA_TEXT, so it showed the conversation title as the "sender". Extract the child's MessagingStyle (public compat API) and reuse its latest message — real sender Person and timestamp — falling back to the extras for children without an extractable style. Reimplements the useful half of an errored Copilot session's partial commit (dropped from the branch): that version used the restricted Message.getMessagesFromBundleArray API and also demoted fresh reactions on already-read messages to historic context, which would have buried the very event a reaction notification exists to surface. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 09d1032 commit d7cff2d

2 files changed

Lines changed: 23 additions & 9 deletions

File tree

core/service/src/androidHostTest/kotlin/org/meshtastic/core/service/MeshNotificationManagerImplConversationTest.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,13 @@ class MeshNotificationManagerImplConversationTest {
182182

183183
val summary = activeByTag("message_summary").single().notification
184184
assertEquals(Notification.GROUP_ALERT_CHILDREN, summary.groupAlertBehavior)
185+
// The summary line is rebuilt from the child's real MessagingStyle, so it carries the actual sender.
186+
val summaryLatest =
187+
androidx.core.app.NotificationCompat.MessagingStyle.extractMessagingStyleFromNotification(summary)
188+
?.messages
189+
?.lastOrNull()
190+
assertEquals("hello", summaryLatest?.text?.toString())
191+
assertEquals("Hawk Ridge", summaryLatest?.person?.name?.toString())
185192

186193
manager.cancelMessageNotification("0^all")
187194

core/service/src/androidMain/kotlin/org/meshtastic/core/service/MeshNotificationManagerImpl.kt

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -523,15 +523,22 @@ class MeshNotificationManagerImpl(
523523
.setConversationTitle(getString(Res.string.meshtastic_app_name))
524524

525525
activeNotifications.forEach { sbn ->
526-
val senderTitle = sbn.notification.extras.getCharSequence(Notification.EXTRA_TITLE)
527-
val messageText = sbn.notification.extras.getCharSequence(Notification.EXTRA_TEXT)
528-
val postTime = sbn.postTime
529-
530-
if (senderTitle != null && messageText != null) {
531-
// For the summary, we're creating a generic Person for the sender from the active notification's title.
532-
// We don't have the original Person object or its colors/ID, so we're just using the name.
533-
val senderPerson = Person.Builder().setName(senderTitle).build()
534-
messagingStyle.addMessage(messageText, postTime, senderPerson)
526+
// Prefer the child's real MessagingStyle: its latest message carries the actual sender (Person, icon) and
527+
// timestamp, so the summary line reads "Hawk Ridge: …" rather than the conversation title.
528+
val latest =
529+
NotificationCompat.MessagingStyle.extractMessagingStyleFromNotification(sbn.notification)
530+
?.messages
531+
?.lastOrNull()
532+
if (latest?.text != null) {
533+
val senderPerson = latest.person ?: Person.Builder().setName(getString(Res.string.you)).build()
534+
messagingStyle.addMessage(latest.text, latest.timestamp, senderPerson)
535+
} else {
536+
// Fallback for children without an extractable style: rebuild a generic line from the extras.
537+
val senderTitle = sbn.notification.extras.getCharSequence(Notification.EXTRA_TITLE)
538+
val messageText = sbn.notification.extras.getCharSequence(Notification.EXTRA_TEXT)
539+
if (senderTitle != null && messageText != null) {
540+
messagingStyle.addMessage(messageText, sbn.postTime, Person.Builder().setName(senderTitle).build())
541+
}
535542
}
536543
}
537544

0 commit comments

Comments
 (0)