Remove any notification of a redacted event (#563)
Also do some cleanup and kotlinification on the code
This commit is contained in:
parent
6f09eea248
commit
7da9cafcc2
|
@ -7,6 +7,7 @@ Features:
|
|||
Improvements:
|
||||
- Add unread indent on room list (#485)
|
||||
- Message Editing: Update notifications (#128)
|
||||
- Remove any notification of a redacted event (#563)
|
||||
|
||||
Other changes:
|
||||
-
|
||||
|
|
|
@ -43,6 +43,7 @@ interface PushRuleService {
|
|||
interface PushRuleListener {
|
||||
fun onMatchRule(event: Event, actions: List<Action>)
|
||||
fun onRoomLeft(roomId: String)
|
||||
fun onEventRedacted(redactedEventId: String)
|
||||
fun batchFinish()
|
||||
}
|
||||
}
|
|
@ -132,6 +132,16 @@ internal class DefaultPushRuleService @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
fun dispatchRedactedEventId(redactedEventId: String) {
|
||||
try {
|
||||
listeners.forEach {
|
||||
it.onEventRedacted(redactedEventId)
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
Timber.e(e, "Error while dispatching room left")
|
||||
}
|
||||
}
|
||||
|
||||
fun dispatchFinish() {
|
||||
try {
|
||||
listeners.forEach {
|
||||
|
|
|
@ -78,6 +78,25 @@ internal class DefaultProcessEventForPushTask @Inject constructor(
|
|||
defaultPushRuleService.dispatchBing(event, it)
|
||||
}
|
||||
}
|
||||
|
||||
val allRedactedEvents = params.syncResponse.join
|
||||
.map { entries ->
|
||||
entries.value.timeline?.events?.filter {
|
||||
it.type == EventType.REDACTION
|
||||
}
|
||||
.orEmpty()
|
||||
.mapNotNull { it.redacts }
|
||||
}
|
||||
.fold(emptyList<String>(), { acc, next ->
|
||||
acc + next
|
||||
})
|
||||
|
||||
Timber.v("[PushRules] Found ${allRedactedEvents.size} redacted events")
|
||||
|
||||
allRedactedEvents.forEach { redactedEventId ->
|
||||
defaultPushRuleService.dispatchRedactedEventId(redactedEventId)
|
||||
}
|
||||
|
||||
defaultPushRuleService.dispatchFinish()
|
||||
}
|
||||
|
||||
|
|
|
@ -196,7 +196,6 @@ class VectorFirebaseMessagingService : FirebaseMessagingService() {
|
|||
// This ID can and should be used to detect duplicate notification requests.
|
||||
val eventId = data["event_id"] ?: return //Just ignore
|
||||
|
||||
|
||||
val eventType = data["type"]
|
||||
if (eventType == null) {
|
||||
//Just add a generic unknown event
|
||||
|
@ -214,10 +213,7 @@ class VectorFirebaseMessagingService : FirebaseMessagingService() {
|
|||
)
|
||||
notificationDrawerManager.onNotifiableEventReceived(simpleNotifiableEvent)
|
||||
notificationDrawerManager.refreshNotificationDrawer()
|
||||
|
||||
return
|
||||
} else {
|
||||
|
||||
val event = parseEvent(data) ?: return
|
||||
|
||||
val notifiableEvent = notifiableEventResolver.resolveEvent(event, session)
|
||||
|
@ -228,8 +224,6 @@ class VectorFirebaseMessagingService : FirebaseMessagingService() {
|
|||
Timber.e("--> ${event}")
|
||||
}
|
||||
} else {
|
||||
|
||||
|
||||
if (notifiableEvent is NotifiableMessageEvent) {
|
||||
if (TextUtils.isEmpty(notifiableEvent.senderName)) {
|
||||
notifiableEvent.senderName = data["sender_display_name"]
|
||||
|
@ -246,7 +240,6 @@ class VectorFirebaseMessagingService : FirebaseMessagingService() {
|
|||
notificationDrawerManager.refreshNotificationDrawer()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun findRoomNameBestEffort(data: Map<String, String>, session: Session?): String? {
|
||||
|
|
|
@ -32,6 +32,7 @@ data class InviteNotifiableEvent(
|
|||
override var isPushGatewayEvent: Boolean = false) : NotifiableEvent {
|
||||
|
||||
override var hasBeenDisplayed: Boolean = false
|
||||
override var isRedacted: Boolean = false
|
||||
override var lockScreenVisibility = NotificationCompat.VISIBILITY_PUBLIC
|
||||
|
||||
}
|
|
@ -31,6 +31,7 @@ interface NotifiableEvent : Serializable {
|
|||
// Compat: Only for android <7, for newer version the sound is defined in the channel
|
||||
var soundName: String?
|
||||
var hasBeenDisplayed: Boolean
|
||||
var isRedacted: Boolean
|
||||
//Used to know if event should be replaced with the one coming from eventstream
|
||||
var isPushGatewayEvent: Boolean
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ data class NotifiableMessageEvent(
|
|||
override var soundName: String? = null
|
||||
override var lockScreenVisibility = NotificationCompat.VISIBILITY_PUBLIC
|
||||
override var hasBeenDisplayed: Boolean = false
|
||||
override var isRedacted: Boolean = false
|
||||
|
||||
var roomAvatarPath: String? = null
|
||||
var senderAvatarPath: String? = null
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
*/
|
||||
package im.vector.riotx.features.notifications
|
||||
|
||||
import android.app.Notification
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import android.os.Handler
|
||||
|
@ -96,7 +95,6 @@ class NotificationDrawerManager @Inject constructor(private val context: Context
|
|||
notifiableEvent.noisy = false
|
||||
eventList.remove(existing)
|
||||
eventList.add(notifiableEvent)
|
||||
|
||||
} else {
|
||||
//keep the existing one, do not replace
|
||||
}
|
||||
|
@ -127,6 +125,15 @@ class NotificationDrawerManager @Inject constructor(private val context: Context
|
|||
}
|
||||
}
|
||||
|
||||
fun onEventRedacted(eventId: String) {
|
||||
synchronized(eventList) {
|
||||
eventList.filter { it.eventId == eventId }.map { notifiableEvent ->
|
||||
notifiableEvent.isRedacted = true
|
||||
notifiableEvent.hasBeenDisplayed = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Clear all known events and refresh the notification drawer
|
||||
*/
|
||||
|
@ -215,20 +222,15 @@ class NotificationDrawerManager @Inject constructor(private val context: Context
|
|||
val summaryInboxStyle = NotificationCompat.InboxStyle()
|
||||
|
||||
//group events by room to create a single MessagingStyle notif
|
||||
val roomIdToEventMap: MutableMap<String, ArrayList<NotifiableMessageEvent>> = HashMap()
|
||||
val simpleEvents: ArrayList<NotifiableEvent> = ArrayList()
|
||||
val notifications: ArrayList<Notification> = ArrayList()
|
||||
val roomIdToEventMap: MutableMap<String, MutableList<NotifiableMessageEvent>> = LinkedHashMap()
|
||||
val simpleEvents: MutableList<NotifiableEvent> = ArrayList()
|
||||
|
||||
val eventIterator = eventList.listIterator()
|
||||
while (eventIterator.hasNext()) {
|
||||
val event = eventIterator.next()
|
||||
if (event is NotifiableMessageEvent) {
|
||||
val roomId = event.roomId
|
||||
var roomEvents = roomIdToEventMap[roomId]
|
||||
if (roomEvents == null) {
|
||||
roomEvents = ArrayList()
|
||||
roomIdToEventMap[roomId] = roomEvents
|
||||
}
|
||||
val roomEvents = roomIdToEventMap.getOrPut(roomId) { ArrayList() }
|
||||
|
||||
if (shouldIgnoreMessageEventInRoom(roomId) || outdatedDetector?.isMessageOutdated(event) == true) {
|
||||
//forget this event
|
||||
|
@ -246,10 +248,10 @@ class NotificationDrawerManager @Inject constructor(private val context: Context
|
|||
|
||||
var globalLastMessageTimestamp = 0L
|
||||
|
||||
//events have been grouped
|
||||
//events have been grouped by roomId
|
||||
for ((roomId, events) in roomIdToEventMap) {
|
||||
|
||||
if (events.isEmpty()) {
|
||||
// Build the notification for the room
|
||||
if (events.isEmpty() || events.all { it.isRedacted }) {
|
||||
//Just clear this notification
|
||||
Timber.v("%%%%%%%% REFRESH NOTIFICATION DRAWER $roomId has no more events")
|
||||
NotificationUtils.cancelNotificationMessage(context, roomId, ROOM_MESSAGES_NOTIFICATION_ID)
|
||||
|
@ -280,7 +282,7 @@ class NotificationDrawerManager @Inject constructor(private val context: Context
|
|||
|
||||
for (event in events) {
|
||||
//if all events in this room have already been displayed there is no need to update it
|
||||
if (!event.hasBeenDisplayed) {
|
||||
if (!event.hasBeenDisplayed && !event.isRedacted) {
|
||||
roomEventGroupInfo.shouldBing = roomEventGroupInfo.shouldBing || event.noisy
|
||||
roomEventGroupInfo.customSound = event.soundName
|
||||
}
|
||||
|
@ -296,7 +298,9 @@ class NotificationDrawerManager @Inject constructor(private val context: Context
|
|||
style.addMessage(context.getString(R.string.notification_inline_reply_failed), event.timestamp, senderPerson)
|
||||
roomEventGroupInfo.hasSmartReplyError = true
|
||||
} else {
|
||||
style.addMessage(event.body, event.timestamp, senderPerson)
|
||||
if (!event.isRedacted) {
|
||||
style.addMessage(event.body, event.timestamp, senderPerson)
|
||||
}
|
||||
}
|
||||
event.hasBeenDisplayed = true //we can consider it as displayed
|
||||
|
||||
|
@ -356,7 +360,6 @@ class NotificationDrawerManager @Inject constructor(private val context: Context
|
|||
myUserDisplayName)
|
||||
?.let {
|
||||
//is there an id for this room?
|
||||
notifications.add(it)
|
||||
NotificationUtils.showNotificationMessage(context, roomId, ROOM_MESSAGES_NOTIFICATION_ID, it)
|
||||
}
|
||||
hasNewEvent = true
|
||||
|
@ -372,7 +375,6 @@ class NotificationDrawerManager @Inject constructor(private val context: Context
|
|||
//We build a simple event
|
||||
if (firstTime || !event.hasBeenDisplayed) {
|
||||
NotificationUtils.buildSimpleEventNotification(context, vectorPreferences, event, null, session.myUserId)?.let {
|
||||
notifications.add(it)
|
||||
NotificationUtils.showNotificationMessage(context, event.eventId, ROOM_EVENT_NOTIFICATION_ID, it)
|
||||
event.hasBeenDisplayed = true //we can consider it as displayed
|
||||
hasNewEvent = true
|
||||
|
@ -396,7 +398,7 @@ class NotificationDrawerManager @Inject constructor(private val context: Context
|
|||
// To ensure the best experience on all devices and versions, always include a group summary when you create a group
|
||||
// https://developer.android.com/training/notify-user/group
|
||||
|
||||
if (eventList.isEmpty()) {
|
||||
if (eventList.isEmpty() || eventList.all { it.isRedacted }) {
|
||||
NotificationUtils.cancelNotificationMessage(context, null, SUMMARY_NOTIFICATION_ID)
|
||||
} else {
|
||||
val nbEvents = roomIdToEventMap.size + simpleEvents.size
|
||||
|
@ -443,12 +445,11 @@ class NotificationDrawerManager @Inject constructor(private val context: Context
|
|||
}
|
||||
}
|
||||
|
||||
private fun getRoomBitmap(events: ArrayList<NotifiableMessageEvent>): Bitmap? {
|
||||
private fun getRoomBitmap(events: List<NotifiableMessageEvent>): Bitmap? {
|
||||
if (events.isEmpty()) return null
|
||||
|
||||
//Use the last event (most recent?)
|
||||
val roomAvatarPath = events.last().roomAvatarPath
|
||||
?: events.last().senderAvatarPath
|
||||
val roomAvatarPath = events.last().roomAvatarPath ?: events.last().senderAvatarPath
|
||||
|
||||
return bitmapLoader.getRoomBitmap(roomAvatarPath)
|
||||
}
|
||||
|
@ -476,14 +477,14 @@ class NotificationDrawerManager @Inject constructor(private val context: Context
|
|||
}
|
||||
}
|
||||
|
||||
private fun loadEventInfo(): ArrayList<NotifiableEvent> {
|
||||
private fun loadEventInfo(): MutableList<NotifiableEvent> {
|
||||
try {
|
||||
val file = File(context.applicationContext.cacheDir, ROOMS_NOTIFICATIONS_FILE_NAME)
|
||||
if (file.exists()) {
|
||||
FileInputStream(file).use {
|
||||
val events: ArrayList<NotifiableEvent>? = activeSessionHolder.getSafeActiveSession()?.loadSecureSecret(it, KEY_ALIAS_SECRET_STORAGE)
|
||||
if (events != null) {
|
||||
return ArrayList(events.mapNotNull { it as? NotifiableEvent })
|
||||
return events.toMutableList()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,6 +60,10 @@ class PushRuleTriggerListener @Inject constructor(
|
|||
notificationDrawerManager.clearMessageEventOfRoom(roomId)
|
||||
}
|
||||
|
||||
override fun onEventRedacted(redactedEventId: String) {
|
||||
notificationDrawerManager.onEventRedacted(redactedEventId)
|
||||
}
|
||||
|
||||
override fun batchFinish() {
|
||||
notificationDrawerManager.refreshNotificationDrawer()
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ data class SimpleNotifiableEvent(
|
|||
override var isPushGatewayEvent: Boolean = false) : NotifiableEvent {
|
||||
|
||||
override var hasBeenDisplayed: Boolean = false
|
||||
override var isRedacted: Boolean = false
|
||||
override var lockScreenVisibility = NotificationCompat.VISIBILITY_PUBLIC
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue