Update message details UI.

This commit is contained in:
Lucio Maciel 2021-08-30 17:52:46 -03:00 committed by Greyson Parrelli
parent f5a6d61362
commit a3d72fc06c
27 changed files with 206 additions and 170 deletions

View file

@ -318,7 +318,8 @@
<activity android:name=".messagedetails.MessageDetailsActivity"
android:windowSoftInputMode="stateHidden"
android:launchMode="singleTask"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"
android:theme="@style/Signal.DayNight.NoActionBar" />
<activity android:name=".groups.ui.invitesandrequests.ManagePendingAndRequestingMembersActivity"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize|uiMode"

View file

@ -194,7 +194,7 @@ public class MmsDatabase extends MessageDatabase {
DELIVERY_RECEIPT_COUNT, READ_RECEIPT_COUNT, MISMATCHED_IDENTITIES, NETWORK_FAILURE, SUBSCRIPTION_ID,
EXPIRES_IN, EXPIRE_STARTED, NOTIFIED, QUOTE_ID, QUOTE_AUTHOR, QUOTE_BODY, QUOTE_ATTACHMENT, QUOTE_MISSING, QUOTE_MENTIONS,
SHARED_CONTACTS, LINK_PREVIEWS, UNIDENTIFIED, VIEW_ONCE, REACTIONS, REACTIONS_UNREAD, REACTIONS_LAST_SEEN,
REMOTE_DELETED, MENTIONS_SELF, NOTIFIED_TIMESTAMP, VIEWED_RECEIPT_COUNT,
REMOTE_DELETED, MENTIONS_SELF, NOTIFIED_TIMESTAMP, VIEWED_RECEIPT_COUNT, RECEIPT_TIMESTAMP,
"json_group_array(json_object(" +
"'" + AttachmentDatabase.ROW_ID + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.ROW_ID + ", " +
"'" + AttachmentDatabase.UNIQUE_ID + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.UNIQUE_ID + ", " +
@ -1980,7 +1980,8 @@ public class MmsDatabase extends MessageDatabase {
false,
false,
0,
0);
0,
-1);
}
}
@ -2032,6 +2033,7 @@ public class MmsDatabase extends MessageDatabase {
int readReceiptCount = cursor.getInt(cursor.getColumnIndexOrThrow(MmsDatabase.READ_RECEIPT_COUNT));
int subscriptionId = cursor.getInt(cursor.getColumnIndexOrThrow(MmsDatabase.SUBSCRIPTION_ID));
int viewedReceiptCount = cursor.getInt(cursor.getColumnIndexOrThrow(MmsSmsColumns.VIEWED_RECEIPT_COUNT));
long receiptTimestamp = CursorUtil.requireLong(cursor, MmsSmsColumns.RECEIPT_TIMESTAMP);
if (!TextSecurePreferences.isReadReceiptsEnabled(context)) {
readReceiptCount = 0;
@ -2053,7 +2055,7 @@ public class MmsDatabase extends MessageDatabase {
addressDeviceId, dateSent, dateReceived, deliveryReceiptCount, threadId,
contentLocationBytes, messageSize, expiry, status,
transactionIdBytes, mailbox, subscriptionId, slideDeck,
readReceiptCount, viewedReceiptCount);
readReceiptCount, viewedReceiptCount, receiptTimestamp);
}
private MediaMmsMessageRecord getMediaMmsMessageRecord(Cursor cursor) {
@ -2081,6 +2083,7 @@ public class MmsDatabase extends MessageDatabase {
boolean mentionsSelf = CursorUtil.requireBoolean(cursor, MENTIONS_SELF);
long notifiedTimestamp = CursorUtil.requireLong(cursor, NOTIFIED_TIMESTAMP);
int viewedReceiptCount = cursor.getInt(cursor.getColumnIndexOrThrow(MmsSmsColumns.VIEWED_RECEIPT_COUNT));
long receiptTimestamp = CursorUtil.requireLong(cursor, MmsSmsColumns.RECEIPT_TIMESTAMP);
if (!TextSecurePreferences.isReadReceiptsEnabled(context)) {
readReceiptCount = 0;
@ -2106,7 +2109,7 @@ public class MmsDatabase extends MessageDatabase {
threadId, body, slideDeck, partCount, box, mismatches,
networkFailures, subscriptionId, expiresIn, expireStarted,
isViewOnce, readReceiptCount, quote, contacts, previews, unidentified, reactions,
remoteDelete, mentionsSelf, notifiedTimestamp, viewedReceiptCount);
remoteDelete, mentionsSelf, notifiedTimestamp, viewedReceiptCount, receiptTimestamp);
}
private List<IdentityKeyMismatch> getMismatchedIdentities(String document) {

View file

@ -104,7 +104,8 @@ public class MmsSmsDatabase extends Database {
MmsSmsColumns.REMOTE_DELETED,
MmsDatabase.MENTIONS_SELF,
MmsSmsColumns.NOTIFIED_TIMESTAMP,
MmsSmsColumns.VIEWED_RECEIPT_COUNT};
MmsSmsColumns.VIEWED_RECEIPT_COUNT,
MmsSmsColumns.RECEIPT_TIMESTAMP};
private static final String SNIPPET_QUERY = "SELECT " + MmsSmsColumns.ID + ", 0 AS " + TRANSPORT + ", " + SmsDatabase.TYPE + " AS " + MmsSmsColumns.NORMALIZED_TYPE + ", " + SmsDatabase.DATE_RECEIVED + " AS " + MmsSmsColumns.NORMALIZED_DATE_RECEIVED + " FROM " + SmsDatabase.TABLE_NAME + " " +
"WHERE " + MmsSmsColumns.THREAD_ID + " = ? AND " + SmsDatabase.TYPE + " NOT IN (" + SmsDatabase.Types.PROFILE_CHANGE_TYPE + ", " + SmsDatabase.Types.GV1_MIGRATION_TYPE + ") " +
@ -679,7 +680,8 @@ public class MmsSmsDatabase extends Database {
MmsSmsColumns.REMOTE_DELETED,
MmsDatabase.MENTIONS_SELF,
MmsSmsColumns.NOTIFIED_TIMESTAMP,
MmsSmsColumns.VIEWED_RECEIPT_COUNT};
MmsSmsColumns.VIEWED_RECEIPT_COUNT,
MmsSmsColumns.RECEIPT_TIMESTAMP};
String[] smsProjection = {SmsDatabase.DATE_SENT + " AS " + MmsSmsColumns.NORMALIZED_DATE_SENT,
SmsDatabase.DATE_RECEIVED + " AS " + MmsSmsColumns.NORMALIZED_DATE_RECEIVED,
@ -712,7 +714,8 @@ public class MmsSmsDatabase extends Database {
MmsSmsColumns.REMOTE_DELETED,
MmsDatabase.MENTIONS_SELF,
MmsSmsColumns.NOTIFIED_TIMESTAMP,
MmsSmsColumns.VIEWED_RECEIPT_COUNT};
MmsSmsColumns.VIEWED_RECEIPT_COUNT,
MmsSmsColumns.RECEIPT_TIMESTAMP};
SQLiteQueryBuilder mmsQueryBuilder = new SQLiteQueryBuilder();
SQLiteQueryBuilder smsQueryBuilder = new SQLiteQueryBuilder();
@ -774,6 +777,7 @@ public class MmsSmsDatabase extends Database {
mmsColumnsPresent.add(MmsDatabase.MENTIONS_SELF);
mmsColumnsPresent.add(MmsSmsColumns.NOTIFIED_TIMESTAMP);
mmsColumnsPresent.add(MmsSmsColumns.VIEWED_RECEIPT_COUNT);
mmsColumnsPresent.add(MmsSmsColumns.RECEIPT_TIMESTAMP);
Set<String> smsColumnsPresent = new HashSet<>();
smsColumnsPresent.add(MmsSmsColumns.ID);
@ -801,6 +805,7 @@ public class MmsSmsDatabase extends Database {
smsColumnsPresent.add(SmsDatabase.REACTIONS_LAST_SEEN);
smsColumnsPresent.add(MmsDatabase.REMOTE_DELETED);
smsColumnsPresent.add(MmsSmsColumns.NOTIFIED_TIMESTAMP);
smsColumnsPresent.add(MmsSmsColumns.RECEIPT_TIMESTAMP);
String mmsGroupBy = includeAttachments ? MmsDatabase.TABLE_NAME + "." + MmsDatabase.ID : null;

View file

@ -146,7 +146,7 @@ public class SmsDatabase extends MessageDatabase {
REPLY_PATH_PRESENT, SUBJECT, BODY, SERVICE_CENTER, DELIVERY_RECEIPT_COUNT,
MISMATCHED_IDENTITIES, SUBSCRIPTION_ID, EXPIRES_IN, EXPIRE_STARTED,
NOTIFIED, READ_RECEIPT_COUNT, UNIDENTIFIED, REACTIONS, REACTIONS_UNREAD, REACTIONS_LAST_SEEN,
REMOTE_DELETED, NOTIFIED_TIMESTAMP
REMOTE_DELETED, NOTIFIED_TIMESTAMP, RECEIPT_TIMESTAMP
};
private static final long IGNORABLE_TYPESMASK_WHEN_COUNTING = Types.END_SESSION_BIT | Types.KEY_EXCHANGE_IDENTITY_UPDATE_BIT | Types.KEY_EXCHANGE_IDENTITY_VERIFIED_BIT;
@ -1591,7 +1591,8 @@ public class SmsDatabase extends MessageDatabase {
false,
Collections.emptyList(),
false,
0);
0,
-1);
}
}
@ -1638,6 +1639,7 @@ public class SmsDatabase extends MessageDatabase {
boolean remoteDelete = cursor.getInt(cursor.getColumnIndexOrThrow(SmsDatabase.REMOTE_DELETED)) == 1;
List<ReactionRecord> reactions = parseReactions(cursor);
long notifiedTimestamp = CursorUtil.requireLong(cursor, NOTIFIED_TIMESTAMP);
long receiptTimestamp = CursorUtil.requireLong(cursor, RECEIPT_TIMESTAMP);
if (!TextSecurePreferences.isReadReceiptsEnabled(context)) {
readReceiptCount = 0;
@ -1653,7 +1655,7 @@ public class SmsDatabase extends MessageDatabase {
threadId, status, mismatches, subscriptionId,
expiresIn, expireStarted,
readReceiptCount, unidentified, reactions, remoteDelete,
notifiedTimestamp);
notifiedTimestamp, receiptTimestamp);
}
private List<IdentityKeyMismatch> getMismatches(String document) {

View file

@ -50,7 +50,8 @@ public class InMemoryMessageRecord extends MessageRecord {
Collections.emptyList(),
false,
0,
0);
0,
-1);
}
@Override

