Remove old Message Details.
parent
027453bbd2
commit
1a09e70a04
|
@ -243,12 +243,6 @@
|
|||
android:theme="@style/TextSecure.LightTheme.Popup"
|
||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize" />
|
||||
|
||||
<activity android:name=".MessageDetailsActivity"
|
||||
android:label="@string/AndroidManifest__message_details"
|
||||
android:windowSoftInputMode="stateHidden"
|
||||
android:launchMode="singleTask"
|
||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
|
||||
|
||||
<activity android:name=".messagedetails.MessageDetailsActivity"
|
||||
android:label="@string/AndroidManifest__message_details"
|
||||
android:windowSoftInputMode="stateHidden"
|
||||
|
|
|
@ -1,451 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2015 Open Whisper Systems
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.thoughtcrime.securesms;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.loader.app.LoaderManager.LoaderCallbacks;
|
||||
import androidx.loader.content.Loader;
|
||||
|
||||
import org.thoughtcrime.securesms.conversation.ConversationItem;
|
||||
import org.thoughtcrime.securesms.database.GroupDatabase;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
|
||||
import android.os.Parcelable;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.thoughtcrime.securesms.MessageDetailsRecipientAdapter.RecipientDeliveryStatus;
|
||||
import org.thoughtcrime.securesms.color.MaterialColor;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.database.GroupReceiptDatabase;
|
||||
import org.thoughtcrime.securesms.database.GroupReceiptDatabase.GroupReceiptInfo;
|
||||
import org.thoughtcrime.securesms.database.MmsDatabase;
|
||||
import org.thoughtcrime.securesms.database.MmsSmsDatabase;
|
||||
import org.thoughtcrime.securesms.database.SmsDatabase;
|
||||
import org.thoughtcrime.securesms.database.loaders.MessageDetailsLoader;
|
||||
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||
import org.thoughtcrime.securesms.mms.GlideApp;
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||
import org.thoughtcrime.securesms.recipients.LiveRecipient;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.sms.MessageSender;
|
||||
import org.thoughtcrime.securesms.util.DateUtils;
|
||||
import org.thoughtcrime.securesms.util.DynamicDarkActionBarTheme;
|
||||
import org.thoughtcrime.securesms.util.DynamicLanguage;
|
||||
import org.thoughtcrime.securesms.util.DynamicTheme;
|
||||
import org.thoughtcrime.securesms.util.ExpirationUtil;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SignalExecutors;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.sql.Date;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* @author Jake McGinty
|
||||
*/
|
||||
public class MessageDetailsActivity extends PassphraseRequiredActionBarActivity implements LoaderCallbacks<Cursor> {
|
||||
private final static String TAG = MessageDetailsActivity.class.getSimpleName();
|
||||
|
||||
public static final String MESSAGE_ID_EXTRA = "message_id";
|
||||
public static final String THREAD_ID_EXTRA = "thread_id";
|
||||
public static final String IS_PUSH_GROUP_EXTRA = "is_push_group";
|
||||
public static final String TYPE_EXTRA = "type";
|
||||
public static final String RECIPIENT_EXTRA = "recipient_id";
|
||||
|
||||
private GlideRequests glideRequests;
|
||||
private long threadId;
|
||||
private boolean isPushGroup;
|
||||
private ConversationItem conversationItem;
|
||||
private ViewGroup itemParent;
|
||||
private View metadataContainer;
|
||||
private View expiresContainer;
|
||||
private TextView errorText;
|
||||
private View resendButton;
|
||||
private TextView sentDate;
|
||||
private TextView receivedDate;
|
||||
private TextView expiresInText;
|
||||
private View receivedContainer;
|
||||
private TextView transport;
|
||||
private TextView toFrom;
|
||||
private ListView recipientsList;
|
||||
private LayoutInflater inflater;
|
||||
|
||||
private DynamicTheme dynamicTheme = new DynamicDarkActionBarTheme();
|
||||
private DynamicLanguage dynamicLanguage = new DynamicLanguage();
|
||||
|
||||
private boolean running;
|
||||
|
||||
@Override
|
||||
protected void onPreCreate() {
|
||||
dynamicTheme.onCreate(this);
|
||||
dynamicLanguage.onCreate(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle bundle, boolean ready) {
|
||||
setContentView(R.layout.message_details_activity);
|
||||
running = true;
|
||||
|
||||
initializeResources();
|
||||
initializeActionBar();
|
||||
getSupportLoaderManager().initLoader(0, null, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
dynamicTheme.onResume(this);
|
||||
dynamicLanguage.onResume(this);
|
||||
|
||||
assert getSupportActionBar() != null;
|
||||
getSupportActionBar().setTitle(R.string.AndroidManifest__message_details);
|
||||
|
||||
ApplicationDependencies.getMessageNotifier().setVisibleThread(threadId);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
ApplicationDependencies.getMessageNotifier().clearVisibleThread();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
running = false;
|
||||
}
|
||||
|
||||
private void initializeActionBar() {
|
||||
assert getSupportActionBar() != null;
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
LiveRecipient recipient = Recipient.live(getIntent().getParcelableExtra(RECIPIENT_EXTRA));
|
||||
recipient.observe(this, r -> setActionBarColor(r.getColor()));
|
||||
|
||||
setActionBarColor(recipient.get().getColor());
|
||||
}
|
||||
|
||||
private void setActionBarColor(MaterialColor color) {
|
||||
assert getSupportActionBar() != null;
|
||||
getSupportActionBar().setBackgroundDrawable(new ColorDrawable(color.toActionBarColor(this)));
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
getWindow().setStatusBarColor(color.toStatusBarColor(this));
|
||||
}
|
||||
}
|
||||
|
||||
private void initializeResources() {
|
||||
inflater = LayoutInflater.from(this);
|
||||
View header = inflater.inflate(R.layout.message_details_header, recipientsList, false);
|
||||
|
||||
threadId = getIntent().getLongExtra(THREAD_ID_EXTRA, -1);
|
||||
isPushGroup = getIntent().getBooleanExtra(IS_PUSH_GROUP_EXTRA, false);
|
||||
glideRequests = GlideApp.with(this);
|
||||
itemParent = header.findViewById(R.id.item_container);
|
||||
recipientsList = findViewById(R.id.recipients_list);
|
||||
metadataContainer = header.findViewById(R.id.metadata_container);
|
||||
errorText = header.findViewById(R.id.error_text);
|
||||
resendButton = header.findViewById(R.id.resend_button);
|
||||
sentDate = header.findViewById(R.id.sent_time);
|
||||
receivedContainer = header.findViewById(R.id.received_container);
|
||||
receivedDate = header.findViewById(R.id.received_time);
|
||||
transport = header.findViewById(R.id.transport);
|
||||
toFrom = header.findViewById(R.id.tofrom);
|
||||
expiresContainer = header.findViewById(R.id.expires_container);
|
||||
expiresInText = header.findViewById(R.id.expires_in);
|
||||
recipientsList.setHeaderDividersEnabled(false);
|
||||
recipientsList.addHeaderView(header, null, false);
|
||||
}
|
||||
|
||||
private void updateTransport(MessageRecord messageRecord) {
|
||||
final String transportText;
|
||||
if (messageRecord.isOutgoing() && messageRecord.isFailed()) {
|
||||
transportText = "-";
|
||||
} else if (messageRecord.isPending()) {
|
||||
transportText = getString(R.string.ConversationFragment_pending);
|
||||
} else if (messageRecord.isPush()) {
|
||||
transportText = getString(R.string.ConversationFragment_push);
|
||||
} else if (messageRecord.isMms()) {
|
||||
transportText = getString(R.string.ConversationFragment_mms);
|
||||
} else {
|
||||
transportText = getString(R.string.ConversationFragment_sms);
|
||||
}
|
||||
|
||||
transport.setText(transportText);
|
||||
}
|
||||
|
||||
private void updateTime(MessageRecord messageRecord) {
|
||||
sentDate.setOnLongClickListener(null);
|
||||
receivedDate.setOnLongClickListener(null);
|
||||
|
||||
if (messageRecord.isPending() || messageRecord.isFailed()) {
|
||||
sentDate.setText("-");
|
||||
receivedContainer.setVisibility(View.GONE);
|
||||
} else {
|
||||
Locale dateLocale = dynamicLanguage.getCurrentLocale();
|
||||
SimpleDateFormat dateFormatter = DateUtils.getDetailedDateFormatter(this, dateLocale);
|
||||
sentDate.setText(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.setOnLongClickListener(v -> {
|
||||
copyToClipboard(String.valueOf(messageRecord.getDateReceived()));
|
||||
return true;
|
||||
});
|
||||
receivedContainer.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
receivedContainer.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateExpirationTime(final MessageRecord messageRecord) {
|
||||
if (messageRecord.getExpiresIn() <= 0 || messageRecord.getExpireStarted() <= 0) {
|
||||
expiresContainer.setVisibility(View.GONE);
|
||||
return;
|
||||
}
|
||||
|
||||
expiresContainer.setVisibility(View.VISIBLE);
|
||||
Util.runOnMain(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
long elapsed = System.currentTimeMillis() - messageRecord.getExpireStarted();
|
||||
long remaining = messageRecord.getExpiresIn() - elapsed;
|
||||
|
||||
String duration = ExpirationUtil.getExpirationDisplayValue(MessageDetailsActivity.this, Math.max((int)(remaining / 1000), 1));
|
||||
expiresInText.setText(duration);
|
||||
|
||||
if (running) {
|
||||
Util.runOnMainDelayed(this, 500);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void updateRecipients(MessageRecord messageRecord, Recipient recipient, List<RecipientDeliveryStatus> recipients) {
|
||||
final int toFromRes;
|
||||
if (messageRecord.isMms() && !messageRecord.isPush() && !messageRecord.isOutgoing()) {
|
||||
toFromRes = R.string.message_details_header__with;
|
||||
} else if (messageRecord.isOutgoing()) {
|
||||
toFromRes = R.string.message_details_header__to;
|
||||
} else {
|
||||
toFromRes = R.string.message_details_header__from;
|
||||
}
|
||||
toFrom.setText(toFromRes);
|
||||
conversationItem.bind(messageRecord, Optional.absent(), Optional.absent(), glideRequests, dynamicLanguage.getCurrentLocale(), new HashSet<>(), recipient, null, false);
|
||||
Parcelable state = recipientsList.onSaveInstanceState();
|
||||
recipientsList.setAdapter(new MessageDetailsRecipientAdapter(this, glideRequests, messageRecord, recipients, isPushGroup));
|
||||
recipientsList.onRestoreInstanceState(state);
|
||||
}
|
||||
|
||||
private void inflateMessageViewIfAbsent(MessageRecord messageRecord) {
|
||||
if (conversationItem == null) {
|
||||
if (messageRecord.isGroupAction()) {
|
||||
conversationItem = (ConversationItem) inflater.inflate(R.layout.conversation_item_update, itemParent, false);
|
||||
} else if (messageRecord.isOutgoing()) {
|
||||
conversationItem = (ConversationItem) inflater.inflate(R.layout.conversation_item_sent_multimedia, itemParent, false);
|
||||
} else {
|
||||
conversationItem = (ConversationItem) inflater.inflate(R.layout.conversation_item_received_multimedia, itemParent, false);
|
||||
}
|
||||
itemParent.addView(conversationItem);
|
||||
}
|
||||
}
|
||||
|
||||
private @Nullable MessageRecord getMessageRecord(Context context, Cursor cursor, String type) {
|
||||
switch (type) {
|
||||
case MmsSmsDatabase.SMS_TRANSPORT:
|
||||
SmsDatabase smsDatabase = DatabaseFactory.getSmsDatabase(context);
|
||||
SmsDatabase.Reader reader = smsDatabase.readerFor(cursor);
|
||||
return reader.getNext();
|
||||
case MmsSmsDatabase.MMS_TRANSPORT:
|
||||
MmsDatabase mmsDatabase = DatabaseFactory.getMmsDatabase(context);
|
||||
MmsDatabase.Reader mmsReader = mmsDatabase.readerFor(cursor);
|
||||
return mmsReader.getNext();
|
||||
default:
|
||||
throw new AssertionError("no valid message type specified");
|
||||
}
|
||||
}
|
||||
|
||||
private void copyToClipboard(@NonNull String text) {
|
||||
((ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE)).setPrimaryClip(ClipData.newPlainText("text", text));
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull Loader<Cursor> onCreateLoader(int id, Bundle args) {
|
||||
return new MessageDetailsLoader(this, getIntent().getStringExtra(TYPE_EXTRA),
|
||||
getIntent().getLongExtra(MESSAGE_ID_EXTRA, -1));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFinished(@NonNull Loader<Cursor> loader, Cursor cursor) {
|
||||
MessageRecord messageRecord = getMessageRecord(this, cursor, getIntent().getStringExtra(TYPE_EXTRA));
|
||||
|
||||
if (messageRecord == null) {
|
||||
finish();
|
||||
} else {
|
||||
new MessageRecipientAsyncTask(this, messageRecord).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoaderReset(@NonNull Loader<Cursor> loader) {
|
||||
recipientsList.setAdapter(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
super.onOptionsItemSelected(item);
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case android.R.id.home: finish(); return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
private class MessageRecipientAsyncTask extends AsyncTask<Void,Void,List<RecipientDeliveryStatus>> {
|
||||
|
||||
private final WeakReference<Context> weakContext;
|
||||
private final MessageRecord messageRecord;
|
||||
|
||||
MessageRecipientAsyncTask(@NonNull Context context, @NonNull MessageRecord messageRecord) {
|
||||
this.weakContext = new WeakReference<>(context);
|
||||
this.messageRecord = messageRecord;
|
||||
}
|
||||
|
||||
protected Context getContext() {
|
||||
return weakContext.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RecipientDeliveryStatus> doInBackground(Void... voids) {
|
||||
Context context = getContext();
|
||||
|
||||
if (context == null) {
|
||||
Log.w(TAG, "associated context is destroyed, finishing early");
|
||||
return null;
|
||||
}
|
||||
|
||||
List<RecipientDeliveryStatus> recipients = new LinkedList<>();
|
||||
|
||||
if (!messageRecord.getRecipient().isGroup()) {
|
||||
recipients.add(new RecipientDeliveryStatus(messageRecord.getRecipient(), getStatusFor(messageRecord.getDeliveryReceiptCount(), messageRecord.getReadReceiptCount(), messageRecord.isPending()), messageRecord.isUnidentified(), -1));
|
||||
} else {
|
||||
List<GroupReceiptInfo> receiptInfoList = DatabaseFactory.getGroupReceiptDatabase(context).getGroupReceiptInfo(messageRecord.getId());
|
||||
|
||||
if (receiptInfoList.isEmpty()) {
|
||||
List<Recipient> group = DatabaseFactory.getGroupDatabase(context).getGroupMembers(messageRecord.getRecipient().requireGroupId(), GroupDatabase.MemberSet.FULL_MEMBERS_EXCLUDING_SELF);
|
||||
|
||||
for (Recipient recipient : group) {
|
||||
recipients.add(new RecipientDeliveryStatus(recipient, RecipientDeliveryStatus.Status.UNKNOWN, false, -1));
|
||||
}
|
||||
} else {
|
||||
for (GroupReceiptInfo info : receiptInfoList) {
|
||||
recipients.add(new RecipientDeliveryStatus(Recipient.resolved(info.getRecipientId()),
|
||||
getStatusFor(info.getStatus(), messageRecord.isPending(), messageRecord.isFailed()),
|
||||
info.isUnidentified(),
|
||||
info.getTimestamp()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return recipients;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPostExecute(List<RecipientDeliveryStatus> recipients) {
|
||||
if (getContext() == null) {
|
||||
Log.w(TAG, "AsyncTask finished with a destroyed context, leaving early.");
|
||||
return;
|
||||
}
|
||||
|
||||
inflateMessageViewIfAbsent(messageRecord);
|
||||
updateRecipients(messageRecord, messageRecord.getRecipient(), recipients);
|
||||
|
||||
boolean isGroupNetworkFailure = messageRecord.isFailed() && !messageRecord.getNetworkFailures().isEmpty();
|
||||
boolean isIndividualNetworkFailure = messageRecord.isFailed() && !isPushGroup && messageRecord.getIdentityKeyMismatches().isEmpty();
|
||||
|
||||
if (isGroupNetworkFailure || isIndividualNetworkFailure) {
|
||||
errorText.setVisibility(View.VISIBLE);
|
||||
resendButton.setVisibility(View.VISIBLE);
|
||||
resendButton.setOnClickListener(this::onResendClicked);
|
||||
metadataContainer.setVisibility(View.GONE);
|
||||
} else if (messageRecord.isFailed()) {
|
||||
errorText.setVisibility(View.VISIBLE);
|
||||
resendButton.setVisibility(View.GONE);
|
||||
resendButton.setOnClickListener(null);
|
||||
metadataContainer.setVisibility(View.GONE);
|
||||
} else {
|
||||
updateTransport(messageRecord);
|
||||
updateTime(messageRecord);
|
||||
updateExpirationTime(messageRecord);
|
||||
errorText.setVisibility(View.GONE);
|
||||
resendButton.setVisibility(View.GONE);
|
||||
resendButton.setOnClickListener(null);
|
||||
metadataContainer.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
private RecipientDeliveryStatus.Status getStatusFor(int deliveryReceiptCount, int readReceiptCount, boolean pending) {
|
||||
if (readReceiptCount > 0) return RecipientDeliveryStatus.Status.READ;
|
||||
else if (deliveryReceiptCount > 0) return RecipientDeliveryStatus.Status.DELIVERED;
|
||||
else if (!pending) return RecipientDeliveryStatus.Status.SENT;
|
||||
else return RecipientDeliveryStatus.Status.PENDING;
|
||||
}
|
||||
|
||||
private RecipientDeliveryStatus.Status getStatusFor(int groupStatus, boolean pending, boolean failed) {
|
||||
if (groupStatus == GroupReceiptDatabase.STATUS_READ) return RecipientDeliveryStatus.Status.READ;
|
||||
else if (groupStatus == GroupReceiptDatabase.STATUS_DELIVERED) return RecipientDeliveryStatus.Status.DELIVERED;
|
||||
else if (groupStatus == GroupReceiptDatabase.STATUS_UNDELIVERED && failed) return RecipientDeliveryStatus.Status.UNKNOWN;
|
||||
else if (groupStatus == GroupReceiptDatabase.STATUS_UNDELIVERED && !pending) return RecipientDeliveryStatus.Status.SENT;
|
||||
else if (groupStatus == GroupReceiptDatabase.STATUS_UNDELIVERED) return RecipientDeliveryStatus.Status.PENDING;
|
||||
else if (groupStatus == GroupReceiptDatabase.STATUS_UNKNOWN) return RecipientDeliveryStatus.Status.UNKNOWN;
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
private void onResendClicked(View v) {
|
||||
resendButton.setVisibility(View.GONE);
|
||||
SignalExecutors.BOUNDED.execute(() -> MessageSender.resend(MessageDetailsActivity.this, messageRecord));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,112 +0,0 @@
|
|||
package org.thoughtcrime.securesms;
|
||||
|
||||
import android.content.Context;
|
||||
import androidx.annotation.NonNull;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AbsListView;
|
||||
import android.widget.BaseAdapter;
|
||||
|
||||
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.util.Conversions;
|
||||
import org.thoughtcrime.securesms.util.adapter.StableIdGenerator;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.List;
|
||||
|
||||
class MessageDetailsRecipientAdapter extends BaseAdapter implements AbsListView.RecyclerListener {
|
||||
|
||||
private final Context context;
|
||||
private final GlideRequests glideRequests;
|
||||
private final MessageRecord record;
|
||||
private final List<RecipientDeliveryStatus> members;
|
||||
private final boolean isPushGroup;
|
||||
private final StableIdGenerator<RecipientId> idGenerator;
|
||||
|
||||
MessageDetailsRecipientAdapter(@NonNull Context context, @NonNull GlideRequests glideRequests,
|
||||
@NonNull MessageRecord record, @NonNull List<RecipientDeliveryStatus> members,
|
||||
boolean isPushGroup)
|
||||
{
|
||||
this.context = context;
|
||||
this.glideRequests = glideRequests;
|
||||
this.record = record;
|
||||
this.isPushGroup = isPushGroup;
|
||||
this.members = members;
|
||||
this.idGenerator = new StableIdGenerator<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return members.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getItem(int position) {
|
||||
return members.get(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
return idGenerator.getId(members.get(position).recipient.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
if (convertView == null) {
|
||||
convertView = LayoutInflater.from(context).inflate(R.layout.message_recipient_list_item, parent, false);
|
||||
}
|
||||
|
||||
RecipientDeliveryStatus member = members.get(position);
|
||||
|
||||
((MessageRecipientListItem)convertView).set(glideRequests, record, member, isPushGroup);
|
||||
return convertView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMovedToScrapHeap(View view) {
|
||||
((MessageRecipientListItem)view).unbind();
|
||||
}
|
||||
|
||||
|
||||
static class RecipientDeliveryStatus {
|
||||
|
||||
enum Status {
|
||||
UNKNOWN, PENDING, SENT, DELIVERED, READ
|
||||
}
|
||||
|
||||
private final Recipient recipient;
|
||||
private final Status deliveryStatus;
|
||||
private final boolean isUnidentified;
|
||||
private final long timestamp;
|
||||
|
||||
RecipientDeliveryStatus(Recipient recipient, Status deliveryStatus, boolean isUnidentified, long timestamp) {
|
||||
this.recipient = recipient;
|
||||
this.deliveryStatus = deliveryStatus;
|
||||
this.isUnidentified = isUnidentified;
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
|
||||
Status getDeliveryStatus() {
|
||||
return deliveryStatus;
|
||||
}
|
||||
|
||||
boolean isUnidentified() {
|
||||
return isUnidentified;
|
||||
}
|
||||
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
public Recipient getRecipient() {
|
||||
return recipient;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,200 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2014 Open Whisper Systems
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.thoughtcrime.securesms;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.thoughtcrime.securesms.MessageDetailsRecipientAdapter.RecipientDeliveryStatus;
|
||||
import org.thoughtcrime.securesms.components.AvatarImageView;
|
||||
import org.thoughtcrime.securesms.components.DeliveryStatusView;
|
||||
import org.thoughtcrime.securesms.components.FromTextView;
|
||||
import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch;
|
||||
import org.thoughtcrime.securesms.database.documents.NetworkFailure;
|
||||
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientForeverObserver;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
|
||||
/**
|
||||
* A simple view to show the recipients of a message
|
||||
*
|
||||
* @author Jake McGinty
|
||||
*/
|
||||
public class MessageRecipientListItem extends RelativeLayout
|
||||
implements RecipientForeverObserver
|
||||
{
|
||||
@SuppressWarnings("unused")
|
||||
private final static String TAG = MessageRecipientListItem.class.getSimpleName();
|
||||
|
||||
private RecipientDeliveryStatus member;
|
||||
private GlideRequests glideRequests;
|
||||
private FromTextView fromView;
|
||||
private TextView errorDescription;
|
||||
private TextView actionDescription;
|
||||
private Button conflictButton;
|
||||
private AvatarImageView contactPhotoImage;
|
||||
private ImageView unidentifiedDeliveryIcon;
|
||||
private DeliveryStatusView deliveryStatusView;
|
||||
|
||||
public MessageRecipientListItem(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public MessageRecipientListItem(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
super.onFinishInflate();
|
||||
this.fromView = findViewById(R.id.from);
|
||||
this.errorDescription = findViewById(R.id.error_description);
|
||||
this.actionDescription = findViewById(R.id.action_description);
|
||||
this.contactPhotoImage = findViewById(R.id.contact_photo_image);
|
||||
this.conflictButton = findViewById(R.id.conflict_button);
|
||||
this.unidentifiedDeliveryIcon = findViewById(R.id.ud_indicator);
|
||||
this.deliveryStatusView = findViewById(R.id.delivery_status);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
observeMember();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
unsubscribeFromMember();
|
||||
super.onDetachedFromWindow();
|
||||
}
|
||||
|
||||
public void set(final GlideRequests glideRequests,
|
||||
final MessageRecord record,
|
||||
final RecipientDeliveryStatus member,
|
||||
final boolean isPushGroup)
|
||||
{
|
||||
unsubscribeFromMember();
|
||||
|
||||
this.glideRequests = glideRequests;
|
||||
this.member = member;
|
||||
observeMember();
|
||||
|
||||
fromView.setText(member.getRecipient());
|
||||
contactPhotoImage.setAvatar(glideRequests, member.getRecipient(), false);
|
||||
setIssueIndicators(record, isPushGroup);
|
||||
unidentifiedDeliveryIcon.setVisibility(TextSecurePreferences.isShowUnidentifiedDeliveryIndicatorsEnabled(getContext()) && member.isUnidentified() ? VISIBLE : GONE);
|
||||
}
|
||||
|
||||
private void observeMember() {
|
||||
if (isAttachedToWindow() && member != null && member.getRecipient() != null) {
|
||||
member.getRecipient().live().observeForever(this);
|
||||
}
|
||||
}
|
||||
|
||||
private void unsubscribeFromMember() {
|
||||
if (member != null && member.getRecipient() != null) member.getRecipient().live().removeForeverObserver(this);
|
||||
}
|
||||
|
||||
private void setIssueIndicators(final MessageRecord record,
|
||||
final boolean isPushGroup)
|
||||
{
|
||||
final NetworkFailure networkFailure = getNetworkFailure(record);
|
||||
final IdentityKeyMismatch keyMismatch = networkFailure == null ? getKeyMismatch(record) : null;
|
||||
|
||||
String errorText = "";
|
||||
|
||||
if (keyMismatch != null) {
|
||||
conflictButton.setVisibility(View.VISIBLE);
|
||||
|
||||
errorText = getContext().getString(R.string.MessageDetailsRecipient_new_safety_number);
|
||||
conflictButton.setOnClickListener(v -> new ConfirmIdentityDialog(getContext(), record, keyMismatch).show());
|
||||
} else if ((networkFailure != null && !record.isPending()) || (!isPushGroup && record.isFailed())) {
|
||||
conflictButton.setVisibility(View.GONE);
|
||||
errorText = getContext().getString(R.string.MessageDetailsRecipient_failed_to_send);
|
||||
} else {
|
||||
if (record.isOutgoing()) {
|
||||
if (member.getDeliveryStatus() == RecipientDeliveryStatus.Status.PENDING || member.getDeliveryStatus() == RecipientDeliveryStatus.Status.UNKNOWN) {
|
||||
deliveryStatusView.setVisibility(View.GONE);
|
||||
} else if (member.getDeliveryStatus() == RecipientDeliveryStatus.Status.READ) {
|
||||
deliveryStatusView.setRead();
|
||||
deliveryStatusView.setVisibility(View.VISIBLE);
|
||||
} else if (member.getDeliveryStatus() == RecipientDeliveryStatus.Status.DELIVERED) {
|
||||
deliveryStatusView.setDelivered();
|
||||
deliveryStatusView.setVisibility(View.VISIBLE);
|
||||
} else if (member.getDeliveryStatus() == RecipientDeliveryStatus.Status.SENT) {
|
||||
deliveryStatusView.setSent();
|
||||
deliveryStatusView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
} else {
|
||||
deliveryStatusView.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
conflictButton.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
errorDescription.setText(errorText);
|
||||
errorDescription.setVisibility(TextUtils.isEmpty(errorText) ? View.GONE : View.VISIBLE);
|
||||
}
|
||||
|
||||
private NetworkFailure getNetworkFailure(final MessageRecord record) {
|
||||
if (record.hasNetworkFailures()) {
|
||||
for (final NetworkFailure failure : record.getNetworkFailures()) {
|
||||
if (failure.getRecipientId(getContext()).equals(member.getRecipient().getId())) {
|
||||
return failure;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private IdentityKeyMismatch getKeyMismatch(final MessageRecord record) {
|
||||
if (record.isIdentityMismatchFailure()) {
|
||||
for (final IdentityKeyMismatch mismatch : record.getIdentityKeyMismatches()) {
|
||||
if (mismatch.getRecipientId(getContext()).equals(member.getRecipient().getId())) {
|
||||
return mismatch;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void unbind() {
|
||||
unsubscribeFromMember();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRecipientChanged(@NonNull Recipient recipient) {
|
||||
if (this.member != null && this.member.getRecipient().equals(recipient)) {
|
||||
Log.d(TAG, "onRecipientChanged -- valid");
|
||||
fromView.setText(recipient);
|
||||
contactPhotoImage.setAvatar(glideRequests, recipient, false);
|
||||
} else {
|
||||
Log.d(TAG, "onRecipientChanged -- invalid");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -60,7 +60,6 @@ import com.annimon.stream.Stream;
|
|||
import com.google.android.collect.Sets;
|
||||
|
||||
import org.thoughtcrime.securesms.ApplicationContext;
|
||||
import org.thoughtcrime.securesms.MessageDetailsActivity;
|
||||
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.attachments.Attachment;
|
||||
|
@ -74,7 +73,6 @@ import org.thoughtcrime.securesms.conversation.ConversationAdapter.ItemClickList
|
|||
import org.thoughtcrime.securesms.conversation.ConversationAdapter.StickyHeaderViewHolder;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.database.MessagingDatabase;
|
||||
import org.thoughtcrime.securesms.database.MmsSmsDatabase;
|
||||
import org.thoughtcrime.securesms.database.RecipientDatabase;
|
||||
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord;
|
||||
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||
|
@ -87,6 +85,7 @@ import org.thoughtcrime.securesms.linkpreview.LinkPreview;
|
|||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.longmessage.LongMessageActivity;
|
||||
import org.thoughtcrime.securesms.mediasend.Media;
|
||||
import org.thoughtcrime.securesms.messagedetails.MessageDetailsActivity;
|
||||
import org.thoughtcrime.securesms.messagerequests.MessageRequestViewModel;
|
||||
import org.thoughtcrime.securesms.mms.GlideApp;
|
||||
import org.thoughtcrime.securesms.mms.OutgoingMediaMessage;
|
||||
|
@ -690,13 +689,7 @@ public class ConversationFragment extends Fragment {
|
|||
|
||||
|
||||
private void handleDisplayDetails(MessageRecord message) {
|
||||
Intent intent = new Intent(getActivity(), org.thoughtcrime.securesms.messagedetails.MessageDetailsActivity.class);
|
||||
intent.putExtra(MessageDetailsActivity.MESSAGE_ID_EXTRA, message.getId());
|
||||
intent.putExtra(MessageDetailsActivity.THREAD_ID_EXTRA, threadId);
|
||||
intent.putExtra(MessageDetailsActivity.TYPE_EXTRA, message.isMms() ? MmsSmsDatabase.MMS_TRANSPORT : MmsSmsDatabase.SMS_TRANSPORT);
|
||||
intent.putExtra(MessageDetailsActivity.RECIPIENT_EXTRA, recipient.getId());
|
||||
intent.putExtra(MessageDetailsActivity.IS_PUSH_GROUP_EXTRA, recipient.get().isGroup() && message.isPush());
|
||||
startActivity(intent);
|
||||
startActivity(MessageDetailsActivity.getIntentForMessageDetails(requireContext(), message, recipient.getId(), threadId));
|
||||
}
|
||||
|
||||
private void handleForwardMessage(MessageRecord message) {
|
||||
|
|
|
@ -58,7 +58,6 @@ import com.annimon.stream.Stream;
|
|||
import org.thoughtcrime.securesms.BindableConversationItem;
|
||||
import org.thoughtcrime.securesms.ConfirmIdentityDialog;
|
||||
import org.thoughtcrime.securesms.MediaPreviewActivity;
|
||||
import org.thoughtcrime.securesms.MessageDetailsActivity;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.attachments.DatabaseAttachment;
|
||||
import org.thoughtcrime.securesms.components.AlertView;
|
||||
|
@ -77,7 +76,6 @@ import org.thoughtcrime.securesms.contactshare.Contact;
|
|||
import org.thoughtcrime.securesms.database.AttachmentDatabase;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.database.MmsDatabase;
|
||||
import org.thoughtcrime.securesms.database.MmsSmsDatabase;
|
||||
import org.thoughtcrime.securesms.database.SmsDatabase;
|
||||
import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch;
|
||||
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord;
|
||||
|
@ -92,6 +90,7 @@ import org.thoughtcrime.securesms.jobs.SmsSendJob;
|
|||
import org.thoughtcrime.securesms.linkpreview.LinkPreview;
|
||||
import org.thoughtcrime.securesms.linkpreview.LinkPreviewUtil;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.messagedetails.MessageDetailsActivity;
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||
import org.thoughtcrime.securesms.mms.ImageSlide;
|
||||
import org.thoughtcrime.securesms.mms.PartAuthority;
|
||||
|
@ -109,7 +108,6 @@ import org.thoughtcrime.securesms.revealable.ViewOnceUtil;
|
|||
import org.thoughtcrime.securesms.stickers.StickerUrl;
|
||||
import org.thoughtcrime.securesms.util.DateUtils;
|
||||
import org.thoughtcrime.securesms.util.DynamicTheme;
|
||||
import org.thoughtcrime.securesms.util.FeatureFlags;
|
||||
import org.thoughtcrime.securesms.util.LongClickCopySpan;
|
||||
import org.thoughtcrime.securesms.util.LongClickMovementMethod;
|
||||
import org.thoughtcrime.securesms.util.SearchUtil;
|
||||
|
@ -1377,13 +1375,7 @@ public class ConversationItem extends LinearLayout implements BindableConversati
|
|||
if (!shouldInterceptClicks(messageRecord) && parent != null) {
|
||||
parent.onClick(v);
|
||||
} else if (messageRecord.isFailed()) {
|
||||
Intent intent = new Intent(context, org.thoughtcrime.securesms.messagedetails.MessageDetailsActivity.class);
|
||||
intent.putExtra(MessageDetailsActivity.MESSAGE_ID_EXTRA, messageRecord.getId());
|
||||
intent.putExtra(MessageDetailsActivity.THREAD_ID_EXTRA, messageRecord.getThreadId());
|
||||
intent.putExtra(MessageDetailsActivity.TYPE_EXTRA, messageRecord.isMms() ? MmsSmsDatabase.MMS_TRANSPORT : MmsSmsDatabase.SMS_TRANSPORT);
|
||||
intent.putExtra(MessageDetailsActivity.IS_PUSH_GROUP_EXTRA, groupThread && messageRecord.isPush());
|
||||
intent.putExtra(MessageDetailsActivity.RECIPIENT_EXTRA, conversationRecipient.getId());
|
||||
context.startActivity(intent);
|
||||
context.startActivity(MessageDetailsActivity.getIntentForMessageDetails(context, messageRecord, conversationRecipient.getId(), messageRecord.getThreadId()));
|
||||
} else if (!messageRecord.isOutgoing() && messageRecord.isIdentityMismatchFailure()) {
|
||||
handleApproveIdentity();
|
||||
} else if (messageRecord.isPendingInsecureSmsFallback()) {
|
||||
|
|
|
@ -1,16 +1,21 @@
|
|||
package org.thoughtcrime.securesms.messagedetails;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.lifecycle.ViewModelProviders;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.color.MaterialColor;
|
||||
import org.thoughtcrime.securesms.database.MmsSmsDatabase;
|
||||
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||
import org.thoughtcrime.securesms.messagedetails.MessageDetailsAdapter.MessageDetailsViewState;
|
||||
import org.thoughtcrime.securesms.messagedetails.MessageDetailsViewModel.Factory;
|
||||
import org.thoughtcrime.securesms.mms.GlideApp;
|
||||
|
@ -25,10 +30,10 @@ import java.util.List;
|
|||
|
||||
public final class MessageDetailsActivity extends PassphraseRequiredActionBarActivity {
|
||||
|
||||
public static final String MESSAGE_ID_EXTRA = "message_id";
|
||||
public static final String THREAD_ID_EXTRA = "thread_id";
|
||||
public static final String TYPE_EXTRA = "type";
|
||||
public static final String RECIPIENT_EXTRA = "recipient_id";
|
||||
private static final String MESSAGE_ID_EXTRA = "message_id";
|
||||
private static final String THREAD_ID_EXTRA = "thread_id";
|
||||
private static final String TYPE_EXTRA = "type";
|
||||
private static final String RECIPIENT_EXTRA = "recipient_id";
|
||||
|
||||
private GlideRequests glideRequests;
|
||||
private MessageDetailsViewModel viewModel;
|
||||
|
@ -36,6 +41,15 @@ public final class MessageDetailsActivity extends PassphraseRequiredActionBarAct
|
|||
|
||||
private DynamicTheme dynamicTheme = new DynamicDarkActionBarTheme();
|
||||
|
||||
public static @NonNull Intent getIntentForMessageDetails(@NonNull Context context, @NonNull MessageRecord message, @NonNull RecipientId recipientId, long threadId) {
|
||||
Intent intent = new Intent(context, MessageDetailsActivity.class);
|
||||
intent.putExtra(MESSAGE_ID_EXTRA, message.getId());
|
||||
intent.putExtra(THREAD_ID_EXTRA, threadId);
|
||||
intent.putExtra(TYPE_EXTRA, message.isMms() ? MmsSmsDatabase.MMS_TRANSPORT : MmsSmsDatabase.SMS_TRANSPORT);
|
||||
intent.putExtra(RECIPIENT_EXTRA, recipientId);
|
||||
return intent;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreCreate() {
|
||||
dynamicTheme.onCreate(this);
|
||||
|
@ -44,7 +58,7 @@ public final class MessageDetailsActivity extends PassphraseRequiredActionBarAct
|
|||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState, boolean ready) {
|
||||
super.onCreate(savedInstanceState, ready);
|
||||
setContentView(R.layout.message_details_2_activity);
|
||||
setContentView(R.layout.message_details_activity);
|
||||
|
||||
glideRequests = GlideApp.with(this);
|
||||
|
||||
|
|
|
@ -32,11 +32,11 @@ final class MessageDetailsAdapter extends ListAdapter<MessageDetailsAdapter.Mess
|
|||
public @NonNull RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
switch (viewType) {
|
||||
case MessageDetailsViewState.MESSAGE_HEADER:
|
||||
return new MessageHeaderViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.message_details_2_header, parent, false), glideRequests);
|
||||
return new MessageHeaderViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.message_details_header, parent, false), glideRequests);
|
||||
case MessageDetailsViewState.RECIPIENT_HEADER:
|
||||
return new RecipientHeaderViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.message_details_2_recipient_header, parent, false));
|
||||
return new RecipientHeaderViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.message_details_recipient_header, parent, false));
|
||||
case MessageDetailsViewState.RECIPIENT:
|
||||
return new RecipientViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.message_details_2_recipient, parent, false));
|
||||
return new RecipientViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.message_details_recipient, parent, false));
|
||||
default:
|
||||
throw new AssertionError("unknown view type");
|
||||
}
|
||||
|
|
|
@ -48,18 +48,18 @@ final class MessageHeaderViewHolder extends RecyclerView.ViewHolder {
|
|||
super(itemView);
|
||||
this.glideRequests = glideRequests;
|
||||
|
||||
sentDate = itemView.findViewById(R.id.sent_time);
|
||||
receivedDate = itemView.findViewById(R.id.received_time);
|
||||
receivedGroup = itemView.findViewById(R.id.received_group);
|
||||
expiresIn = itemView.findViewById(R.id.expires_in);
|
||||
expiresGroup = itemView.findViewById(R.id.expires_group);
|
||||
transport = itemView.findViewById(R.id.transport);
|
||||
errorText = itemView.findViewById(R.id.error_text);
|
||||
resendButton = itemView.findViewById(R.id.resend_button);
|
||||
messageMetadata = itemView.findViewById(R.id.message_metadata);
|
||||
updateStub = itemView.findViewById(R.id.message_view_update);
|
||||
sentStub = itemView.findViewById(R.id.message_view_sent_multimedia);
|
||||
receivedStub = itemView.findViewById(R.id.message_view_received_multimedia);
|
||||
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);
|
||||
messageMetadata = itemView.findViewById(R.id.message_details_header_message_metadata);
|
||||
updateStub = itemView.findViewById(R.id.message_details_header_message_view_update);
|
||||
sentStub = itemView.findViewById(R.id.message_details_header_message_view_sent_multimedia);
|
||||
receivedStub = itemView.findViewById(R.id.message_details_header_message_view_received_multimedia);
|
||||
}
|
||||
|
||||
void bind(MessageRecord messageRecord, boolean running) {
|
||||
|
|
|
@ -9,12 +9,9 @@ import org.thoughtcrime.securesms.ConfirmIdentityDialog;
|
|||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.components.AvatarImageView;
|
||||
import org.thoughtcrime.securesms.components.FromTextView;
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||
import org.thoughtcrime.securesms.util.DateUtils;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
|
||||
import java.sql.Date;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Locale;
|
||||
|
||||
final class RecipientViewHolder extends RecyclerView.ViewHolder {
|
||||
|
@ -28,12 +25,12 @@ final class RecipientViewHolder extends RecyclerView.ViewHolder {
|
|||
RecipientViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
|
||||
fromView = itemView.findViewById(R.id.recipient_name);
|
||||
avatar = itemView.findViewById(R.id.recipient_avatar);
|
||||
timestamp = itemView.findViewById(R.id.recipient_timestamp);
|
||||
error = itemView.findViewById(R.id.error_description);
|
||||
conflictButton = itemView.findViewById(R.id.conflict_button);
|
||||
unidentifiedDeliveryIcon = itemView.findViewById(R.id.ud_indicator);
|
||||
fromView = itemView.findViewById(R.id.message_details_recipient_name);
|
||||
avatar = itemView.findViewById(R.id.message_details_recipient_avatar);
|
||||
timestamp = itemView.findViewById(R.id.message_details_recipient_timestamp);
|
||||
error = itemView.findViewById(R.id.message_details_recipient_error_description);
|
||||
conflictButton = itemView.findViewById(R.id.message_details_recipient_conflict_button);
|
||||
unidentifiedDeliveryIcon = itemView.findViewById(R.id.message_details_recipient_ud_indicator);
|
||||
}
|
||||
|
||||
void bind(RecipientDeliveryStatus data) {
|
||||
|
@ -45,13 +42,13 @@ final class RecipientViewHolder extends RecyclerView.ViewHolder {
|
|||
timestamp.setVisibility(View.GONE);
|
||||
error.setVisibility(View.VISIBLE);
|
||||
conflictButton.setVisibility(View.VISIBLE);
|
||||
error.setText(itemView.getContext().getString(R.string.MessageDetailsRecipient_new_safety_number));
|
||||
error.setText(itemView.getContext().getString(R.string.message_details_recipient__new_safety_number));
|
||||
conflictButton.setOnClickListener(unused -> new ConfirmIdentityDialog(itemView.getContext(), data.getMessageRecord(), data.getKeyMismatchFailure()).show());
|
||||
} else if ((data.getNetworkFailure() != null && !data.getMessageRecord().isPending()) || (!data.getMessageRecord().getRecipient().isPushGroup() && data.getMessageRecord().isFailed())) {
|
||||
timestamp.setVisibility(View.GONE);
|
||||
error.setVisibility(View.VISIBLE);
|
||||
conflictButton.setVisibility(View.GONE);
|
||||
error.setText(itemView.getContext().getString(R.string.MessageDetailsRecipient_failed_to_send));
|
||||
error.setText(itemView.getContext().getString(R.string.message_details_recipient__failed_to_send));
|
||||
} else {
|
||||
timestamp.setVisibility(View.VISIBLE);
|
||||
error.setVisibility(View.GONE);
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.recyclerview.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/message_details_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?pref_divider"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
|
|
@ -1,189 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.cardview.widget.CardView 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:id="@+id/group_media_card"
|
||||
style="@style/Widget.Signal.CardView.PreferenceRow"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout
|
||||
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">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/message_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<ViewStub
|
||||
android:id="@+id/message_view_update"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout="@layout/conversation_item_update"/>
|
||||
|
||||
<ViewStub
|
||||
android:id="@+id/message_view_sent_multimedia"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout="@layout/conversation_item_sent_multimedia"/>
|
||||
|
||||
<ViewStub
|
||||
android:id="@+id/message_view_received_multimedia"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout="@layout/conversation_item_received_multimedia"/>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/error_text"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:visibility="gone"
|
||||
android:textSize="16sp"
|
||||
android:padding="5dp"
|
||||
tools:visibility="visible"
|
||||
android:text="@string/message_details_header__issues_need_your_attention"
|
||||
android:drawablePadding="4dp"
|
||||
app:drawableStartCompat="@drawable/ic_info_outline_message_details_24"
|
||||
android:gravity="center_vertical" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/resend_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="38sp"
|
||||
style="@style/InfoButton"
|
||||
android:paddingStart="10dp"
|
||||
android:paddingEnd="10dp"
|
||||
android:paddingTop="5dp"
|
||||
android:paddingBottom="5dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:drawableStart="@drawable/ic_refresh_white_18dp"
|
||||
android:text="@string/message_recipients_list_item__resend"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/message_metadata"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sent_time_label"
|
||||
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"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sent_time"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/message_details_table_row_pad"
|
||||
android:background="?selectableItemBackground"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/sent_time_label"
|
||||
app:layout_constraintStart_toEndOf="@+id/label_barrier"
|
||||
tools:text="Jan 18, 2015, 12:29:37 AM GMT-08:00" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/received_time_label"
|
||||
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"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/sent_time_label" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/received_time"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/message_details_table_row_pad"
|
||||
android:background="?selectableItemBackground"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/received_time_label"
|
||||
app:layout_constraintStart_toEndOf="@id/label_barrier"
|
||||
tools:text="Jan 18, 2015, 12:31:15 AM GMT-08:00" />
|
||||
|
||||
<androidx.constraintlayout.widget.Group
|
||||
android:id="@+id/received_group"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:constraint_referenced_ids="received_time_label,received_time" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/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"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/received_time_label" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/expires_in"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/message_details_table_row_pad"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/expires_in_label"
|
||||
app:layout_constraintStart_toEndOf="@id/label_barrier"
|
||||
tools:text="1 week" />
|
||||
|
||||
<androidx.constraintlayout.widget.Group
|
||||
android:id="@+id/expires_group"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:constraint_referenced_ids="expires_in_label,expires_in" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/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"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/expires_in_label" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/transport"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/message_details_table_row_pad"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/transport_label"
|
||||
app:layout_constraintStart_toEndOf="@id/label_barrier"
|
||||
tools:text="Push (TextSecure)" />
|
||||
|
||||
<androidx.constraintlayout.widget.Barrier
|
||||
android:id="@+id/label_barrier"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:barrierDirection="end"
|
||||
app:constraint_referenced_ids="sent_time_label,received_time_label,expires_in_label" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
|
@ -1,14 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/container"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ListView android:id="@+id/recipients_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
tools:listitem="@layout/message_recipient_list_item" />
|
||||
|
||||
</LinearLayout>
|
||||
<androidx.recyclerview.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/message_details_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?pref_divider"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
|
|
@ -1,32 +1,51 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<FrameLayout android:id="@+id/item_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="15dp"
|
||||
android:paddingBottom="15dp"
|
||||
android:elevation="2dp" />
|
||||
<androidx.cardview.widget.CardView 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:id="@+id/group_media_card"
|
||||
style="@style/Widget.Signal.CardView.PreferenceRow"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingStart="10dp"
|
||||
android:paddingEnd="10dp">
|
||||
android:paddingStart="16dp"
|
||||
android:paddingTop="24dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:paddingBottom="24dp">
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<ViewStub
|
||||
android:id="@+id/message_details_header_message_view_update"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout="@layout/conversation_item_update"/>
|
||||
|
||||
<ViewStub
|
||||
android:id="@+id/message_details_header_message_view_sent_multimedia"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout="@layout/conversation_item_sent_multimedia"/>
|
||||
|
||||
<ViewStub
|
||||
android:id="@+id/message_details_header_message_view_received_multimedia"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout="@layout/conversation_item_received_multimedia"/>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/error_text"
|
||||
android:id="@+id/message_details_header_error_text"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
|
@ -40,7 +59,7 @@
|
|||
android:gravity="center_vertical" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/resend_button"
|
||||
android:id="@+id/message_details_header_resend_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="38sp"
|
||||
style="@style/InfoButton"
|
||||
|
@ -56,100 +75,114 @@
|
|||
|
||||
</LinearLayout>
|
||||
|
||||
<TableLayout android:id="@+id/metadata_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:shrinkColumns="1">
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/message_details_header_message_metadata"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TableRow android:id="@+id/sent_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="@dimen/message_details_table_row_pad">
|
||||
<TextView
|
||||
android:id="@+id/message_details_header_sent_time_label"
|
||||
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"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/message_details_header__sent"
|
||||
android:gravity="end"
|
||||
android:textStyle="bold" />
|
||||
<TextView
|
||||
android:id="@+id/message_details_header_sent_time"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/message_details_table_row_pad"
|
||||
android:background="?selectableItemBackground"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/message_details_header_sent_time_label"
|
||||
app:layout_constraintStart_toEndOf="@+id/message_details_header_label_barrier"
|
||||
tools:text="Jan 18, 2015, 12:29:37 AM GMT-08:00" />
|
||||
|
||||
<TextView android:id="@+id/sent_time"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/message_details_table_row_pad"
|
||||
tools:text="Jan 18, 2015, 12:29:37 AM GMT-08:00" />
|
||||
<TextView
|
||||
android:id="@+id/message_details_header_received_time_label"
|
||||
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"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/message_details_header_sent_time_label" />
|
||||
|
||||
</TableRow>
|
||||
<TextView
|
||||
android:id="@+id/message_details_header_received_time"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/message_details_table_row_pad"
|
||||
android:background="?selectableItemBackground"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/message_details_header_received_time_label"
|
||||
app:layout_constraintStart_toEndOf="@id/message_details_header_label_barrier"
|
||||
tools:text="Jan 18, 2015, 12:31:15 AM GMT-08:00" />
|
||||
|
||||
<TableRow android:id="@+id/received_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="@dimen/message_details_table_row_pad">
|
||||
<androidx.constraintlayout.widget.Group
|
||||
android:id="@+id/message_details_header_received_group"
|
||||
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:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/message_details_header__received"
|
||||
android:gravity="end"
|
||||
android:textStyle="bold" />
|
||||
<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"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/message_details_header_received_time_label" />
|
||||
|
||||
<TextView android:id="@+id/received_time"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/message_details_table_row_pad"
|
||||
tools:text="Jan 18, 2015, 12:31:15 AM GMT-08:00" />
|
||||
<TextView
|
||||
android:id="@+id/message_details_header_expires_in"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/message_details_table_row_pad"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/message_details_header_expires_in_label"
|
||||
app:layout_constraintStart_toEndOf="@id/message_details_header_label_barrier"
|
||||
tools:text="1 week" />
|
||||
|
||||
</TableRow>
|
||||
<androidx.constraintlayout.widget.Group
|
||||
android:id="@+id/message_details_header_expires_group"
|
||||
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" />
|
||||
|
||||
<TableRow android:id="@+id/expires_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="@dimen/message_details_table_row_pad"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible">
|
||||
<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"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/message_details_header_expires_in_label" />
|
||||
|
||||
<TextView android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/message_details_header__disappears"
|
||||
android:gravity="end"
|
||||
android:textStyle="bold"/>
|
||||
<TextView
|
||||
android:id="@+id/message_details_header_transport"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/message_details_table_row_pad"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/message_details_header_transport_label"
|
||||
app:layout_constraintStart_toEndOf="@id/message_details_header_label_barrier"
|
||||
tools:text="Push (TextSecure)" />
|
||||
|
||||
<TextView android:id="@+id/expires_in"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/message_details_table_row_pad"
|
||||
tools:text="1 week"/>
|
||||
<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" />
|
||||
|
||||
</TableRow>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<TableRow android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="@dimen/message_details_table_row_pad">
|
||||
|
||||
<TextView android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/message_details_header__via"
|
||||
android:gravity="end"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView android:id="@+id/transport"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/message_details_table_row_pad"
|
||||
tools:text="Push (TextSecure)" />
|
||||
|
||||
</TableRow>
|
||||
|
||||
<TableRow android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="@dimen/message_details_table_row_pad">
|
||||
|
||||
<TextView android:id="@+id/tofrom"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
tools:text="@string/message_details_header__to"
|
||||
android:textStyle="bold" />
|
||||
|
||||
</TableRow>
|
||||
|
||||
</TableLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
android:padding="16dp">
|
||||
|
||||
<org.thoughtcrime.securesms.components.AvatarImageView
|
||||
android:id="@+id/recipient_avatar"
|
||||
android:id="@+id/message_details_recipient_avatar"
|
||||
android:foreground="@drawable/contact_photo_background"
|
||||
android:layout_width="36dp"
|
||||
android:layout_height="36dp"
|
||||
|
@ -23,12 +23,12 @@
|
|||
tools:src="@drawable/ic_contact_picture"
|
||||
android:contentDescription="@string/SingleContactSelectionActivity_contact_photo"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/recipient_name"
|
||||
app:layout_constraintEnd_toStartOf="@+id/message_details_recipient_name"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"/>
|
||||
|
||||
<org.thoughtcrime.securesms.components.FromTextView
|
||||
android:id="@+id/recipient_name"
|
||||
android:id="@+id/message_details_recipient_name"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="4dp"
|
||||
|
@ -37,34 +37,34 @@
|
|||
android:singleLine="true"
|
||||
tools:text="Jules Bonnot"
|
||||
android:ellipsize="marquee"
|
||||
app:layout_constraintStart_toEndOf="@+id/recipient_avatar"
|
||||
app:layout_constraintEnd_toStartOf="@+id/recipient_timestamp"
|
||||
app:layout_constraintStart_toEndOf="@+id/message_details_recipient_avatar"
|
||||
app:layout_constraintEnd_toStartOf="@+id/message_details_recipient_timestamp"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toTopOf="@+id/error_description"/>
|
||||
app:layout_constraintBottom_toTopOf="@+id/message_details_recipient_error_description"/>
|
||||
|
||||
<TextView android:id="@+id/error_description"
|
||||
<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:text="New identity"
|
||||
app:layout_constraintStart_toStartOf="@+id/recipient_name"
|
||||
app:layout_constraintTop_toBottomOf="@+id/recipient_name"
|
||||
app:layout_constraintStart_toStartOf="@+id/message_details_recipient_name"
|
||||
app:layout_constraintTop_toBottomOf="@+id/message_details_recipient_name"
|
||||
app:layout_constraintBottom_toBottomOf="parent"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/recipient_timestamp"
|
||||
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/recipient_name"
|
||||
app:layout_constraintEnd_toStartOf="@+id/conflict_button"
|
||||
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"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/conflict_button"
|
||||
android:id="@+id/message_details_recipient_conflict_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="36dp"
|
||||
style="@style/ErrorButton"
|
||||
|
@ -75,20 +75,20 @@
|
|||
android:drawableStart="@drawable/ic_error_white_18dp"
|
||||
android:text="@string/message_recipients_list_item__view"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintStart_toEndOf="@+id/recipient_timestamp"
|
||||
app:layout_constraintEnd_toStartOf="@+id/ud_indicator"
|
||||
app:layout_constraintStart_toEndOf="@+id/message_details_recipient_timestamp"
|
||||
app:layout_constraintEnd_toStartOf="@+id/message_details_recipient_ud_indicator"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
tools:visibility="gone" />
|
||||
|
||||
<ImageView android:id="@+id/ud_indicator"
|
||||
<ImageView 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="?attr/conversation_item_sent_text_secondary_color"
|
||||
app:layout_constraintStart_toEndOf="@+id/conflict_button"
|
||||
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"/>
|
|
@ -1,99 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<org.thoughtcrime.securesms.MessageRecipientListItem
|
||||
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:gravity="center_vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="16dp">
|
||||
|
||||
<org.thoughtcrime.securesms.components.AvatarImageView
|
||||
android:id="@+id/contact_photo_image"
|
||||
android:foreground="@drawable/contact_photo_background"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_marginTop="3dp"
|
||||
android:layout_marginBottom="3dp"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:cropToPadding="true"
|
||||
tools:src="@drawable/ic_contact_picture"
|
||||
android:contentDescription="@string/SingleContactSelectionActivity_contact_photo" />
|
||||
|
||||
<LinearLayout android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dip"
|
||||
android:layout_marginBottom="4dip"
|
||||
android:layout_toEndOf="@id/contact_photo_image"
|
||||
android:layout_centerVertical="true"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<LinearLayout android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<org.thoughtcrime.securesms.components.FromTextView
|
||||
android:id="@+id/from"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:textColor="?attr/conversation_list_item_contact_color"
|
||||
android:singleLine="true"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_gravity="center_vertical"
|
||||
tools:text="Jules Bonnot"
|
||||
android:ellipsize="marquee" />
|
||||
|
||||
<TextView android:id="@+id/error_description"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="#FFF44336"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible"
|
||||
tools:text="New identity" />
|
||||
|
||||
<TextView android:id="@+id/action_description"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible"
|
||||
tools:text="action" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<Button android:id="@+id/conflict_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="38sp"
|
||||
style="@style/ErrorButton"
|
||||
android:paddingStart="10dp"
|
||||
android:paddingEnd="10dp"
|
||||
android:paddingTop="5dp"
|
||||
android:paddingBottom="5dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:drawableStart="@drawable/ic_error_white_18dp"
|
||||
android:text="@string/message_recipients_list_item__view"
|
||||
android:visibility="gone"
|
||||
tools:visibility="gone" />
|
||||
|
||||
<ImageView android:id="@+id/ud_indicator"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="4dp"
|
||||
android:layout_marginEnd="4dp"
|
||||
android:src="@drawable/ic_unidentified_delivery"
|
||||
android:tint="?attr/conversation_item_sent_text_secondary_color"/>
|
||||
|
||||
<org.thoughtcrime.securesms.components.DeliveryStatusView
|
||||
android:id="@+id/delivery_status"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:iconColor="?attr/conversation_item_sent_text_secondary_color"
|
||||
android:visibility="gone"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</org.thoughtcrime.securesms.MessageRecipientListItem>
|
|
@ -647,10 +647,6 @@
|
|||
<!-- LearnMoreTextView -->
|
||||
<string name="LearnMoreTextView_learn_more">Learn more</string>
|
||||
|
||||
<!-- MessageDetailsRecipient -->
|
||||
<string name="MessageDetailsRecipient_failed_to_send">Failed to send</string>
|
||||
<string name="MessageDetailsRecipient_new_safety_number">New safety number</string>
|
||||
|
||||
<!-- LongMessageActivity -->
|
||||
<string name="LongMessageActivity_unable_to_find_message">Unable to find message</string>
|
||||
<string name="LongMessageActivity_message_from_s">Message from %1$s</string>
|
||||
|
@ -1713,9 +1709,6 @@
|
|||
<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__to">To:</string>
|
||||
<string name="message_details_header__from">From:</string>
|
||||
<string name="message_details_header__with">With:</string>
|
||||
|
||||
<!-- message_details_recipient_header -->
|
||||
<string name="message_details_recipient_header__pending_send">Pending</string>
|
||||
|
@ -1725,6 +1718,10 @@
|
|||
<string name="message_details_recipient_header__read_by">Read by</string>
|
||||
<string name="message_details_recipient_header__not_sent">Not sent</string>
|
||||
|
||||
<!-- message_Details_recipient -->
|
||||
<string name="message_details_recipient__failed_to_send">Failed to send</string>
|
||||
<string name="message_details_recipient__new_safety_number">New safety number</string>
|
||||
|
||||
<!-- AndroidManifest.xml -->
|
||||
<string name="AndroidManifest__create_passphrase">Create passphrase</string>
|
||||
<string name="AndroidManifest__select_contacts">Select contacts</string>
|
||||
|
|
Loading…
Reference in New Issue