diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index defad7b175..dfa060a161 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -26,8 +26,8 @@ configurations.configureEach {
exclude(module = "commons-logging")
}
-val canonicalVersionCode = 429
-val canonicalVersionName = "1.29.0"
+val canonicalVersionCode = 430
+val canonicalVersionName = "1.29.1"
val postFixSize = 10
val abiPostFix = mapOf(
diff --git a/app/src/main/java/org/session/libsession/messaging/sending_receiving/ReceivedMessageHandler.kt b/app/src/main/java/org/session/libsession/messaging/sending_receiving/ReceivedMessageHandler.kt
index 3954404ac3..277efe3054 100644
--- a/app/src/main/java/org/session/libsession/messaging/sending_receiving/ReceivedMessageHandler.kt
+++ b/app/src/main/java/org/session/libsession/messaging/sending_receiving/ReceivedMessageHandler.kt
@@ -409,8 +409,10 @@ class ReceivedMessageHandler @Inject constructor(
runThreadUpdate = runThreadUpdate
) ?: return null
- // If we have previously "hidden" the sender, we should flip the flag back to visible
- if (senderAddress is Address.Standard && senderAddress.address != userPublicKey) {
+ // If we have previously "hidden" the sender, we should flip the flag back to visible,
+ // and this should only be done only for 1:1 messages
+ if (senderAddress is Address.Standard && senderAddress.address != userPublicKey
+ && context.threadAddress is Address.Standard) {
val existingContact =
configFactory.withUserConfigs { it.contacts.get(senderAddress.accountId.hexString) }
diff --git a/app/src/main/java/org/session/libsession/utilities/Address.kt b/app/src/main/java/org/session/libsession/utilities/Address.kt
index 108bbfeec2..f94c823de4 100644
--- a/app/src/main/java/org/session/libsession/utilities/Address.kt
+++ b/app/src/main/java/org/session/libsession/utilities/Address.kt
@@ -175,7 +175,7 @@ sealed interface Address : Parcelable, Comparable
{
/**
* A marker interface for addresses that represent a group-like entity.
*/
- sealed interface GroupLike : Address
+ sealed interface GroupLike : Conversable
sealed interface WithAccountId {
val accountId: AccountId
diff --git a/app/src/main/java/org/thoughtcrime/securesms/contacts/ContactAccessor.java b/app/src/main/java/org/thoughtcrime/securesms/contacts/ContactAccessor.java
deleted file mode 100644
index bd3c7c1cc6..0000000000
--- a/app/src/main/java/org/thoughtcrime/securesms/contacts/ContactAccessor.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/**
- * Copyright (C) 2011 Whisper Systems
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-package org.thoughtcrime.securesms.contacts;
-
-import android.content.Context;
-import android.net.Uri;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import org.session.libsession.utilities.GroupRecord;
-import org.session.libsession.utilities.TextSecurePreferences;
-import org.thoughtcrime.securesms.database.GroupDatabase;
-import org.thoughtcrime.securesms.dependencies.DatabaseComponent;
-
-import java.util.LinkedList;
-import java.util.List;
-
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
-import network.loki.messenger.R;
-
-/**
- * This class was originally a layer of indirection between
- * ContactAccessorNewApi and ContactAccesorOldApi, which corresponded
- * to the API changes between 1.x and 2.x.
- *
- * Now that we no longer support 1.x, this class mostly serves as a place
- * to encapsulate Contact-related logic. It's still a singleton, mostly
- * just because that's how it's currently called from everywhere.
- *
- * @author Moxie Marlinspike
- */
-
-@Singleton
-public class ContactAccessor {
- private final GroupDatabase groupDatabase;
-
- @Inject
- public ContactAccessor(GroupDatabase groupDatabase) {
- this.groupDatabase = groupDatabase;
- }
-
-
- public List getNumbersForThreadSearchFilter(Context context, String constraint) {
- LinkedList numberList = new LinkedList<>();
-
- GroupRecord record;
- try (GroupDatabase.Reader reader = groupDatabase.getGroupsFilteredByTitle(constraint)) {
- while ((record = reader.getNext()) != null) {
- numberList.add(record.getEncodedId());
- }
- }
-
- return numberList;
- }
-
- public static class NumberData implements Parcelable {
-
- public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
- public NumberData createFromParcel(Parcel in) {
- return new NumberData(in);
- }
-
- public NumberData[] newArray(int size) {
- return new NumberData[size];
- }
- };
-
- public final String number;
- public final String type;
-
-
- public NumberData(Parcel in) {
- number = in.readString();
- type = in.readString();
- }
-
- public int describeContents() {
- return 0;
- }
-
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeString(number);
- dest.writeString(type);
- }
- }
-
- public static class ContactData implements Parcelable {
-
- public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
- public ContactData createFromParcel(Parcel in) {
- return new ContactData(in);
- }
-
- public ContactData[] newArray(int size) {
- return new ContactData[size];
- }
- };
-
- public final long id;
- public final String name;
- public final List numbers;
-
- public ContactData(Parcel in) {
- id = in.readLong();
- name = in.readString();
- numbers = new LinkedList();
- in.readTypedList(numbers, NumberData.CREATOR);
- }
-
- public int describeContents() {
- return 0;
- }
-
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeLong(id);
- dest.writeString(name);
- dest.writeTypedList(numbers);
- }
- }
-
-}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationViewModel.kt
index 89c980c0c5..5a87cc3cef 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationViewModel.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationViewModel.kt
@@ -225,6 +225,10 @@ class ConversationViewModel @AssistedInject constructor(
it.currentUserRole in EnumSet.of(GroupMemberRole.ADMIN, GroupMemberRole.HIDDEN_ADMIN)
}
+ val canModerate: StateFlow = recipientFlow.mapStateFlow(viewModelScope) {
+ it.currentUserRole.canModerate
+ }
+
private val _searchOpened = MutableStateFlow(false)
val appBarData: StateFlow = combine(
@@ -750,7 +754,7 @@ class ConversationViewModel @AssistedInject constructor(
}
// If the user is an admin or is interacting with their own message And are allowed to delete for everyone
- (isAdmin.value || allSentByCurrentUser) && canDeleteForEveryone -> {
+ (canModerate.value || allSentByCurrentUser) && canDeleteForEveryone -> {
_dialogsState.update {
it.copy(
deleteEveryone = DeleteForEveryoneDialogData(
diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java
index 0ab54cbdca..f7b51cef35 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java
@@ -146,8 +146,6 @@ public void postKey(SQLiteConnection connection) {
);
this.jsonProvider = jsonProvider;
-
- Log.d(TAG, "SQLCipherOpenHelper created with database secret: " + databaseSecret.asString());
}
@Override
diff --git a/app/src/main/java/org/thoughtcrime/securesms/home/HomeActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/home/HomeActivity.kt
index 9e18662ea9..c200357545 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/home/HomeActivity.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/home/HomeActivity.kt
@@ -172,7 +172,7 @@ class HomeActivity : ScreenLockActionBarActivity(),
is GlobalSearchAdapter.Model.GroupConversation -> ConversationActivityV2
.createIntent(
this,
- address = Address.fromSerialized(model.groupId) as Address.Conversable
+ address = model.address
)
else -> {
@@ -466,7 +466,7 @@ class HomeActivity : ScreenLockActionBarActivity(),
.map {
GlobalSearchAdapter.Model.Contact(
contact = it.value,
- isSelf = it.value.address.address == publicKey,
+ isSelf = it.value.isSelf,
showProBadge = it.value.proStatus.shouldShowProBadge()
)
}
@@ -479,8 +479,9 @@ class HomeActivity : ScreenLockActionBarActivity(),
isSelf = it.isSelf,
showProBadge = it.proStatus.shouldShowProBadge()
) } +
- threads.map {
- GlobalSearchAdapter.Model.GroupConversation(it, showProBadge = recipientRepository.getRecipientSync(it.encodedId.toAddress()).proStatus.shouldShowProBadge())
+ threads.mapNotNull {
+ if(it.address is Address.GroupLike) GlobalSearchAdapter.Model.GroupConversation(it)
+ else null
}
private val GlobalSearchResult.messageResults: List get() {
diff --git a/app/src/main/java/org/thoughtcrime/securesms/home/search/GlobalSearchAdapter.kt b/app/src/main/java/org/thoughtcrime/securesms/home/search/GlobalSearchAdapter.kt
index 5a5b09c708..4808702b2a 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/home/search/GlobalSearchAdapter.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/home/search/GlobalSearchAdapter.kt
@@ -14,8 +14,11 @@ import org.session.libsession.messaging.MessagingModuleConfiguration
import org.session.libsession.utilities.Address
import org.session.libsession.utilities.GroupRecord
import org.session.libsession.utilities.recipients.Recipient
+import org.session.libsession.utilities.recipients.RecipientData
import org.session.libsession.utilities.recipients.displayName
+import org.session.libsession.utilities.recipients.shouldShowProBadge
import org.session.libsignal.utilities.AccountId
+import org.session.libsignal.utilities.Log
import org.thoughtcrime.securesms.search.model.MessageResult
import org.thoughtcrime.securesms.ui.GetString
import org.thoughtcrime.securesms.util.DateUtils
@@ -147,6 +150,8 @@ class GlobalSearchAdapter(
onContactLongPressed(model)
true
}
+ } else {
+ binding.root.setOnLongClickListener(null)
}
}
}
@@ -167,26 +172,39 @@ class GlobalSearchAdapter(
this(contact.address as Address.Conversable, contact.displayName(false), isSelf, showProBadge)
}
data class GroupConversation(
- val isLegacy: Boolean,
- val groupId: String,
+ val address: Address.GroupLike,
val title: String,
val legacyMembersString: String?,
val showProBadge: Boolean
) : Model {
- constructor(groupRecord: GroupRecord, showProBadge: Boolean):
+ constructor(recipient: Recipient):
this(
- isLegacy = groupRecord.isLegacyGroup,
- groupId = groupRecord.encodedId,
- title = groupRecord.title,
- legacyMembersString = if (groupRecord.isLegacyGroup) {
- val recipients = groupRecord.members.map {
- MessagingModuleConfiguration.shared.recipientRepository.getRecipientSync(it)
+ address = recipient.address as Address.GroupLike,
+ title = recipient.displayName(),
+ legacyMembersString = when (recipient.address) {
+ is Address.LegacyGroup -> {
+ val data = (recipient.data as? RecipientData.LegacyGroup)
+ if(data == null) null
+ else {
+ if(data.secondMember != null) "${data.firstMember.displayName()}, ${data.secondMember.displayName()}".plus(
+ if(data.members.size > 2) ", ..." else ""
+ )
+ else data.firstMember.displayName().plus(
+ if(data.members.size > 1) ", ..." else ""
+ )
+ }
+ }
+
+ is Address.Group -> {
+ val data = (recipient.data as? RecipientData.Group)
+ data?.partial?.members?.joinToString(", ") { it.name }
+ }
+
+ else -> {
+ null
}
- recipients.joinToString(transform = { it.searchName })
- } else {
- null
},
- showProBadge = showProBadge
+ showProBadge = recipient.proStatus.shouldShowProBadge()
)
}
data class Message(val messageResult: MessageResult, val unread: Int, val isSelf: Boolean, val showProBadge: Boolean) : Model
diff --git a/app/src/main/java/org/thoughtcrime/securesms/home/search/GlobalSearchAdapterUtils.kt b/app/src/main/java/org/thoughtcrime/securesms/home/search/GlobalSearchAdapterUtils.kt
index 72239f1bd0..d356be5fe4 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/home/search/GlobalSearchAdapterUtils.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/home/search/GlobalSearchAdapterUtils.kt
@@ -11,6 +11,7 @@ import androidx.recyclerview.widget.DiffUtil
import network.loki.messenger.R
import org.session.libsession.messaging.MessagingModuleConfiguration
import org.session.libsession.utilities.Address
+import org.session.libsession.utilities.isLegacyGroup
import org.session.libsession.utilities.recipients.Recipient
import org.session.libsession.utilities.recipients.displayName
import org.session.libsession.utilities.truncateIdForDisplay
@@ -111,10 +112,9 @@ private fun ComposeView.setupTitleWithBadge(title: String, showProBadge: Boolean
fun ContentView.bindModel(query: String?, model: GroupConversation) {
binding.searchResultProfilePicture.isVisible = true
- binding.searchResultSubtitle.isVisible = model.isLegacy
binding.searchResultTimestamp.isVisible = false
val threadRecipient = MessagingModuleConfiguration.shared.recipientRepository.getRecipientSync(
- Address.fromSerialized(model.groupId)
+ model.address
)
binding.searchResultProfilePicture.setThemedContent {
@@ -130,7 +130,10 @@ fun ContentView.bindModel(query: String?, model: GroupConversation) {
)
if (model.legacyMembersString != null) {
+ binding.searchResultSubtitle.isVisible = true
binding.searchResultSubtitle.text = getHighlight(query, model.legacyMembersString)
+ } else {
+ binding.searchResultSubtitle.isVisible = false
}
}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/home/search/GlobalSearchResult.kt b/app/src/main/java/org/thoughtcrime/securesms/home/search/GlobalSearchResult.kt
index 3f74aa6528..04b28c0ea4 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/home/search/GlobalSearchResult.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/home/search/GlobalSearchResult.kt
@@ -8,7 +8,7 @@ import org.thoughtcrime.securesms.search.model.SearchResult
data class GlobalSearchResult(
val query: String,
val contacts: List = emptyList(),
- val threads: List = emptyList(),
+ val threads: List = emptyList(),
val messages: List = emptyList(),
val showNoteToSelf: Boolean = false
) {
diff --git a/app/src/main/java/org/thoughtcrime/securesms/search/SearchRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/search/SearchRepository.kt
index 83a8059914..16bde5de03 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/search/SearchRepository.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/search/SearchRepository.kt
@@ -3,24 +3,20 @@ package org.thoughtcrime.securesms.search
import android.content.Context
import android.database.Cursor
import dagger.hilt.android.qualifiers.ApplicationContext
+import network.loki.messenger.libsession_util.util.GroupInfo
import org.session.libsession.utilities.Address
import org.session.libsession.utilities.Address.Companion.fromSerialized
import org.session.libsession.utilities.Address.Companion.toAddress
import org.session.libsession.utilities.ConfigFactoryProtocol
-import org.session.libsession.utilities.GroupRecord
-import org.session.libsession.utilities.TextSecurePreferences
import org.session.libsession.utilities.concurrent.SignalExecutors
import org.session.libsession.utilities.recipients.Recipient
import org.session.libsession.utilities.recipients.RecipientData
-import org.session.libsession.utilities.toGroupString
+import org.session.libsession.utilities.recipients.displayName
import org.session.libsignal.utilities.AccountId
-import org.thoughtcrime.securesms.contacts.ContactAccessor
import org.thoughtcrime.securesms.database.CursorList
-import org.thoughtcrime.securesms.database.GroupDatabase
import org.thoughtcrime.securesms.database.MmsSmsColumns
import org.thoughtcrime.securesms.database.RecipientRepository
import org.thoughtcrime.securesms.database.SearchDatabase
-import org.thoughtcrime.securesms.database.ThreadDatabase
import org.thoughtcrime.securesms.repository.ConversationRepository
import org.thoughtcrime.securesms.search.model.MessageResult
import org.thoughtcrime.securesms.search.model.SearchResult
@@ -33,13 +29,9 @@ import javax.inject.Singleton
class SearchRepository @Inject constructor(
@param:ApplicationContext private val context: Context,
private val searchDatabase: SearchDatabase,
- private val threadDatabase: ThreadDatabase,
- private val groupDatabase: GroupDatabase,
- private val contactAccessor: ContactAccessor,
private val recipientRepository: RecipientRepository,
private val conversationRepository: ConversationRepository,
private val configFactory: ConfigFactoryProtocol,
- private val prefs: TextSecurePreferences,
) {
private val executor = SignalExecutors.SERIAL
@@ -128,12 +120,41 @@ class SearchRepository @Inject constructor(
private fun queryConversations(
query: String,
- ): List {
- val numbers = contactAccessor.getNumbersForThreadSearchFilter(context, query)
- val addresses = numbers.map { fromSerialized(it) }
+ ) : List {
+ if(query.isEmpty()) return emptyList()
- return threadDatabase.getThreads(addresses)
- .map { groupDatabase.getGroup(it.recipient.address.toGroupString()).get() }
+ return configFactory.withUserConfigs { configs ->
+ configs.userGroups.all()
+ }.asSequence()
+ .mapNotNull { group ->
+ when (group) {
+ is GroupInfo.ClosedGroupInfo -> {
+ if(group.invited) null // do not show groups V2 we have not yet accepted
+ else recipientRepository.getRecipientSync(
+ Address.Group(AccountId(group.groupAccountId))
+ )
+ }
+
+ is GroupInfo.LegacyGroupInfo -> {
+ recipientRepository.getRecipientSync(
+ Address.LegacyGroup(group.accountId)
+ )
+ }
+
+ is GroupInfo.CommunityGroupInfo -> {
+ recipientRepository.getRecipientSync(
+ Address.Community(
+ serverUrl = group.community.baseUrl,
+ room = group.community.room
+ )
+ )
+ }
+ }
+ }
+ .filter { group ->
+ group.displayName().contains(query, ignoreCase = true)
+ }
+ .toList()
}
private fun queryMessages(query: String): CursorList {
diff --git a/app/src/main/java/org/thoughtcrime/securesms/search/model/SearchResult.kt b/app/src/main/java/org/thoughtcrime/securesms/search/model/SearchResult.kt
index d1dfc64124..d501cd0d8c 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/search/model/SearchResult.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/search/model/SearchResult.kt
@@ -11,7 +11,7 @@ import org.thoughtcrime.securesms.database.CursorList
class SearchResult(
val query: String = "",
val contacts: List = emptyList(),
- val conversations: List = emptyList(),
+ val conversations: List = emptyList(),
val messages: CursorList = CursorList.emptyList()
) {
fun size(): Int {