Hide message notification content when the app is locked (#6902)
* Hide message notification content by default when the app is locked * Make this the default without an option * Fix test * Update DefaultNotificationDrawerManager.kt * Fix
This commit is contained in:
+50
-1
@@ -11,6 +11,7 @@ package io.element.android.libraries.push.impl.notifications
|
||||
import dev.zacsweers.metro.AppScope
|
||||
import dev.zacsweers.metro.ContributesBinding
|
||||
import dev.zacsweers.metro.SingleIn
|
||||
import io.element.android.features.lockscreen.api.LockScreenService
|
||||
import io.element.android.libraries.di.annotations.AppCoroutineScope
|
||||
import io.element.android.libraries.matrix.api.MatrixClientProvider
|
||||
import io.element.android.libraries.matrix.api.core.EventId
|
||||
@@ -37,6 +38,7 @@ import io.element.android.services.appnavstate.api.currentRoomId
|
||||
import io.element.android.services.appnavstate.api.currentSessionId
|
||||
import io.element.android.services.appnavstate.api.currentThreadId
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
/**
|
||||
@@ -55,6 +57,7 @@ class DefaultNotificationDrawerManager(
|
||||
private val matrixClientProvider: MatrixClientProvider,
|
||||
private val imageLoaderHolder: ImageLoaderHolder,
|
||||
private val activeNotificationsProvider: ActiveNotificationsProvider,
|
||||
private val lockScreenService: LockScreenService,
|
||||
sessionObserver: SessionObserver,
|
||||
) : NotificationCleaner {
|
||||
// TODO EAx add a setting per user for this
|
||||
@@ -197,6 +200,8 @@ class DefaultNotificationDrawerManager(
|
||||
it.sessionId
|
||||
}
|
||||
|
||||
val isAppLocked = lockScreenService.isPinSetup().first()
|
||||
|
||||
for ((sessionId, notifiableEvents) in eventsForSessions) {
|
||||
val client = matrixClientProvider.getOrRestore(sessionId).getOrThrow()
|
||||
val imageLoader = imageLoaderHolder.get(client)
|
||||
@@ -207,7 +212,25 @@ class DefaultNotificationDrawerManager(
|
||||
} else {
|
||||
client.getUserProfile().getOrNull() ?: MatrixUser(sessionId)
|
||||
}
|
||||
notificationRenderer.render(currentUser, useCompleteNotificationFormat, notifiableEvents, imageLoader)
|
||||
if (isAppLocked) {
|
||||
// When the app is locked, show a single fallback notification with event count
|
||||
// instead of per-room notifications with message content/sender info.
|
||||
clearAllMessagesEvents(sessionId)
|
||||
val fallbackEvents = notifiableEvents.mapNotNull { it.toFallbackNotifiableEvent() }
|
||||
notificationRenderer.render(
|
||||
currentUser = currentUser,
|
||||
useCompleteNotificationFormat = false,
|
||||
eventsToProcess = fallbackEvents,
|
||||
imageLoader = imageLoader,
|
||||
)
|
||||
} else {
|
||||
notificationRenderer.render(
|
||||
currentUser = currentUser,
|
||||
useCompleteNotificationFormat = useCompleteNotificationFormat,
|
||||
eventsToProcess = notifiableEvents,
|
||||
imageLoader = imageLoader,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -238,3 +261,29 @@ private fun AppNavigationState.shouldIgnoreEvent(event: NotifiableEvent): Boolea
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a [NotifiableEvent] into a [FallbackNotifiableEvent], stripping all content and sender info.
|
||||
* Used when notification content should be hidden (app locked with PIN).
|
||||
*/
|
||||
private fun NotifiableEvent.toFallbackNotifiableEvent(): FallbackNotifiableEvent? {
|
||||
val timestamp = when (this) {
|
||||
is NotifiableMessageEvent -> timestamp
|
||||
is InviteNotifiableEvent -> timestamp
|
||||
is SimpleNotifiableEvent -> timestamp
|
||||
is FallbackNotifiableEvent -> timestamp
|
||||
is NotifiableRingingCallEvent -> return null
|
||||
}
|
||||
return FallbackNotifiableEvent(
|
||||
sessionId = sessionId,
|
||||
roomId = roomId,
|
||||
eventId = eventId,
|
||||
editedEventId = null,
|
||||
description = null,
|
||||
canBeReplaced = false,
|
||||
isRedacted = false,
|
||||
isUpdated = false,
|
||||
timestamp = timestamp,
|
||||
cause = null,
|
||||
)
|
||||
}
|
||||
|
||||
+1
-1
@@ -67,7 +67,7 @@ class DefaultRoomGroupMessageCreator(
|
||||
val roomIsDm = !roomIsGroup
|
||||
return notificationCreator.createMessagesListNotification(
|
||||
notificationAccountParams = notificationAccountParams,
|
||||
RoomEventGroupInfo(
|
||||
roomInfo = RoomEventGroupInfo(
|
||||
sessionId = notificationAccountParams.user.userId,
|
||||
roomId = roomId,
|
||||
roomDisplayName = roomName,
|
||||
|
||||
+4
@@ -13,6 +13,8 @@ import androidx.compose.ui.graphics.Color
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import io.element.android.features.enterprise.api.EnterpriseService
|
||||
import io.element.android.features.enterprise.test.FakeEnterpriseService
|
||||
import io.element.android.features.lockscreen.api.LockScreenService
|
||||
import io.element.android.features.lockscreen.test.FakeLockScreenService
|
||||
import io.element.android.libraries.matrix.test.AN_EVENT_ID
|
||||
import io.element.android.libraries.matrix.test.A_ROOM_ID
|
||||
import io.element.android.libraries.matrix.test.A_ROOM_ID_2
|
||||
@@ -510,6 +512,7 @@ fun TestScope.createDefaultNotificationDrawerManager(
|
||||
enterpriseService: EnterpriseService = FakeEnterpriseService(),
|
||||
sessionObserver: SessionObserver = FakeSessionObserver(),
|
||||
analyticsService: FakeAnalyticsService = FakeAnalyticsService(),
|
||||
lockScreenService: LockScreenService = FakeLockScreenService(),
|
||||
): DefaultNotificationDrawerManager {
|
||||
return DefaultNotificationDrawerManager(
|
||||
notificationDisplayer = notificationDisplayer,
|
||||
@@ -530,6 +533,7 @@ fun TestScope.createDefaultNotificationDrawerManager(
|
||||
matrixClientProvider = matrixClientProvider,
|
||||
imageLoaderHolder = FakeImageLoaderHolder(),
|
||||
activeNotificationsProvider = activeNotificationsProvider,
|
||||
lockScreenService = lockScreenService,
|
||||
sessionObserver = sessionObserver,
|
||||
)
|
||||
}
|
||||
|
||||
+11
-1
@@ -57,7 +57,17 @@ class FakeNotificationCreator(
|
||||
events: List<NotifiableMessageEvent>,
|
||||
): Notification {
|
||||
return createMessagesListNotificationResult(
|
||||
listOf(notificationAccountParams, roomInfo, threadId, largeIcon, lastMessageTimestamp, tickerText, existingNotification, imageLoader, events)
|
||||
listOf(
|
||||
notificationAccountParams,
|
||||
roomInfo,
|
||||
threadId,
|
||||
largeIcon,
|
||||
lastMessageTimestamp,
|
||||
tickerText,
|
||||
existingNotification,
|
||||
imageLoader,
|
||||
events,
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
-1
@@ -56,7 +56,6 @@ class UserPushStoreDataStore(
|
||||
private val currentPushKey = stringPreferencesKey("currentPushKey")
|
||||
private val notificationEnabled = booleanPreferencesKey("notificationEnabled")
|
||||
private val ignoreRegistrationError = booleanPreferencesKey("ignoreRegistrationError")
|
||||
|
||||
override suspend fun getPushProviderName(): String? {
|
||||
return store.data.first()[pushProviderName]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user