diff --git a/app/build.gradle b/app/build.gradle index 562cbe713c..1bbe66bea0 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -142,7 +142,7 @@ dependencies { testImplementation 'org.robolectric:shadows-multidex:4.2' } -def canonicalVersionCode = 211 +def canonicalVersionCode = 215 def canonicalVersionName = "1.11.7" def postFixSize = 10 diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/ProfilePictureView.kt b/app/src/main/java/org/thoughtcrime/securesms/components/ProfilePictureView.kt index 6ae90d4270..eff857f699 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/ProfilePictureView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/ProfilePictureView.kt @@ -53,17 +53,15 @@ class ProfilePictureView : RelativeLayout { return recipient.isOpenGroupRecipient && recipient.groupAvatarId != null } if (recipient.isGroupRecipient && !isOpenGroupWithProfilePicture(recipient)) { - val users = MentionsManager.userPublicKeyCache[threadID]?.toMutableList() ?: mutableListOf() - users.remove(TextSecurePreferences.getLocalNumber(context)) - val randomUsers = users.sorted().toMutableList() // Sort to provide a level of stability - if (users.count() == 1) { - val userPublicKey = TextSecurePreferences.getLocalNumber(context)!! - randomUsers.add(0, userPublicKey) // Ensure the current user is at the back visually - } - val pk = randomUsers.getOrNull(0) ?: "" + val members = DatabaseFactory.getGroupDatabase(context) + .getGroupMemberAddresses(recipient.address.toGroupString(), true) + .sorted() + .take(2) + .toMutableList() + val pk = members.getOrNull(0)?.serialize() ?: "" publicKey = pk displayName = getUserDisplayName(pk) - val apk = randomUsers.getOrNull(1) ?: "" + val apk = members.getOrNull(1)?.serialize() ?: "" additionalPublicKey = apk additionalDisplayName = getUserDisplayName(apk) } else { diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/utilities/MentionManagerUtilities.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/utilities/MentionManagerUtilities.kt index 31d650a671..ca1aeeed2b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/utilities/MentionManagerUtilities.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/utilities/MentionManagerUtilities.kt @@ -9,15 +9,17 @@ import org.thoughtcrime.securesms.database.model.MessageRecord object MentionManagerUtilities { fun populateUserPublicKeyCacheIfNeeded(threadID: Long, context: Context) { + // exit early if we need to + if (MentionsManager.userPublicKeyCache[threadID] != null) return + val result = mutableSetOf() - val recipient = DatabaseFactory.getThreadDatabase(context).getRecipientForThreadId(threadID) - if (recipient != null && recipient.address.isClosedGroup) { + val recipient = DatabaseFactory.getThreadDatabase(context).getRecipientForThreadId(threadID) ?: return + if (recipient.address.isClosedGroup) { val members = DatabaseFactory.getGroupDatabase(context).getGroupMembers(recipient.address.toGroupString(), false).map { it.address.serialize() } result.addAll(members) } else { - if (MentionsManager.userPublicKeyCache[threadID] != null) { return } val messageDatabase = DatabaseFactory.getMmsSmsDatabase(context) - val reader = messageDatabase.readerFor(messageDatabase.getConversation(threadID)) + val reader = messageDatabase.readerFor(messageDatabase.getConversation(threadID, 0, 200)) var record: MessageRecord? = reader.next while (record != null) { result.add(record.individualRecipient.address.serialize()) diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/GroupDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/GroupDatabase.java index 340506ac30..78cc9b405d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/GroupDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/GroupDatabase.java @@ -14,6 +14,7 @@ import com.annimon.stream.Stream; import net.sqlcipher.database.SQLiteDatabase; +import org.session.libsession.utilities.TextSecurePreferences; import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; import org.thoughtcrime.securesms.util.BitmapUtil; @@ -155,6 +156,20 @@ public class GroupDatabase extends Database implements LokiOpenGroupDatabaseProt return recipients; } + public @NonNull List
getGroupMemberAddresses(String groupId, boolean includeSelf) { + List
members = getCurrentMembers(groupId, false); + if (!includeSelf) { + String ownNumber = TextSecurePreferences.getLocalNumber(context); + if (ownNumber == null) return members; + Address ownAddress = Address.fromSerialized(ownNumber); + int indexOfSelf = members.indexOf(ownAddress); + if (indexOfSelf >= 0) { + members.remove(indexOfSelf); + } + } + return members; + } + public @NonNull List getGroupZombieMembers(String groupId) { List
members = getCurrentZombieMembers(groupId); List recipients = new LinkedList<>(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/ThreadDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/ThreadDatabase.java index 9852fdd2e7..c9fa010e8b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/ThreadDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/ThreadDatabase.java @@ -651,7 +651,7 @@ public class ThreadDatabase extends Database { groupRecord = Optional.absent(); } - Recipient recipient = Recipient.from(context, address, settings, groupRecord, false); + Recipient recipient = Recipient.from(context, address, settings, groupRecord, true); String body = cursor.getString(cursor.getColumnIndexOrThrow(ThreadDatabase.SNIPPET)); long date = cursor.getLong(cursor.getColumnIndexOrThrow(ThreadDatabase.DATE)); long count = cursor.getLong(cursor.getColumnIndexOrThrow(ThreadDatabase.MESSAGE_COUNT)); diff --git a/app/src/main/java/org/thoughtcrime/securesms/home/ConversationView.kt b/app/src/main/java/org/thoughtcrime/securesms/home/ConversationView.kt index 9454070e77..28531ff4cc 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/home/ConversationView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/home/ConversationView.kt @@ -14,7 +14,6 @@ import androidx.recyclerview.widget.RecyclerView import kotlinx.android.synthetic.main.view_conversation.view.* import network.loki.messenger.R import org.session.libsession.utilities.recipients.Recipient -import org.thoughtcrime.securesms.conversation.v2.utilities.MentionManagerUtilities.populateUserPublicKeyCacheIfNeeded import org.thoughtcrime.securesms.conversation.v2.utilities.MentionUtilities.highlightMentions import org.thoughtcrime.securesms.database.RecipientDatabase import org.thoughtcrime.securesms.database.model.ThreadRecord @@ -40,7 +39,7 @@ class ConversationView : LinearLayout { // region Updating fun bind(thread: ThreadRecord, isTyping: Boolean, glide: GlideRequests) { this.thread = thread - populateUserPublicKeyCacheIfNeeded(thread.threadId, context) // FIXME: This is a bad place to do this + profilePictureView.glide = glide val unreadCount = thread.unreadCount if (thread.recipient.isBlocked) { accentView.setBackgroundResource(R.color.destructive) @@ -55,9 +54,8 @@ class ConversationView : LinearLayout { unreadCountTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, textSize) unreadCountTextView.setTypeface(Typeface.DEFAULT, if (unreadCount < 100) Typeface.BOLD else Typeface.NORMAL) unreadCountIndicator.isVisible = (unreadCount != 0) - profilePictureView.glide = glide - profilePictureView.update(thread.recipient, thread.threadId) - val senderDisplayName = getUserDisplayName(thread.recipient) ?: thread.recipient.address.toString() + val senderDisplayName = getUserDisplayName(thread.recipient) + ?: thread.recipient.address.toString() conversationViewDisplayNameTextView.text = senderDisplayName timestampTextView.text = DateUtils.getDisplayFormattedTimeSpanString(context, Locale.getDefault(), thread.date) val recipient = thread.recipient @@ -84,13 +82,16 @@ class ConversationView : LinearLayout { !thread.isOutgoing -> statusIndicatorImageView.visibility = View.GONE thread.isFailed -> { val drawable = ContextCompat.getDrawable(context, R.drawable.ic_error)?.mutate() - drawable?.setTint(ContextCompat.getColor(context,R.color.destructive)) + drawable?.setTint(ContextCompat.getColor(context, R.color.destructive)) statusIndicatorImageView.setImageDrawable(drawable) } thread.isPending -> statusIndicatorImageView.setImageResource(R.drawable.ic_circle_dot_dot_dot) thread.isRead -> statusIndicatorImageView.setImageResource(R.drawable.ic_filled_circle_check) else -> statusIndicatorImageView.setImageResource(R.drawable.ic_circle_check) } + post { + profilePictureView.update(thread.recipient, thread.threadId) + } } fun recycle() { 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 4a59fcdba8..d8bc59d7da 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/home/HomeActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/home/HomeActivity.kt @@ -80,8 +80,7 @@ class HomeActivity : PassphraseRequiredActionBarActivity(), ConversationClickLis // Set up seed reminder view val hasViewedSeed = TextSecurePreferences.getHasViewedSeed(this) if (!hasViewedSeed) { - seedReminderStub.isVisible = true - seedReminderStub.apply { + seedReminderStub.inflate().apply { val seedReminderView = this.seedReminderView val seedReminderViewTitle = SpannableString("You're almost finished! 80%") // Intentionally not yet translated seedReminderViewTitle.setSpan(ForegroundColorSpan(resources.getColorWithID(R.color.accent, theme)), 24, 27, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) 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 5b31ded3c5..3018286423 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 @@ -153,6 +153,7 @@ public class Recipient implements RecipientModifiedListener { this.profileSharing = stale.profileSharing; this.unidentifiedAccessMode = stale.unidentifiedAccessMode; this.forceSmsSelection = stale.forceSmsSelection; + this.notifyType = stale.notifyType; this.participants.clear(); this.participants.addAll(stale.participants); @@ -180,6 +181,7 @@ public class Recipient implements RecipientModifiedListener { this.profileSharing = details.get().profileSharing; this.unidentifiedAccessMode = details.get().unidentifiedAccessMode; this.forceSmsSelection = details.get().forceSmsSelection; + this.notifyType = details.get().notifyType; this.participants.clear(); this.participants.addAll(details.get().participants);