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
pull/933/head
Harris 3 years ago committed by GitHub
parent ba60e8a8ee
commit 344e7f333e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -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)
} }
storage.incrementUnread(threadId, trueUnreadCount) if (trueUnreadCount > 0) {
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…
Cancel
Save