fix: finally fix the darn unread count issue by

This commit is contained in:
0x330a 2023-05-01 14:39:17 +10:00
parent ac736744f6
commit 216070fa5d
No known key found for this signature in database
GPG Key ID: 267811D6E6A2698C
8 changed files with 43 additions and 17 deletions

View File

@ -443,7 +443,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
storage.markConversationAsRead(viewModel.threadId, SnodeAPI.nowWithOffset) storage.markConversationAsRead(viewModel.threadId, SnodeAPI.nowWithOffset)
} }
val bufferedFlow = bufferedLastSeenChannel.consumeAsFlow() val bufferedFlow = bufferedLastSeenChannel.consumeAsFlow().debounce(3.seconds)
bufferedFlow.collectLatest { bufferedFlow.collectLatest {
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
storage.markConversationAsRead(viewModel.threadId, SnodeAPI.nowWithOffset) storage.markConversationAsRead(viewModel.threadId, SnodeAPI.nowWithOffset)

View File

@ -362,7 +362,7 @@ class MmsDatabase(context: Context, databaseHelper: SQLCipherOpenHelper) : Messa
fun setMessagesRead(threadId: Long, beforeTime: Long): List<MarkedMessageInfo> { fun setMessagesRead(threadId: Long, beforeTime: Long): List<MarkedMessageInfo> {
return setMessagesRead( return setMessagesRead(
THREAD_ID + " = ? AND (" + READ + " = 0 OR " + REACTIONS_UNREAD + " = 1) AND " + DATE_RECEIVED + " <= ?", THREAD_ID + " = ? AND (" + READ + " = 0 OR " + REACTIONS_UNREAD + " = 1) AND " + DATE_SENT + " <= ?",
arrayOf(threadId.toString(), beforeTime.toString()) arrayOf(threadId.toString(), beforeTime.toString())
) )
} }

View File

@ -319,7 +319,7 @@ public class SmsDatabase extends MessagingDatabase {
} }
public List<MarkedMessageInfo> setMessagesRead(long threadId, long beforeTime) { public List<MarkedMessageInfo> setMessagesRead(long threadId, long beforeTime) {
return setMessagesRead(THREAD_ID + " = ? AND (" + READ + " = 0 OR " + REACTIONS_UNREAD + " = 1) AND " + DATE_RECEIVED + " <= ?", new String[]{threadId+"", beforeTime+""}); return setMessagesRead(THREAD_ID + " = ? AND (" + READ + " = 0 OR " + REACTIONS_UNREAD + " = 1) AND " + DATE_SENT + " <= ?", new String[]{threadId+"", beforeTime+""});
} }
public List<MarkedMessageInfo> setMessagesRead(long threadId) { public List<MarkedMessageInfo> setMessagesRead(long threadId) {
return setMessagesRead(THREAD_ID + " = ? AND (" + READ + " = 0 OR " + REACTIONS_UNREAD + " = 1)", new String[] {String.valueOf(threadId)}); return setMessagesRead(THREAD_ID + " = ? AND (" + READ + " = 0 OR " + REACTIONS_UNREAD + " = 1)", new String[] {String.valueOf(threadId)});

View File

@ -216,7 +216,8 @@ open class Storage(context: Context, helper: SQLCipherOpenHelper, private val co
override fun markConversationAsRead(threadId: Long, lastSeenTime: Long) { override fun markConversationAsRead(threadId: Long, lastSeenTime: Long) {
val threadDb = DatabaseComponent.get(context).threadDatabase() val threadDb = DatabaseComponent.get(context).threadDatabase()
getRecipientForThread(threadId)?.let { recipient -> getRecipientForThread(threadId)?.let { recipient ->
threadDb.markAllAsRead(threadId, recipient.isGroupRecipient, lastSeenTime) // don't set the last read in the volatile if we didn't set it in the DB
if (!threadDb.markAllAsRead(threadId, recipient.isGroupRecipient, lastSeenTime)) return
// don't process configs for inbox recipients // don't process configs for inbox recipients
if (recipient.isOpenGroupInboxRecipient) return if (recipient.isOpenGroupInboxRecipient) return
@ -1060,7 +1061,6 @@ open class Storage(context: Context, helper: SQLCipherOpenHelper, private val co
} }
override fun addLibSessionContacts(contacts: List<LibSessionContact>) { override fun addLibSessionContacts(contacts: List<LibSessionContact>) {
Log.d("Loki-DBG", "Adding contacts from execution context:\n${Thread.currentThread().stackTrace.joinToString("\n")}")
val mappingDb = DatabaseComponent.get(context).blindedIdMappingDatabase() val mappingDb = DatabaseComponent.get(context).blindedIdMappingDatabase()
val moreContacts = contacts.filter { contact -> val moreContacts = contacts.filter { contact ->
val id = SessionId(contact.id) val id = SessionId(contact.id)

View File

@ -315,6 +315,7 @@ public class ThreadDatabase extends Database {
ContentValues contentValues = new ContentValues(1); ContentValues contentValues = new ContentValues(1);
contentValues.put(READ, 1); contentValues.put(READ, 1);
Log.d("Loki-DBG", "setRead "+threadId+" @ "+lastReadTime);
contentValues.put(LAST_SEEN, lastReadTime); contentValues.put(LAST_SEEN, lastReadTime);
SQLiteDatabase db = databaseHelper.getWritableDatabase(); SQLiteDatabase db = databaseHelper.getWritableDatabase();
@ -335,6 +336,7 @@ public class ThreadDatabase extends Database {
contentValues.put(UNREAD_MENTION_COUNT, 0); contentValues.put(UNREAD_MENTION_COUNT, 0);
if (lastSeen) { if (lastSeen) {
Log.d("Loki-DBG", "setRead "+threadId+" @ current time");
contentValues.put(LAST_SEEN, SnodeAPI.getNowWithOffset()); contentValues.put(LAST_SEEN, SnodeAPI.getNowWithOffset());
} }
@ -526,9 +528,16 @@ public class ThreadDatabase extends Database {
return db.rawQuery(query, null); return db.rawQuery(query, null);
} }
public void setLastSeen(long threadId, long timestamp) { /**
* @param threadId
* @param timestamp
* @return true if we have set the last seen for the thread, false if there were no messages in the thread
*/
public boolean setLastSeen(long threadId, long timestamp) {
// edge case where we set the last seen time for a conversation before it loads messages (joining community for example) // edge case where we set the last seen time for a conversation before it loads messages (joining community for example)
if (getMessageCount(threadId) <= 0) return; MmsSmsDatabase mmsSmsDatabase = DatabaseComponent.get(context).mmsSmsDatabase();
if (mmsSmsDatabase.getConversationCount(threadId) <= 0) return false;
Log.d("Loki-DBG", "setLastSeen "+threadId+" @ "+timestamp);
SQLiteDatabase db = databaseHelper.getWritableDatabase(); SQLiteDatabase db = databaseHelper.getWritableDatabase();
@ -552,11 +561,17 @@ public class ThreadDatabase extends Database {
db.execSQL(reflectUpdates, new Object[]{threadId}); db.execSQL(reflectUpdates, new Object[]{threadId});
db.setTransactionSuccessful(); db.setTransactionSuccessful();
db.endTransaction(); db.endTransaction();
Log.d("Loki-DBG", "Updated last seen to "+timestamp);
notifyConversationListListeners(); notifyConversationListListeners();
return true;
} }
public void setLastSeen(long threadId) { /**
setLastSeen(threadId, -1); * @param threadId
* @return true if we have set the last seen for the thread, false if there were no messages in the thread
*/
public boolean setLastSeen(long threadId) {
return setLastSeen(threadId, -1);
} }
public Pair<Long, Boolean> getLastSeenAndHasSent(long threadId) { public Pair<Long, Boolean> getLastSeenAndHasSent(long threadId) {
@ -716,7 +731,7 @@ public class ThreadDatabase extends Database {
MmsSmsDatabase mmsSmsDatabase = DatabaseComponent.get(context).mmsSmsDatabase(); MmsSmsDatabase mmsSmsDatabase = DatabaseComponent.get(context).mmsSmsDatabase();
long count = mmsSmsDatabase.getConversationCount(threadId); long count = mmsSmsDatabase.getConversationCount(threadId);
boolean shouldDeleteEmptyThread = !shouldDeleteOnEmpty ? false : deleteThreadOnEmpty(threadId); boolean shouldDeleteEmptyThread = shouldDeleteOnEmpty && deleteThreadOnEmpty(threadId);
if (count == 0 && shouldDeleteEmptyThread) { if (count == 0 && shouldDeleteEmptyThread) {
deleteThread(threadId); deleteThread(threadId);
@ -778,7 +793,16 @@ public class ThreadDatabase extends Database {
} }
} }
public void markAllAsRead(long threadId, boolean isGroupRecipient, long lastSeenTime) { /**
* @param threadId
* @param isGroupRecipient
* @param lastSeenTime
* @return true if we have set the last seen for the thread, false if there were no messages in the thread
*/
public boolean markAllAsRead(long threadId, boolean isGroupRecipient, long lastSeenTime) {
MmsSmsDatabase mmsSmsDatabase = DatabaseComponent.get(context).mmsSmsDatabase();
if (mmsSmsDatabase.getConversationCount(threadId) <= 0) return false;
Log.d("Loki-DBG", "markAllAsRead "+threadId+" @ "+lastSeenTime);
List<MarkedMessageInfo> messages = setRead(threadId, lastSeenTime); List<MarkedMessageInfo> messages = setRead(threadId, lastSeenTime);
if (isGroupRecipient) { if (isGroupRecipient) {
for (MarkedMessageInfo message: messages) { for (MarkedMessageInfo message: messages) {
@ -788,7 +812,7 @@ public class ThreadDatabase extends Database {
MarkReadReceiver.process(context, messages); MarkReadReceiver.process(context, messages);
} }
ApplicationContext.getInstance(context).messageNotifier.updateNotification(context, threadId); ApplicationContext.getInstance(context).messageNotifier.updateNotification(context, threadId);
setLastSeen(threadId, lastSeenTime); return setLastSeen(threadId, lastSeenTime);
} }
private boolean deleteThreadOnEmpty(long threadId) { private boolean deleteThreadOnEmpty(long threadId) {

View File

@ -240,8 +240,8 @@ public class DefaultMessageNotifier implements MessageNotifier {
!(recipient.isApproved() || threads.getLastSeenAndHasSent(threadId).second())) { !(recipient.isApproved() || threads.getLastSeenAndHasSent(threadId).second())) {
TextSecurePreferences.removeHasHiddenMessageRequests(context); TextSecurePreferences.removeHasHiddenMessageRequests(context);
} }
if (isVisible && recipient != null) { if (isVisible && recipient != null && threads.getMessageCount(threadId) > 0) {
List<MarkedMessageInfo> messageIds = threads.setRead(threadId, false); List<MarkedMessageInfo> messageIds = threads.setRead(threadId, true);
if (SessionMetaProtocol.shouldSendReadReceipt(recipient)) { MarkReadReceiver.process(context, messageIds); } if (SessionMetaProtocol.shouldSendReadReceipt(recipient)) { MarkReadReceiver.process(context, messageIds); }
} }

View File

@ -85,7 +85,6 @@ object ConfigurationMessageUtilities {
if (ConfigBase.isNewConfigEnabled) { if (ConfigBase.isNewConfigEnabled) {
// schedule job if none exist // schedule job if none exist
// don't schedule job if we already have one // don't schedule job if we already have one
Log.d("Loki-DBG", "Forcing config sync")
scheduleConfigSync(userPublicKey) scheduleConfigSync(userPublicKey)
return Promise.ofSuccess(Unit) return Promise.ofSuccess(Unit)
} }

View File

@ -155,7 +155,8 @@ class BatchMessageReceiveJob(
// The LinkedHashMap should preserve insertion order // The LinkedHashMap should preserve insertion order
val messageIds = linkedMapOf<Long, Pair<Boolean, Boolean>>() val messageIds = linkedMapOf<Long, Pair<Boolean, Boolean>>()
val myLastSeen = storage.getLastSeen(threadId) val myLastSeen = storage.getLastSeen(threadId)
var newLastSeen = myLastSeen var newLastSeen = if (myLastSeen == -1L) 0 else myLastSeen
Log.d("Loki-DBG", "myLastSeen = $newLastSeen")
messages.forEach { (parameters, message, proto) -> messages.forEach { (parameters, message, proto) ->
try { try {
when (message) { when (message) {
@ -224,10 +225,12 @@ class BatchMessageReceiveJob(
// increment unreads, notify, and update thread // increment unreads, notify, and update thread
// last seen will be the current last seen if not changed (re-computes the read counts for thread record) // last seen will be the current last seen if not changed (re-computes the read counts for thread record)
// might have been updated from a different thread at this point // might have been updated from a different thread at this point
val currentLastSeen = storage.getLastSeen(threadId) val currentLastSeen = storage.getLastSeen(threadId).let { if (it == -1L) 0 else it }
Log.d("Loki-DBG", "currentLastSeen = $currentLastSeen")
if (currentLastSeen > newLastSeen) { if (currentLastSeen > newLastSeen) {
newLastSeen = currentLastSeen newLastSeen = currentLastSeen
} }
Log.d("Loki-DBG", "newLastSeen = $newLastSeen")
storage.markConversationAsRead(threadId, newLastSeen) storage.markConversationAsRead(threadId, newLastSeen)
storage.updateThread(threadId, true) storage.updateThread(threadId, true)
SSKEnvironment.shared.notificationManager.updateNotification(context, threadId) SSKEnvironment.shared.notificationManager.updateNotification(context, threadId)