diff --git a/app/build.gradle b/app/build.gradle index 7f537a9990..796595afaf 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,8 +15,8 @@ configurations.configureEach { exclude module: "commons-logging" } -def canonicalVersionCode = 383 -def canonicalVersionName = "1.20.1" +def canonicalVersionCode = 384 +def canonicalVersionName = "1.20.2" def postFixSize = 10 def abiPostFix = ['armeabi-v7a' : 1, diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/dialogs/DownloadDialog.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/dialogs/DownloadDialog.kt index 7ee19c53fd..1f84f09ceb 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/dialogs/DownloadDialog.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/dialogs/DownloadDialog.kt @@ -48,10 +48,7 @@ class AutoDownloadDialog(private val threadRecipient: Recipient, val explanation = Phrase.from(context, R.string.attachmentsAutoDownloadModalDescription) .put(CONVERSATION_NAME_KEY, displayName) .format() - val spannable = SpannableStringBuilder(explanation) - val startIndex = explanation.indexOf(displayName) - spannable.setSpan(StyleSpan(Typeface.BOLD), startIndex, startIndex + displayName.count(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) - text(spannable) + text(explanation) button(R.string.download, R.string.AccessibilityId_download) { setAutoDownload() diff --git a/app/src/main/java/org/thoughtcrime/securesms/dependencies/ConfigFactory.kt b/app/src/main/java/org/thoughtcrime/securesms/dependencies/ConfigFactory.kt index 27a53b0f2d..fd4fe2525d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/dependencies/ConfigFactory.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/dependencies/ConfigFactory.kt @@ -329,6 +329,18 @@ class ConfigFactory @Inject constructor( } } + override fun getConfigTimestamp(forConfigObject: ConfigBase, publicKey: String): Long { + val variant = when (forConfigObject) { + is UserProfile -> SharedConfigMessage.Kind.USER_PROFILE.name + is Contacts -> SharedConfigMessage.Kind.CONTACTS.name + is ConversationVolatileConfig -> SharedConfigMessage.Kind.CONVO_INFO_VOLATILE.name + is UserGroupsConfig -> SharedConfigMessage.Kind.GROUPS.name + else -> throw UnsupportedOperationException("Can't support type of ${forConfigObject::class.simpleName} yet") + } + + return configDatabase.retrieveConfigLastUpdateTimestamp(variant, publicKey) + } + override fun conversationInConfig( publicKey: String?, groupPublicKey: String?, diff --git a/libsession/src/main/java/org/session/libsession/messaging/jobs/BatchMessageReceiveJob.kt b/libsession/src/main/java/org/session/libsession/messaging/jobs/BatchMessageReceiveJob.kt index 94bee1524d..31f7f4a622 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/jobs/BatchMessageReceiveJob.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/jobs/BatchMessageReceiveJob.kt @@ -7,11 +7,13 @@ import kotlinx.coroutines.async import kotlinx.coroutines.awaitAll import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.runBlocking +import network.loki.messenger.libsession_util.ConfigBase import nl.komponents.kovenant.Promise import nl.komponents.kovenant.task import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.messaging.messages.Destination import org.session.libsession.messaging.messages.Message +import org.session.libsession.messaging.messages.Message.Companion.senderOrSync import org.session.libsession.messaging.messages.control.CallMessage import org.session.libsession.messaging.messages.control.ClosedGroupControlMessage import org.session.libsession.messaging.messages.control.ConfigurationMessage @@ -101,6 +103,26 @@ class BatchMessageReceiveJob( executeAsync(dispatcherName) } + private fun isHidden(message: Message): Boolean{ + // if the contact is marked as hidden for 1on1 messages + // and the message's sentTimestamp is earlier than the sentTimestamp of the last config + val config = MessagingModuleConfiguration.shared.configFactory + val publicKey = MessagingModuleConfiguration.shared.storage.getUserPublicKey() + if(config.contacts == null || message.sentTimestamp == null || publicKey == null) return false + val contactConfigTimestamp = config.getConfigTimestamp(config.contacts!!, publicKey) + if(message.groupPublicKey == null && // not a group + message.openGroupServerMessageID == null && // not a community + // not marked as hidden + config.contacts?.get(message.senderOrSync)?.priority == ConfigBase.PRIORITY_HIDDEN && + // the message's sentTimestamp is earlier than the sentTimestamp of the last config + message.sentTimestamp!! < contactConfigTimestamp + ) { + return true + } + + return false + } + suspend fun executeAsync(dispatcherName: String) { val threadMap = mutableMapOf>() val storage = MessagingModuleConfiguration.shared.storage @@ -122,6 +144,9 @@ class BatchMessageReceiveJob( ) message.serverHash = serverHash val parsedParams = ParsedMessage(messageParameters, message, proto) + + if(isHidden(message)) return@forEach + val threadID = Message.getThreadId( message = message, openGroupID = openGroupID, diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/Message.kt b/libsession/src/main/java/org/session/libsession/messaging/messages/Message.kt index f61277b573..de05b78585 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/Message.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/Message.kt @@ -32,12 +32,13 @@ abstract class Message { companion object { fun getThreadId(message: Message, openGroupID: String?, storage: StorageProtocol, shouldCreateThread: Boolean): Long? { - val senderOrSync = when (message) { - is VisibleMessage -> message.syncTarget ?: message.sender!! - is ExpirationTimerUpdate -> message.syncTarget ?: message.sender!! - else -> message.sender!! - } - return storage.getThreadIdFor(senderOrSync, message.groupPublicKey, openGroupID, createThread = shouldCreateThread) + return storage.getThreadIdFor(message.senderOrSync, message.groupPublicKey, openGroupID, createThread = shouldCreateThread) + } + + val Message.senderOrSync get() = when(this) { + is VisibleMessage -> syncTarget ?: sender!! + is ExpirationTimerUpdate -> syncTarget ?: sender!! + else -> sender!! } } diff --git a/libsession/src/main/java/org/session/libsession/utilities/ConfigFactoryProtocol.kt b/libsession/src/main/java/org/session/libsession/utilities/ConfigFactoryProtocol.kt index d2a54f30d6..326b653311 100644 --- a/libsession/src/main/java/org/session/libsession/utilities/ConfigFactoryProtocol.kt +++ b/libsession/src/main/java/org/session/libsession/utilities/ConfigFactoryProtocol.kt @@ -5,6 +5,7 @@ import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.onStart import kotlinx.coroutines.withTimeoutOrNull +import network.loki.messenger.libsession_util.ConfigBase import network.loki.messenger.libsession_util.MutableConfig import network.loki.messenger.libsession_util.MutableContacts import network.loki.messenger.libsession_util.MutableConversationVolatileConfig @@ -44,6 +45,8 @@ interface ConfigFactoryProtocol { fun conversationInConfig(publicKey: String?, groupPublicKey: String?, openGroupId: String?, visibleOnly: Boolean): Boolean fun canPerformChange(variant: String, publicKey: String, changeTimestampMs: Long): Boolean + fun getConfigTimestamp(userConfigType: UserConfigType, publicKey: String): Long + fun getGroupAuth(groupId: AccountId): SwarmAuth? fun removeGroup(groupId: AccountId) @@ -71,6 +74,7 @@ interface ConfigFactoryProtocol { info: Pair?, keysPush: ConfigPushResult? ) + } class ConfigMessage(