diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt index 64bc0a4e7..b8b568f11 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt @@ -105,13 +105,12 @@ import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity import org.thoughtcrime.securesms.attachments.ScreenshotObserver import org.thoughtcrime.securesms.audio.AudioRecorder import org.thoughtcrime.securesms.contacts.SelectContactsActivity.Companion.selectedContactsKey -import org.thoughtcrime.securesms.util.SimpleTextWatcher import org.thoughtcrime.securesms.conversation.v2.ConversationReactionOverlay.OnActionSelectedListener import org.thoughtcrime.securesms.conversation.v2.ConversationReactionOverlay.OnReactionSelectedListener import org.thoughtcrime.securesms.conversation.v2.MessageDetailActivity.Companion.MESSAGE_TIMESTAMP +import org.thoughtcrime.securesms.conversation.v2.MessageDetailActivity.Companion.ON_DELETE import org.thoughtcrime.securesms.conversation.v2.MessageDetailActivity.Companion.ON_REPLY import org.thoughtcrime.securesms.conversation.v2.MessageDetailActivity.Companion.ON_RESEND -import org.thoughtcrime.securesms.conversation.v2.MessageDetailActivity.Companion.ON_DELETE import org.thoughtcrime.securesms.conversation.v2.dialogs.BlockedDialog import org.thoughtcrime.securesms.conversation.v2.dialogs.LinkPreviewDialog import org.thoughtcrime.securesms.conversation.v2.dialogs.SendSeedDialog @@ -174,6 +173,7 @@ 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.SimpleTextWatcher import org.thoughtcrime.securesms.util.isScrolledToBottom import org.thoughtcrime.securesms.util.push import org.thoughtcrime.securesms.util.toPx @@ -240,11 +240,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe val address = if (sessionId.prefix == IdPrefix.BLINDED && openGroup != null) { storage.getOrCreateBlindedIdMapping(sessionId.hexString, openGroup.server, openGroup.publicKey).sessionId?.let { fromSerialized(it) - } ?: run { - val openGroupInboxId = - "${openGroup.server}!${openGroup.publicKey}!${sessionId.hexString}".toByteArray() - fromSerialized(GroupUtil.getEncodedOpenGroupInboxID(openGroupInboxId)) - } + } ?: GroupUtil.getEncodedOpenGroupInboxID(openGroup, sessionId) } else { it } @@ -596,7 +592,10 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe // called from onCreate private fun setUpInputBar() { - binding!!.inputBar.isVisible = viewModel.openGroup == null || viewModel.openGroup?.canWrite == true + val recipient = viewModel.recipient ?: return + binding!!.inputBar.isVisible = + viewModel.openGroup?.canWrite == true + || (viewModel.openGroup == null && !recipient.blocksCommunityMessageRequests) binding!!.inputBar.delegate = this binding!!.inputBarRecordingView.delegate = this // GIF button @@ -1074,6 +1073,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe val (textResource, insertParam) = when { recipient.isLocalNumber -> R.string.activity_conversation_empty_state_note_to_self to null openGroup != null && !openGroup.canWrite -> R.string.activity_conversation_empty_state_read_only to recipient.toShortString() + openGroup == null && recipient.blocksCommunityMessageRequests -> R.string.activity_conversation_empty_state_blocks_community_requests to recipient.toShortString() else -> R.string.activity_conversation_empty_state_default to recipient.toShortString() } val showPlaceholder = adapter.itemCount == 0 diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/RecipientDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/RecipientDatabase.java index 6fce86090..dde5847ff 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/RecipientDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/RecipientDatabase.java @@ -406,7 +406,7 @@ public class RecipientDatabase extends Database { ContentValues contentValues = new ContentValues(1); contentValues.put(BLOCKS_COMMUNITY_MESSAGE_REQUESTS, isBlocked ? 1 : 0); updateOrInsert(recipient.getAddress(), contentValues); - recipient.setBlocksCommunityMessageRequests(isBlocked); + recipient.resolve().setBlocksCommunityMessageRequests(isBlocked); notifyRecipientListeners(); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt index c77ad1c63..1abed8748 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt @@ -190,6 +190,11 @@ open class Storage(context: Context, helper: SQLCipherOpenHelper, private val co db.setProfileKey(recipient, newProfileKey) } + override fun setBlocksCommunityMessageRequests(recipient: Recipient, blocksMessageRequests: Boolean) { + val db = DatabaseComponent.get(context).recipientDatabase() + db.setBlocksCommunityMessageRequests(recipient, blocksMessageRequests) + } + override fun setUserProfilePicture(newProfilePicture: String?, newProfileKey: ByteArray?) { val ourRecipient = fromSerialized(getUserPublicKey()!!).let { Recipient.from(context, it, false) @@ -430,6 +435,10 @@ open class Storage(context: Context, helper: SQLCipherOpenHelper, private val co return configFactory.canPerformChange(variant, publicKey, changeTimestampMs) } + override fun isCheckingCommunityRequests(): Boolean { + return configFactory.user?.getBlocksCommunityMessageRequests() != true + } + fun notifyUpdates(forConfigObject: ConfigBase) { when (forConfigObject) { is UserProfile -> updateUser(forConfigObject) diff --git a/app/src/main/java/org/thoughtcrime/securesms/preferences/PrivacySettingsActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/preferences/PrivacySettingsActivity.kt index b8606a3d5..de136694f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/preferences/PrivacySettingsActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/preferences/PrivacySettingsActivity.kt @@ -1,9 +1,11 @@ package org.thoughtcrime.securesms.preferences import android.os.Bundle +import dagger.hilt.android.AndroidEntryPoint import network.loki.messenger.R import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity +@AndroidEntryPoint class PrivacySettingsActivity : PassphraseRequiredActionBarActivity() { override fun onCreate(savedInstanceState: Bundle?, isReady: Boolean) { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b031d37b1..64c2421dc 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1036,6 +1036,7 @@ Some of your devices are using outdated versions. Syncing may be unreliable until they are updated. There are no messages in %s. + %s has message requests from Community conversations turned off, so you cannot send them a message. You have no messages in Note to Self. You have no messages from %s.\nSend a message to start the conversation! diff --git a/app/src/main/res/xml/preferences_app_protection.xml b/app/src/main/res/xml/preferences_app_protection.xml index 3cc41e6e6..9e60f3a93 100644 --- a/app/src/main/res/xml/preferences_app_protection.xml +++ b/app/src/main/res/xml/preferences_app_protection.xml @@ -23,8 +23,7 @@ diff --git a/libsession-util/src/main/cpp/user_profile.cpp b/libsession-util/src/main/cpp/user_profile.cpp index afc939e4a..57a0f6ded 100644 --- a/libsession-util/src/main/cpp/user_profile.cpp +++ b/libsession-util/src/main/cpp/user_profile.cpp @@ -106,7 +106,7 @@ Java_network_loki_messenger_libsession_1util_UserProfile_getBlocksCommunityMessa if (blinded_msg_requests.has_value()) { return *blinded_msg_requests; } - return false; + return true; } extern "C" diff --git a/libsession/src/main/java/org/session/libsession/database/StorageProtocol.kt b/libsession/src/main/java/org/session/libsession/database/StorageProtocol.kt index 4fff83383..1de94cfe3 100644 --- a/libsession/src/main/java/org/session/libsession/database/StorageProtocol.kt +++ b/libsession/src/main/java/org/session/libsession/database/StorageProtocol.kt @@ -42,6 +42,7 @@ interface StorageProtocol { fun getUserProfile(): Profile fun setProfileAvatar(recipient: Recipient, profileAvatar: String?) fun setProfilePicture(recipient: Recipient, newProfilePicture: String?, newProfileKey: ByteArray?) + fun setBlocksCommunityMessageRequests(recipient: Recipient, blocksMessageRequests: Boolean) fun setUserProfilePicture(newProfilePicture: String?, newProfileKey: ByteArray?) fun clearUserPic() // Signal @@ -228,4 +229,5 @@ interface StorageProtocol { fun notifyConfigUpdates(forConfigObject: ConfigBase) fun conversationInConfig(publicKey: String?, groupPublicKey: String?, openGroupId: String?, visibleOnly: Boolean): Boolean fun canPerformConfigChange(variant: String, publicKey: String, changeTimestampMs: Long): Boolean + fun isCheckingCommunityRequests(): Boolean } diff --git a/libsession/src/main/java/org/session/libsession/messaging/open_groups/OpenGroupApi.kt b/libsession/src/main/java/org/session/libsession/messaging/open_groups/OpenGroupApi.kt index dc6d1475f..c6b6186c9 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/open_groups/OpenGroupApi.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/open_groups/OpenGroupApi.kt @@ -753,7 +753,8 @@ object OpenGroupApi { ) } val serverCapabilities = storage.getServerCapabilities(server) - if (serverCapabilities.contains(Capability.BLIND.name.lowercase())) { + val isAcceptingCommunityRequests = storage.isCheckingCommunityRequests() + if (serverCapabilities.contains(Capability.BLIND.name.lowercase()) && isAcceptingCommunityRequests) { requests.add( if (lastInboxMessageId == null) { BatchRequestInfo( diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/ReceivedMessageHandler.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/ReceivedMessageHandler.kt index 066201b55..9ac29f985 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/ReceivedMessageHandler.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/ReceivedMessageHandler.kt @@ -261,7 +261,17 @@ fun MessageReceiver.handleVisibleMessage( val storage = MessagingModuleConfiguration.shared.storage val context = MessagingModuleConfiguration.shared.context val userPublicKey = storage.getUserPublicKey() - val messageSender: String? = message.sender + val openGroup = if (!openGroupID.isNullOrEmpty()) { + storage.getThreadId(Address.fromSerialized(GroupUtil.getEncodedOpenGroupID(openGroupID.toByteArray())))?.let { + storage.getOpenGroup(it) + } + } else null + val senderId = SessionId(message.sender!!) + val messageSender: String? = if (openGroup != null && senderId.prefix == IdPrefix.BLINDED) { + message.sender?.let { + GroupUtil.getEncodedOpenGroupInboxID(openGroup, SessionId(it)).serialize() + } + } else message.sender // Do nothing if the message was outdated if (MessageReceiver.messageIsOutdated(message, threadId, openGroupID)) { return null } @@ -306,7 +316,7 @@ fun MessageReceiver.handleVisibleMessage( } if (userPublicKey != messageSender && !isUserBlindedSender) { - recipient.setBlocksCommunityMessageRequests(message.blocksMessageRequests) + storage.setBlocksCommunityMessageRequests(recipient, message.blocksMessageRequests) } } // Parse quote if needed diff --git a/libsession/src/main/java/org/session/libsession/utilities/GroupUtil.kt b/libsession/src/main/java/org/session/libsession/utilities/GroupUtil.kt index bfab2585d..be505f082 100644 --- a/libsession/src/main/java/org/session/libsession/utilities/GroupUtil.kt +++ b/libsession/src/main/java/org/session/libsession/utilities/GroupUtil.kt @@ -1,6 +1,7 @@ package org.session.libsession.utilities -import network.loki.messenger.libsession_util.util.GroupInfo +import org.session.libsession.messaging.open_groups.OpenGroup +import org.session.libsession.messaging.utilities.SessionId import org.session.libsignal.messages.SignalServiceGroup import org.session.libsignal.utilities.Hex import java.io.IOException @@ -15,6 +16,13 @@ object GroupUtil { return OPEN_GROUP_PREFIX + Hex.toStringCondensed(groupID) } + @JvmStatic + fun getEncodedOpenGroupInboxID(openGroup: OpenGroup, sessionId: SessionId): Address { + val openGroupInboxId = + "${openGroup.server}!${openGroup.publicKey}!${sessionId.hexString}".toByteArray() + return Address.fromSerialized(getEncodedOpenGroupInboxID(openGroupInboxId)) + } + @JvmStatic fun getEncodedOpenGroupInboxID(groupInboxID: ByteArray): String { return OPEN_GROUP_INBOX_PREFIX + Hex.toStringCondensed(groupInboxID) diff --git a/libsession/src/main/java/org/session/libsession/utilities/recipients/Recipient.java b/libsession/src/main/java/org/session/libsession/utilities/recipients/Recipient.java index 31c6f042e..12183733b 100644 --- a/libsession/src/main/java/org/session/libsession/utilities/recipients/Recipient.java +++ b/libsession/src/main/java/org/session/libsession/utilities/recipients/Recipient.java @@ -349,6 +349,10 @@ public class Recipient implements RecipientModifiedListener { if (notify) notifyListeners(); } + public boolean getBlocksCommunityMessageRequests() { + return blocksCommunityMessageRequests; + } + public void setBlocksCommunityMessageRequests(boolean blocksCommunityMessageRequests) { synchronized (this) { this.blocksCommunityMessageRequests = blocksCommunityMessageRequests;