mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-25 02:55:23 +00:00
feat: add broken unreads everywhere
This commit is contained in:
parent
2f2ebe9451
commit
66fb6b30e9
@ -3,18 +3,31 @@ package org.thoughtcrime.securesms.conversation.v2
|
|||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.animation.FloatEvaluator
|
import android.animation.FloatEvaluator
|
||||||
import android.animation.ValueAnimator
|
import android.animation.ValueAnimator
|
||||||
import android.content.*
|
import android.content.ClipData
|
||||||
|
import android.content.ClipboardManager
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.DialogInterface
|
||||||
|
import android.content.Intent
|
||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
||||||
import android.database.Cursor
|
import android.database.Cursor
|
||||||
import android.graphics.Rect
|
import android.graphics.Rect
|
||||||
import android.graphics.Typeface
|
import android.graphics.Typeface
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.*
|
import android.os.AsyncTask
|
||||||
|
import android.os.Build
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.os.Handler
|
||||||
|
import android.os.Looper
|
||||||
import android.provider.MediaStore
|
import android.provider.MediaStore
|
||||||
import android.text.TextUtils
|
import android.text.TextUtils
|
||||||
import android.util.Pair
|
import android.util.Pair
|
||||||
import android.util.TypedValue
|
import android.util.TypedValue
|
||||||
import android.view.*
|
import android.view.ActionMode
|
||||||
|
import android.view.Menu
|
||||||
|
import android.view.MenuItem
|
||||||
|
import android.view.MotionEvent
|
||||||
|
import android.view.View
|
||||||
|
import android.view.WindowManager
|
||||||
import android.widget.LinearLayout
|
import android.widget.LinearLayout
|
||||||
import android.widget.RelativeLayout
|
import android.widget.RelativeLayout
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
@ -57,8 +70,12 @@ import org.session.libsession.messaging.sending_receiving.attachments.Attachment
|
|||||||
import org.session.libsession.messaging.sending_receiving.link_preview.LinkPreview
|
import org.session.libsession.messaging.sending_receiving.link_preview.LinkPreview
|
||||||
import org.session.libsession.messaging.sending_receiving.quotes.QuoteModel
|
import org.session.libsession.messaging.sending_receiving.quotes.QuoteModel
|
||||||
import org.session.libsession.messaging.utilities.SessionId
|
import org.session.libsession.messaging.utilities.SessionId
|
||||||
import org.session.libsession.utilities.*
|
import org.session.libsession.utilities.Address
|
||||||
import org.session.libsession.utilities.Address.Companion.fromSerialized
|
import org.session.libsession.utilities.Address.Companion.fromSerialized
|
||||||
|
import org.session.libsession.utilities.GroupUtil
|
||||||
|
import org.session.libsession.utilities.MediaTypes
|
||||||
|
import org.session.libsession.utilities.Stub
|
||||||
|
import org.session.libsession.utilities.TextSecurePreferences
|
||||||
import org.session.libsession.utilities.concurrent.SimpleTask
|
import org.session.libsession.utilities.concurrent.SimpleTask
|
||||||
import org.session.libsession.utilities.recipients.Recipient
|
import org.session.libsession.utilities.recipients.Recipient
|
||||||
import org.session.libsession.utilities.recipients.RecipientModifiedListener
|
import org.session.libsession.utilities.recipients.RecipientModifiedListener
|
||||||
@ -91,10 +108,25 @@ import org.thoughtcrime.securesms.conversation.v2.messages.VisibleMessageView
|
|||||||
import org.thoughtcrime.securesms.conversation.v2.messages.VisibleMessageViewDelegate
|
import org.thoughtcrime.securesms.conversation.v2.messages.VisibleMessageViewDelegate
|
||||||
import org.thoughtcrime.securesms.conversation.v2.search.SearchBottomBar
|
import org.thoughtcrime.securesms.conversation.v2.search.SearchBottomBar
|
||||||
import org.thoughtcrime.securesms.conversation.v2.search.SearchViewModel
|
import org.thoughtcrime.securesms.conversation.v2.search.SearchViewModel
|
||||||
import org.thoughtcrime.securesms.conversation.v2.utilities.*
|
import org.thoughtcrime.securesms.conversation.v2.utilities.AttachmentManager
|
||||||
|
import org.thoughtcrime.securesms.conversation.v2.utilities.BaseDialog
|
||||||
|
import org.thoughtcrime.securesms.conversation.v2.utilities.MentionManagerUtilities
|
||||||
|
import org.thoughtcrime.securesms.conversation.v2.utilities.MentionUtilities
|
||||||
|
import org.thoughtcrime.securesms.conversation.v2.utilities.ResendMessageUtilities
|
||||||
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil
|
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil
|
||||||
import org.thoughtcrime.securesms.crypto.MnemonicUtilities
|
import org.thoughtcrime.securesms.crypto.MnemonicUtilities
|
||||||
import org.thoughtcrime.securesms.database.*
|
import org.thoughtcrime.securesms.database.GroupDatabase
|
||||||
|
import org.thoughtcrime.securesms.database.LokiAPIDatabase
|
||||||
|
import org.thoughtcrime.securesms.database.LokiMessageDatabase
|
||||||
|
import org.thoughtcrime.securesms.database.LokiThreadDatabase
|
||||||
|
import org.thoughtcrime.securesms.database.MmsDatabase
|
||||||
|
import org.thoughtcrime.securesms.database.MmsSmsDatabase
|
||||||
|
import org.thoughtcrime.securesms.database.ReactionDatabase
|
||||||
|
import org.thoughtcrime.securesms.database.RecipientDatabase
|
||||||
|
import org.thoughtcrime.securesms.database.SessionContactDatabase
|
||||||
|
import org.thoughtcrime.securesms.database.SmsDatabase
|
||||||
|
import org.thoughtcrime.securesms.database.Storage
|
||||||
|
import org.thoughtcrime.securesms.database.ThreadDatabase
|
||||||
import org.thoughtcrime.securesms.database.model.MessageId
|
import org.thoughtcrime.securesms.database.model.MessageId
|
||||||
import org.thoughtcrime.securesms.database.model.MessageRecord
|
import org.thoughtcrime.securesms.database.model.MessageRecord
|
||||||
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
|
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
|
||||||
@ -107,12 +139,25 @@ import org.thoughtcrime.securesms.linkpreview.LinkPreviewViewModel
|
|||||||
import org.thoughtcrime.securesms.linkpreview.LinkPreviewViewModel.LinkPreviewState
|
import org.thoughtcrime.securesms.linkpreview.LinkPreviewViewModel.LinkPreviewState
|
||||||
import org.thoughtcrime.securesms.mediasend.Media
|
import org.thoughtcrime.securesms.mediasend.Media
|
||||||
import org.thoughtcrime.securesms.mediasend.MediaSendActivity
|
import org.thoughtcrime.securesms.mediasend.MediaSendActivity
|
||||||
import org.thoughtcrime.securesms.mms.*
|
import org.thoughtcrime.securesms.mms.AudioSlide
|
||||||
|
import org.thoughtcrime.securesms.mms.GifSlide
|
||||||
|
import org.thoughtcrime.securesms.mms.GlideApp
|
||||||
|
import org.thoughtcrime.securesms.mms.ImageSlide
|
||||||
|
import org.thoughtcrime.securesms.mms.MediaConstraints
|
||||||
|
import org.thoughtcrime.securesms.mms.Slide
|
||||||
|
import org.thoughtcrime.securesms.mms.SlideDeck
|
||||||
|
import org.thoughtcrime.securesms.mms.VideoSlide
|
||||||
import org.thoughtcrime.securesms.permissions.Permissions
|
import org.thoughtcrime.securesms.permissions.Permissions
|
||||||
import org.thoughtcrime.securesms.reactions.ReactionsDialogFragment
|
import org.thoughtcrime.securesms.reactions.ReactionsDialogFragment
|
||||||
import org.thoughtcrime.securesms.reactions.any.ReactWithAnyEmojiDialogFragment
|
import org.thoughtcrime.securesms.reactions.any.ReactWithAnyEmojiDialogFragment
|
||||||
import org.thoughtcrime.securesms.util.*
|
import org.thoughtcrime.securesms.util.ActivityDispatcher
|
||||||
import java.util.*
|
import org.thoughtcrime.securesms.util.ConfigurationMessageUtilities
|
||||||
|
import org.thoughtcrime.securesms.util.DateUtils
|
||||||
|
import org.thoughtcrime.securesms.util.MediaUtil
|
||||||
|
import org.thoughtcrime.securesms.util.SaveAttachmentTask
|
||||||
|
import org.thoughtcrime.securesms.util.push
|
||||||
|
import org.thoughtcrime.securesms.util.toPx
|
||||||
|
import java.util.Locale
|
||||||
import java.util.concurrent.ExecutionException
|
import java.util.concurrent.ExecutionException
|
||||||
import java.util.concurrent.atomic.AtomicLong
|
import java.util.concurrent.atomic.AtomicLong
|
||||||
import java.util.concurrent.atomic.AtomicReference
|
import java.util.concurrent.atomic.AtomicReference
|
||||||
@ -363,10 +408,9 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
|
|||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
ApplicationContext.getInstance(this).messageNotifier.setVisibleThread(viewModel.threadId)
|
ApplicationContext.getInstance(this).messageNotifier.setVisibleThread(viewModel.threadId)
|
||||||
val recipient = viewModel.recipient ?: return
|
|
||||||
|
|
||||||
lifecycleScope.launch(Dispatchers.IO) {
|
lifecycleScope.launch(Dispatchers.IO) {
|
||||||
threadDb.markAllAsRead(viewModel.threadId, recipient.isOpenGroupRecipient)
|
storage.markConversationAsRead(viewModel.threadId, System.currentTimeMillis())
|
||||||
}
|
}
|
||||||
|
|
||||||
contentResolver.registerContentObserver(
|
contentResolver.registerContentObserver(
|
||||||
|
@ -35,7 +35,7 @@ class ConfigDatabase(context: Context, helper: SQLCipherOpenHelper): Database(co
|
|||||||
|
|
||||||
fun retrieveConfigAndHashes(variant: String, publicKey: String): Pair<ByteArray,List<String>>? {
|
fun retrieveConfigAndHashes(variant: String, publicKey: String): Pair<ByteArray,List<String>>? {
|
||||||
val db = readableDatabase
|
val db = readableDatabase
|
||||||
val query = db.query(TABLE_NAME, arrayOf(DATA), VARIANT_AND_PUBKEY_WHERE, arrayOf(variant, publicKey),null, null, null)
|
val query = db.query(TABLE_NAME, arrayOf(DATA, COMBINED_MESSAGE_HASHES), VARIANT_AND_PUBKEY_WHERE, arrayOf(variant, publicKey),null, null, null)
|
||||||
return query?.use { cursor ->
|
return query?.use { cursor ->
|
||||||
if (!cursor.moveToFirst()) return@use null
|
if (!cursor.moveToFirst()) return@use null
|
||||||
val bytes = cursor.getBlobOrNull(cursor.getColumnIndex(DATA)) ?: return@use null
|
val bytes = cursor.getBlobOrNull(cursor.getColumnIndex(DATA)) ?: return@use null
|
||||||
|
@ -366,10 +366,7 @@ class MmsDatabase(context: Context, databaseHelper: SQLCipherOpenHelper) : Messa
|
|||||||
val attachmentDatabase = get(context).attachmentDatabase()
|
val attachmentDatabase = get(context).attachmentDatabase()
|
||||||
queue(Runnable { attachmentDatabase.deleteAttachmentsForMessage(messageId) })
|
queue(Runnable { attachmentDatabase.deleteAttachmentsForMessage(messageId) })
|
||||||
val threadId = getThreadIdForMessage(messageId)
|
val threadId = getThreadIdForMessage(messageId)
|
||||||
if (!read) {
|
|
||||||
val mentionChange = if (hasMention) { 1 } else { 0 }
|
|
||||||
get(context).threadDatabase().decrementUnread(threadId, 1, mentionChange)
|
|
||||||
}
|
|
||||||
updateMailboxBitmask(
|
updateMailboxBitmask(
|
||||||
messageId,
|
messageId,
|
||||||
MmsSmsColumns.Types.BASE_TYPE_MASK,
|
MmsSmsColumns.Types.BASE_TYPE_MASK,
|
||||||
@ -634,7 +631,6 @@ class MmsDatabase(context: Context, databaseHelper: SQLCipherOpenHelper) : Messa
|
|||||||
contentLocation: String,
|
contentLocation: String,
|
||||||
threadId: Long, mailbox: Long,
|
threadId: Long, mailbox: Long,
|
||||||
serverTimestamp: Long,
|
serverTimestamp: Long,
|
||||||
runIncrement: Boolean,
|
|
||||||
runThreadUpdate: Boolean
|
runThreadUpdate: Boolean
|
||||||
): Optional<InsertResult> {
|
): Optional<InsertResult> {
|
||||||
var threadId = threadId
|
var threadId = threadId
|
||||||
@ -699,10 +695,6 @@ class MmsDatabase(context: Context, databaseHelper: SQLCipherOpenHelper) : Messa
|
|||||||
null,
|
null,
|
||||||
)
|
)
|
||||||
if (!MmsSmsColumns.Types.isExpirationTimerUpdate(mailbox)) {
|
if (!MmsSmsColumns.Types.isExpirationTimerUpdate(mailbox)) {
|
||||||
if (runIncrement) {
|
|
||||||
val mentionAmount = if (retrieved.hasMention()) { 1 } else { 0 }
|
|
||||||
get(context).threadDatabase().incrementUnread(threadId, 1, mentionAmount)
|
|
||||||
}
|
|
||||||
if (runThreadUpdate) {
|
if (runThreadUpdate) {
|
||||||
get(context).threadDatabase().update(threadId, true)
|
get(context).threadDatabase().update(threadId, true)
|
||||||
}
|
}
|
||||||
@ -753,7 +745,6 @@ class MmsDatabase(context: Context, databaseHelper: SQLCipherOpenHelper) : Messa
|
|||||||
retrieved: IncomingMediaMessage,
|
retrieved: IncomingMediaMessage,
|
||||||
threadId: Long,
|
threadId: Long,
|
||||||
serverTimestamp: Long = 0,
|
serverTimestamp: Long = 0,
|
||||||
runIncrement: Boolean,
|
|
||||||
runThreadUpdate: Boolean
|
runThreadUpdate: Boolean
|
||||||
): Optional<InsertResult> {
|
): Optional<InsertResult> {
|
||||||
var type = MmsSmsColumns.Types.BASE_INBOX_TYPE or MmsSmsColumns.Types.SECURE_MESSAGE_BIT
|
var type = MmsSmsColumns.Types.BASE_INBOX_TYPE or MmsSmsColumns.Types.SECURE_MESSAGE_BIT
|
||||||
@ -772,7 +763,7 @@ class MmsDatabase(context: Context, databaseHelper: SQLCipherOpenHelper) : Messa
|
|||||||
if (retrieved.isMessageRequestResponse) {
|
if (retrieved.isMessageRequestResponse) {
|
||||||
type = type or MmsSmsColumns.Types.MESSAGE_REQUEST_RESPONSE_BIT
|
type = type or MmsSmsColumns.Types.MESSAGE_REQUEST_RESPONSE_BIT
|
||||||
}
|
}
|
||||||
return insertMessageInbox(retrieved, "", threadId, type, serverTimestamp, runIncrement, runThreadUpdate)
|
return insertMessageInbox(retrieved, "", threadId, type, serverTimestamp, runThreadUpdate)
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
|
@ -218,10 +218,6 @@ public class SmsDatabase extends MessagingDatabase {
|
|||||||
contentValues.put(BODY, "");
|
contentValues.put(BODY, "");
|
||||||
contentValues.put(HAS_MENTION, 0);
|
contentValues.put(HAS_MENTION, 0);
|
||||||
database.update(TABLE_NAME, contentValues, ID_WHERE, new String[] {String.valueOf(messageId)});
|
database.update(TABLE_NAME, contentValues, ID_WHERE, new String[] {String.valueOf(messageId)});
|
||||||
long threadId = getThreadIdForMessage(messageId);
|
|
||||||
if (!read) {
|
|
||||||
DatabaseComponent.get(context).threadDatabase().decrementUnread(threadId, 1, (hasMention ? 1 : 0));
|
|
||||||
}
|
|
||||||
updateTypeBitmask(messageId, Types.BASE_TYPE_MASK, Types.BASE_DELETED_TYPE);
|
updateTypeBitmask(messageId, Types.BASE_TYPE_MASK, Types.BASE_DELETED_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -394,7 +390,7 @@ public class SmsDatabase extends MessagingDatabase {
|
|||||||
return new Pair<>(messageId, threadId);
|
return new Pair<>(messageId, threadId);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Optional<InsertResult> insertMessageInbox(IncomingTextMessage message, long type, long serverTimestamp, boolean runIncrement, boolean runThreadUpdate) {
|
protected Optional<InsertResult> insertMessageInbox(IncomingTextMessage message, long type, long serverTimestamp, boolean runThreadUpdate) {
|
||||||
if (message.isSecureMessage()) {
|
if (message.isSecureMessage()) {
|
||||||
type |= Types.SECURE_MESSAGE_BIT;
|
type |= Types.SECURE_MESSAGE_BIT;
|
||||||
} else if (message.isGroup()) {
|
} else if (message.isGroup()) {
|
||||||
@ -473,10 +469,6 @@ public class SmsDatabase extends MessagingDatabase {
|
|||||||
SQLiteDatabase db = databaseHelper.getWritableDatabase();
|
SQLiteDatabase db = databaseHelper.getWritableDatabase();
|
||||||
long messageId = db.insert(TABLE_NAME, null, values);
|
long messageId = db.insert(TABLE_NAME, null, values);
|
||||||
|
|
||||||
if (unread && runIncrement) {
|
|
||||||
DatabaseComponent.get(context).threadDatabase().incrementUnread(threadId, 1, (message.hasMention() ? 1 : 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (runThreadUpdate) {
|
if (runThreadUpdate) {
|
||||||
DatabaseComponent.get(context).threadDatabase().update(threadId, true);
|
DatabaseComponent.get(context).threadDatabase().update(threadId, true);
|
||||||
}
|
}
|
||||||
@ -491,16 +483,16 @@ public class SmsDatabase extends MessagingDatabase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Optional<InsertResult> insertMessageInbox(IncomingTextMessage message, boolean runIncrement, boolean runThreadUpdate) {
|
public Optional<InsertResult> insertMessageInbox(IncomingTextMessage message, boolean runThreadUpdate) {
|
||||||
return insertMessageInbox(message, Types.BASE_INBOX_TYPE, 0, runIncrement, runThreadUpdate);
|
return insertMessageInbox(message, Types.BASE_INBOX_TYPE, 0, runThreadUpdate);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Optional<InsertResult> insertCallMessage(IncomingTextMessage message) {
|
public Optional<InsertResult> insertCallMessage(IncomingTextMessage message) {
|
||||||
return insertMessageInbox(message, 0, 0, true, true);
|
return insertMessageInbox(message, 0, 0, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Optional<InsertResult> insertMessageInbox(IncomingTextMessage message, long serverTimestamp, boolean runIncrement, boolean runThreadUpdate) {
|
public Optional<InsertResult> insertMessageInbox(IncomingTextMessage message, long serverTimestamp, boolean runThreadUpdate) {
|
||||||
return insertMessageInbox(message, Types.BASE_INBOX_TYPE, serverTimestamp, runIncrement, runThreadUpdate);
|
return insertMessageInbox(message, Types.BASE_INBOX_TYPE, serverTimestamp, runThreadUpdate);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Optional<InsertResult> insertMessageOutbox(long threadId, OutgoingTextMessage message, long serverTimestamp, boolean runThreadUpdate) {
|
public Optional<InsertResult> insertMessageOutbox(long threadId, OutgoingTextMessage message, long serverTimestamp, boolean runThreadUpdate) {
|
||||||
|
@ -121,14 +121,16 @@ class Storage(context: Context, helper: SQLCipherOpenHelper, private val configF
|
|||||||
return database.getAttachmentsForMessage(messageID)
|
return database.getAttachmentsForMessage(messageID)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun markConversationAsRead(threadId: Long, updateLastSeen: Boolean) {
|
override fun getLastSeen(threadId: Long): Long {
|
||||||
val threadDb = DatabaseComponent.get(context).threadDatabase()
|
val threadDb = DatabaseComponent.get(context).threadDatabase()
|
||||||
threadDb.setRead(threadId, updateLastSeen)
|
return threadDb.getLastSeenAndHasSent(threadId)?.first() ?: 0L
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun incrementUnread(threadId: Long, amount: Int, unreadMentionAmount: Int) {
|
override fun markConversationAsRead(threadId: Long, lastSeenTime: Long) {
|
||||||
val threadDb = DatabaseComponent.get(context).threadDatabase()
|
val threadDb = DatabaseComponent.get(context).threadDatabase()
|
||||||
threadDb.incrementUnread(threadId, amount, unreadMentionAmount)
|
getRecipientForThread(threadId)?.let {
|
||||||
|
threadDb.markAllAsRead(threadId, it.isGroupRecipient, lastSeenTime)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun updateThread(threadId: Long, unarchive: Boolean) {
|
override fun updateThread(threadId: Long, unarchive: Boolean) {
|
||||||
@ -142,7 +144,6 @@ class Storage(context: Context, helper: SQLCipherOpenHelper, private val configF
|
|||||||
groupPublicKey: String?,
|
groupPublicKey: String?,
|
||||||
openGroupID: String?,
|
openGroupID: String?,
|
||||||
attachments: List<Attachment>,
|
attachments: List<Attachment>,
|
||||||
runIncrement: Boolean,
|
|
||||||
runThreadUpdate: Boolean): Long? {
|
runThreadUpdate: Boolean): Long? {
|
||||||
var messageID: Long? = null
|
var messageID: Long? = null
|
||||||
val senderAddress = fromSerialized(message.sender!!)
|
val senderAddress = fromSerialized(message.sender!!)
|
||||||
@ -189,7 +190,7 @@ class Storage(context: Context, helper: SQLCipherOpenHelper, private val configF
|
|||||||
it.toSignalPointer()
|
it.toSignalPointer()
|
||||||
}
|
}
|
||||||
val mediaMessage = IncomingMediaMessage.from(message, senderAddress, targetRecipient.expireMessages * 1000L, group, signalServiceAttachments, quote, linkPreviews)
|
val mediaMessage = IncomingMediaMessage.from(message, senderAddress, targetRecipient.expireMessages * 1000L, group, signalServiceAttachments, quote, linkPreviews)
|
||||||
mmsDatabase.insertSecureDecryptedMessageInbox(mediaMessage, message.threadID ?: -1, message.receivedTimestamp ?: 0, runIncrement, runThreadUpdate)
|
mmsDatabase.insertSecureDecryptedMessageInbox(mediaMessage, message.threadID ?: -1, message.receivedTimestamp ?: 0, runThreadUpdate)
|
||||||
}
|
}
|
||||||
if (insertResult.isPresent) {
|
if (insertResult.isPresent) {
|
||||||
messageID = insertResult.get().messageId
|
messageID = insertResult.get().messageId
|
||||||
@ -206,7 +207,7 @@ class Storage(context: Context, helper: SQLCipherOpenHelper, private val configF
|
|||||||
val textMessage = if (isOpenGroupInvitation) IncomingTextMessage.fromOpenGroupInvitation(message.openGroupInvitation, senderAddress, message.sentTimestamp)
|
val textMessage = if (isOpenGroupInvitation) IncomingTextMessage.fromOpenGroupInvitation(message.openGroupInvitation, senderAddress, message.sentTimestamp)
|
||||||
else IncomingTextMessage.from(message, senderAddress, group, targetRecipient.expireMessages * 1000L)
|
else IncomingTextMessage.from(message, senderAddress, group, targetRecipient.expireMessages * 1000L)
|
||||||
val encrypted = IncomingEncryptedMessage(textMessage, textMessage.messageBody)
|
val encrypted = IncomingEncryptedMessage(textMessage, textMessage.messageBody)
|
||||||
smsDatabase.insertMessageInbox(encrypted, message.receivedTimestamp ?: 0, runIncrement, runThreadUpdate)
|
smsDatabase.insertMessageInbox(encrypted, message.receivedTimestamp ?: 0, runThreadUpdate)
|
||||||
}
|
}
|
||||||
insertResult.orNull()?.let { result ->
|
insertResult.orNull()?.let { result ->
|
||||||
messageID = result.messageId
|
messageID = result.messageId
|
||||||
@ -344,6 +345,10 @@ class Storage(context: Context, helper: SQLCipherOpenHelper, private val configF
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Log.d("Loki-DBG", "Should update thread $threadId")
|
Log.d("Loki-DBG", "Should update thread $threadId")
|
||||||
|
if (threadId >= 0) {
|
||||||
|
DatabaseComponent.get(context).threadDatabase()
|
||||||
|
.setLastSeen(threadId, conversation.lastRead)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -578,7 +583,7 @@ class Storage(context: Context, helper: SQLCipherOpenHelper, private val configF
|
|||||||
val updateData = UpdateMessageData.buildGroupUpdate(type, name, members)?.toJSON()
|
val updateData = UpdateMessageData.buildGroupUpdate(type, name, members)?.toJSON()
|
||||||
val infoMessage = IncomingGroupMessage(m, groupID, updateData, true)
|
val infoMessage = IncomingGroupMessage(m, groupID, updateData, true)
|
||||||
val smsDB = DatabaseComponent.get(context).smsDatabase()
|
val smsDB = DatabaseComponent.get(context).smsDatabase()
|
||||||
smsDB.insertMessageInbox(infoMessage, true, true)
|
smsDB.insertMessageInbox(infoMessage, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun insertOutgoingInfoMessage(context: Context, groupID: String, type: SignalServiceGroup.Type, name: String, members: Collection<String>, admins: Collection<String>, threadID: Long, sentTimestamp: Long) {
|
override fun insertOutgoingInfoMessage(context: Context, groupID: String, type: SignalServiceGroup.Type, name: String, members: Collection<String>, admins: Collection<String>, threadID: Long, sentTimestamp: Long) {
|
||||||
@ -866,7 +871,7 @@ class Storage(context: Context, helper: SQLCipherOpenHelper, private val configF
|
|||||||
Optional.of(message)
|
Optional.of(message)
|
||||||
)
|
)
|
||||||
|
|
||||||
database.insertSecureDecryptedMessageInbox(mediaMessage, -1, runIncrement = true, runThreadUpdate = true)
|
database.insertSecureDecryptedMessageInbox(mediaMessage, -1, runThreadUpdate = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun insertMessageRequestResponse(response: MessageRequestResponse) {
|
override fun insertMessageRequestResponse(response: MessageRequestResponse) {
|
||||||
@ -959,7 +964,7 @@ class Storage(context: Context, helper: SQLCipherOpenHelper, private val configF
|
|||||||
Optional.absent(),
|
Optional.absent(),
|
||||||
Optional.absent()
|
Optional.absent()
|
||||||
)
|
)
|
||||||
mmsDb.insertSecureDecryptedMessageInbox(message, threadId, runIncrement = true, runThreadUpdate = true)
|
mmsDb.insertSecureDecryptedMessageInbox(message, threadId, runThreadUpdate = true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,6 +35,7 @@ import com.annimon.stream.Stream;
|
|||||||
import net.zetetic.database.sqlcipher.SQLiteDatabase;
|
import net.zetetic.database.sqlcipher.SQLiteDatabase;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.session.libsession.snode.SnodeAPI;
|
||||||
import org.session.libsession.utilities.Address;
|
import org.session.libsession.utilities.Address;
|
||||||
import org.session.libsession.utilities.Contact;
|
import org.session.libsession.utilities.Contact;
|
||||||
import org.session.libsession.utilities.DelimiterUtil;
|
import org.session.libsession.utilities.DelimiterUtil;
|
||||||
@ -101,6 +102,8 @@ public class ThreadDatabase extends Database {
|
|||||||
public static final String HAS_SENT = "has_sent";
|
public static final String HAS_SENT = "has_sent";
|
||||||
public static final String IS_PINNED = "is_pinned";
|
public static final String IS_PINNED = "is_pinned";
|
||||||
|
|
||||||
|
public static final String LAST_SEEN_TRIGGER = "thread_last_seen_trigger";
|
||||||
|
|
||||||
public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" +
|
public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" +
|
||||||
ID + " INTEGER PRIMARY KEY, " + DATE + " INTEGER DEFAULT 0, " +
|
ID + " INTEGER PRIMARY KEY, " + DATE + " INTEGER DEFAULT 0, " +
|
||||||
MESSAGE_COUNT + " INTEGER DEFAULT 0, " + ADDRESS + " TEXT, " + SNIPPET + " TEXT, " +
|
MESSAGE_COUNT + " INTEGER DEFAULT 0, " + ADDRESS + " TEXT, " + SNIPPET + " TEXT, " +
|
||||||
@ -296,18 +299,17 @@ public class ThreadDatabase extends Database {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public List<MarkedMessageInfo> setRead(long threadId, long lastReadTime) {
|
public List<MarkedMessageInfo> setRead(long threadId, long lastReadTime) {
|
||||||
|
|
||||||
|
final List<MarkedMessageInfo> smsRecords = DatabaseComponent.get(context).smsDatabase().setMessagesRead(threadId, lastReadTime);
|
||||||
|
final List<MarkedMessageInfo> mmsRecords = DatabaseComponent.get(context).mmsDatabase().setMessagesRead(threadId, lastReadTime);
|
||||||
|
|
||||||
ContentValues contentValues = new ContentValues(1);
|
ContentValues contentValues = new ContentValues(1);
|
||||||
contentValues.put(READ, 1);
|
contentValues.put(READ, 1);
|
||||||
contentValues.put(UNREAD_COUNT, 0);
|
|
||||||
contentValues.put(UNREAD_MENTION_COUNT, 0);
|
|
||||||
contentValues.put(LAST_SEEN, lastReadTime);
|
contentValues.put(LAST_SEEN, lastReadTime);
|
||||||
|
|
||||||
SQLiteDatabase db = databaseHelper.getWritableDatabase();
|
SQLiteDatabase db = databaseHelper.getWritableDatabase();
|
||||||
db.update(TABLE_NAME, contentValues, ID_WHERE, new String[] {threadId+""});
|
db.update(TABLE_NAME, contentValues, ID_WHERE, new String[] {threadId+""});
|
||||||
|
|
||||||
final List<MarkedMessageInfo> smsRecords = DatabaseComponent.get(context).smsDatabase().setMessagesRead(threadId, lastReadTime);
|
|
||||||
final List<MarkedMessageInfo> mmsRecords = DatabaseComponent.get(context).mmsDatabase().setMessagesRead(threadId, lastReadTime);
|
|
||||||
|
|
||||||
notifyConversationListListeners();
|
notifyConversationListListeners();
|
||||||
|
|
||||||
return new LinkedList<MarkedMessageInfo>() {{
|
return new LinkedList<MarkedMessageInfo>() {{
|
||||||
@ -340,30 +342,6 @@ public class ThreadDatabase extends Database {
|
|||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
public void incrementUnread(long threadId, int amount, int unreadMentionAmount) {
|
|
||||||
SQLiteDatabase db = databaseHelper.getWritableDatabase();
|
|
||||||
db.execSQL("UPDATE " + TABLE_NAME + " SET " + READ + " = 0, " +
|
|
||||||
UNREAD_COUNT + " = " + UNREAD_COUNT + " + ?, " +
|
|
||||||
UNREAD_MENTION_COUNT + " = " + UNREAD_MENTION_COUNT + " + ? WHERE " + ID + " = ?",
|
|
||||||
new String[] {
|
|
||||||
String.valueOf(amount),
|
|
||||||
String.valueOf(unreadMentionAmount),
|
|
||||||
String.valueOf(threadId)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void decrementUnread(long threadId, int amount, int unreadMentionAmount) {
|
|
||||||
SQLiteDatabase db = databaseHelper.getWritableDatabase();
|
|
||||||
db.execSQL("UPDATE " + TABLE_NAME + " SET " + READ + " = 0, " +
|
|
||||||
UNREAD_COUNT + " = " + UNREAD_COUNT + " - ?, " +
|
|
||||||
UNREAD_MENTION_COUNT + " = " + UNREAD_MENTION_COUNT + " - ? WHERE " + ID + " = ? AND " + UNREAD_COUNT + " > 0",
|
|
||||||
new String[] {
|
|
||||||
String.valueOf(amount),
|
|
||||||
String.valueOf(unreadMentionAmount),
|
|
||||||
String.valueOf(threadId)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDistributionType(long threadId, int distributionType) {
|
public void setDistributionType(long threadId, int distributionType) {
|
||||||
ContentValues contentValues = new ContentValues(1);
|
ContentValues contentValues = new ContentValues(1);
|
||||||
contentValues.put(TYPE, distributionType);
|
contentValues.put(TYPE, distributionType);
|
||||||
@ -541,13 +519,15 @@ public class ThreadDatabase extends Database {
|
|||||||
public void setLastSeen(long threadId, long timestamp) {
|
public void setLastSeen(long threadId, long timestamp) {
|
||||||
SQLiteDatabase db = databaseHelper.getWritableDatabase();
|
SQLiteDatabase db = databaseHelper.getWritableDatabase();
|
||||||
ContentValues contentValues = new ContentValues(1);
|
ContentValues contentValues = new ContentValues(1);
|
||||||
if (timestamp == -1) {
|
long lastSeenTime = timestamp == -1 ? SnodeAPI.INSTANCE.getNowWithOffset() : timestamp;
|
||||||
contentValues.put(LAST_SEEN, System.currentTimeMillis());
|
contentValues.put(LAST_SEEN, lastSeenTime);
|
||||||
} else {
|
db.beginTransaction();
|
||||||
contentValues.put(LAST_SEEN, timestamp);
|
|
||||||
}
|
|
||||||
|
|
||||||
db.update(TABLE_NAME, contentValues, ID_WHERE, new String[] {String.valueOf(threadId)});
|
db.update(TABLE_NAME, contentValues, ID_WHERE, new String[] {String.valueOf(threadId)});
|
||||||
|
String countSubQuery = "SELECT COUNT(*) FROM "+SmsDatabase.TABLE_NAME+" AS s INNER JOIN "+TABLE_NAME+" AS t ON s.thread_id = t._id WHERE t._id = ? AND s."+SmsDatabase.DATE_SENT+" > t."+LAST_SEEN+"";
|
||||||
|
String reflectUpdates = "UPDATE "+TABLE_NAME+" AS t SET "+UNREAD_COUNT+" = ("+countSubQuery+") WHERE t."+ID+" = ?";
|
||||||
|
db.query(reflectUpdates, new String[]{threadId+"", threadId+""});
|
||||||
|
db.setTransactionSuccessful();
|
||||||
|
db.endTransaction();
|
||||||
notifyConversationListListeners();
|
notifyConversationListListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -755,8 +735,8 @@ public class ThreadDatabase extends Database {
|
|||||||
notifyConversationListeners(threadId);
|
notifyConversationListeners(threadId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void markAllAsRead(long threadId, boolean isGroupRecipient) {
|
public void markAllAsRead(long threadId, boolean isGroupRecipient, long lastSeenTime) {
|
||||||
List<MarkedMessageInfo> messages = setRead(threadId, true);
|
List<MarkedMessageInfo> messages = setRead(threadId, lastSeenTime);
|
||||||
if (isGroupRecipient) {
|
if (isGroupRecipient) {
|
||||||
for (MarkedMessageInfo message: messages) {
|
for (MarkedMessageInfo message: messages) {
|
||||||
MarkReadReceiver.scheduleDeletion(context, message.getExpirationInfo());
|
MarkReadReceiver.scheduleDeletion(context, message.getExpirationInfo());
|
||||||
@ -765,6 +745,7 @@ public class ThreadDatabase extends Database {
|
|||||||
MarkReadReceiver.process(context, messages);
|
MarkReadReceiver.process(context, messages);
|
||||||
}
|
}
|
||||||
ApplicationContext.getInstance(context).messageNotifier.updateNotification(context, false, 0);
|
ApplicationContext.getInstance(context).messageNotifier.updateNotification(context, false, 0);
|
||||||
|
setLastSeen(threadId, lastSeenTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean deleteThreadOnEmpty(long threadId) {
|
private boolean deleteThreadOnEmpty(long threadId) {
|
||||||
|
@ -88,9 +88,10 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
|
|||||||
private static final int lokiV39 = 60;
|
private static final int lokiV39 = 60;
|
||||||
private static final int lokiV40 = 61;
|
private static final int lokiV40 = 61;
|
||||||
private static final int lokiV41 = 62;
|
private static final int lokiV41 = 62;
|
||||||
|
private static final int lokiV42 = 63;
|
||||||
|
|
||||||
// Loki - onUpgrade(...) must be updated to use Loki version numbers if Signal makes any database changes
|
// Loki - onUpgrade(...) must be updated to use Loki version numbers if Signal makes any database changes
|
||||||
private static final int DATABASE_VERSION = lokiV41;
|
private static final int DATABASE_VERSION = lokiV42;
|
||||||
private static final int MIN_DATABASE_VERSION = lokiV7;
|
private static final int MIN_DATABASE_VERSION = lokiV7;
|
||||||
private static final String CIPHER3_DATABASE_NAME = "signal.db";
|
private static final String CIPHER3_DATABASE_NAME = "signal.db";
|
||||||
public static final String DATABASE_NAME = "signal_v4.db";
|
public static final String DATABASE_NAME = "signal_v4.db";
|
||||||
@ -324,6 +325,7 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
|
|||||||
executeStatements(db, ReactionDatabase.CREATE_INDEXS);
|
executeStatements(db, ReactionDatabase.CREATE_INDEXS);
|
||||||
|
|
||||||
executeStatements(db, ReactionDatabase.CREATE_REACTION_TRIGGERS);
|
executeStatements(db, ReactionDatabase.CREATE_REACTION_TRIGGERS);
|
||||||
|
// db.execSQL(ThreadDatabase.getCreateLastSeenTrigger());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -560,6 +562,10 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
|
|||||||
db.execSQL(ConfigDatabase.CREATE_CONFIG_TABLE_COMMAND);
|
db.execSQL(ConfigDatabase.CREATE_CONFIG_TABLE_COMMAND);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (oldVersion < lokiV42) {
|
||||||
|
// db.execSQL(ThreadDatabase.getCreateLastSeenTrigger());
|
||||||
|
}
|
||||||
|
|
||||||
db.setTransactionSuccessful();
|
db.setTransactionSuccessful();
|
||||||
} finally {
|
} finally {
|
||||||
db.endTransaction();
|
db.endTransaction();
|
||||||
|
@ -28,6 +28,7 @@ import network.loki.messenger.databinding.ViewMessageRequestBannerBinding
|
|||||||
import org.greenrobot.eventbus.EventBus
|
import org.greenrobot.eventbus.EventBus
|
||||||
import org.greenrobot.eventbus.Subscribe
|
import org.greenrobot.eventbus.Subscribe
|
||||||
import org.greenrobot.eventbus.ThreadMode
|
import org.greenrobot.eventbus.ThreadMode
|
||||||
|
import org.session.libsession.messaging.MessagingModuleConfiguration
|
||||||
import org.session.libsession.messaging.jobs.JobQueue
|
import org.session.libsession.messaging.jobs.JobQueue
|
||||||
import org.session.libsession.messaging.sending_receiving.MessageSender
|
import org.session.libsession.messaging.sending_receiving.MessageSender
|
||||||
import org.session.libsession.utilities.Address
|
import org.session.libsession.utilities.Address
|
||||||
@ -556,7 +557,7 @@ class HomeActivity : PassphraseRequiredActionBarActivity(),
|
|||||||
|
|
||||||
private fun markAllAsRead(thread: ThreadRecord) {
|
private fun markAllAsRead(thread: ThreadRecord) {
|
||||||
ThreadUtils.queue {
|
ThreadUtils.queue {
|
||||||
threadDb.markAllAsRead(thread.threadId, thread.recipient.isOpenGroupRecipient)
|
MessagingModuleConfiguration.shared.storage.markConversationAsRead(thread.threadId, System.currentTimeMillis())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,7 +120,7 @@ public class ExpiringMessageManager implements SSKEnvironment.MessageExpirationM
|
|||||||
Optional.absent(),
|
Optional.absent(),
|
||||||
Optional.absent());
|
Optional.absent());
|
||||||
//insert the timer update message
|
//insert the timer update message
|
||||||
database.insertSecureDecryptedMessageInbox(mediaMessage, -1, true, true);
|
database.insertSecureDecryptedMessageInbox(mediaMessage, -1, true);
|
||||||
|
|
||||||
//set the timer to the conversation
|
//set the timer to the conversation
|
||||||
DatabaseComponent.get(context).recipientDatabase().setExpireMessages(recipient, duration);
|
DatabaseComponent.get(context).recipientDatabase().setExpireMessages(recipient, duration);
|
||||||
|
@ -7,8 +7,6 @@ import org.session.libsession.messaging.messages.signal.IncomingTextMessage
|
|||||||
import org.session.libsession.messaging.messages.signal.OutgoingTextMessage
|
import org.session.libsession.messaging.messages.signal.OutgoingTextMessage
|
||||||
import org.session.libsession.messaging.open_groups.OpenGroup
|
import org.session.libsession.messaging.open_groups.OpenGroup
|
||||||
import org.session.libsession.messaging.open_groups.OpenGroupApi
|
import org.session.libsession.messaging.open_groups.OpenGroupApi
|
||||||
import org.session.libsession.messaging.sending_receiving.notifications.PushNotificationAPI
|
|
||||||
import org.session.libsession.messaging.sending_receiving.pollers.ClosedGroupPollerV2
|
|
||||||
import org.session.libsession.utilities.Address
|
import org.session.libsession.utilities.Address
|
||||||
import org.session.libsession.utilities.GroupUtil
|
import org.session.libsession.utilities.GroupUtil
|
||||||
import org.session.libsession.utilities.recipients.Recipient
|
import org.session.libsession.utilities.recipients.Recipient
|
||||||
@ -21,7 +19,6 @@ import org.thoughtcrime.securesms.crypto.KeyPairUtilities
|
|||||||
import org.thoughtcrime.securesms.dependencies.DatabaseComponent
|
import org.thoughtcrime.securesms.dependencies.DatabaseComponent
|
||||||
import org.thoughtcrime.securesms.groups.GroupManager
|
import org.thoughtcrime.securesms.groups.GroupManager
|
||||||
import java.security.SecureRandom
|
import java.security.SecureRandom
|
||||||
import java.util.*
|
|
||||||
import kotlin.random.asKotlinRandom
|
import kotlin.random.asKotlinRandom
|
||||||
|
|
||||||
object MockDataGenerator {
|
object MockDataGenerator {
|
||||||
@ -139,7 +136,6 @@ object MockDataGenerator {
|
|||||||
false
|
false
|
||||||
),
|
),
|
||||||
(timestampNow - (index * 5000)),
|
(timestampNow - (index * 5000)),
|
||||||
false,
|
|
||||||
false
|
false
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -269,7 +265,6 @@ object MockDataGenerator {
|
|||||||
false
|
false
|
||||||
),
|
),
|
||||||
(timestampNow - (index * 5000)),
|
(timestampNow - (index * 5000)),
|
||||||
false,
|
|
||||||
false
|
false
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -395,7 +390,6 @@ object MockDataGenerator {
|
|||||||
false
|
false
|
||||||
),
|
),
|
||||||
(timestampNow - (index * 5000)),
|
(timestampNow - (index * 5000)),
|
||||||
false,
|
|
||||||
false
|
false
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 3fd0e0977d156a2e748a14aaa0c94da0bb71560e
|
Subproject commit bbdc35d2ec8204c1a36bbe45714625d093b82602
|
@ -177,9 +177,9 @@ interface StorageProtocol {
|
|||||||
/**
|
/**
|
||||||
* Returns the ID of the `TSIncomingMessage` that was constructed.
|
* Returns the ID of the `TSIncomingMessage` that was constructed.
|
||||||
*/
|
*/
|
||||||
fun persist(message: VisibleMessage, quotes: QuoteModel?, linkPreview: List<LinkPreview?>, groupPublicKey: String?, openGroupID: String?, attachments: List<Attachment>, runIncrement: Boolean, runThreadUpdate: Boolean): Long?
|
fun persist(message: VisibleMessage, quotes: QuoteModel?, linkPreview: List<LinkPreview?>, groupPublicKey: String?, openGroupID: String?, attachments: List<Attachment>, runThreadUpdate: Boolean): Long?
|
||||||
fun markConversationAsRead(threadId: Long, updateLastSeen: Boolean)
|
fun markConversationAsRead(threadId: Long, lastSeenTime: Long)
|
||||||
fun incrementUnread(threadId: Long, amount: Int, unreadMentionAmount: Int)
|
fun getLastSeen(threadId: Long): Long
|
||||||
fun updateThread(threadId: Long, unarchive: Boolean)
|
fun updateThread(threadId: Long, unarchive: Boolean)
|
||||||
fun insertDataExtractionNotificationMessage(senderPublicKey: String, message: DataExtractionNotificationInfoMessage, sentTimestamp: Long)
|
fun insertDataExtractionNotificationMessage(senderPublicKey: String, message: DataExtractionNotificationInfoMessage, sentTimestamp: Long)
|
||||||
fun insertMessageRequestResponse(response: MessageRequestResponse)
|
fun insertMessageRequestResponse(response: MessageRequestResponse)
|
||||||
|
@ -123,7 +123,7 @@ class BatchMessageReceiveJob(
|
|||||||
async {
|
async {
|
||||||
// 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>>()
|
||||||
|
var myLastSeen = storage.getLastSeen(threadId)
|
||||||
messages.forEach { (parameters, message, proto) ->
|
messages.forEach { (parameters, message, proto) ->
|
||||||
try {
|
try {
|
||||||
when (message) {
|
when (message) {
|
||||||
@ -137,6 +137,12 @@ class BatchMessageReceiveJob(
|
|||||||
if (messageId != null && message.reaction == null) {
|
if (messageId != null && message.reaction == null) {
|
||||||
val isUserBlindedSender = message.sender == serverPublicKey?.let { SodiumUtilities.blindedKeyPair(it, MessagingModuleConfiguration.shared.getUserED25519KeyPair()!!) }?.let { SessionId(
|
val isUserBlindedSender = message.sender == serverPublicKey?.let { SodiumUtilities.blindedKeyPair(it, MessagingModuleConfiguration.shared.getUserED25519KeyPair()!!) }?.let { SessionId(
|
||||||
IdPrefix.BLINDED, it.publicKey.asBytes).hexString }
|
IdPrefix.BLINDED, it.publicKey.asBytes).hexString }
|
||||||
|
if (message.sender == localUserPublicKey || isUserBlindedSender) {
|
||||||
|
val sentTimestamp = message.sentTimestamp
|
||||||
|
if (sentTimestamp != null && sentTimestamp > myLastSeen) {
|
||||||
|
myLastSeen = sentTimestamp // use sent timestamp here since that is technically the last one we have
|
||||||
|
}
|
||||||
|
}
|
||||||
messageIds[messageId] = Pair(
|
messageIds[messageId] = Pair(
|
||||||
(message.sender == localUserPublicKey || isUserBlindedSender),
|
(message.sender == localUserPublicKey || isUserBlindedSender),
|
||||||
message.hasMention
|
message.hasMention
|
||||||
@ -169,21 +175,8 @@ class BatchMessageReceiveJob(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// increment unreads, notify, and update thread
|
// increment unreads, notify, and update thread
|
||||||
val unreadFromMine = messageIds.map { it.value.first }.indexOfLast { it }
|
// last seen will be the current last seen if not changed (re-computes the read counts for thread record)
|
||||||
var trueUnreadCount = messageIds.filter { !it.value.first }.size
|
storage.markConversationAsRead(threadId, 0)
|
||||||
var trueUnreadMentionCount = messageIds.filter { !it.value.first && it.value.second }.size
|
|
||||||
if (unreadFromMine >= 0) {
|
|
||||||
storage.markConversationAsRead(threadId, false)
|
|
||||||
|
|
||||||
val trueUnreadIds = messageIds.keys.toList().subList(unreadFromMine + 1, messageIds.keys.count())
|
|
||||||
trueUnreadCount = trueUnreadIds.size
|
|
||||||
trueUnreadMentionCount = messageIds
|
|
||||||
.filter { trueUnreadIds.contains(it.key) && !it.value.first && it.value.second }
|
|
||||||
.size
|
|
||||||
}
|
|
||||||
if (trueUnreadCount > 0) {
|
|
||||||
storage.incrementUnread(threadId, trueUnreadCount, trueUnreadMentionCount)
|
|
||||||
}
|
|
||||||
storage.updateThread(threadId, true)
|
storage.updateThread(threadId, true)
|
||||||
SSKEnvironment.shared.notificationManager.updateNotification(context, threadId)
|
SSKEnvironment.shared.notificationManager.updateNotification(context, threadId)
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,8 @@ object MessageSender {
|
|||||||
return if (destination is Destination.LegacyOpenGroup || destination is Destination.OpenGroup || destination is Destination.OpenGroupInbox) {
|
return if (destination is Destination.LegacyOpenGroup || destination is Destination.OpenGroup || destination is Destination.OpenGroupInbox) {
|
||||||
sendToOpenGroupDestination(destination, message)
|
sendToOpenGroupDestination(destination, message)
|
||||||
} else {
|
} else {
|
||||||
sendToSnodeDestination(destination, message)
|
val userPublicKey = MessagingModuleConfiguration.shared.storage.getUserPublicKey()
|
||||||
|
sendToSnodeDestination(destination, message, destination is Destination.Contact && destination.publicKey == userPublicKey)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -343,7 +343,7 @@ fun MessageReceiver.handleVisibleMessage(message: VisibleMessage,
|
|||||||
message.threadID = threadID
|
message.threadID = threadID
|
||||||
val messageID =
|
val messageID =
|
||||||
storage.persist(message, quoteModel, linkPreviews, message.groupPublicKey, openGroupID,
|
storage.persist(message, quoteModel, linkPreviews, message.groupPublicKey, openGroupID,
|
||||||
attachments, runIncrement, runThreadUpdate
|
attachments, runThreadUpdate
|
||||||
) ?: return null
|
) ?: return null
|
||||||
val openGroupServerID = message.openGroupServerMessageID
|
val openGroupServerID = message.openGroupServerMessageID
|
||||||
if (openGroupServerID != null) {
|
if (openGroupServerID != null) {
|
||||||
|
Loading…
Reference in New Issue
Block a user