View file

@ -86,12 +86,13 @@ public class MediaMmsMessageRecord extends MmsMessageRecord {
boolean remoteDelete,
boolean mentionsSelf,
long notifiedTimestamp,
int viewedReceiptCount)
int viewedReceiptCount,
long receiptTimestamp)
{
super(id, body, conversationRecipient, individualRecipient, recipientDeviceId, dateSent,
dateReceived, dateServer, threadId, Status.STATUS_NONE, deliveryReceiptCount, mailbox, mismatches, failures,
subscriptionId, expiresIn, expireStarted, viewOnce, slideDeck,
readReceiptCount, quote, contacts, linkPreviews, unidentified, reactions, remoteDelete, notifiedTimestamp, viewedReceiptCount);
readReceiptCount, quote, contacts, linkPreviews, unidentified, reactions, remoteDelete, notifiedTimestamp, viewedReceiptCount, receiptTimestamp);
this.partCount = partCount;
this.mentionsSelf = mentionsSelf;
}
@ -143,7 +144,7 @@ public class MediaMmsMessageRecord extends MmsMessageRecord {
return new MediaMmsMessageRecord(getId(), getRecipient(), getIndividualRecipient(), getRecipientDeviceId(), getDateSent(), getDateReceived(), getServerTimestamp(), getDeliveryReceiptCount(), getThreadId(), getBody(), slideDeck,
getPartCount(), getType(), getIdentityKeyMismatches(), getNetworkFailures(), getSubscriptionId(), getExpiresIn(), getExpireStarted(), isViewOnce(),
getReadReceiptCount(), quote, contacts, linkPreviews, isUnidentified(), getReactions(), isRemoteDelete(), mentionsSelf,
getNotifiedTimestamp(), getViewedReceiptCount());
getNotifiedTimestamp(), getViewedReceiptCount(), getReceiptTimestamp());
}
private static @NonNull List<Contact> updateContacts(@NonNull List<Contact> contacts, @NonNull Map<AttachmentId, DatabaseAttachment> attachmentIdMap) {

View file

@ -87,6 +87,7 @@ public abstract class MessageRecord extends DisplayRecord {
private final long serverTimestamp;
private final boolean remoteDelete;
private final long notifiedTimestamp;
private final long receiptTimestamp;
MessageRecord(long id, String body, Recipient conversationRecipient,
Recipient individualRecipient, int recipientDeviceId,
@ -97,7 +98,7 @@ public abstract class MessageRecord extends DisplayRecord {
int subscriptionId, long expiresIn, long expireStarted,
int readReceiptCount, boolean unidentified,
@NonNull List<ReactionRecord> reactions, boolean remoteDelete, long notifiedTimestamp,
int viewedReceiptCount)
int viewedReceiptCount, long receiptTimestamp)
{
super(body, conversationRecipient, dateSent, dateReceived,
threadId, deliveryStatus, deliveryReceiptCount, type,
@ -115,6 +116,7 @@ public abstract class MessageRecord extends DisplayRecord {
this.serverTimestamp = dateServer;
this.remoteDelete = remoteDelete;
this.notifiedTimestamp = notifiedTimestamp;
this.receiptTimestamp = receiptTimestamp;
}
public abstract boolean isMms();
@ -580,6 +582,14 @@ public abstract class MessageRecord extends DisplayRecord {
return notifiedTimestamp;
}
public long getReceiptTimestamp() {
if (!isOutgoing()) {
return getDateSent();
} else {
return receiptTimestamp;
}
}
public static final class InviteAddState {
private final boolean invited;

View file

@ -34,9 +34,12 @@ public abstract class MmsMessageRecord extends MessageRecord {
@Nullable Quote quote, @NonNull List<Contact> contacts,
@NonNull List<LinkPreview> linkPreviews, boolean unidentified,
@NonNull List<ReactionRecord> reactions, boolean remoteDelete, long notifiedTimestamp,
int viewedReceiptCount)
int viewedReceiptCount, long receiptTimestamp)
{
super(id, body, conversationRecipient, individualRecipient, recipientDeviceId, dateSent, dateReceived, dateServer, threadId, deliveryStatus, deliveryReceiptCount, type, mismatches, networkFailures, subscriptionId, expiresIn, expireStarted, readReceiptCount, unidentified, reactions, remoteDelete, notifiedTimestamp, viewedReceiptCount);
super(id, body, conversationRecipient, individualRecipient, recipientDeviceId,
dateSent, dateReceived, dateServer, threadId, deliveryStatus, deliveryReceiptCount,
type, mismatches, networkFailures, subscriptionId, expiresIn, expireStarted, readReceiptCount,
unidentified, reactions, remoteDelete, notifiedTimestamp, viewedReceiptCount, receiptTimestamp);
this.slideDeck = slideDeck;
this.quote = quote;

View file

@ -52,13 +52,13 @@ public class NotificationMmsMessageRecord extends MmsMessageRecord {
long threadId, byte[] contentLocation, long messageSize,
long expiry, int status, byte[] transactionId, long mailbox,
int subscriptionId, SlideDeck slideDeck, int readReceiptCount,
int viewedReceiptCount)
int viewedReceiptCount, long receiptTimestamp)
{
super(id, "", conversationRecipient, individualRecipient, recipientDeviceId,
dateSent, dateReceived, -1, threadId, Status.STATUS_NONE, deliveryReceiptCount, mailbox,
new LinkedList<>(), new LinkedList<>(), subscriptionId,
0, 0, false, slideDeck, readReceiptCount, null, Collections.emptyList(), Collections.emptyList(), false,
Collections.emptyList(), false, 0, viewedReceiptCount);
Collections.emptyList(), false, 0, viewedReceiptCount, receiptTimestamp);
this.contentLocation = contentLocation;
this.messageSize = messageSize;

View file

@ -51,12 +51,12 @@ public class SmsMessageRecord extends MessageRecord {
int subscriptionId, long expiresIn, long expireStarted,
int readReceiptCount, boolean unidentified,
@NonNull List<ReactionRecord> reactions, boolean remoteDelete,
long notifiedTimestamp)
long notifiedTimestamp, long receiptTimestamp)
{
super(id, body, recipient, individualRecipient, recipientDeviceId,
dateSent, dateReceived, dateServer, threadId, status, deliveryReceiptCount, type,
mismatches, new LinkedList<>(), subscriptionId,
expiresIn, expireStarted, readReceiptCount, unidentified, reactions, remoteDelete, notifiedTimestamp, 0);
expiresIn, expireStarted, readReceiptCount, unidentified, reactions, remoteDelete, notifiedTimestamp, 0, receiptTimestamp);
}
public long getType() {

View file

@ -36,7 +36,9 @@ final class MessageDetails {
notSent = new TreeSet<>(RECIPIENT_COMPARATOR);
viewed = new TreeSet<>(RECIPIENT_COMPARATOR);
if (conversationMessage.getMessageRecord().isOutgoing()) {
if (conversationMessage.getMessageRecord().getRecipient().isSelf()) {
read.addAll(recipients);
} else if (conversationMessage.getMessageRecord().isOutgoing()) {
for (RecipientDeliveryStatus status : recipients) {
switch (status.getDeliveryStatus()) {
case UNKNOWN:

View file

@ -4,14 +4,17 @@ import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.MenuItem;
import android.view.View;
import android.widget.FrameLayout;
import androidx.annotation.NonNull;
import androidx.appcompat.widget.Toolbar;
import androidx.lifecycle.ViewModelProviders;
import androidx.recyclerview.widget.RecyclerView;
import org.thoughtcrime.securesms.PassphraseRequiredActivity;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.components.recyclerview.ToolbarShadowAnimationHelper;
import org.thoughtcrime.securesms.conversation.colors.Colorizer;
import org.thoughtcrime.securesms.conversation.colors.ColorizerView;
import org.thoughtcrime.securesms.conversation.ui.error.SafetyNumberChangeDialog;
@ -25,6 +28,7 @@ import org.thoughtcrime.securesms.messagedetails.MessageDetailsViewModel.Factory
import org.thoughtcrime.securesms.mms.GlideApp;
import org.thoughtcrime.securesms.mms.GlideRequests;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme;
import org.thoughtcrime.securesms.util.DynamicTheme;
import java.util.ArrayList;
@ -43,7 +47,7 @@ public final class MessageDetailsActivity extends PassphraseRequiredActivity {
private MessageDetailsAdapter adapter;
private Colorizer colorizer;
private DynamicTheme dynamicTheme = new DynamicTheme();
private DynamicTheme dynamicTheme = new DynamicNoActionBarTheme();
public static @NonNull Intent getIntentForMessageDetails(@NonNull Context context, @NonNull MessageRecord message, @NonNull RecipientId recipientId, long threadId) {
Intent intent = new Intent(context, MessageDetailsActivity.class);
@ -97,12 +101,14 @@ public final class MessageDetailsActivity extends PassphraseRequiredActivity {
private void initializeList() {
RecyclerView list = findViewById(R.id.message_details_list);
ColorizerView colorizerView = findViewById(R.id.message_details_colorizer);
View toolbarShadow = findViewById(R.id.toolbar_shadow);
colorizer = new Colorizer(colorizerView);
adapter = new MessageDetailsAdapter(this, glideRequests, colorizer, this::onErrorClicked);
list.setAdapter(adapter);
list.setItemAnimator(null);
list.addOnScrollListener(new ToolbarShadowAnimationHelper(toolbarShadow));
colorizer.attachToRecyclerView(list);
}
@ -133,6 +139,7 @@ public final class MessageDetailsActivity extends PassphraseRequiredActivity {
}
private void initializeActionBar() {
setSupportActionBar(findViewById(R.id.toolbar));
requireSupportActionBar().setDisplayHomeAsUpEnabled(true);
requireSupportActionBar().setTitle(R.string.AndroidManifest__message_details);
}

View file

@ -51,7 +51,7 @@ final class MessageDetailsRepository {
messageRecord.getRecipient(),
getStatusFor(messageRecord),
messageRecord.isUnidentified(),
-1,
messageRecord.getReceiptTimestamp(),
getNetworkFailure(messageRecord, messageRecord.getRecipient()),
getKeyMismatchFailure(messageRecord, messageRecord.getRecipient())));
} else {
@ -65,7 +65,7 @@ final class MessageDetailsRepository {
recipient,
RecipientDeliveryStatus.Status.UNKNOWN,
false,
-1,
messageRecord.getReceiptTimestamp(),
getNetworkFailure(messageRecord, recipient),
getKeyMismatchFailure(messageRecord, recipient)));
}

View file

@ -3,6 +3,9 @@ package org.thoughtcrime.securesms.messagedetails;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.style.StyleSpan;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewStub;
@ -48,8 +51,6 @@ final class MessageHeaderViewHolder extends RecyclerView.ViewHolder implements G
private final TextView receivedDate;
private final TextView expiresIn;
private final TextView transport;
private final View expiresGroup;
private final View receivedGroup;
private final TextView errorText;
private final View resendButton;
private final View messageMetadata;
@ -70,9 +71,7 @@ final class MessageHeaderViewHolder extends RecyclerView.ViewHolder implements G
sentDate = itemView.findViewById(R.id.message_details_header_sent_time);
receivedDate = itemView.findViewById(R.id.message_details_header_received_time);
receivedGroup = itemView.findViewById(R.id.message_details_header_received_group);
expiresIn = itemView.findViewById(R.id.message_details_header_expires_in);
expiresGroup = itemView.findViewById(R.id.message_details_header_expires_group);
transport = itemView.findViewById(R.id.message_details_header_transport);
errorText = itemView.findViewById(R.id.message_details_header_error_text);
resendButton = itemView.findViewById(R.id.message_details_header_resend_button);
@ -152,26 +151,26 @@ final class MessageHeaderViewHolder extends RecyclerView.ViewHolder implements G
receivedDate.setOnLongClickListener(null);
if (messageRecord.isPending() || messageRecord.isFailed()) {
sentDate.setText("-");
receivedGroup.setVisibility(View.GONE);
sentDate.setText(formatBoldString(R.string.message_details_header__sent, "-"));
receivedDate.setVisibility(View.GONE);
} else {
Locale dateLocale = Locale.getDefault();
SimpleDateFormat dateFormatter = DateUtils.getDetailedDateFormatter(itemView.getContext(), dateLocale);
sentDate.setText(dateFormatter.format(new Date(messageRecord.getDateSent())));
sentDate.setText(formatBoldString(R.string.message_details_header__sent, dateFormatter.format(new Date(messageRecord.getDateSent()))));
sentDate.setOnLongClickListener(v -> {
copyToClipboard(String.valueOf(messageRecord.getDateSent()));
return true;
});
if (messageRecord.getDateReceived() != messageRecord.getDateSent() && !messageRecord.isOutgoing()) {
receivedDate.setText(dateFormatter.format(new Date(messageRecord.getDateReceived())));
receivedDate.setText(formatBoldString(R.string.message_details_header__received, dateFormatter.format(new Date(messageRecord.getDateReceived()))));
receivedDate.setOnLongClickListener(v -> {
copyToClipboard(String.valueOf(messageRecord.getDateReceived()));
return true;
});
receivedGroup.setVisibility(View.VISIBLE);
receivedDate.setVisibility(View.VISIBLE);
} else {
receivedGroup.setVisibility(View.GONE);
receivedDate.setVisibility(View.GONE);
}
}
}
@ -183,11 +182,11 @@ final class MessageHeaderViewHolder extends RecyclerView.ViewHolder implements G
}
if (messageRecord.getExpiresIn() <= 0 || messageRecord.getExpireStarted() <= 0) {
expiresGroup.setVisibility(View.GONE);
expiresIn.setVisibility(View.GONE);
return;
}
expiresGroup.setVisibility(View.VISIBLE);
expiresIn.setVisibility(View.VISIBLE);
if (running) {
expiresUpdater = new ExpiresUpdater(messageRecord);
ThreadUtil.runOnMain(expiresUpdater);
@ -208,7 +207,18 @@ final class MessageHeaderViewHolder extends RecyclerView.ViewHolder implements G
transportText = itemView.getContext().getString(R.string.ConversationFragment_sms);
}
transport.setText(transportText);
transport.setText(formatBoldString(R.string.message_details_header__via, transportText));
}
private CharSequence formatBoldString(int boldTextRes, CharSequence otherText) {
SpannableStringBuilder builder = new SpannableStringBuilder();
StyleSpan boldSpan = new StyleSpan(android.graphics.Typeface.BOLD);
CharSequence boldText = itemView.getContext().getString(boldTextRes);
builder.append(boldText).append(" ").append(otherText);
builder.setSpan(boldSpan, 0, boldText.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
return builder;
}
private void copyToClipboard(String text) {
@ -286,7 +296,7 @@ final class MessageHeaderViewHolder extends RecyclerView.ViewHolder implements G
int expirationTime = Math.max((int) (remaining / 1000), 1);
String duration = ExpirationUtil.getExpirationDisplayValue(itemView.getContext(), expirationTime);
expiresIn.setText(duration);
expiresIn.setText(formatBoldString(R.string.message_details_header__disappears, duration));
if (running && expirationTime > 1) {
ThreadUtil.runOnMainDelayed(this, 500);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 238 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 146 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 198 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 302 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 334 B

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="18dp"
android:height="13dp"
android:viewportWidth="18"
android:viewportHeight="13">
<path
android:pathData="M7.5,13H1.5C1.1022,13 0.7206,12.842 0.4393,12.5607C0.158,12.2794 0,11.8978 0,11.5V5.5C0,5.1022 0.158,4.7206 0.4393,4.4393C0.7206,4.158 1.1022,4 1.5,4H7.5V13ZM14.5,11.5H13V13H14.5V11.5ZM18,11.5H16.5V13C16.8978,13 17.2794,12.842 17.5607,12.5607C17.842,12.2794 18,11.8978 18,11.5ZM18,8H16.5V9.5H18V8ZM18,4.5V2C18,1.6022 17.842,1.2206 17.5607,0.9393C17.2794,0.658 16.8978,0.5 16.5,0.5H10.5C10.1022,0.5 9.7206,0.658 9.4393,0.9393C9.158,1.2206 9,1.6022 9,2V13L18,4.5Z"
android:fillColor="#848484"/>
</vector>

View file

@ -1,14 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/preference_divider">
android:background="@color/signal_background_primary">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="56dp"
android:theme="?attr/settingsToolbarStyle"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navigationIcon="@drawable/ic_arrow_left_24"
app:titleTextAppearance="@style/Signal.Text.Title"
app:navigationContentDescription="@string/DSLSettingsToolbar__navigate_up"
tools:title="Message Details" />
<org.thoughtcrime.securesms.conversation.colors.ColorizerView
android:id="@+id/message_details_colorizer"
android:layout_width="match_parent"
android:layout_height="match_parent" />
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/toolbar" />
<FrameLayout
android:id="@+id/video_container"
@ -17,7 +35,22 @@
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/message_details_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/toolbar"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
</FrameLayout>
<View
android:id="@+id/toolbar_shadow"
android:layout_width="match_parent"
android:layout_height="5dp"
android:alpha="0"
android:background="@drawable/toolbar_shadow"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/toolbar" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -11,14 +11,14 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingStart="16dp"
android:paddingTop="24dp"
android:paddingEnd="16dp"
android:paddingBottom="24dp">
android:paddingBottom="32dp">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp">
<ViewStub
android:id="@+id/message_details_header_message_view_update"
@ -36,13 +36,17 @@
android:id="@+id/message_details_header_message_view_received_multimedia"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:visibility="visible"
android:layout="@layout/conversation_item_received_multimedia"/>
</FrameLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dsl_settings_gutter"
android:layout_marginEnd="@dimen/dsl_settings_gutter"
tools:visibility="visible">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/message_details_header_error_text"
@ -77,120 +81,58 @@
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/message_details_header_message_metadata"
android:layout_marginTop="12dp"
android:layout_marginStart="@dimen/dsl_settings_gutter"
android:layout_marginEnd="@dimen/dsl_settings_gutter"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/message_details_header_sent_time_label"
android:id="@+id/message_details_header_sent_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:gravity="end"
android:text="@string/message_details_header__sent"
android:textStyle="bold"
android:layout_marginTop="4dp"
tools:text="@string/message_details_header__sent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/message_details_header_sent_time"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/message_details_table_row_pad"
android:background="?selectableItemBackground"
android:maxLines="2"
app:layout_constraintTop_toTopOf="@+id/message_details_header_sent_time_label"
app:layout_constraintStart_toEndOf="@+id/message_details_header_label_barrier"
app:layout_constraintEnd_toEndOf="parent"
tools:text="Jan 18, 2015, 12:29:37 AM GMT-08:00" />
<TextView
android:id="@+id/message_details_header_received_time_label"
android:id="@+id/message_details_header_received_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:gravity="end"
android:text="@string/message_details_header__received"
android:textStyle="bold"
android:layout_marginTop="4dp"
tools:text="@string/message_details_header__received"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/message_details_header_sent_time" />
<TextView
android:id="@+id/message_details_header_received_time"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/message_details_table_row_pad"
android:background="?selectableItemBackground"
android:maxLines="2"
app:layout_constraintTop_toTopOf="@+id/message_details_header_received_time_label"
app:layout_constraintStart_toEndOf="@id/message_details_header_label_barrier"
app:layout_constraintEnd_toEndOf="parent"
tools:text="Jan 18, 2015, 12:31:15 AM GMT-08:00" />
<androidx.constraintlayout.widget.Group
android:id="@+id/message_details_header_received_group"
android:id="@+id/message_details_header_expires_in"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="message_details_header_received_time_label,message_details_header_received_time" />
<TextView
android:id="@+id/message_details_header_expires_in_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:gravity="end"
android:text="@string/message_details_header__disappears"
android:textStyle="bold"
android:layout_marginTop="4dp"
tools:text="@string/message_details_header__disappears"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/message_details_header_received_time" />
<TextView
android:id="@+id/message_details_header_expires_in"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/message_details_table_row_pad"
android:maxLines="2"
app:layout_constraintTop_toTopOf="@+id/message_details_header_expires_in_label"
app:layout_constraintStart_toEndOf="@id/message_details_header_label_barrier"
app:layout_constraintEnd_toEndOf="parent"
tools:text="1 week 6 days 23 hours 54 minutes 16 seconds and 200 milliseconds" />
<androidx.constraintlayout.widget.Group
android:id="@+id/message_details_header_expires_group"
android:id="@+id/message_details_header_transport"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="message_details_header_expires_in_label,message_details_header_expires_in" />
<TextView
android:id="@+id/message_details_header_transport_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:gravity="end"
android:text="@string/message_details_header__via"
android:textStyle="bold"
android:layout_marginTop="4dp"
tools:text="@string/message_details_header__via"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/message_details_header_expires_in" />
<TextView
android:id="@+id/message_details_header_transport"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/message_details_table_row_pad"
android:maxLines="2"
app:layout_constraintTop_toTopOf="@+id/message_details_header_transport_label"
app:layout_constraintStart_toEndOf="@id/message_details_header_label_barrier"
app:layout_constraintEnd_toEndOf="parent"
tools:text="Data (Signal)" />
<androidx.constraintlayout.widget.Barrier
android:id="@+id/message_details_header_label_barrier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="end"
app:constraint_referenced_ids="message_details_header_sent_time_label,message_details_header_received_time_label,message_details_header_expires_in_label" />
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="2dp"
android:layout_marginBottom="8dp"
android:layout_gravity="bottom"
android:background="@color/signal_inverse_transparent_05" />
</androidx.cardview.widget.CardView>

View file

@ -11,14 +11,17 @@
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp">
android:paddingTop="12dp"
android:paddingBottom="12dp"
android:paddingStart="@dimen/dsl_settings_gutter"
android:paddingEnd="@dimen/dsl_settings_gutter">
<org.thoughtcrime.securesms.components.AvatarImageView
android:id="@+id/message_details_recipient_avatar"
android:foreground="@drawable/contact_photo_background"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginEnd="8dp"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginEnd="16dp"
android:cropToPadding="true"
tools:src="@drawable/ic_contact_picture"
android:contentDescription="@string/SingleContactSelectionActivity_contact_photo"
@ -32,22 +35,22 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="4dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="@color/signal_text_primary"
android:singleLine="true"
tools:text="Jules Bonnot"
android:ellipsize="marquee"
app:layout_constraintStart_toEndOf="@+id/message_details_recipient_avatar"
app:layout_constraintEnd_toStartOf="@+id/message_details_recipient_timestamp"
app:layout_constraintEnd_toStartOf="@+id/message_details_recipient_ud_indicator"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@+id/message_details_recipient_error_description"/>
app:layout_constraintBottom_toTopOf="@+id/message_details_recipient_error_description"
style="@style/Signal.Text.Body"/>
<TextView android:id="@+id/message_details_recipient_error_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFF44336"
android:visibility="gone"
tools:visibility="visible"
tools:visibility="gone"
tools:text="New identity"
app:layout_constraintStart_toStartOf="@+id/message_details_recipient_name"
app:layout_constraintTop_toBottomOf="@+id/message_details_recipient_name"
@ -57,11 +60,13 @@
android:id="@+id/message_details_recipient_timestamp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="05/27/20 1:32 PM"
app:layout_constraintStart_toEndOf="@+id/message_details_recipient_name"
app:layout_constraintEnd_toStartOf="@+id/message_details_recipient_conflict_button"
android:textColor="@color/signal_text_secondary"
tools:text="1:32 pm"
app:layout_constraintStart_toEndOf="@+id/message_details_recipient_conflict_button"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
app:layout_constraintBottom_toBottomOf="parent"
style="@style/Signal.Text.Preview"/>
<Button
android:id="@+id/message_details_recipient_conflict_button"
@ -75,8 +80,8 @@
android:drawableStart="@drawable/ic_error_white_18dp"
android:text="@string/message_recipients_list_item__view"
android:visibility="gone"
app:layout_constraintStart_toEndOf="@+id/message_details_recipient_timestamp"
app:layout_constraintEnd_toStartOf="@+id/message_details_recipient_ud_indicator"
app:layout_constraintStart_toEndOf="@+id/message_details_recipient_ud_indicator"
app:layout_constraintEnd_toStartOf="@+id/message_details_recipient_timestamp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
tools:visibility="gone" />
@ -85,14 +90,14 @@
android:id="@+id/message_details_recipient_ud_indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="4dp"
android:src="@drawable/ic_unidentified_delivery"
android:tint="@color/signal_text_secondary"
app:layout_constraintStart_toEndOf="@+id/message_details_recipient_conflict_button"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginStart="4dp"
android:layout_marginEnd="9dp"
app:srcCompat="@drawable/ic_unidentified_delivery"
android:tint="@color/signal_text_hint"
app:layout_constraintStart_toEndOf="@+id/message_details_recipient_name"
app:layout_constraintEnd_toStartOf="@+id/message_details_recipient_conflict_button"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
app:layout_constraintBottom_toBottomOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>

View file

@ -5,29 +5,30 @@
android:id="@+id/group_media_card"
style="@style/Widget.Signal.CardView.PreferenceRow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp">
android:layout_height="wrap_content">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="16dp"
android:paddingTop="12dp"
android:paddingEnd="16dp"
android:paddingBottom="4dp">
android:paddingStart="@dimen/dsl_settings_gutter"
android:paddingTop="24dp"
android:paddingEnd="@dimen/dsl_settings_gutter"
android:paddingBottom="12dp">
<TextView
android:id="@+id/recipient_header_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:textAppearance="@style/TextAppearance.Signal.Body1.Bold"
android:textStyle="bold"
tools:text="Read by" />
<org.thoughtcrime.securesms.components.DeliveryStatusView
android:id="@+id/recipient_header_delivery_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:iconColor="@color/signal_text_secondary"
app:iconColor="@color/signal_inverse_primary"
android:layout_gravity="end|center_vertical" />
</FrameLayout>

View file

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -11,7 +12,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:src="@drawable/ic_unidentified_delivery"
app:srcCompat="@drawable/ic_unidentified_delivery"
android:tint="@color/signal_text_secondary"/>
<TextView

View file

@ -2173,10 +2173,10 @@
<!-- message_details_header -->
<string name="message_details_header__issues_need_your_attention">Some issues need your attention.</string>
<string name="message_details_header__sent">Sent</string>
<string name="message_details_header__received">Received</string>
<string name="message_details_header__disappears">Disappears</string>
<string name="message_details_header__via">Via</string>
<string name="message_details_header__sent">Sent:</string>
<string name="message_details_header__received">Received:</string>
<string name="message_details_header__disappears">Disappears:</string>
<string name="message_details_header__via">Via:</string>
<!-- message_details_recipient_header -->
<string name="message_details_recipient_header__pending_send">Pending</string>

View file

@ -470,7 +470,7 @@
<style name="Widget.Signal.CardView.PreferenceRow" parent="Widget.MaterialComponents.CardView">
<item name="cardCornerRadius">0dp</item>
<item name="cardElevation">0.5dp</item>
<item name="cardElevation">0dp</item>
<item name="cardBackgroundColor">?android:attr/windowBackground</item>
</style>