diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageView.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageView.kt index 2b4a66ab91..1118c79146 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageView.kt @@ -12,10 +12,14 @@ import android.util.AttributeSet import android.util.Log import android.view.* import android.widget.LinearLayout +import androidx.annotation.ColorRes +import androidx.annotation.DrawableRes import androidx.core.content.ContextCompat import androidx.core.graphics.withClip import androidx.core.view.isVisible +import kotlinx.android.synthetic.main.view_conversation.view.* import kotlinx.android.synthetic.main.view_visible_message.view.* +import kotlinx.android.synthetic.main.view_visible_message.view.profilePictureView import network.loki.messenger.R import org.session.libsession.messaging.contacts.Contact.ContactContext import org.session.libsession.utilities.ViewUtil @@ -113,6 +117,17 @@ class VisibleMessageView : LinearLayout { // Gravity val gravity = if (message.isOutgoing) Gravity.RIGHT else Gravity.LEFT mainContainer.gravity = gravity or Gravity.BOTTOM + // Message status indicator + val iconID = getMessageStatusImage(message) + if (iconID != null) { + messageStatusImageView.setImageResource(iconID) + } + if (message.isOutgoing) { + val lastMessageID = DatabaseFactory.getMmsSmsDatabase(context).getLastMessageID(message.threadId) + messageStatusImageView.isVisible = !message.isSent || message.id == lastMessageID + } else { + messageStatusImageView.isVisible = false + } // Populate content view messageContentView.bind(message, isStartOfMessageCluster, isEndOfMessageCluster, glide) } @@ -144,6 +159,16 @@ class VisibleMessageView : LinearLayout { } } + private fun getMessageStatusImage(message: MessageRecord): Int? { + when { + !message.isOutgoing -> return null + message.isFailed -> return R.drawable.ic_error + message.isPending -> return R.drawable.ic_circle_dot_dot_dot + message.isRead -> return R.drawable.ic_filled_circle_check + else -> return R.drawable.ic_circle_check + } + } + private fun handleIsSelectedChanged() { background = if (snIsSelected) { ColorDrawable(context.resources.getColorWithID(R.color.message_selected, context.theme)) 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 f21b1ae622..42284a4ff0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MmsSmsDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MmsSmsDatabase.java @@ -129,7 +129,17 @@ public class MmsSmsDatabase extends Database { String order = MmsSmsColumns.NORMALIZED_DATE_RECEIVED + " DESC"; String selection = MmsSmsColumns.THREAD_ID + " = " + threadId; - return queryTables(PROJECTION, selection, order, "1"); + return queryTables(PROJECTION, selection, order, "1"); + } + + public long getLastMessageID(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.getColumnIndex(MmsSmsColumns.ID)); + } } public Cursor getUnread() { diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/model/DisplayRecord.java b/app/src/main/java/org/thoughtcrime/securesms/database/model/DisplayRecord.java index 6e3f63c5ec..3adb9cbda5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/model/DisplayRecord.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/model/DisplayRecord.java @@ -63,33 +63,23 @@ public abstract class DisplayRecord { return body == null ? "" : body; } public abstract SpannableString getDisplayBody(@NonNull Context context); - public Recipient getRecipient() { - return recipient; - } - public long getDateSent() { - return dateSent; - } - public long getDateReceived() { - return dateReceived; - } - public long getThreadId() { - return threadId; - } - public int getDeliveryStatus() { - return deliveryStatus; - } - public int getDeliveryReceiptCount() { - return deliveryReceiptCount; - } - public int getReadReceiptCount() { - return readReceiptCount; - } + public Recipient getRecipient() { return recipient; } + public long getDateSent() { return dateSent; } + public long getDateReceived() { return dateReceived; } + public long getThreadId() { return threadId; } + public int getDeliveryStatus() { return deliveryStatus; } + public int getDeliveryReceiptCount() { return deliveryReceiptCount; } + public int getReadReceiptCount() { return readReceiptCount; } public boolean isDelivered() { return (deliveryStatus >= SmsDatabase.Status.STATUS_COMPLETE && deliveryStatus < SmsDatabase.Status.STATUS_PENDING) || deliveryReceiptCount > 0; } + public boolean isSent() { + return !isFailed() && !isPending(); + } + public boolean isFailed() { return MmsSmsColumns.Types.isFailedMessageType(type) || MmsSmsColumns.Types.isPendingSecureSmsFallbackType(type) diff --git a/app/src/main/res/layout/view_open_group_invitation.xml b/app/src/main/res/layout/view_open_group_invitation.xml index b2c58feb8e..89d5483190 100644 --- a/app/src/main/res/layout/view_open_group_invitation.xml +++ b/app/src/main/res/layout/view_open_group_invitation.xml @@ -58,6 +58,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" tools:text="http://117.204.71.34" + android:layout_marginTop="2dp" android:textColor="@color/black" android:maxLines="1" android:ellipsize="end" diff --git a/app/src/main/res/layout/view_visible_message.xml b/app/src/main/res/layout/view_visible_message.xml index c94fd2318d..366a64cc56 100644 --- a/app/src/main/res/layout/view_visible_message.xml +++ b/app/src/main/res/layout/view_visible_message.xml @@ -3,6 +3,7 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" + xmlns:app="http://schemas.android.com/apk/res-auto" android:orientation="vertical"> - + + + + + + +