Do not render notification if the user has dismiss the notification.
It should not change anything, just avoid doing useless notification rendering.
This commit is contained in:
parent
3bf8093cca
commit
096c935874
5 changed files with 44 additions and 31 deletions
|
|
@ -141,7 +141,7 @@ class InviteListPresenter @Inject constructor(
|
||||||
suspend {
|
suspend {
|
||||||
client.getRoom(roomId)?.use {
|
client.getRoom(roomId)?.use {
|
||||||
it.join().getOrThrow()
|
it.join().getOrThrow()
|
||||||
notificationDrawerManager.clearMembershipNotificationForRoom(client.sessionId, roomId)
|
notificationDrawerManager.clearMembershipNotificationForRoom(client.sessionId, roomId, doRender = true)
|
||||||
analyticsService.capture(it.toAnalyticsJoinedRoom(JoinedRoom.Trigger.Invite))
|
analyticsService.capture(it.toAnalyticsJoinedRoom(JoinedRoom.Trigger.Invite))
|
||||||
}
|
}
|
||||||
roomId
|
roomId
|
||||||
|
|
@ -152,7 +152,7 @@ class InviteListPresenter @Inject constructor(
|
||||||
suspend {
|
suspend {
|
||||||
client.getRoom(roomId)?.use {
|
client.getRoom(roomId)?.use {
|
||||||
it.leave().getOrThrow()
|
it.leave().getOrThrow()
|
||||||
notificationDrawerManager.clearMembershipNotificationForRoom(client.sessionId, roomId)
|
notificationDrawerManager.clearMembershipNotificationForRoom(client.sessionId, roomId, doRender = true)
|
||||||
}.let { }
|
}.let { }
|
||||||
}.runCatchingUpdatingState(declinedAction)
|
}.runCatchingUpdatingState(declinedAction)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,5 +21,5 @@ import io.element.android.libraries.matrix.api.core.SessionId
|
||||||
|
|
||||||
interface NotificationDrawerManager {
|
interface NotificationDrawerManager {
|
||||||
fun clearMembershipNotificationForSession(sessionId: SessionId)
|
fun clearMembershipNotificationForSession(sessionId: SessionId)
|
||||||
fun clearMembershipNotificationForRoom(sessionId: SessionId, roomId: RoomId)
|
fun clearMembershipNotificationForRoom(sessionId: SessionId, roomId: RoomId, doRender: Boolean)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,11 @@ class DefaultNotificationDrawerManager @Inject constructor(
|
||||||
is NavigationState.Space -> {}
|
is NavigationState.Space -> {}
|
||||||
is NavigationState.Room -> {
|
is NavigationState.Room -> {
|
||||||
// Cleanup notification for current room
|
// Cleanup notification for current room
|
||||||
clearMessagesForRoom(navigationState.parentSpace.parentSession.sessionId, navigationState.roomId)
|
clearMessagesForRoom(
|
||||||
|
sessionId = navigationState.parentSpace.parentSession.sessionId,
|
||||||
|
roomId = navigationState.roomId,
|
||||||
|
doRender = true,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
is NavigationState.Thread -> {
|
is NavigationState.Thread -> {
|
||||||
onEnteringThread(
|
onEnteringThread(
|
||||||
|
|
@ -132,7 +136,7 @@ class DefaultNotificationDrawerManager @Inject constructor(
|
||||||
* Events might be grouped and there might not be one notification per event!
|
* Events might be grouped and there might not be one notification per event!
|
||||||
*/
|
*/
|
||||||
fun onNotifiableEventReceived(notifiableEvent: NotifiableEvent) {
|
fun onNotifiableEventReceived(notifiableEvent: NotifiableEvent) {
|
||||||
updateEvents {
|
updateEvents(doRender = true) {
|
||||||
it.onNotifiableEventReceived(notifiableEvent)
|
it.onNotifiableEventReceived(notifiableEvent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -140,8 +144,8 @@ class DefaultNotificationDrawerManager @Inject constructor(
|
||||||
/**
|
/**
|
||||||
* Clear all known events and refresh the notification drawer.
|
* Clear all known events and refresh the notification drawer.
|
||||||
*/
|
*/
|
||||||
fun clearAllMessagesEvents(sessionId: SessionId) {
|
fun clearAllMessagesEvents(sessionId: SessionId, doRender: Boolean) {
|
||||||
updateEvents {
|
updateEvents(doRender = doRender) {
|
||||||
it.clearMessagesForSession(sessionId)
|
it.clearMessagesForSession(sessionId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -150,7 +154,7 @@ class DefaultNotificationDrawerManager @Inject constructor(
|
||||||
* Clear all notifications related to the session and refresh the notification drawer.
|
* Clear all notifications related to the session and refresh the notification drawer.
|
||||||
*/
|
*/
|
||||||
fun clearAllEvents(sessionId: SessionId) {
|
fun clearAllEvents(sessionId: SessionId) {
|
||||||
updateEvents {
|
updateEvents(doRender = true) {
|
||||||
it.clearAllForSession(sessionId)
|
it.clearAllForSession(sessionId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -160,14 +164,14 @@ class DefaultNotificationDrawerManager @Inject constructor(
|
||||||
* Used to ignore events related to that room (no need to display notification) and clean any existing notification on this room.
|
* Used to ignore events related to that room (no need to display notification) and clean any existing notification on this room.
|
||||||
* Can also be called when a notification for this room is dismissed by the user.
|
* Can also be called when a notification for this room is dismissed by the user.
|
||||||
*/
|
*/
|
||||||
fun clearMessagesForRoom(sessionId: SessionId, roomId: RoomId) {
|
fun clearMessagesForRoom(sessionId: SessionId, roomId: RoomId, doRender: Boolean) {
|
||||||
updateEvents {
|
updateEvents(doRender = doRender) {
|
||||||
it.clearMessagesForRoom(sessionId, roomId)
|
it.clearMessagesForRoom(sessionId, roomId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun clearMembershipNotificationForSession(sessionId: SessionId) {
|
override fun clearMembershipNotificationForSession(sessionId: SessionId) {
|
||||||
updateEvents {
|
updateEvents(doRender = true) {
|
||||||
it.clearMembershipNotificationForSession(sessionId)
|
it.clearMembershipNotificationForSession(sessionId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -175,8 +179,12 @@ class DefaultNotificationDrawerManager @Inject constructor(
|
||||||
/**
|
/**
|
||||||
* Clear invitation notification for the provided room.
|
* Clear invitation notification for the provided room.
|
||||||
*/
|
*/
|
||||||
override fun clearMembershipNotificationForRoom(sessionId: SessionId, roomId: RoomId) {
|
override fun clearMembershipNotificationForRoom(
|
||||||
updateEvents {
|
sessionId: SessionId,
|
||||||
|
roomId: RoomId,
|
||||||
|
doRender: Boolean,
|
||||||
|
) {
|
||||||
|
updateEvents(doRender = doRender) {
|
||||||
it.clearMembershipNotificationForRoom(sessionId, roomId)
|
it.clearMembershipNotificationForRoom(sessionId, roomId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -184,8 +192,8 @@ class DefaultNotificationDrawerManager @Inject constructor(
|
||||||
/**
|
/**
|
||||||
* Clear the notifications for a single event.
|
* Clear the notifications for a single event.
|
||||||
*/
|
*/
|
||||||
fun clearEvent(eventId: EventId) {
|
fun clearEvent(eventId: EventId, doRender: Boolean) {
|
||||||
updateEvents {
|
updateEvents(doRender = doRender) {
|
||||||
it.clearEvent(eventId)
|
it.clearEvent(eventId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -195,14 +203,14 @@ class DefaultNotificationDrawerManager @Inject constructor(
|
||||||
* Used to ignore events related to that thread (no need to display notification) and clean any existing notification on this room.
|
* Used to ignore events related to that thread (no need to display notification) and clean any existing notification on this room.
|
||||||
*/
|
*/
|
||||||
private fun onEnteringThread(sessionId: SessionId, roomId: RoomId, threadId: ThreadId) {
|
private fun onEnteringThread(sessionId: SessionId, roomId: RoomId, threadId: ThreadId) {
|
||||||
updateEvents {
|
updateEvents(doRender = true) {
|
||||||
it.clearMessagesForThread(sessionId, roomId, threadId)
|
it.clearMessagesForThread(sessionId, roomId, threadId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO EAx Must be per account
|
// TODO EAx Must be per account
|
||||||
fun notificationStyleChanged() {
|
fun notificationStyleChanged() {
|
||||||
updateEvents {
|
updateEvents(doRender = true) {
|
||||||
val newSettings = true // pushDataStore.useCompleteNotificationFormat()
|
val newSettings = true // pushDataStore.useCompleteNotificationFormat()
|
||||||
if (newSettings != useCompleteNotificationFormat) {
|
if (newSettings != useCompleteNotificationFormat) {
|
||||||
// Settings has changed, remove all current notifications
|
// Settings has changed, remove all current notifications
|
||||||
|
|
@ -212,21 +220,24 @@ class DefaultNotificationDrawerManager @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateEvents(action: DefaultNotificationDrawerManager.(NotificationEventQueue) -> Unit) {
|
private fun updateEvents(
|
||||||
|
doRender: Boolean,
|
||||||
|
action: DefaultNotificationDrawerManager.(NotificationEventQueue) -> Unit,
|
||||||
|
) {
|
||||||
notificationState.updateQueuedEvents(this) { queuedEvents, _ ->
|
notificationState.updateQueuedEvents(this) { queuedEvents, _ ->
|
||||||
action(queuedEvents)
|
action(queuedEvents)
|
||||||
}
|
}
|
||||||
coroutineScope.refreshNotificationDrawer()
|
coroutineScope.refreshNotificationDrawer(doRender)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun CoroutineScope.refreshNotificationDrawer() = launch {
|
private fun CoroutineScope.refreshNotificationDrawer(doRender: Boolean) = launch {
|
||||||
// Implement last throttler
|
// Implement last throttler
|
||||||
val canHandle = firstThrottler.canHandle()
|
val canHandle = firstThrottler.canHandle()
|
||||||
Timber.v("refreshNotificationDrawer(), delay: ${canHandle.waitMillis()} ms")
|
Timber.v("refreshNotificationDrawer(), delay: ${canHandle.waitMillis()} ms")
|
||||||
withContext(dispatchers.io) {
|
withContext(dispatchers.io) {
|
||||||
delay(canHandle.waitMillis())
|
delay(canHandle.waitMillis())
|
||||||
try {
|
try {
|
||||||
refreshNotificationDrawerBg()
|
refreshNotificationDrawerBg(doRender)
|
||||||
} catch (throwable: Throwable) {
|
} catch (throwable: Throwable) {
|
||||||
// It can happen if for instance session has been destroyed. It's a bit ugly to try catch like this, but it's safer
|
// It can happen if for instance session has been destroyed. It's a bit ugly to try catch like this, but it's safer
|
||||||
Timber.w(throwable, "refreshNotificationDrawerBg failure")
|
Timber.w(throwable, "refreshNotificationDrawerBg failure")
|
||||||
|
|
@ -234,7 +245,7 @@ class DefaultNotificationDrawerManager @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun refreshNotificationDrawerBg() {
|
private suspend fun refreshNotificationDrawerBg(doRender: Boolean) {
|
||||||
Timber.v("refreshNotificationDrawerBg()")
|
Timber.v("refreshNotificationDrawerBg()")
|
||||||
val eventsToRender = notificationState.updateQueuedEvents(this) { queuedEvents, renderedEvents ->
|
val eventsToRender = notificationState.updateQueuedEvents(this) { queuedEvents, renderedEvents ->
|
||||||
notifiableEventProcessor.process(queuedEvents.rawEvents(), renderedEvents).also {
|
notifiableEventProcessor.process(queuedEvents.rawEvents(), renderedEvents).also {
|
||||||
|
|
@ -246,7 +257,9 @@ class DefaultNotificationDrawerManager @Inject constructor(
|
||||||
Timber.d("Skipping notification update due to event list not changing")
|
Timber.d("Skipping notification update due to event list not changing")
|
||||||
} else {
|
} else {
|
||||||
notificationState.clearAndAddRenderedEvents(eventsToRender)
|
notificationState.clearAndAddRenderedEvents(eventsToRender)
|
||||||
renderEvents(eventsToRender)
|
if (doRender) {
|
||||||
|
renderEvents(eventsToRender)
|
||||||
|
}
|
||||||
persistEvents()
|
persistEvents()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,26 +50,26 @@ class NotificationBroadcastReceiver : BroadcastReceiver() {
|
||||||
actionIds.smartReply ->
|
actionIds.smartReply ->
|
||||||
handleSmartReply(intent, context)
|
handleSmartReply(intent, context)
|
||||||
actionIds.dismissRoom -> if (roomId != null) {
|
actionIds.dismissRoom -> if (roomId != null) {
|
||||||
defaultNotificationDrawerManager.clearMessagesForRoom(sessionId, roomId)
|
defaultNotificationDrawerManager.clearMessagesForRoom(sessionId, roomId, doRender = false)
|
||||||
}
|
}
|
||||||
actionIds.dismissSummary ->
|
actionIds.dismissSummary ->
|
||||||
defaultNotificationDrawerManager.clearAllMessagesEvents(sessionId)
|
defaultNotificationDrawerManager.clearAllMessagesEvents(sessionId, doRender = false)
|
||||||
actionIds.dismissInvite -> if (roomId != null) {
|
actionIds.dismissInvite -> if (roomId != null) {
|
||||||
defaultNotificationDrawerManager.clearMembershipNotificationForRoom(sessionId, roomId)
|
defaultNotificationDrawerManager.clearMembershipNotificationForRoom(sessionId, roomId, doRender = false)
|
||||||
}
|
}
|
||||||
actionIds.dismissEvent -> if (eventId != null) {
|
actionIds.dismissEvent -> if (eventId != null) {
|
||||||
defaultNotificationDrawerManager.clearEvent(eventId)
|
defaultNotificationDrawerManager.clearEvent(eventId, doRender = false)
|
||||||
}
|
}
|
||||||
actionIds.markRoomRead -> if (roomId != null) {
|
actionIds.markRoomRead -> if (roomId != null) {
|
||||||
defaultNotificationDrawerManager.clearMessagesForRoom(sessionId, roomId)
|
defaultNotificationDrawerManager.clearMessagesForRoom(sessionId, roomId, doRender = true)
|
||||||
handleMarkAsRead(sessionId, roomId)
|
handleMarkAsRead(sessionId, roomId)
|
||||||
}
|
}
|
||||||
actionIds.join -> if (roomId != null) {
|
actionIds.join -> if (roomId != null) {
|
||||||
defaultNotificationDrawerManager.clearMembershipNotificationForRoom(sessionId, roomId)
|
defaultNotificationDrawerManager.clearMembershipNotificationForRoom(sessionId, roomId, doRender = true)
|
||||||
handleJoinRoom(sessionId, roomId)
|
handleJoinRoom(sessionId, roomId)
|
||||||
}
|
}
|
||||||
actionIds.reject -> if (roomId != null) {
|
actionIds.reject -> if (roomId != null) {
|
||||||
defaultNotificationDrawerManager.clearMembershipNotificationForRoom(sessionId, roomId)
|
defaultNotificationDrawerManager.clearMembershipNotificationForRoom(sessionId, roomId, doRender = true)
|
||||||
handleRejectRoom(sessionId, roomId)
|
handleRejectRoom(sessionId, roomId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ class FakeNotificationDrawerManager : NotificationDrawerManager {
|
||||||
clearMemberShipNotificationForSessionCallsCount.merge(sessionId.value, 1) { oldValue, value -> oldValue + value }
|
clearMemberShipNotificationForSessionCallsCount.merge(sessionId.value, 1) { oldValue, value -> oldValue + value }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun clearMembershipNotificationForRoom(sessionId: SessionId, roomId: RoomId) {
|
override fun clearMembershipNotificationForRoom(sessionId: SessionId, roomId: RoomId, doRender: Boolean) {
|
||||||
val key = getMembershipNotificationKey(sessionId, roomId)
|
val key = getMembershipNotificationKey(sessionId, roomId)
|
||||||
clearMemberShipNotificationForRoomCallsCount.merge(key, 1) { oldValue, value -> oldValue + value }
|
clearMemberShipNotificationForRoomCallsCount.merge(key, 1) { oldValue, value -> oldValue + value }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue