From c0d5c22a2163ab58c2d1b7cf5e383643a55d67fa Mon Sep 17 00:00:00 2001 From: Ryan ZHAO Date: Wed, 2 Sep 2020 16:59:52 +1000 Subject: [PATCH 1/8] WIP: show attachment in conversation preview as iOS --- res/values/strings.xml | 4 +++ .../securesms/database/ThreadDatabase.java | 10 +++++-- src/org/thoughtcrime/securesms/mms/Slide.java | 29 ++++++++++++++++++- 3 files changed, 39 insertions(+), 4 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 4a2b5ca5e3..d61a5ce87c 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -1855,4 +1855,8 @@ Secure session reset done + + Attachment + Voice Message + diff --git a/src/org/thoughtcrime/securesms/database/ThreadDatabase.java b/src/org/thoughtcrime/securesms/database/ThreadDatabase.java index 1de021e206..d614b412f7 100644 --- a/src/org/thoughtcrime/securesms/database/ThreadDatabase.java +++ b/src/org/thoughtcrime/securesms/database/ThreadDatabase.java @@ -618,9 +618,13 @@ public class ThreadDatabase extends Database { } private @NonNull String getFormattedBodyFor(@NonNull MessageRecord messageRecord) { - if (messageRecord.isMms() && ((MmsMessageRecord) messageRecord).getSharedContacts().size() > 0) { - Contact contact = ((MmsMessageRecord) messageRecord).getSharedContacts().get(0); - return ContactUtil.getStringSummary(context, contact).toString(); + if (messageRecord.isMms()) { + MmsMessageRecord record = (MmsMessageRecord) messageRecord; + if (record.getSlideDeck().getBody()) + if (record.getSharedContacts().size() > 0) { + Contact contact = ((MmsMessageRecord) messageRecord).getSharedContacts().get(0); + return ContactUtil.getStringSummary(context, contact).toString(); + } } return messageRecord.getBody(); diff --git a/src/org/thoughtcrime/securesms/mms/Slide.java b/src/org/thoughtcrime/securesms/mms/Slide.java index 2c5dc1cb16..bd3838c4aa 100644 --- a/src/org/thoughtcrime/securesms/mms/Slide.java +++ b/src/org/thoughtcrime/securesms/mms/Slide.java @@ -22,6 +22,7 @@ import android.net.Uri; import androidx.annotation.DrawableRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import com.google.android.exoplayer2.util.MimeTypes; import org.thoughtcrime.securesms.attachments.Attachment; import org.thoughtcrime.securesms.attachments.UriAttachment; @@ -33,6 +34,8 @@ import org.whispersystems.libsignal.util.guava.Optional; import java.security.SecureRandom; +import network.loki.messenger.R; + public abstract class Slide { protected final Attachment attachment; @@ -59,7 +62,31 @@ public abstract class Slide { @NonNull public Optional getBody() { - return Optional.absent(); + String attachmentString = context.getString(R.string.attachment); + + if (MimeTypes.isAudio(attachment.getContentType())) { + // a missing filename is the legacy way to determine if an audio attachment is + // a voice note vs. other arbitrary audio attachments. + if (attachment.isVoiceNote() || !attachment.getFileName().isEmpty()) { + attachmentString = context.getString(R.string.attachment_type_voice_message); + return Optional.fromNullable("🎤 " + attachmentString); + } + } + return Optional.fromNullable(emojiForMimeType(attachment.getContentType()) + attachmentString); + } + + private String emojiForMimeType(String contentType) { + if (MimeTypes.isVideo(contentType)) { + return "📷 "; + } else if (MimeTypes.isVideo(contentType)) { + return "🎥 "; + } else if (MimeTypes.isAudio(contentType)) { + return "🎧 "; + } else if (MimeTypes.is) { + return "🎡 "; + } else { + return "📎 "; + } } @NonNull From ce6e5a7fc93fde16cb8ca834773c81a769f4ea2b Mon Sep 17 00:00:00 2001 From: Anton Chekulaev Date: Thu, 3 Sep 2020 12:49:42 +1000 Subject: [PATCH 2/8] Fixed new outlined camera icon cannot be rendered on the API 21 devices. --- res/drawable/ic_outline_photo_camera_24.xml | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/res/drawable/ic_outline_photo_camera_24.xml b/res/drawable/ic_outline_photo_camera_24.xml index 58dee806f9..59e933eea1 100644 --- a/res/drawable/ic_outline_photo_camera_24.xml +++ b/res/drawable/ic_outline_photo_camera_24.xml @@ -3,13 +3,11 @@ android:height="24dp" android:viewportWidth="24" android:viewportHeight="24" - android:tint="?attr/colorControlNormal"> + android:tint="?android:colorControlNormal"> + android:pathData="M8.8496,2.2148L8.627,2.459L7.1289,4.0938L4.4805,4.0938C3.0376,4.0938 1.8496,5.28 1.8496,6.7227L1.8496,17.9961C1.8496,19.4388 3.0376,20.625 4.4805,20.625L19.5195,20.625C20.9624,20.625 22.1504,19.4388 22.1504,17.9961L22.1504,6.7227C22.1504,5.28 20.9624,4.0938 19.5195,4.0938L16.8711,4.0938L15.1504,2.2148L8.8496,2.2148zM9.5098,3.7148L14.4902,3.7148L16.2109,5.5938L19.5195,5.5938C20.1447,5.5938 20.6504,6.0987 20.6504,6.7227L20.6504,17.9961C20.6504,18.6201 20.1447,19.125 19.5195,19.125L4.4805,19.125C3.8553,19.125 3.3496,18.62 3.3496,17.9961L3.3496,6.7227C3.3496,6.0987 3.8553,5.5938 4.4805,5.5938L7.7891,5.5938L9.5098,3.7148z" + android:fillColor="#000000"/> + android:pathData="M12,7.4648C9.2499,7.4648 7.0039,9.7109 7.0039,12.4609C7.0039,15.211 9.2499,17.457 12,17.457C14.7501,17.457 16.9961,15.211 16.9961,12.4609C16.9961,9.7109 14.7501,7.4648 12,7.4648zM12,8.9648C13.9394,8.9648 15.4961,10.5215 15.4961,12.4609C15.4961,14.4003 13.9394,15.957 12,15.957C10.0606,15.957 8.5039,14.4003 8.5039,12.4609C8.5039,10.5215 10.0606,8.9648 12,8.9648z" + android:fillColor="#000000"/> From 74378a88abe663d10ed55d5cb8a1b921cf13d098 Mon Sep 17 00:00:00 2001 From: Ryan ZHAO Date: Thu, 3 Sep 2020 13:14:26 +1000 Subject: [PATCH 3/8] fix duplicated sent messages in open groups --- src/org/thoughtcrime/securesms/loki/api/PublicChatPoller.kt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/org/thoughtcrime/securesms/loki/api/PublicChatPoller.kt b/src/org/thoughtcrime/securesms/loki/api/PublicChatPoller.kt index 80b52c533e..443cc84a59 100644 --- a/src/org/thoughtcrime/securesms/loki/api/PublicChatPoller.kt +++ b/src/org/thoughtcrime/securesms/loki/api/PublicChatPoller.kt @@ -186,6 +186,12 @@ class PublicChatPoller(private val context: Context, private val group: PublicCh } fun processOutgoingMessage(message: PublicChatMessage) { val messageServerID = message.serverID ?: return + val messageID = DatabaseFactory.getLokiMessageDatabase(context).getMessageID(messageServerID) + var isDuplicate = false + if (messageID != null) { + isDuplicate = DatabaseFactory.getMmsDatabase(context).getThreadIdForMessage(messageID) > 0 || DatabaseFactory.getSmsDatabase(context).getThreadIdForMessage(messageID) > 0 + } + if (isDuplicate) { return } if (message.body.isEmpty() && message.attachments.isEmpty() && message.quote == null) { return } val userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(context) val dataMessage = getDataMessage(message) From 79086e41fcb6bf7aa7fe2709f4f2fa327cf649fd Mon Sep 17 00:00:00 2001 From: Anton Chekulaev Date: Thu, 3 Sep 2020 13:27:02 +1000 Subject: [PATCH 4/8] Do not treat SVGs as regular images. --- src/org/thoughtcrime/securesms/util/MediaUtil.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/org/thoughtcrime/securesms/util/MediaUtil.java b/src/org/thoughtcrime/securesms/util/MediaUtil.java index 6163ba16d6..6278073fd0 100644 --- a/src/org/thoughtcrime/securesms/util/MediaUtil.java +++ b/src/org/thoughtcrime/securesms/util/MediaUtil.java @@ -226,7 +226,9 @@ public class MediaUtil { } public static boolean isImageType(String contentType) { - return (null != contentType) && contentType.startsWith("image/"); + return (null != contentType) + && contentType.startsWith("image/") + && !contentType.contains("svg"); // Do not treat SVGs as regular images. } public static boolean isAudioType(String contentType) { From f42855f43ec491bc92f238f0000828d8bc157d75 Mon Sep 17 00:00:00 2001 From: Ryan ZHAO Date: Thu, 3 Sep 2020 14:41:00 +1000 Subject: [PATCH 5/8] show attachment emoji in conversation previews --- .../securesms/database/ThreadDatabase.java | 9 +++++++-- .../securesms/mms/OutgoingMediaMessage.java | 7 ++----- src/org/thoughtcrime/securesms/mms/Slide.java | 20 +++++++++---------- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/org/thoughtcrime/securesms/database/ThreadDatabase.java b/src/org/thoughtcrime/securesms/database/ThreadDatabase.java index d614b412f7..41903ae23e 100644 --- a/src/org/thoughtcrime/securesms/database/ThreadDatabase.java +++ b/src/org/thoughtcrime/securesms/database/ThreadDatabase.java @@ -620,13 +620,18 @@ public class ThreadDatabase extends Database { private @NonNull String getFormattedBodyFor(@NonNull MessageRecord messageRecord) { if (messageRecord.isMms()) { MmsMessageRecord record = (MmsMessageRecord) messageRecord; - if (record.getSlideDeck().getBody()) if (record.getSharedContacts().size() > 0) { Contact contact = ((MmsMessageRecord) messageRecord).getSharedContacts().get(0); return ContactUtil.getStringSummary(context, contact).toString(); } + String attachmentString = record.getSlideDeck().getBody(); + if (!attachmentString.isEmpty()) { + if (!messageRecord.getBody().isEmpty()) { + attachmentString = attachmentString + ": " + messageRecord.getBody(); + } + return attachmentString; + } } - return messageRecord.getBody(); } diff --git a/src/org/thoughtcrime/securesms/mms/OutgoingMediaMessage.java b/src/org/thoughtcrime/securesms/mms/OutgoingMediaMessage.java index 6a73726448..cb5252a657 100644 --- a/src/org/thoughtcrime/securesms/mms/OutgoingMediaMessage.java +++ b/src/org/thoughtcrime/securesms/mms/OutgoingMediaMessage.java @@ -146,13 +146,10 @@ public class OutgoingMediaMessage { } private static String buildMessage(SlideDeck slideDeck, String message) { - if (!TextUtils.isEmpty(message) && !TextUtils.isEmpty(slideDeck.getBody())) { - return slideDeck.getBody() + "\n\n" + message; - } else if (!TextUtils.isEmpty(message)) { + if (!TextUtils.isEmpty(message)) { return message; - } else { - return slideDeck.getBody(); } + return ""; } } diff --git a/src/org/thoughtcrime/securesms/mms/Slide.java b/src/org/thoughtcrime/securesms/mms/Slide.java index bd3838c4aa..fe9a7a9b77 100644 --- a/src/org/thoughtcrime/securesms/mms/Slide.java +++ b/src/org/thoughtcrime/securesms/mms/Slide.java @@ -22,8 +22,6 @@ import android.net.Uri; import androidx.annotation.DrawableRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import com.google.android.exoplayer2.util.MimeTypes; - import org.thoughtcrime.securesms.attachments.Attachment; import org.thoughtcrime.securesms.attachments.UriAttachment; import org.thoughtcrime.securesms.database.AttachmentDatabase; @@ -64,7 +62,7 @@ public abstract class Slide { public Optional getBody() { String attachmentString = context.getString(R.string.attachment); - if (MimeTypes.isAudio(attachment.getContentType())) { + if (MediaUtil.isAudio(attachment)) { // a missing filename is the legacy way to determine if an audio attachment is // a voice note vs. other arbitrary audio attachments. if (attachment.isVoiceNote() || !attachment.getFileName().isEmpty()) { @@ -72,20 +70,20 @@ public abstract class Slide { return Optional.fromNullable("🎤 " + attachmentString); } } - return Optional.fromNullable(emojiForMimeType(attachment.getContentType()) + attachmentString); + return Optional.fromNullable(emojiForMimeType() + attachmentString); } - private String emojiForMimeType(String contentType) { - if (MimeTypes.isVideo(contentType)) { + private String emojiForMimeType() { + if (MediaUtil.isImage(attachment)) { return "📷 "; - } else if (MimeTypes.isVideo(contentType)) { + } else if (MediaUtil.isVideo(attachment)) { return "🎥 "; - } else if (MimeTypes.isAudio(contentType)) { + } else if (MediaUtil.isAudio(attachment)) { return "🎧 "; - } else if (MimeTypes.is) { - return "🎡 "; - } else { + } else if (MediaUtil.isFile(attachment)) { return "📎 "; + } else { + return "🎡 "; } } From d575867d6b7afefb7adf7326ce5ee936279dcad4 Mon Sep 17 00:00:00 2001 From: Ryan ZHAO Date: Thu, 3 Sep 2020 15:07:59 +1000 Subject: [PATCH 6/8] show attachment emoji in notification --- .../securesms/notifications/DefaultMessageNotifier.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/org/thoughtcrime/securesms/notifications/DefaultMessageNotifier.java b/src/org/thoughtcrime/securesms/notifications/DefaultMessageNotifier.java index 6945c05027..974667cb6f 100644 --- a/src/org/thoughtcrime/securesms/notifications/DefaultMessageNotifier.java +++ b/src/org/thoughtcrime/securesms/notifications/DefaultMessageNotifier.java @@ -479,13 +479,13 @@ public class DefaultMessageNotifier implements MessageNotifier { body = SpanUtil.italic(context.getString(R.string.MessageNotifier_sticker)); slideDeck = ((MmsMessageRecord) record).getSlideDeck(); } else if (record.isMms() && TextUtils.isEmpty(body) && !((MmsMessageRecord) record).getSlideDeck().getSlides().isEmpty()) { - body = SpanUtil.italic(context.getString(R.string.MessageNotifier_media_message)); slideDeck = ((MediaMmsMessageRecord)record).getSlideDeck(); + body = SpanUtil.italic(slideDeck.getBody()); } else if (record.isMms() && !record.isMmsNotification() && !((MmsMessageRecord) record).getSlideDeck().getSlides().isEmpty()) { - String message = context.getString(R.string.MessageNotifier_media_message_with_text, body); + slideDeck = ((MediaMmsMessageRecord)record).getSlideDeck(); + String message = slideDeck.getBody() + ": " + record.getBody(); int italicLength = message.length() - body.length(); body = SpanUtil.italic(message, italicLength); - slideDeck = ((MediaMmsMessageRecord)record).getSlideDeck(); } if (threadRecipients == null || !threadRecipients.isMuted()) { From 95f4d21ecddb895e403cd390d7aa9c1d411529ca Mon Sep 17 00:00:00 2001 From: nielsandriesse Date: Thu, 3 Sep 2020 15:25:49 +1000 Subject: [PATCH 7/8] Update build number --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 7cc758288b..ea141a6d88 100644 --- a/build.gradle +++ b/build.gradle @@ -182,7 +182,7 @@ dependencies { implementation "com.opencsv:opencsv:4.6" } -def canonicalVersionCode = 83 +def canonicalVersionCode = 84 def canonicalVersionName = "1.5.0" def postFixSize = 10 From 47af97be57ebea88713676ff18104b48e1f71927 Mon Sep 17 00:00:00 2001 From: nielsandriesse Date: Thu, 3 Sep 2020 17:23:23 +1000 Subject: [PATCH 8/8] Fix inverted flag --- res/values/strings.xml | 1 - src/org/thoughtcrime/securesms/loki/api/PublicChatPoller.kt | 3 ++- src/org/thoughtcrime/securesms/mms/Slide.java | 5 +++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index c56c0332cf..674ce114f2 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -1862,7 +1862,6 @@ Copy Session ID - Attachment Voice Message diff --git a/src/org/thoughtcrime/securesms/loki/api/PublicChatPoller.kt b/src/org/thoughtcrime/securesms/loki/api/PublicChatPoller.kt index 443cc84a59..147b01400c 100644 --- a/src/org/thoughtcrime/securesms/loki/api/PublicChatPoller.kt +++ b/src/org/thoughtcrime/securesms/loki/api/PublicChatPoller.kt @@ -189,7 +189,8 @@ class PublicChatPoller(private val context: Context, private val group: PublicCh val messageID = DatabaseFactory.getLokiMessageDatabase(context).getMessageID(messageServerID) var isDuplicate = false if (messageID != null) { - isDuplicate = DatabaseFactory.getMmsDatabase(context).getThreadIdForMessage(messageID) > 0 || DatabaseFactory.getSmsDatabase(context).getThreadIdForMessage(messageID) > 0 + isDuplicate = DatabaseFactory.getMmsDatabase(context).getThreadIdForMessage(messageID) > 0 + || DatabaseFactory.getSmsDatabase(context).getThreadIdForMessage(messageID) > 0 } if (isDuplicate) { return } if (message.body.isEmpty() && message.attachments.isEmpty() && message.quote == null) { return } diff --git a/src/org/thoughtcrime/securesms/mms/Slide.java b/src/org/thoughtcrime/securesms/mms/Slide.java index fe9a7a9b77..cdf5ce5456 100644 --- a/src/org/thoughtcrime/securesms/mms/Slide.java +++ b/src/org/thoughtcrime/securesms/mms/Slide.java @@ -63,9 +63,10 @@ public abstract class Slide { String attachmentString = context.getString(R.string.attachment); if (MediaUtil.isAudio(attachment)) { - // a missing filename is the legacy way to determine if an audio attachment is + // A missing file name is the legacy way to determine if an audio attachment is // a voice note vs. other arbitrary audio attachments. - if (attachment.isVoiceNote() || !attachment.getFileName().isEmpty()) { + if (attachment.isVoiceNote() || attachment.getFileName() == null || + attachment.getFileName().isEmpty()) { attachmentString = context.getString(R.string.attachment_type_voice_message); return Optional.fromNullable("🎤 " + attachmentString); }