Push: обработка read-событий в тихих уведомлениях
This commit is contained in:
@@ -73,10 +73,13 @@ class RosettaFirebaseMessagingService : FirebaseMessagingService() {
|
||||
val variants = buildDialogKeyVariants(senderPublicKey)
|
||||
for (key in variants) {
|
||||
notificationManager.cancel(getNotificationIdForChat(key))
|
||||
lastNotifTimestamps.remove(key)
|
||||
}
|
||||
// Fallback: некоторые серверные payload могут прийти без sender key.
|
||||
// Для них используется ID от пустой строки — тоже очищаем при входе в диалог.
|
||||
notificationManager.cancel(getNotificationIdForChat(""))
|
||||
lastNotifTimestamps.remove("__no_sender__")
|
||||
lastNotifTimestamps.remove("__simple__")
|
||||
}
|
||||
|
||||
private fun buildDialogKeyVariants(rawKey: String): Set<String> {
|
||||
@@ -196,8 +199,14 @@ class RosettaFirebaseMessagingService : FirebaseMessagingService() {
|
||||
|
||||
when {
|
||||
isReadEvent -> {
|
||||
if (!dialogKey.isNullOrBlank()) {
|
||||
cancelNotificationForChat(applicationContext, dialogKey)
|
||||
val keysToClear = collectReadDialogKeys(data, dialogKey, senderPublicKey)
|
||||
if (keysToClear.isEmpty()) {
|
||||
Log.d(TAG, "READ push received but no dialog key in payload: $data")
|
||||
} else {
|
||||
keysToClear.forEach { key ->
|
||||
cancelNotificationForChat(applicationContext, key)
|
||||
}
|
||||
Log.d(TAG, "READ push cleared notifications for keys=$keysToClear")
|
||||
}
|
||||
handledByData = true
|
||||
}
|
||||
@@ -541,6 +550,44 @@ class RosettaFirebaseMessagingService : FirebaseMessagingService() {
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a robust list of dialog keys for silent READ pushes.
|
||||
* Server payloads may evolve (dialog/from/to/peer/group_* aliases), so we parse
|
||||
* all known aliases and exclude current account public key.
|
||||
*/
|
||||
private fun collectReadDialogKeys(
|
||||
data: Map<String, String>,
|
||||
parsedDialogKey: String?,
|
||||
parsedSenderKey: String?
|
||||
): Set<String> {
|
||||
val currentAccount = AccountManager(applicationContext).getLastLoggedPublicKey().orEmpty().trim()
|
||||
val candidates = linkedSetOf<String>()
|
||||
|
||||
fun addCandidate(raw: String?) {
|
||||
val value = raw?.trim().orEmpty()
|
||||
if (value.isBlank()) return
|
||||
if (currentAccount.isNotBlank() && value == currentAccount) return
|
||||
candidates.add(value)
|
||||
}
|
||||
|
||||
addCandidate(parsedDialogKey)
|
||||
addCandidate(parsedSenderKey)
|
||||
addCandidate(firstNonBlank(data, "dialog", "dialog_key", "dialogPublicKey", "dialog_public_key"))
|
||||
addCandidate(firstNonBlank(data, "peer", "peer_key", "peerPublicKey", "peer_public_key", "chat", "chat_key"))
|
||||
addCandidate(firstNonBlank(data, "to", "toPublicKey", "to_public_key", "dst", "dst_public_key"))
|
||||
addCandidate(firstNonBlank(data, "from", "fromPublicKey", "from_public_key", "src", "src_public_key"))
|
||||
|
||||
// Group aliases from some server payloads
|
||||
val groupId = firstNonBlank(data, "group", "group_id", "groupId")
|
||||
if (!groupId.isNullOrBlank()) {
|
||||
addCandidate(groupId)
|
||||
addCandidate("group:$groupId")
|
||||
addCandidate("#group:$groupId")
|
||||
}
|
||||
|
||||
return candidates
|
||||
}
|
||||
|
||||
private fun isAvatarInNotificationsEnabled(): Boolean {
|
||||
return runCatching {
|
||||
runBlocking(Dispatchers.IO) {
|
||||
|
||||
Reference in New Issue
Block a user