Merge pull request #562 from vector-im/feature/notification_edited

Message Editing: Update notifications (#128)
This commit is contained in:
Benoit Marty 2019-09-19 12:59:10 +02:00 committed by GitHub
commit 6f09eea248
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 59 additions and 7 deletions

View file

@ -6,6 +6,7 @@ Features:
Improvements:
- Add unread indent on room list (#485)
- Message Editing: Update notifications (#128)
Other changes:
-

View file

@ -18,6 +18,7 @@ package im.vector.matrix.android.api.session.room.timeline
import im.vector.matrix.android.api.session.events.model.Event
import im.vector.matrix.android.api.session.events.model.EventType
import im.vector.matrix.android.api.session.events.model.RelationType
import im.vector.matrix.android.api.session.events.model.toModel
import im.vector.matrix.android.api.session.room.model.EventAnnotationsSummary
import im.vector.matrix.android.api.session.room.model.ReadReceipt
@ -92,6 +93,13 @@ data class TimelineEvent(
*/
fun TimelineEvent.hasBeenEdited() = annotations?.editSummary != null
/**
* Get the eventId which was edited by this event if any
*/
fun TimelineEvent.getEditedEventId(): String? {
return root.getClearContent().toModel<MessageContent>()?.relatesTo?.takeIf { it.type == RelationType.REPLACE }?.eventId
}
/**
* Get last MessageContent, after a possible edition
*/
@ -99,6 +107,20 @@ fun TimelineEvent.getLastMessageContent(): MessageContent? = annotations?.editSu
?: root.getClearContent().toModel()
/**
* Get last Message body, after a possible edition
*/
fun TimelineEvent.getLastMessageBody(): String? {
val lastMessageContent = getLastMessageContent()
if (lastMessageContent != null) {
return lastMessageContent.newContent?.toModel<MessageContent>()?.body ?: lastMessageContent.body
}
return null
}
fun TimelineEvent.getTextEditableContent(): String? {
val originalContent = root.getClearContent().toModel<MessageContent>() ?: return null
val isReply = originalContent.isReply() || root.content.toModel<EncryptedEventContent>()?.relatesTo?.inReplyTo?.eventId != null

View file

@ -203,6 +203,7 @@ class VectorFirebaseMessagingService : FirebaseMessagingService() {
val simpleNotifiableEvent = SimpleNotifiableEvent(
session.myUserId,
eventId,
null,
true, //It's an issue in this case, all event will bing even if expected to be silent.
title = getString(R.string.notification_unknown_new_event),
description = "",

View file

@ -21,6 +21,7 @@ import androidx.core.app.NotificationCompat
data class InviteNotifiableEvent(
override var matrixID: String?,
override val eventId: String,
override val editedEventId: String?,
var roomId: String,
override var noisy: Boolean,
override val title: String,

View file

@ -20,6 +20,7 @@ import java.io.Serializable
interface NotifiableEvent : Serializable {
var matrixID: String?
val eventId: String
val editedEventId: String?
var noisy: Boolean
val title: String
val description: String?

View file

@ -25,7 +25,8 @@ import im.vector.matrix.android.api.session.events.model.toModel
import im.vector.matrix.android.api.session.room.model.Membership
import im.vector.matrix.android.api.session.room.model.RoomMember
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
import im.vector.matrix.android.api.session.room.timeline.getLastMessageContent
import im.vector.matrix.android.api.session.room.timeline.getEditedEventId
import im.vector.matrix.android.api.session.room.timeline.getLastMessageBody
import im.vector.matrix.android.internal.crypto.algorithms.olm.OlmDecryptionResult
import im.vector.riotx.BuildConfig
import im.vector.riotx.R
@ -72,6 +73,7 @@ class NotifiableEventResolver @Inject constructor(private val stringProvider: St
return SimpleNotifiableEvent(
session.myUserId,
eventId = event.eventId!!,
editedEventId = timelineEvent.getEditedEventId(),
noisy = false,//will be updated
timestamp = event.originServerTs ?: System.currentTimeMillis(),
description = bodyPreview,
@ -82,7 +84,6 @@ class NotifiableEventResolver @Inject constructor(private val stringProvider: St
}
}
private fun resolveMessageEvent(event: TimelineEvent, session: Session): NotifiableEvent? {
//The event only contains an eventId, and roomId (type is m.room.*) , we need to get the displayable content (names, avatar, text, etc...)
@ -93,14 +94,14 @@ class NotifiableEventResolver @Inject constructor(private val stringProvider: St
Timber.e("## Unable to resolve room for eventId [${event}]")
// Ok room is not known in store, but we can still display something
val body =
event.getLastMessageContent()
?.body
event.getLastMessageBody()
?: stringProvider.getString(R.string.notification_unknown_new_event)
val roomName = stringProvider.getString(R.string.notification_unknown_room_name)
val senderDisplayName = event.senderName ?: event.root.senderId
val notifiableEvent = NotifiableMessageEvent(
eventId = event.root.eventId!!,
editedEventId = event.getEditedEventId(),
timestamp = event.root.originServerTs ?: 0,
noisy = false,//will be updated
senderName = senderDisplayName,
@ -128,14 +129,14 @@ class NotifiableEventResolver @Inject constructor(private val stringProvider: St
}
}
val body = event.getLastMessageContent()
?.body
val body = event.getLastMessageBody()
?: stringProvider.getString(R.string.notification_unknown_new_event)
val roomName = room.roomSummary()?.displayName ?: ""
val senderDisplayName = event.senderName ?: event.root.senderId
val notifiableEvent = NotifiableMessageEvent(
eventId = event.root.eventId!!,
editedEventId = event.getEditedEventId(),
timestamp = event.root.originServerTs ?: 0,
noisy = false,//will be updated
senderName = senderDisplayName,
@ -177,6 +178,7 @@ class NotifiableEventResolver @Inject constructor(private val stringProvider: St
return InviteNotifiableEvent(
session.myUserId,
eventId = event.eventId!!,
editedEventId = null,
roomId = roomId,
timestamp = event.originServerTs ?: 0,
noisy = false,//will be set later

View file

@ -20,6 +20,7 @@ import im.vector.matrix.android.api.session.events.model.EventType
data class NotifiableMessageEvent(
override val eventId: String,
override val editedEventId: String?,
override var noisy: Boolean,
override val timestamp: Long,
var senderName: String?,

View file

@ -119,6 +119,7 @@ class NotificationBroadcastReceiver : BroadcastReceiver() {
val notifiableMessageEvent = NotifiableMessageEvent(
// Generate a Fake event id
UUID.randomUUID().toString(),
null,
false,
System.currentTimeMillis(),
session.getUser(session.myUserId)?.displayName

View file

@ -101,7 +101,28 @@ class NotificationDrawerManager @Inject constructor(private val context: Context
//keep the existing one, do not replace
}
} else {
// Check if this is an edit
if (notifiableEvent.editedEventId != null) {
// This is an edition
val eventBeforeEdition = eventList.firstOrNull {
// Edition of an event
it.eventId == notifiableEvent.editedEventId
// or edition of an edition
|| it.editedEventId == notifiableEvent.editedEventId
}
if (eventBeforeEdition != null) {
// Replace the existing notification with the new content
eventList.remove(eventBeforeEdition)
eventList.add(notifiableEvent)
} else {
// Ignore an edit of a not displayed event in the notification drawer
}
} else {
// Not an edit
eventList.add(notifiableEvent)
}
}
}
}

View file

@ -20,6 +20,7 @@ import androidx.core.app.NotificationCompat
data class SimpleNotifiableEvent(
override var matrixID: String?,
override val eventId: String,
override val editedEventId: String?,
override var noisy: Boolean,
override val title: String,
override val description: String,