mirror of
https://github.com/oxen-io/session-android.git
synced 2025-07-19 15:08:29 +00:00
Fix notification release issues (#925)
* fix: background polling issue for 1on1 messages, update the HomeDiffUtil.kt to include more cases to compare content equality, add synchronized ConversationNotificationDebouncer.kt and reduce the debouncer time * fix: replace updateNotification to be thread-specific to fix unread behaviour and currently visible thread behaviour * refactor: remove trimmed text limits
This commit is contained in:
parent
ba60e8a8ee
commit
344e7f333e
@ -8,12 +8,13 @@ import org.thoughtcrime.securesms.ApplicationContext
|
|||||||
class ConversationNotificationDebouncer(private val context: Context) {
|
class ConversationNotificationDebouncer(private val context: Context) {
|
||||||
private val threadIDs = mutableSetOf<Long>()
|
private val threadIDs = mutableSetOf<Long>()
|
||||||
private val handler = (context.applicationContext as ApplicationContext).conversationListNotificationHandler
|
private val handler = (context.applicationContext as ApplicationContext).conversationListNotificationHandler
|
||||||
private val debouncer = Debouncer(handler, 1000)
|
private val debouncer = Debouncer(handler, 100)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@SuppressLint("StaticFieldLeak")
|
@SuppressLint("StaticFieldLeak")
|
||||||
lateinit var shared: ConversationNotificationDebouncer
|
lateinit var shared: ConversationNotificationDebouncer
|
||||||
|
|
||||||
|
@Synchronized
|
||||||
fun get(context: Context): ConversationNotificationDebouncer {
|
fun get(context: Context): ConversationNotificationDebouncer {
|
||||||
if (::shared.isInitialized) { return shared }
|
if (::shared.isInitialized) { return shared }
|
||||||
shared = ConversationNotificationDebouncer(context)
|
shared = ConversationNotificationDebouncer(context)
|
||||||
|
@ -34,6 +34,9 @@ class HomeDiffUtil(
|
|||||||
if (!sameUsername) return false
|
if (!sameUsername) return false
|
||||||
val sameSnippet = oldItem.getDisplayBody(context) == newItem.getDisplayBody(context)
|
val sameSnippet = oldItem.getDisplayBody(context) == newItem.getDisplayBody(context)
|
||||||
if (!sameSnippet) return false
|
if (!sameSnippet) return false
|
||||||
|
val sameSendStatus = oldItem.isFailed == newItem.isFailed && oldItem.isDelivered == newItem.isDelivered
|
||||||
|
&& oldItem.isSent == newItem.isSent && oldItem.isPending == newItem.isPending
|
||||||
|
if (!sameSendStatus) return false
|
||||||
|
|
||||||
// all same
|
// all same
|
||||||
return true
|
return true
|
||||||
|
@ -3,12 +3,19 @@ package org.thoughtcrime.securesms.notifications
|
|||||||
import android.content.BroadcastReceiver
|
import android.content.BroadcastReceiver
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import androidx.work.*
|
import androidx.work.Constraints
|
||||||
|
import androidx.work.ExistingPeriodicWorkPolicy
|
||||||
|
import androidx.work.NetworkType
|
||||||
|
import androidx.work.PeriodicWorkRequestBuilder
|
||||||
|
import androidx.work.WorkManager
|
||||||
|
import androidx.work.Worker
|
||||||
|
import androidx.work.WorkerParameters
|
||||||
import nl.komponents.kovenant.Promise
|
import nl.komponents.kovenant.Promise
|
||||||
import nl.komponents.kovenant.all
|
import nl.komponents.kovenant.all
|
||||||
import nl.komponents.kovenant.functional.map
|
import nl.komponents.kovenant.functional.bind
|
||||||
import org.session.libsession.messaging.MessagingModuleConfiguration
|
import org.session.libsession.messaging.MessagingModuleConfiguration
|
||||||
import org.session.libsession.messaging.jobs.MessageReceiveJob
|
import org.session.libsession.messaging.jobs.BatchMessageReceiveJob
|
||||||
|
import org.session.libsession.messaging.jobs.MessageReceiveParameters
|
||||||
import org.session.libsession.messaging.sending_receiving.pollers.ClosedGroupPollerV2
|
import org.session.libsession.messaging.sending_receiving.pollers.ClosedGroupPollerV2
|
||||||
import org.session.libsession.messaging.sending_receiving.pollers.OpenGroupPollerV2
|
import org.session.libsession.messaging.sending_receiving.pollers.OpenGroupPollerV2
|
||||||
import org.session.libsession.snode.SnodeAPI
|
import org.session.libsession.snode.SnodeAPI
|
||||||
@ -48,13 +55,14 @@ class BackgroundPollWorker(val context: Context, params: WorkerParameters) : Wor
|
|||||||
|
|
||||||
// DMs
|
// DMs
|
||||||
val userPublicKey = TextSecurePreferences.getLocalNumber(context)!!
|
val userPublicKey = TextSecurePreferences.getLocalNumber(context)!!
|
||||||
val dmsPromise = SnodeAPI.getMessages(userPublicKey).map { envelopes ->
|
val dmsPromise = SnodeAPI.getMessages(userPublicKey).bind { envelopes ->
|
||||||
envelopes.map { (envelope, serverHash) ->
|
val params = envelopes.map { (envelope, serverHash) ->
|
||||||
// FIXME: Using a job here seems like a bad idea...
|
// FIXME: Using a job here seems like a bad idea...
|
||||||
MessageReceiveJob(envelope.toByteArray(), serverHash).executeAsync()
|
MessageReceiveParameters(envelope.toByteArray(), serverHash, null)
|
||||||
}
|
}
|
||||||
|
BatchMessageReceiveJob(params).executeAsync()
|
||||||
}
|
}
|
||||||
promises.addAll(dmsPromise.get())
|
promises.add(dmsPromise)
|
||||||
|
|
||||||
// Closed groups
|
// Closed groups
|
||||||
val closedGroupPoller = ClosedGroupPollerV2() // Intentionally don't use shared
|
val closedGroupPoller = ClosedGroupPollerV2() // Intentionally don't use shared
|
||||||
|
@ -301,15 +301,6 @@ public class DefaultMessageNotifier implements MessageNotifier {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getTrimmedText(CharSequence text) {
|
|
||||||
String trimmedText = "";
|
|
||||||
if (text != null) {
|
|
||||||
int trimEnd = Math.min(text.length(), 50);
|
|
||||||
trimmedText = text.subSequence(0,trimEnd) + (text.length() >= 50 ? "..." : "");
|
|
||||||
}
|
|
||||||
return trimmedText;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void sendSingleThreadNotification(@NonNull Context context,
|
private void sendSingleThreadNotification(@NonNull Context context,
|
||||||
@NonNull NotificationState notificationState,
|
@NonNull NotificationState notificationState,
|
||||||
boolean signal, boolean bundled)
|
boolean signal, boolean bundled)
|
||||||
@ -342,13 +333,12 @@ public class DefaultMessageNotifier implements MessageNotifier {
|
|||||||
builder.putStringExtra(LATEST_MESSAGE_ID_TAG, messageIdTag);
|
builder.putStringExtra(LATEST_MESSAGE_ID_TAG, messageIdTag);
|
||||||
|
|
||||||
CharSequence text = notifications.get(0).getText();
|
CharSequence text = notifications.get(0).getText();
|
||||||
String trimmedText = getTrimmedText(text);
|
|
||||||
|
|
||||||
builder.setThread(notifications.get(0).getRecipient());
|
builder.setThread(notifications.get(0).getRecipient());
|
||||||
builder.setMessageCount(notificationState.getMessageCount());
|
builder.setMessageCount(notificationState.getMessageCount());
|
||||||
MentionManagerUtilities.INSTANCE.populateUserPublicKeyCacheIfNeeded(notifications.get(0).getThreadId(),context);
|
MentionManagerUtilities.INSTANCE.populateUserPublicKeyCacheIfNeeded(notifications.get(0).getThreadId(),context);
|
||||||
builder.setPrimaryMessageBody(recipient, notifications.get(0).getIndividualRecipient(),
|
builder.setPrimaryMessageBody(recipient, notifications.get(0).getIndividualRecipient(),
|
||||||
MentionUtilities.highlightMentions(trimmedText,
|
MentionUtilities.highlightMentions(text == null ? "" : text,
|
||||||
notifications.get(0).getThreadId(),
|
notifications.get(0).getThreadId(),
|
||||||
context),
|
context),
|
||||||
notifications.get(0).getSlideDeck());
|
notifications.get(0).getSlideDeck());
|
||||||
|
@ -128,19 +128,21 @@ class BatchMessageReceiveJob(
|
|||||||
}
|
}
|
||||||
// increment unreads, notify, and update thread
|
// increment unreads, notify, and update thread
|
||||||
val unreadFromMine = messageIds.indexOfLast { (_,fromMe) -> fromMe }
|
val unreadFromMine = messageIds.indexOfLast { (_,fromMe) -> fromMe }
|
||||||
var trueUnreadCount = messageIds.size
|
var trueUnreadCount = messageIds.filter { (_,fromMe) -> !fromMe }.size
|
||||||
if (unreadFromMine >= 0) {
|
if (unreadFromMine >= 0) {
|
||||||
trueUnreadCount -= (unreadFromMine + 1)
|
trueUnreadCount -= (unreadFromMine + 1)
|
||||||
storage.markConversationAsRead(threadId, false)
|
storage.markConversationAsRead(threadId, false)
|
||||||
}
|
}
|
||||||
|
if (trueUnreadCount > 0) {
|
||||||
storage.incrementUnread(threadId, trueUnreadCount)
|
storage.incrementUnread(threadId, trueUnreadCount)
|
||||||
|
}
|
||||||
storage.updateThread(threadId, true)
|
storage.updateThread(threadId, true)
|
||||||
|
SSKEnvironment.shared.notificationManager.updateNotification(context, threadId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// await all thread processing
|
// await all thread processing
|
||||||
deferredThreadMap.awaitAll()
|
deferredThreadMap.awaitAll()
|
||||||
}
|
}
|
||||||
SSKEnvironment.shared.notificationManager.updateNotification(context)
|
|
||||||
if (failures.isEmpty()) {
|
if (failures.isEmpty()) {
|
||||||
handleSuccess()
|
handleSuccess()
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user