mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-23 18:15:22 +00:00
Support for multi-select in the conversation list.
// FREEBIE Closes #1601 Closes #2214 Fixes #2188 Fixes #786
This commit is contained in:
parent
ebf6a2d833
commit
ed556fbd3a
@ -118,7 +118,7 @@
|
||||
<string name="ConversationFragment_transport_s_sent_received_s">Transport: %1$s\nSent/Received: %2$s</string>
|
||||
<string name="ConversationFragment_sender_s_transport_s_sent_s_received_s">Sender: %1$s\nTransport: %2$s\nSent: %3$s\nReceived: %4$s</string>
|
||||
<string name="ConversationFragment_confirm_message_delete">Confirm message delete</string>
|
||||
<string name="ConversationFragment_are_you_sure_you_want_to_permanently_delete_this_message">Are you sure that you want to permanently delete this message?</string>
|
||||
<string name="ConversationFragment_are_you_sure_you_want_to_permanently_delete_all_selected_messages">Are you sure that you want to permanently delete all selected messages?</string>
|
||||
<string name="ConversationFragment_save_to_sd_card">Save to storage?</string>
|
||||
<string name="ConversationFragment_this_media_has_been_stored_in_an_encrypted_database_warning">Saving this media to storage will allow any other apps on your phone to access it.\n\nContinue?</string>
|
||||
<string name="ConversationFragment_error_while_saving_attachment_to_sd_card">Error while saving attachment to storage!</string>
|
||||
@ -130,6 +130,8 @@
|
||||
<string name="ConversationFragment_push">PUSH</string>
|
||||
<string name="ConversationFragment_mms">MMS</string>
|
||||
<string name="ConversationFragment_sms">SMS</string>
|
||||
<string name="ConversationFragment_deleting">Deleting...</string>
|
||||
<string name="ConversationFragment_deleting_messages">Deleting messages...</string>
|
||||
|
||||
<!-- ConversationListFragment -->
|
||||
<string name="ConversationListFragment_delete_threads_question">Delete threads?</string>
|
||||
|
@ -35,7 +35,11 @@ import org.thoughtcrime.securesms.util.LRUCache;
|
||||
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.thoughtcrime.securesms.ConversationFragment.SelectionClickListener;
|
||||
|
||||
/**
|
||||
* A cursor adapter for a conversation thread. Ultimately
|
||||
@ -55,19 +59,23 @@ public class ConversationAdapter extends CursorAdapter implements AbsListView.Re
|
||||
public static final int MESSAGE_TYPE_INCOMING = 1;
|
||||
public static final int MESSAGE_TYPE_GROUP_ACTION = 2;
|
||||
|
||||
private final Handler failedIconClickHandler;
|
||||
private final Context context;
|
||||
private final MasterSecret masterSecret;
|
||||
private final boolean groupThread;
|
||||
private final boolean pushDestination;
|
||||
private final LayoutInflater inflater;
|
||||
private final Set<MessageRecord> batchSelected = Collections.synchronizedSet(new HashSet<MessageRecord>());
|
||||
|
||||
public ConversationAdapter(Context context, MasterSecret masterSecret,
|
||||
private final SelectionClickListener selectionClickListener;
|
||||
private final Handler failedIconClickHandler;
|
||||
private final Context context;
|
||||
private final MasterSecret masterSecret;
|
||||
private final boolean groupThread;
|
||||
private final boolean pushDestination;
|
||||
private final LayoutInflater inflater;
|
||||
|
||||
public ConversationAdapter(Context context, MasterSecret masterSecret, SelectionClickListener selectionClickListener,
|
||||
Handler failedIconClickHandler, boolean groupThread, boolean pushDestination)
|
||||
{
|
||||
super(context, null, 0);
|
||||
this.context = context;
|
||||
this.masterSecret = masterSecret;
|
||||
this.selectionClickListener = selectionClickListener;
|
||||
this.failedIconClickHandler = failedIconClickHandler;
|
||||
this.groupThread = groupThread;
|
||||
this.pushDestination = pushDestination;
|
||||
@ -81,7 +89,8 @@ public class ConversationAdapter extends CursorAdapter implements AbsListView.Re
|
||||
String type = cursor.getString(cursor.getColumnIndexOrThrow(MmsSmsDatabase.TRANSPORT));
|
||||
MessageRecord messageRecord = getMessageRecord(id, cursor, type);
|
||||
|
||||
item.set(masterSecret, messageRecord, failedIconClickHandler, groupThread, pushDestination);
|
||||
item.set(masterSecret, messageRecord, batchSelected, selectionClickListener,
|
||||
failedIconClickHandler, groupThread, pushDestination);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -158,6 +167,18 @@ public class ConversationAdapter extends CursorAdapter implements AbsListView.Re
|
||||
this.getCursor().close();
|
||||
}
|
||||
|
||||
public void toggleBatchSelected(MessageRecord messageRecord) {
|
||||
if (batchSelected.contains(messageRecord)) {
|
||||
batchSelected.remove(messageRecord);
|
||||
} else {
|
||||
batchSelected.add(messageRecord);
|
||||
}
|
||||
}
|
||||
|
||||
public Set<MessageRecord> getBatchSelected() {
|
||||
return batchSelected;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMovedToScrapHeap(View view) {
|
||||
((ConversationItem)view).unbind();
|
||||
|
@ -40,17 +40,23 @@ import org.thoughtcrime.securesms.sms.MessageSender;
|
||||
import org.thoughtcrime.securesms.util.Dialogs;
|
||||
import org.thoughtcrime.securesms.util.DirectoryHelper;
|
||||
import org.thoughtcrime.securesms.util.FutureTaskListener;
|
||||
import org.thoughtcrime.securesms.util.ProgressDialogAsyncTask;
|
||||
import org.thoughtcrime.securesms.util.SaveAttachmentTask;
|
||||
import org.thoughtcrime.securesms.util.SaveAttachmentTask.Attachment;
|
||||
|
||||
import java.sql.Date;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public class ConversationFragment extends ListFragment
|
||||
implements LoaderManager.LoaderCallbacks<Cursor>
|
||||
{
|
||||
private static final String TAG = ConversationFragment.class.getSimpleName();
|
||||
|
||||
private final ActionModeCallback actionModeCallback = new ActionModeCallback();
|
||||
private final SelectionClickListener selectionClickListener = new SelectionClickListener();
|
||||
|
||||
private ConversationFragmentListener listener;
|
||||
|
||||
private MasterSecret masterSecret;
|
||||
@ -96,7 +102,7 @@ public class ConversationFragment extends ListFragment
|
||||
|
||||
private void initializeListAdapter() {
|
||||
if (this.recipients != null && this.threadId != -1) {
|
||||
this.setListAdapter(new ConversationAdapter(getActivity(), masterSecret,
|
||||
this.setListAdapter(new ConversationAdapter(getActivity(), masterSecret, selectionClickListener,
|
||||
new FailedIconClickHandler(),
|
||||
(!this.recipients.isSingleRecipient()) || this.recipients.isGroupRecipient(),
|
||||
DirectoryHelper.isPushDestination(getActivity(), this.recipients)));
|
||||
@ -106,49 +112,50 @@ public class ConversationFragment extends ListFragment
|
||||
}
|
||||
|
||||
private void initializeContextualActionBar() {
|
||||
getListView().setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
|
||||
@Override
|
||||
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
if (actionMode != null) {
|
||||
view.setSelected(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
actionMode = ((ActionBarActivity)getActivity()).startSupportActionMode(actionModeCallback);
|
||||
view.setSelected(true);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
getListView().setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
if (actionMode != null) {
|
||||
view.setSelected(true);
|
||||
setCorrectMenuVisibility(getMessageRecord(), actionMode.getMenu());
|
||||
}
|
||||
}
|
||||
});
|
||||
getListView().setOnItemClickListener(selectionClickListener);
|
||||
getListView().setOnItemLongClickListener(selectionClickListener);
|
||||
}
|
||||
|
||||
private void setCorrectMenuVisibility(MessageRecord messageRecord, Menu menu) {
|
||||
MenuItem resend = menu.findItem(R.id.menu_context_resend);
|
||||
MenuItem saveAttachment = menu.findItem(R.id.menu_context_save_attachment);
|
||||
private void setCorrectMenuVisibility(Menu menu) {
|
||||
ConversationAdapter adapter = (ConversationAdapter) getListAdapter();
|
||||
List<MessageRecord> messageRecords = getSelectedMessageRecords();
|
||||
|
||||
if (messageRecord.isFailed()) resend.setVisible(true);
|
||||
else resend.setVisible(false);
|
||||
if (actionMode != null && messageRecords.size() == 0) {
|
||||
adapter.getBatchSelected().clear();
|
||||
adapter.notifyDataSetChanged();
|
||||
actionMode.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
if (messageRecord.isMms() && !messageRecord.isMmsNotification()) {
|
||||
saveAttachment.setVisible(((MediaMmsMessageRecord)messageRecord).containsMediaSlide());
|
||||
if (messageRecords.size() > 1) {
|
||||
menu.findItem(R.id.menu_context_forward).setVisible(false);
|
||||
menu.findItem(R.id.menu_context_copy).setVisible(false);
|
||||
menu.findItem(R.id.menu_context_details).setVisible(false);
|
||||
menu.findItem(R.id.menu_context_save_attachment).setVisible(false);
|
||||
menu.findItem(R.id.menu_context_resend).setVisible(false);
|
||||
} else {
|
||||
saveAttachment.setVisible(false);
|
||||
MessageRecord messageRecord = messageRecords.get(0);
|
||||
|
||||
menu.findItem(R.id.menu_context_resend).setVisible(messageRecord.isFailed());
|
||||
menu.findItem(R.id.menu_context_save_attachment).setVisible(messageRecord.isMms() &&
|
||||
!messageRecord.isMmsNotification() &&
|
||||
((MediaMmsMessageRecord)messageRecord).containsMediaSlide());
|
||||
|
||||
menu.findItem(R.id.menu_context_forward).setVisible(true);
|
||||
menu.findItem(R.id.menu_context_details).setVisible(true);
|
||||
menu.findItem(R.id.menu_context_copy).setVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
private MessageRecord getMessageRecord() {
|
||||
Cursor cursor = ((CursorAdapter)getListAdapter()).getCursor();
|
||||
ConversationItem conversationItem = (ConversationItem)(((ConversationAdapter)getListAdapter()).newView(getActivity(), cursor, null));
|
||||
return conversationItem.getMessageRecord();
|
||||
private MessageRecord getSelectedMessageRecord() {
|
||||
List<MessageRecord> messageRecords = getSelectedMessageRecords();
|
||||
|
||||
if (messageRecords.size() == 1) return messageRecords.get(0);
|
||||
else throw new AssertionError();
|
||||
}
|
||||
|
||||
private List<MessageRecord> getSelectedMessageRecords() {
|
||||
return new LinkedList<>(((ConversationAdapter)getListAdapter()).getBatchSelected());
|
||||
}
|
||||
|
||||
public void reload(Recipients recipients, long threadId) {
|
||||
@ -177,23 +184,32 @@ public class ConversationFragment extends ListFragment
|
||||
clipboard.setText(body);
|
||||
}
|
||||
|
||||
private void handleDeleteMessage(final MessageRecord message) {
|
||||
final long messageId = message.getId();
|
||||
|
||||
private void handleDeleteMessages(final List<MessageRecord> messageRecords) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||
builder.setTitle(R.string.ConversationFragment_confirm_message_delete);
|
||||
builder.setIcon(Dialogs.resolveIcon(getActivity(), R.attr.dialog_alert_icon));
|
||||
builder.setCancelable(true);
|
||||
builder.setMessage(R.string.ConversationFragment_are_you_sure_you_want_to_permanently_delete_this_message);
|
||||
|
||||
builder.setMessage(R.string.ConversationFragment_are_you_sure_you_want_to_permanently_delete_all_selected_messages);
|
||||
builder.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
if (message.isMms()) {
|
||||
DatabaseFactory.getMmsDatabase(getActivity()).delete(messageId);
|
||||
} else {
|
||||
DatabaseFactory.getSmsDatabase(getActivity()).deleteMessage(messageId);
|
||||
}
|
||||
new ProgressDialogAsyncTask<MessageRecord, Void, Void>(getActivity(),
|
||||
R.string.ConversationFragment_deleting,
|
||||
R.string.ConversationFragment_deleting_messages)
|
||||
{
|
||||
@Override
|
||||
protected Void doInBackground(MessageRecord... messageRecords) {
|
||||
for (MessageRecord messageRecord : messageRecords) {
|
||||
if (messageRecord.isMms()) {
|
||||
DatabaseFactory.getMmsDatabase(getActivity()).delete(messageRecord.getId());
|
||||
} else {
|
||||
DatabaseFactory.getSmsDatabase(getActivity()).deleteMessage(messageRecord.getId());
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}.execute(messageRecords.toArray(new MessageRecord[messageRecords.size()]));
|
||||
}
|
||||
});
|
||||
|
||||
@ -312,16 +328,43 @@ public class ConversationFragment extends ListFragment
|
||||
public void setComposeText(String text);
|
||||
}
|
||||
|
||||
private ActionMode.Callback actionModeCallback = new ActionMode.Callback() {
|
||||
public class SelectionClickListener
|
||||
implements AdapterView.OnItemLongClickListener, AdapterView.OnItemClickListener
|
||||
{
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
if (actionMode != null && view instanceof ConversationItem) {
|
||||
MessageRecord messageRecord = ((ConversationItem)view).getMessageRecord();
|
||||
((ConversationAdapter) getListAdapter()).toggleBatchSelected(messageRecord);
|
||||
((ConversationAdapter) getListAdapter()).notifyDataSetChanged();
|
||||
|
||||
setCorrectMenuVisibility(actionMode.getMenu());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
if (actionMode == null && view instanceof ConversationItem) {
|
||||
MessageRecord messageRecord = ((ConversationItem)view).getMessageRecord();
|
||||
((ConversationAdapter) getListAdapter()).toggleBatchSelected(messageRecord);
|
||||
((ConversationAdapter) getListAdapter()).notifyDataSetChanged();
|
||||
|
||||
actionMode = ((ActionBarActivity)getActivity()).startSupportActionMode(actionModeCallback);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private class ActionModeCallback implements ActionMode.Callback {
|
||||
|
||||
@Override
|
||||
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
|
||||
MenuInflater inflater = mode.getMenuInflater();
|
||||
inflater.inflate(R.menu.conversation_context, menu);
|
||||
|
||||
MessageRecord messageRecord = getMessageRecord();
|
||||
setCorrectMenuVisibility(messageRecord, menu);
|
||||
|
||||
setCorrectMenuVisibility(menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -332,41 +375,37 @@ public class ConversationFragment extends ListFragment
|
||||
|
||||
@Override
|
||||
public void onDestroyActionMode(ActionMode mode) {
|
||||
if (getListView() != null && getListView().getChildCount() > 0) {
|
||||
for (int i = 0; i < getListView().getChildCount(); i++){
|
||||
getListView().getChildAt(i).setSelected(false);
|
||||
}
|
||||
}
|
||||
((ConversationAdapter)getListAdapter()).getBatchSelected().clear();
|
||||
((ConversationAdapter)getListAdapter()).notifyDataSetChanged();
|
||||
|
||||
actionMode = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
|
||||
MessageRecord messageRecord = getMessageRecord();
|
||||
|
||||
switch(item.getItemId()) {
|
||||
case R.id.menu_context_copy:
|
||||
handleCopyMessage(messageRecord);
|
||||
handleCopyMessage(getSelectedMessageRecord());
|
||||
actionMode.finish();
|
||||
return true;
|
||||
case R.id.menu_context_delete_message:
|
||||
handleDeleteMessage(messageRecord);
|
||||
handleDeleteMessages(getSelectedMessageRecords());
|
||||
actionMode.finish();
|
||||
return true;
|
||||
case R.id.menu_context_details:
|
||||
handleDisplayDetails(messageRecord);
|
||||
handleDisplayDetails(getSelectedMessageRecord());
|
||||
actionMode.finish();
|
||||
return true;
|
||||
case R.id.menu_context_forward:
|
||||
handleForwardMessage(messageRecord);
|
||||
handleForwardMessage(getSelectedMessageRecord());
|
||||
actionMode.finish();
|
||||
return true;
|
||||
case R.id.menu_context_resend:
|
||||
handleResendMessage(messageRecord);
|
||||
handleResendMessage(getSelectedMessageRecord());
|
||||
actionMode.finish();
|
||||
return true;
|
||||
case R.id.menu_context_save_attachment:
|
||||
handleSaveAttachment((MediaMmsMessageRecord)messageRecord);
|
||||
handleSaveAttachment((MediaMmsMessageRecord)getSelectedMessageRecord());
|
||||
actionMode.finish();
|
||||
return true;
|
||||
}
|
||||
|
@ -25,10 +25,8 @@ import android.content.res.TypedArray;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.provider.Contacts.Intents;
|
||||
import android.provider.ContactsContract;
|
||||
import android.provider.ContactsContract.QuickContact;
|
||||
import android.util.AttributeSet;
|
||||
@ -40,9 +38,10 @@ import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.thoughtcrime.securesms.ConversationFragment.SelectionClickListener;
|
||||
import org.thoughtcrime.securesms.contacts.ContactPhotoFactory;
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.contacts.ContactPhotoFactory;
|
||||
import org.thoughtcrime.securesms.database.MmsDatabase;
|
||||
import org.thoughtcrime.securesms.database.SmsDatabase;
|
||||
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord;
|
||||
@ -61,6 +60,8 @@ import org.thoughtcrime.securesms.util.Emoji;
|
||||
import org.thoughtcrime.securesms.util.FutureTaskListener;
|
||||
import org.thoughtcrime.securesms.util.ListenableFutureTask;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* A view that displays an individual conversation item within a conversation
|
||||
* thread. Used by ComposeMessageActivity's ListActivity via a ConversationAdapter.
|
||||
@ -81,13 +82,13 @@ public class ConversationItem extends LinearLayout {
|
||||
R.attr.conversation_item_sent_push_pending_background,
|
||||
R.attr.conversation_item_sent_push_pending_triangle_background};
|
||||
|
||||
private final static int SENT_PUSH = 0;
|
||||
private final static int SENT_PUSH_TRIANGLE = 1;
|
||||
private final static int SENT_SMS = 2;
|
||||
private final static int SENT_SMS_TRIANGLE = 3;
|
||||
private final static int SENT_SMS_PENDING = 4;
|
||||
private final static int SENT_SMS_PENDING_TRIANGLE = 5;
|
||||
private final static int SENT_PUSH_PENDING = 6;
|
||||
private final static int SENT_PUSH = 0;
|
||||
private final static int SENT_PUSH_TRIANGLE = 1;
|
||||
private final static int SENT_SMS = 2;
|
||||
private final static int SENT_SMS_TRIANGLE = 3;
|
||||
private final static int SENT_SMS_PENDING = 4;
|
||||
private final static int SENT_SMS_PENDING_TRIANGLE = 5;
|
||||
private final static int SENT_PUSH_PENDING = 6;
|
||||
private final static int SENT_PUSH_PENDING_TRIANGLE = 7;
|
||||
|
||||
private Handler failedIconHandler;
|
||||
@ -108,19 +109,21 @@ public class ConversationItem extends LinearLayout {
|
||||
private View triangleTick;
|
||||
private ImageView pendingIndicator;
|
||||
|
||||
private View mmsContainer;
|
||||
private ImageView mmsThumbnail;
|
||||
private Button mmsDownloadButton;
|
||||
private TextView mmsDownloadingLabel;
|
||||
private ListenableFutureTask<SlideDeck> slideDeck;
|
||||
private FutureTaskListener<SlideDeck> slideDeckListener;
|
||||
private TypedArray backgroundDrawables;
|
||||
private Set<MessageRecord> batchSelected;
|
||||
private SelectionClickListener selectionClickListener;
|
||||
private View mmsContainer;
|
||||
private ImageView mmsThumbnail;
|
||||
private Button mmsDownloadButton;
|
||||
private TextView mmsDownloadingLabel;
|
||||
private ListenableFutureTask<SlideDeck> slideDeck;
|
||||
private FutureTaskListener<SlideDeck> slideDeckListener;
|
||||
private TypedArray backgroundDrawables;
|
||||
|
||||
private final FailedIconClickListener failedIconClickListener = new FailedIconClickListener();
|
||||
private final MmsDownloadClickListener mmsDownloadClickListener = new MmsDownloadClickListener();
|
||||
private final FailedIconClickListener failedIconClickListener = new FailedIconClickListener();
|
||||
private final MmsDownloadClickListener mmsDownloadClickListener = new MmsDownloadClickListener();
|
||||
private final MmsPreferencesClickListener mmsPreferencesClickListener = new MmsPreferencesClickListener();
|
||||
private final ClickListener clickListener = new ClickListener();
|
||||
private final Handler handler = new Handler();
|
||||
private final ClickListener clickListener = new ClickListener();
|
||||
private final Handler handler = new Handler();
|
||||
private final Context context;
|
||||
|
||||
public ConversationItem(Context context) {
|
||||
@ -157,19 +160,23 @@ public class ConversationItem extends LinearLayout {
|
||||
setOnClickListener(clickListener);
|
||||
if (failedImage != null) failedImage.setOnClickListener(failedIconClickListener);
|
||||
if (mmsDownloadButton != null) mmsDownloadButton.setOnClickListener(mmsDownloadClickListener);
|
||||
if (mmsThumbnail != null) mmsThumbnail.setOnLongClickListener(new MultiSelectLongClickListener());
|
||||
}
|
||||
|
||||
public void set(MasterSecret masterSecret, MessageRecord messageRecord,
|
||||
Set<MessageRecord> batchSelected, SelectionClickListener selectionClickListener,
|
||||
Handler failedIconHandler, boolean groupThread, boolean pushDestination)
|
||||
{
|
||||
this.masterSecret = masterSecret;
|
||||
this.messageRecord = messageRecord;
|
||||
this.batchSelected = batchSelected;
|
||||
this.selectionClickListener = selectionClickListener;
|
||||
this.failedIconHandler = failedIconHandler;
|
||||
this.groupThread = groupThread;
|
||||
this.pushDestination = pushDestination;
|
||||
|
||||
this.messageRecord = messageRecord;
|
||||
this.masterSecret = masterSecret;
|
||||
this.failedIconHandler = failedIconHandler;
|
||||
this.groupThread = groupThread;
|
||||
this.pushDestination = pushDestination;
|
||||
|
||||
setBackgroundDrawables(messageRecord);
|
||||
setConversationBackgroundDrawables(messageRecord);
|
||||
setSelectionBackgroundDrawables(messageRecord);
|
||||
setBodyText(messageRecord);
|
||||
|
||||
if (!messageRecord.isGroupAction()) {
|
||||
@ -211,33 +218,57 @@ public class ConversationItem extends LinearLayout {
|
||||
|
||||
/// MessageRecord Attribute Parsers
|
||||
|
||||
private void setBackgroundDrawables(MessageRecord messageRecord) {
|
||||
private void setConversationBackgroundDrawables(MessageRecord messageRecord) {
|
||||
if (conversationParent != null && backgroundDrawables != null) {
|
||||
if (messageRecord.isOutgoing()) {
|
||||
final int background;
|
||||
final int triangleBackground;
|
||||
if (messageRecord.isPending() && pushDestination && !messageRecord.isForcedSms()) {
|
||||
background = SENT_PUSH_PENDING;
|
||||
background = SENT_PUSH_PENDING;
|
||||
triangleBackground = SENT_PUSH_PENDING_TRIANGLE;
|
||||
} else if (messageRecord.isPending() || messageRecord.isPendingSmsFallback()) {
|
||||
background = SENT_SMS_PENDING;
|
||||
background = SENT_SMS_PENDING;
|
||||
triangleBackground = SENT_SMS_PENDING_TRIANGLE;
|
||||
} else if (messageRecord.isPush()) {
|
||||
background = SENT_PUSH;
|
||||
background = SENT_PUSH;
|
||||
triangleBackground = SENT_PUSH_TRIANGLE;
|
||||
} else {
|
||||
background = SENT_SMS;
|
||||
background = SENT_SMS;
|
||||
triangleBackground = SENT_SMS_TRIANGLE;
|
||||
}
|
||||
|
||||
setViewBackgroundWithoutResettingPadding(conversationParent, backgroundDrawables.getResourceId(background, -1));
|
||||
setViewBackgroundWithoutResettingPadding(triangleTick, backgroundDrawables.getResourceId(triangleBackground, -1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setSelectionBackgroundDrawables(MessageRecord messageRecord) {
|
||||
int[] attributes = new int[]{R.attr.conversation_list_item_background_selected,
|
||||
R.attr.conversation_item_background};
|
||||
|
||||
TypedArray drawables = context.obtainStyledAttributes(attributes);
|
||||
|
||||
if (batchSelected.contains(messageRecord)) {
|
||||
setBackgroundDrawable(drawables.getDrawable(0));
|
||||
} else {
|
||||
setBackgroundDrawable(drawables.getDrawable(1));
|
||||
}
|
||||
|
||||
drawables.recycle();
|
||||
}
|
||||
|
||||
private void setBodyText(MessageRecord messageRecord) {
|
||||
bodyText.setText(Emoji.getInstance(context).emojify(messageRecord.getDisplayBody(), new Emoji.InvalidatingPageLoadedListener(bodyText)),
|
||||
TextView.BufferType.SPANNABLE);
|
||||
bodyText.setClickable(false);
|
||||
bodyText.setFocusable(false);
|
||||
bodyText.setText(Emoji.getInstance(context).emojify(messageRecord.getDisplayBody(),
|
||||
new Emoji.InvalidatingPageLoadedListener(bodyText)),
|
||||
TextView.BufferType.SPANNABLE);
|
||||
|
||||
if (bodyText.isClickable() && bodyText.isFocusable()) {
|
||||
bodyText.setOnLongClickListener(new MultiSelectLongClickListener());
|
||||
bodyText.setOnClickListener(new MultiSelectLongClickListener());
|
||||
}
|
||||
}
|
||||
|
||||
private void setContactPhoto(MessageRecord messageRecord) {
|
||||
@ -365,12 +396,6 @@ public class ConversationItem extends LinearLayout {
|
||||
if (slide.hasImage()) {
|
||||
slide.setThumbnailOn(mmsThumbnail);
|
||||
mmsThumbnail.setOnClickListener(new ThumbnailClickListener(slide));
|
||||
mmsThumbnail.setOnLongClickListener(new OnLongClickListener() {
|
||||
@Override
|
||||
public boolean onLongClick(View v) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
mmsThumbnail.setVisibility(View.VISIBLE);
|
||||
return;
|
||||
}
|
||||
@ -474,7 +499,9 @@ public class ConversationItem extends LinearLayout {
|
||||
}
|
||||
|
||||
public void onClick(View v) {
|
||||
if (MediaPreviewActivity.isContentTypeSupported(slide.getContentType())) {
|
||||
if (!batchSelected.isEmpty()) {
|
||||
selectionClickListener.onItemClick(null, ConversationItem.this, -1, -1);
|
||||
} else if (MediaPreviewActivity.isContentTypeSupported(slide.getContentType())) {
|
||||
Intent intent = new Intent(context, MediaPreviewActivity.class);
|
||||
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||
intent.setDataAndType(slide.getUri(), slide.getContentType());
|
||||
@ -545,6 +572,19 @@ public class ConversationItem extends LinearLayout {
|
||||
}
|
||||
}
|
||||
|
||||
private class MultiSelectLongClickListener implements OnLongClickListener, OnClickListener {
|
||||
@Override
|
||||
public boolean onLongClick(View view) {
|
||||
selectionClickListener.onItemLongClick(null, ConversationItem.this, -1, -1);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
selectionClickListener.onItemClick(null, ConversationItem.this, -1, -1);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleMessageApproval() {
|
||||
final int title;
|
||||
final int message;
|
||||
|
@ -182,4 +182,15 @@ public abstract class MessageRecord extends DisplayRecord {
|
||||
|
||||
return spannable;
|
||||
}
|
||||
|
||||
public boolean equals(Object other) {
|
||||
return other != null &&
|
||||
other instanceof MessageRecord &&
|
||||
((MessageRecord) other).getId() == getId() &&
|
||||
((MessageRecord) other).isMms() == isMms();
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return (int)getId();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user