Improve the text for mentions and replies in notifications (#3328)

This commit is contained in:
Jorge Martin Espinosa 2024-08-22 19:25:44 +02:00 committed by GitHub
parent 77195bfd5e
commit 49440ecef0
5 changed files with 29 additions and 12 deletions

View file

@ -104,11 +104,6 @@ class DefaultNotifiableEventResolver @Inject constructor(
is NotificationContent.MessageLike.RoomMessage -> { is NotificationContent.MessageLike.RoomMessage -> {
val senderDisambiguatedDisplayName = getDisambiguatedDisplayName(content.senderId) val senderDisambiguatedDisplayName = getDisambiguatedDisplayName(content.senderId)
val messageBody = descriptionFromMessageContent(content, senderDisambiguatedDisplayName) val messageBody = descriptionFromMessageContent(content, senderDisambiguatedDisplayName)
val notificationBody = if (hasMention) {
stringProvider.getString(R.string.notification_mentioned_you_body, messageBody)
} else {
messageBody
}
buildNotifiableMessageEvent( buildNotifiableMessageEvent(
sessionId = userId, sessionId = userId,
senderId = content.senderId, senderId = content.senderId,
@ -117,12 +112,13 @@ class DefaultNotifiableEventResolver @Inject constructor(
noisy = isNoisy, noisy = isNoisy,
timestamp = this.timestamp, timestamp = this.timestamp,
senderDisambiguatedDisplayName = senderDisambiguatedDisplayName, senderDisambiguatedDisplayName = senderDisambiguatedDisplayName,
body = notificationBody, body = messageBody,
imageUriString = fetchImageIfPresent(client)?.toString(), imageUriString = fetchImageIfPresent(client)?.toString(),
roomName = roomDisplayName, roomName = roomDisplayName,
roomIsDm = isDm, roomIsDm = isDm,
roomAvatarPath = roomAvatarUrl, roomAvatarPath = roomAvatarUrl,
senderAvatarPath = senderAvatarUrl, senderAvatarPath = senderAvatarUrl,
hasMentionOrReply = hasMention,
) )
} }
is NotificationContent.StateEvent.RoomMemberContent -> { is NotificationContent.StateEvent.RoomMemberContent -> {
@ -340,6 +336,7 @@ internal fun buildNotifiableMessageEvent(
isRedacted: Boolean = false, isRedacted: Boolean = false,
isUpdated: Boolean = false, isUpdated: Boolean = false,
type: String = EventType.MESSAGE, type: String = EventType.MESSAGE,
hasMentionOrReply: Boolean = false,
) = NotifiableMessageEvent( ) = NotifiableMessageEvent(
sessionId = sessionId, sessionId = sessionId,
senderId = senderId, senderId = senderId,
@ -363,4 +360,5 @@ internal fun buildNotifiableMessageEvent(
isRedacted = isRedacted, isRedacted = isRedacted,
isUpdated = isUpdated, isUpdated = isUpdated,
type = type, type = type,
hasMentionOrReply = hasMentionOrReply,
) )

View file

@ -397,10 +397,22 @@ class DefaultNotificationCreator @Inject constructor(
val senderPerson = if (event.outGoingMessage) { val senderPerson = if (event.outGoingMessage) {
null null
} else { } else {
val senderName = event.senderDisambiguatedDisplayName.orEmpty()
// If the notification is for a mention or reply, we create a fake `Person` with a custom name and key
val displayName = if (event.hasMentionOrReply) {
stringProvider.getString(R.string.notification_sender_mention_reply, senderName)
} else {
senderName
}
val key = if (event.hasMentionOrReply) {
"mention-or-reply:${event.eventId.value}"
} else {
event.senderId.value
}
Person.Builder() Person.Builder()
.setName(event.senderDisambiguatedDisplayName?.annotateForDebug(70)) .setName(displayName.annotateForDebug(70))
.setIcon(bitmapLoader.getUserIcon(event.senderAvatarPath, imageLoader)) .setIcon(bitmapLoader.getUserIcon(event.senderAvatarPath, imageLoader))
.setKey(event.senderId.value) .setKey(key)
.build() .build()
} }
when { when {

View file

@ -52,7 +52,8 @@ data class NotifiableMessageEvent(
val outGoingMessageFailed: Boolean = false, val outGoingMessageFailed: Boolean = false,
override val isRedacted: Boolean = false, override val isRedacted: Boolean = false,
override val isUpdated: Boolean = false, override val isUpdated: Boolean = false,
val type: String = EventType.MESSAGE val type: String = EventType.MESSAGE,
val hasMentionOrReply: Boolean = false,
) : NotifiableEvent { ) : NotifiableEvent {
override val description: String = body ?: "" override val description: String = body ?: ""

View file

@ -123,7 +123,7 @@ class DefaultNotifiableEventResolverTest {
) )
) )
val result = sut.resolveEvent(A_SESSION_ID, A_ROOM_ID, AN_EVENT_ID) val result = sut.resolveEvent(A_SESSION_ID, A_ROOM_ID, AN_EVENT_ID)
val expectedResult = createNotifiableMessageEvent(body = "Mentioned you: Hello world") val expectedResult = createNotifiableMessageEvent(body = "Hello world", hasMentionOrReply = true)
assertThat(result).isEqualTo(expectedResult) assertThat(result).isEqualTo(expectedResult)
} }
@ -687,7 +687,10 @@ class DefaultNotifiableEventResolverTest {
) )
} }
private fun createNotifiableMessageEvent(body: String): NotifiableMessageEvent { private fun createNotifiableMessageEvent(
body: String,
hasMentionOrReply: Boolean = false,
): NotifiableMessageEvent {
return NotifiableMessageEvent( return NotifiableMessageEvent(
sessionId = A_SESSION_ID, sessionId = A_SESSION_ID,
roomId = A_ROOM_ID, roomId = A_ROOM_ID,
@ -708,7 +711,8 @@ class DefaultNotifiableEventResolverTest {
outGoingMessage = false, outGoingMessage = false,
outGoingMessageFailed = false, outGoingMessageFailed = false,
isRedacted = false, isRedacted = false,
isUpdated = false isUpdated = false,
hasMentionOrReply = hasMentionOrReply,
) )
} }
} }

View file

@ -112,6 +112,7 @@
<string name="action_tap_for_options">"Tap for options"</string> <string name="action_tap_for_options">"Tap for options"</string>
<string name="action_try_again">"Try again"</string> <string name="action_try_again">"Try again"</string>
<string name="action_unpin">"Unpin"</string> <string name="action_unpin">"Unpin"</string>
<string name="action_view_in_timeline">"View in timeline"</string>
<string name="action_view_source">"View source"</string> <string name="action_view_source">"View source"</string>
<string name="action_yes">"Yes"</string> <string name="action_yes">"Yes"</string>
<string name="common_about">"About"</string> <string name="common_about">"About"</string>
@ -177,6 +178,7 @@ Reason: %1$s."</string>
<string name="common_people">"People"</string> <string name="common_people">"People"</string>
<string name="common_permalink">"Permalink"</string> <string name="common_permalink">"Permalink"</string>
<string name="common_permission">"Permission"</string> <string name="common_permission">"Permission"</string>
<string name="common_pinned">"Pinned"</string>
<string name="common_please_wait">"Please wait…"</string> <string name="common_please_wait">"Please wait…"</string>
<string name="common_poll_end_confirmation">"Are you sure you want to end this poll?"</string> <string name="common_poll_end_confirmation">"Are you sure you want to end this poll?"</string>
<string name="common_poll_summary">"Poll: %1$s"</string> <string name="common_poll_summary">"Poll: %1$s"</string>