Push: обработка read-событий в тихих уведомлениях
This commit is contained in:
@@ -73,10 +73,13 @@ class RosettaFirebaseMessagingService : FirebaseMessagingService() {
|
|||||||
val variants = buildDialogKeyVariants(senderPublicKey)
|
val variants = buildDialogKeyVariants(senderPublicKey)
|
||||||
for (key in variants) {
|
for (key in variants) {
|
||||||
notificationManager.cancel(getNotificationIdForChat(key))
|
notificationManager.cancel(getNotificationIdForChat(key))
|
||||||
|
lastNotifTimestamps.remove(key)
|
||||||
}
|
}
|
||||||
// Fallback: некоторые серверные payload могут прийти без sender key.
|
// Fallback: некоторые серверные payload могут прийти без sender key.
|
||||||
// Для них используется ID от пустой строки — тоже очищаем при входе в диалог.
|
// Для них используется ID от пустой строки — тоже очищаем при входе в диалог.
|
||||||
notificationManager.cancel(getNotificationIdForChat(""))
|
notificationManager.cancel(getNotificationIdForChat(""))
|
||||||
|
lastNotifTimestamps.remove("__no_sender__")
|
||||||
|
lastNotifTimestamps.remove("__simple__")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun buildDialogKeyVariants(rawKey: String): Set<String> {
|
private fun buildDialogKeyVariants(rawKey: String): Set<String> {
|
||||||
@@ -196,8 +199,14 @@ class RosettaFirebaseMessagingService : FirebaseMessagingService() {
|
|||||||
|
|
||||||
when {
|
when {
|
||||||
isReadEvent -> {
|
isReadEvent -> {
|
||||||
if (!dialogKey.isNullOrBlank()) {
|
val keysToClear = collectReadDialogKeys(data, dialogKey, senderPublicKey)
|
||||||
cancelNotificationForChat(applicationContext, dialogKey)
|
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
|
handledByData = true
|
||||||
}
|
}
|
||||||
@@ -541,6 +550,44 @@ class RosettaFirebaseMessagingService : FirebaseMessagingService() {
|
|||||||
return null
|
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 {
|
private fun isAvatarInNotificationsEnabled(): Boolean {
|
||||||
return runCatching {
|
return runCatching {
|
||||||
runBlocking(Dispatchers.IO) {
|
runBlocking(Dispatchers.IO) {
|
||||||
|
|||||||
Reference in New Issue
Block a user