Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Splitting notifications into separate creation and displaying passes #4185

Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,4 @@ data class InviteNotifiableEvent(
val timestamp: Long,
val soundName: String?,
override val isRedacted: Boolean = false
) : NotifiableEvent {

override var hasBeenDisplayed = false
}
) : NotifiableEvent
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import java.io.Serializable
sealed interface NotifiableEvent : Serializable {
val eventId: String
val editedEventId: String?
var hasBeenDisplayed: Boolean

// Used to know if event should be replaced with the one coming from eventstream
val canBeReplaced: Boolean
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* Copyright (c) 2021 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package im.vector.app.features.notifications

import im.vector.app.features.invite.AutoAcceptInvites
import timber.log.Timber
import javax.inject.Inject

class NotifiableEventProcessor @Inject constructor(
private val outdatedDetector: OutdatedEventDetector,
private val autoAcceptInvites: AutoAcceptInvites
) {

fun modifyAndProcess(eventList: MutableList<NotifiableEvent>, currentRoomId: String?): ProcessedNotificationEvents {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

val roomIdToEventMap: MutableMap<String, MutableList<NotifiableMessageEvent>> = LinkedHashMap()
val simpleEvents: MutableMap<String, SimpleNotifiableEvent?> = LinkedHashMap()
val invitationEvents: MutableMap<String, InviteNotifiableEvent?> = LinkedHashMap()

val eventIterator = eventList.listIterator()
while (eventIterator.hasNext()) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can further improve this by only calculating the diff between what we've rendered and the new eventList state

when (val event = eventIterator.next()) {
is NotifiableMessageEvent -> {
val roomId = event.roomId
val roomEvents = roomIdToEventMap.getOrPut(roomId) { ArrayList() }

// should we limit to last 7 messages per room?
if (shouldIgnoreMessageEventInRoom(currentRoomId, roomId) || outdatedDetector.isMessageOutdated(event)) {
// forget this event
eventIterator.remove()
} else {
roomEvents.add(event)
}
}
is InviteNotifiableEvent -> {
if (autoAcceptInvites.hideInvites) {
// Forget this event
eventIterator.remove()
invitationEvents[event.roomId] = null
} else {
invitationEvents[event.roomId] = event
}
}
is SimpleNotifiableEvent -> simpleEvents[event.eventId] = event
else -> Timber.w("Type not handled")
}
}
return ProcessedNotificationEvents(roomIdToEventMap, simpleEvents, invitationEvents)
}

private fun shouldIgnoreMessageEventInRoom(currentRoomId: String?, roomId: String?): Boolean {
return currentRoomId != null && roomId == currentRoomId
}
}

data class ProcessedNotificationEvents(
val roomEvents: Map<String, List<NotifiableMessageEvent>>,
val simpleEvents: Map<String, SimpleNotifiableEvent?>,
val invitationEvents: Map<String, InviteNotifiableEvent?>
)
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,6 @@ data class NotifiableMessageEvent(
override val isRedacted: Boolean = false
) : NotifiableEvent {

override var hasBeenDisplayed: Boolean = false

val type: String = EventType.MESSAGE
val description: String = body ?: ""
val title: String = senderName ?: ""
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright (c) 2021 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package im.vector.app.features.notifications

import android.app.Notification
import android.content.Context
import androidx.core.app.NotificationManagerCompat
import timber.log.Timber
import javax.inject.Inject

class NotificationDisplayer @Inject constructor(context: Context) {

private val notificationManager = NotificationManagerCompat.from(context)

fun showNotificationMessage(tag: String?, id: Int, notification: Notification) {
notificationManager.notify(tag, id, notification)
}

fun cancelNotificationMessage(tag: String?, id: Int) {
notificationManager.cancel(tag, id)
}

fun cancelAllNotifications() {
// Keep this try catch (reported by GA)
try {
notificationManager.cancelAll()
} catch (e: Exception) {
Timber.e(e, "## cancelAllNotifications() failed")
}
}
}
Loading