From 916f705c50deabe69f9cb92771285fff7b53dd0f Mon Sep 17 00:00:00 2001 From: andrew Date: Mon, 31 Jul 2023 14:44:43 +0930 Subject: [PATCH 01/46] Prefix message with name in HomeActivity --- .../securesms/database/MmsSmsDatabase.java | 10 +++++++ .../securesms/database/ThreadDatabase.java | 10 ++++++- .../database/model/ThreadRecord.java | 4 ++- .../securesms/home/ConversationView.kt | 29 +++++++++++++------ 4 files changed, 42 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MmsSmsDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/MmsSmsDatabase.java index 0db4dd00e5..3d175fd8bd 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MmsSmsDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MmsSmsDatabase.java @@ -209,6 +209,16 @@ public class MmsSmsDatabase extends Database { } } + public long getLastMessageTimestamp(long threadId) { + String order = MmsSmsColumns.NORMALIZED_DATE_SENT + " DESC"; + String selection = MmsSmsColumns.THREAD_ID + " = " + threadId; + + try (Cursor cursor = queryTables(PROJECTION, selection, order, "1")) { + cursor.moveToFirst(); + return cursor.getLong(cursor.getColumnIndexOrThrow(MmsSmsColumns.NORMALIZED_DATE_SENT)); + } + } + public Cursor getUnread() { String order = MmsSmsColumns.NORMALIZED_DATE_SENT + " ASC"; String selection = "(" + MmsSmsColumns.READ + " = 0 OR " + MmsSmsColumns.REACTIONS_UNREAD + " = 1) AND " + MmsSmsColumns.NOTIFIED + " = 0"; 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 5044529981..c525f05e7d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/ThreadDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/ThreadDatabase.java @@ -951,7 +951,9 @@ public class ThreadDatabase extends Database { readReceiptCount = 0; } - return new ThreadRecord(body, snippetUri, recipient, date, count, + MessageRecord lastMessage = count > 0 ? getLastMessage(threadId) : null; + + return new ThreadRecord(body, snippetUri, lastMessage, recipient, date, count, unreadCount, unreadMentionCount, threadId, deliveryReceiptCount, status, type, distributionType, archived, expiresIn, lastSeen, readReceiptCount, pinned); } @@ -976,4 +978,10 @@ public class ThreadDatabase extends Database { } } } + + private MessageRecord getLastMessage(long threadId) { + MmsSmsDatabase mmsSmsDatabase = DatabaseComponent.get(context).mmsSmsDatabase(); + long messageTimestamp = mmsSmsDatabase.getLastMessageTimestamp(threadId); + return mmsSmsDatabase.getMessageForTimestamp(messageTimestamp); + } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/model/ThreadRecord.java b/app/src/main/java/org/thoughtcrime/securesms/database/model/ThreadRecord.java index f3e72a8747..0c023a8f29 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/model/ThreadRecord.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/model/ThreadRecord.java @@ -43,6 +43,7 @@ import network.loki.messenger.R; public class ThreadRecord extends DisplayRecord { private @Nullable final Uri snippetUri; + public @Nullable final MessageRecord lastMessage; private final long count; private final int unreadCount; private final int unreadMentionCount; @@ -54,13 +55,14 @@ public class ThreadRecord extends DisplayRecord { private final int initialRecipientHash; public ThreadRecord(@NonNull String body, @Nullable Uri snippetUri, - @NonNull Recipient recipient, long date, long count, int unreadCount, + @Nullable MessageRecord lastMessage, @NonNull Recipient recipient, long date, long count, int unreadCount, int unreadMentionCount, long threadId, int deliveryReceiptCount, int status, long snippetType, int distributionType, boolean archived, long expiresIn, long lastSeen, int readReceiptCount, boolean pinned) { super(body, recipient, date, date, threadId, status, deliveryReceiptCount, snippetType, readReceiptCount); this.snippetUri = snippetUri; + this.lastMessage = lastMessage; this.count = count; this.unreadCount = unreadCount; this.unreadMentionCount = unreadMentionCount; 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 31b281c6de..454bcef18d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/home/ConversationView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/home/ConversationView.kt @@ -4,6 +4,8 @@ import android.content.Context import android.content.res.Resources import android.graphics.Typeface import android.graphics.drawable.ColorDrawable +import android.text.SpannableString +import android.text.TextUtils import android.util.AttributeSet import android.util.TypedValue import android.view.View @@ -89,7 +91,7 @@ class ConversationView : LinearLayout { || (configFactory.convoVolatile?.getConversationUnread(thread) == true) binding.unreadMentionTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, textSize) binding.unreadMentionIndicator.isVisible = (thread.unreadMentionCount != 0 && thread.recipient.address.isGroup) - val senderDisplayName = getUserDisplayName(thread.recipient) + val senderDisplayName = getTitle(thread.recipient) ?: thread.recipient.address.toString() binding.conversationViewDisplayNameTextView.text = senderDisplayName binding.timestampTextView.text = DateUtils.getDisplayFormattedTimeSpanString(context, Locale.getDefault(), thread.date) @@ -101,9 +103,7 @@ class ConversationView : LinearLayout { R.drawable.ic_notifications_mentions } binding.muteIndicatorImageView.setImageResource(drawableRes) - val rawSnippet = thread.getDisplayBody(context) - val snippet = highlightMentions(rawSnippet, thread.threadId, context) - binding.snippetTextView.text = snippet + binding.snippetTextView.text = highlightMentions(getSnippet(thread), thread.threadId, context) binding.snippetTextView.typeface = if (unreadCount > 0 && !thread.isRead) Typeface.DEFAULT_BOLD else Typeface.DEFAULT binding.snippetTextView.visibility = if (isTyping) View.GONE else View.VISIBLE if (isTyping) { @@ -131,11 +131,22 @@ class ConversationView : LinearLayout { binding.profilePictureView.recycle() } - private fun getUserDisplayName(recipient: Recipient): String? { - return if (recipient.isLocalNumber) { - context.getString(R.string.note_to_self) - } else { - recipient.toShortString() // Internally uses the Contact API + private fun getTitle(recipient: Recipient): String? = when { + recipient.isLocalNumber -> context.getString(R.string.note_to_self) + else -> recipient.toShortString() // Internally uses the Contact API + } + + private fun getSnippet(thread: ThreadRecord): CharSequence { + thread.apply { + val body = getDisplayBody(context) + + val snippetAuthor = lastMessage?.individualRecipient + + return if (lastMessage?.isOutgoing == true) { + TextUtils.concat(resources.getString(R.string.MessageRecord_you), ": ", body) + } else { + return snippetAuthor?.toShortString()?.let { TextUtils.concat(it, ": ", body) } ?: body + } } } // endregion From dd345cbf074bb54e7e86d1f4e2a82f446f3dd2d3 Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 31 Jul 2023 19:40:20 +0930 Subject: [PATCH 02/46] Hide sender prefix for note to self --- .../securesms/home/ConversationView.kt | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) 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 454bcef18d..5191e05d77 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/home/ConversationView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/home/ConversationView.kt @@ -136,17 +136,19 @@ class ConversationView : LinearLayout { else -> recipient.toShortString() // Internally uses the Contact API } - private fun getSnippet(thread: ThreadRecord): CharSequence { - thread.apply { - val body = getDisplayBody(context) + private fun getSnippet(thread: ThreadRecord): CharSequence = thread.run { + val body = getDisplayBody(context) - val snippetAuthor = lastMessage?.individualRecipient - - return if (lastMessage?.isOutgoing == true) { + when { + recipient.isLocalNumber -> body // Note to self + lastMessage?.isOutgoing == true -> { TextUtils.concat(resources.getString(R.string.MessageRecord_you), ": ", body) - } else { - return snippetAuthor?.toShortString()?.let { TextUtils.concat(it, ": ", body) } ?: body } + else -> lastMessage + ?.individualRecipient + ?.toShortString() + ?.let { TextUtils.concat(it, ": ", body) } + ?: body } } // endregion From b487d5aa6407a1b91f48346ee4a7171401828814 Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 31 Jul 2023 19:48:45 +0930 Subject: [PATCH 03/46] Hide sender prefix for control messages --- .../java/org/thoughtcrime/securesms/home/ConversationView.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 5191e05d77..b1bd55b20a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/home/ConversationView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/home/ConversationView.kt @@ -140,7 +140,7 @@ class ConversationView : LinearLayout { val body = getDisplayBody(context) when { - recipient.isLocalNumber -> body // Note to self + recipient.isLocalNumber || lastMessage?.isControlMessage == true -> body // Note to self lastMessage?.isOutgoing == true -> { TextUtils.concat(resources.getString(R.string.MessageRecord_you), ": ", body) } From f70aa9155b04b2980da1ce726826f483ceef6c49 Mon Sep 17 00:00:00 2001 From: andrew Date: Mon, 7 Aug 2023 10:26:20 +0930 Subject: [PATCH 04/46] Remove problematic getLastMessage() --- .../securesms/database/ThreadDatabase.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) 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 c525f05e7d..f4ab65f56c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/ThreadDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/ThreadDatabase.java @@ -951,7 +951,13 @@ public class ThreadDatabase extends Database { readReceiptCount = 0; } - MessageRecord lastMessage = count > 0 ? getLastMessage(threadId) : null; + MessageRecord lastMessage = null; + + if (count > 0) { + MmsSmsDatabase mmsSmsDatabase = DatabaseComponent.get(context).mmsSmsDatabase(); + long messageTimestamp = mmsSmsDatabase.getLastMessageTimestamp(threadId); + lastMessage = mmsSmsDatabase.getMessageForTimestamp(messageTimestamp); + } return new ThreadRecord(body, snippetUri, lastMessage, recipient, date, count, unreadCount, unreadMentionCount, threadId, deliveryReceiptCount, status, type, @@ -978,10 +984,4 @@ public class ThreadDatabase extends Database { } } } - - private MessageRecord getLastMessage(long threadId) { - MmsSmsDatabase mmsSmsDatabase = DatabaseComponent.get(context).mmsSmsDatabase(); - long messageTimestamp = mmsSmsDatabase.getLastMessageTimestamp(threadId); - return mmsSmsDatabase.getMessageForTimestamp(messageTimestamp); - } } From 50fd3292c8b9cb45d6b7f8da212adcf2d15da2f7 Mon Sep 17 00:00:00 2001 From: andrew Date: Mon, 7 Aug 2023 10:46:38 +0930 Subject: [PATCH 05/46] Refactor snippet formatting --- .../securesms/home/ConversationView.kt | 24 ++++++++----------- 1 file changed, 10 insertions(+), 14 deletions(-) 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 b1bd55b20a..47a37a092a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/home/ConversationView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/home/ConversationView.kt @@ -103,7 +103,7 @@ class ConversationView : LinearLayout { R.drawable.ic_notifications_mentions } binding.muteIndicatorImageView.setImageResource(drawableRes) - binding.snippetTextView.text = highlightMentions(getSnippet(thread), thread.threadId, context) + binding.snippetTextView.text = highlightMentions(thread.getSnippet(), thread.threadId, context) binding.snippetTextView.typeface = if (unreadCount > 0 && !thread.isRead) Typeface.DEFAULT_BOLD else Typeface.DEFAULT binding.snippetTextView.visibility = if (isTyping) View.GONE else View.VISIBLE if (isTyping) { @@ -136,20 +136,16 @@ class ConversationView : LinearLayout { else -> recipient.toShortString() // Internally uses the Contact API } - private fun getSnippet(thread: ThreadRecord): CharSequence = thread.run { - val body = getDisplayBody(context) + private fun ThreadRecord.getSnippet(): CharSequence = + concatSnippet(getSnippetPrefix(), getDisplayBody(context)) - when { - recipient.isLocalNumber || lastMessage?.isControlMessage == true -> body // Note to self - lastMessage?.isOutgoing == true -> { - TextUtils.concat(resources.getString(R.string.MessageRecord_you), ": ", body) - } - else -> lastMessage - ?.individualRecipient - ?.toShortString() - ?.let { TextUtils.concat(it, ": ", body) } - ?: body - } + private fun concatSnippet(prefix: CharSequence?, body: CharSequence): CharSequence = + prefix?.let { TextUtils.concat(it, ": ", body) } ?: body + + private fun ThreadRecord.getSnippetPrefix(): CharSequence? = when { + recipient.isLocalNumber || lastMessage?.isControlMessage == true -> null + lastMessage?.isOutgoing == true -> resources.getString(R.string.MessageRecord_you) + else -> lastMessage?.individualRecipient?.toShortString() } // endregion } From 1f6542eff367b96e733c4f488700330715937ce8 Mon Sep 17 00:00:00 2001 From: andrew Date: Fri, 22 Sep 2023 00:16:10 +0930 Subject: [PATCH 06/46] Fix dialog button style --- .../org/thoughtcrime/securesms/SessionDialogBuilder.kt | 7 ++----- .../destructive_dialog_text_button_background.xml | 1 - .../unimportant_dialog_text_button_background.xml | 1 - app/src/main/res/layout/dialog_clear_all_data.xml | 8 +++----- app/src/main/res/layout/dialog_send_seed.xml | 4 ++-- app/src/main/res/values/dimens.xml | 1 + app/src/main/res/values/styles.xml | 1 + 7 files changed, 9 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/SessionDialogBuilder.kt b/app/src/main/java/org/thoughtcrime/securesms/SessionDialogBuilder.kt index 44c30741ef..18113ea474 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/SessionDialogBuilder.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/SessionDialogBuilder.kt @@ -14,14 +14,12 @@ import androidx.annotation.LayoutRes import androidx.annotation.StringRes import androidx.annotation.StyleRes import androidx.appcompat.app.AlertDialog -import androidx.core.view.setMargins import androidx.core.view.setPadding import androidx.core.view.updateMargins import androidx.fragment.app.Fragment import network.loki.messenger.R import org.thoughtcrime.securesms.util.toPx - @DslMarker @Target(AnnotationTarget.CLASS, AnnotationTarget.TYPE) annotation class DialogDsl @@ -31,6 +29,7 @@ class SessionDialogBuilder(val context: Context) { private val dp20 = toPx(20, context.resources) private val dp40 = toPx(40, context.resources) + private val dp60 = toPx(60, context.resources) private val dialogBuilder: AlertDialog.Builder = AlertDialog.Builder(context) @@ -64,7 +63,6 @@ class SessionDialogBuilder(val context: Context) { } } - private fun text(text: CharSequence?, @StyleRes style: Int, modify: TextView.() -> Unit) { text ?: return TextView(context, null, 0, style) @@ -125,8 +123,7 @@ class SessionDialogBuilder(val context: Context) { ) = Button(context, null, 0, style).apply { setText(text) contentDescription = resources.getString(contentDescriptionRes) - layoutParams = LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT, 1f) - .apply { setMargins(toPx(20, resources)) } + layoutParams = LinearLayout.LayoutParams(MATCH_PARENT, dp60, 1f) setOnClickListener { listener.invoke() if (dismiss) dismiss() diff --git a/app/src/main/res/drawable/destructive_dialog_text_button_background.xml b/app/src/main/res/drawable/destructive_dialog_text_button_background.xml index f3e13c8000..3ba98c4992 100644 --- a/app/src/main/res/drawable/destructive_dialog_text_button_background.xml +++ b/app/src/main/res/drawable/destructive_dialog_text_button_background.xml @@ -4,7 +4,6 @@ - diff --git a/app/src/main/res/drawable/unimportant_dialog_text_button_background.xml b/app/src/main/res/drawable/unimportant_dialog_text_button_background.xml index f3e13c8000..3ba98c4992 100644 --- a/app/src/main/res/drawable/unimportant_dialog_text_button_background.xml +++ b/app/src/main/res/drawable/unimportant_dialog_text_button_background.xml @@ -4,7 +4,6 @@ - diff --git a/app/src/main/res/layout/dialog_clear_all_data.xml b/app/src/main/res/layout/dialog_clear_all_data.xml index db95647dad..94d4828e21 100644 --- a/app/src/main/res/layout/dialog_clear_all_data.xml +++ b/app/src/main/res/layout/dialog_clear_all_data.xml @@ -6,8 +6,7 @@ android:layout_height="match_parent" android:gravity="center_horizontal" android:orientation="vertical" - android:elevation="4dp" - android:padding="@dimen/medium_spacing"> + android:elevation="4dp">