Merge pull request #4140 from k9mail/MessageListAdapter_refactoring
MessageListAdapter refactoring
This commit is contained in:
commit
2fe416b300
4 changed files with 454 additions and 403 deletions
|
@ -1,360 +0,0 @@
|
|||
package com.fsck.k9.fragment;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.Resources.Theme;
|
||||
import android.content.res.TypedArray;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Typeface;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.format.DateUtils;
|
||||
import android.text.style.AbsoluteSizeSpan;
|
||||
import android.text.style.ForegroundColorSpan;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.CursorAdapter;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.fsck.k9.Account;
|
||||
import com.fsck.k9.FontSizes;
|
||||
import com.fsck.k9.K9;
|
||||
import com.fsck.k9.ui.R;
|
||||
import com.fsck.k9.mail.Address;
|
||||
import com.fsck.k9.mailstore.DatabasePreviewType;
|
||||
import com.fsck.k9.ui.ContactBadge;
|
||||
|
||||
import static com.fsck.k9.fragment.MLFProjectionInfo.ANSWERED_COLUMN;
|
||||
import static com.fsck.k9.fragment.MLFProjectionInfo.ATTACHMENT_COUNT_COLUMN;
|
||||
import static com.fsck.k9.fragment.MLFProjectionInfo.CC_LIST_COLUMN;
|
||||
import static com.fsck.k9.fragment.MLFProjectionInfo.DATE_COLUMN;
|
||||
import static com.fsck.k9.fragment.MLFProjectionInfo.FLAGGED_COLUMN;
|
||||
import static com.fsck.k9.fragment.MLFProjectionInfo.FOLDER_SERVER_ID_COLUMN;
|
||||
import static com.fsck.k9.fragment.MLFProjectionInfo.FORWARDED_COLUMN;
|
||||
import static com.fsck.k9.fragment.MLFProjectionInfo.PREVIEW_COLUMN;
|
||||
import static com.fsck.k9.fragment.MLFProjectionInfo.PREVIEW_TYPE_COLUMN;
|
||||
import static com.fsck.k9.fragment.MLFProjectionInfo.READ_COLUMN;
|
||||
import static com.fsck.k9.fragment.MLFProjectionInfo.SENDER_LIST_COLUMN;
|
||||
import static com.fsck.k9.fragment.MLFProjectionInfo.SUBJECT_COLUMN;
|
||||
import static com.fsck.k9.fragment.MLFProjectionInfo.THREAD_COUNT_COLUMN;
|
||||
import static com.fsck.k9.fragment.MLFProjectionInfo.TO_LIST_COLUMN;
|
||||
import static com.fsck.k9.fragment.MLFProjectionInfo.UID_COLUMN;
|
||||
|
||||
|
||||
public class MessageListAdapter extends CursorAdapter {
|
||||
|
||||
private final MessageListFragment fragment;
|
||||
private Drawable mForwardedIcon;
|
||||
private Drawable mAnsweredIcon;
|
||||
private Drawable mForwardedAnsweredIcon;
|
||||
private int previewTextColor;
|
||||
private int activeItemBackgroundColor;
|
||||
private int selectedItemBackgroundColor;
|
||||
private int readItemBackgroundColor;
|
||||
private int unreadItemBackgroundColor;
|
||||
private FontSizes fontSizes = K9.getFontSizes();
|
||||
|
||||
MessageListAdapter(MessageListFragment fragment) {
|
||||
super(fragment.getActivity(), null, 0);
|
||||
this.fragment = fragment;
|
||||
|
||||
int[] attributes = new int[] {
|
||||
R.attr.messageListAnswered,
|
||||
R.attr.messageListForwarded,
|
||||
R.attr.messageListAnsweredForwarded,
|
||||
R.attr.messageListPreviewTextColor,
|
||||
R.attr.messageListActiveItemBackgroundColor,
|
||||
R.attr.messageListSelectedBackgroundColor,
|
||||
R.attr.messageListReadItemBackgroundColor,
|
||||
R.attr.messageListUnreadItemBackgroundColor
|
||||
};
|
||||
|
||||
Theme theme = fragment.requireActivity().getTheme();
|
||||
TypedArray array = theme.obtainStyledAttributes(attributes);
|
||||
|
||||
Resources res = fragment.getResources();
|
||||
mAnsweredIcon = res.getDrawable(array.getResourceId(0, R.drawable.ic_messagelist_answered_dark));
|
||||
mForwardedIcon = res.getDrawable(array.getResourceId(1, R.drawable.ic_messagelist_forwarded_dark));
|
||||
mForwardedAnsweredIcon = res.getDrawable(array.getResourceId(2, R.drawable.ic_messagelist_answered_forwarded_dark));
|
||||
previewTextColor = array.getColor(3, Color.BLACK);
|
||||
activeItemBackgroundColor = array.getColor(4, Color.BLACK);
|
||||
selectedItemBackgroundColor = array.getColor(5, Color.BLACK);
|
||||
readItemBackgroundColor = array.getColor(6, Color.BLACK);
|
||||
unreadItemBackgroundColor = array.getColor(7, Color.BLACK);
|
||||
|
||||
array.recycle();
|
||||
}
|
||||
|
||||
private String recipientSigil(boolean toMe, boolean ccMe) {
|
||||
if (toMe) {
|
||||
return fragment.getString(R.string.messagelist_sent_to_me_sigil);
|
||||
} else if (ccMe) {
|
||||
return fragment.getString(R.string.messagelist_sent_cc_me_sigil);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public View newView(Context context, Cursor cursor, ViewGroup parent) {
|
||||
View view = fragment.getK9LayoutInflater().inflate(R.layout.message_list_item, parent, false);
|
||||
|
||||
MessageViewHolder holder = new MessageViewHolder(fragment);
|
||||
holder.date = view.findViewById(R.id.date);
|
||||
holder.chip = view.findViewById(R.id.chip);
|
||||
holder.attachment = view.findViewById(R.id.attachment);
|
||||
holder.status = view.findViewById(R.id.status);
|
||||
holder.preview = view.findViewById(R.id.preview);
|
||||
holder.flagged = view.findViewById(R.id.star);
|
||||
|
||||
ContactBadge contactBadge = view.findViewById(R.id.contact_badge);
|
||||
if (fragment.contactsPictureLoader != null) {
|
||||
holder.contactBadge = contactBadge;
|
||||
} else {
|
||||
contactBadge.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if (fragment.senderAboveSubject) {
|
||||
holder.from = view.findViewById(R.id.subject);
|
||||
fontSizes.setViewTextSize(holder.from, fontSizes.getMessageListSender());
|
||||
|
||||
} else {
|
||||
holder.subject = view.findViewById(R.id.subject);
|
||||
fontSizes.setViewTextSize(holder.subject, fontSizes.getMessageListSubject());
|
||||
|
||||
}
|
||||
|
||||
fontSizes.setViewTextSize(holder.date, fontSizes.getMessageListDate());
|
||||
|
||||
|
||||
// 1 preview line is needed even if it is set to 0, because subject is part of the same text view
|
||||
holder.preview.setLines(Math.max(fragment.previewLines,1));
|
||||
fontSizes.setViewTextSize(holder.preview, fontSizes.getMessageListPreview());
|
||||
holder.threadCount = view.findViewById(R.id.thread_count);
|
||||
fontSizes.setViewTextSize(holder.threadCount, fontSizes.getMessageListSubject()); // thread count is next to subject
|
||||
view.findViewById(R.id.selected_checkbox_wrapper).setVisibility((fragment.checkboxes) ? View.VISIBLE : View.GONE);
|
||||
|
||||
holder.flagged.setVisibility(fragment.stars ? View.VISIBLE : View.GONE);
|
||||
holder.flagged.setOnClickListener(holder);
|
||||
|
||||
|
||||
holder.selected = view.findViewById(R.id.selected_checkbox);
|
||||
holder.selected.setOnClickListener(holder);
|
||||
|
||||
|
||||
view.setTag(holder);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindView(View view, Context context, Cursor cursor) {
|
||||
Account account = fragment.getAccountFromCursor(cursor);
|
||||
|
||||
String fromList = cursor.getString(SENDER_LIST_COLUMN);
|
||||
String toList = cursor.getString(TO_LIST_COLUMN);
|
||||
String ccList = cursor.getString(CC_LIST_COLUMN);
|
||||
Address[] fromAddrs = Address.unpack(fromList);
|
||||
Address[] toAddrs = Address.unpack(toList);
|
||||
Address[] ccAddrs = Address.unpack(ccList);
|
||||
|
||||
boolean fromMe = fragment.messageHelper.toMe(account, fromAddrs);
|
||||
boolean toMe = fragment.messageHelper.toMe(account, toAddrs);
|
||||
boolean ccMe = fragment.messageHelper.toMe(account, ccAddrs);
|
||||
|
||||
CharSequence displayName = fragment.messageHelper.getDisplayName(account, fromAddrs, toAddrs);
|
||||
CharSequence displayDate = DateUtils.getRelativeTimeSpanString(context, cursor.getLong(DATE_COLUMN));
|
||||
|
||||
Address counterpartyAddress = fetchCounterPartyAddress(fromMe, toAddrs, ccAddrs, fromAddrs);
|
||||
|
||||
int threadCount = (fragment.showingThreadedList) ? cursor.getInt(THREAD_COUNT_COLUMN) : 0;
|
||||
|
||||
String subject = MlfUtils.buildSubject(cursor.getString(SUBJECT_COLUMN),
|
||||
fragment.getString(R.string.general_no_subject), threadCount);
|
||||
|
||||
boolean read = (cursor.getInt(READ_COLUMN) == 1);
|
||||
boolean flagged = (cursor.getInt(FLAGGED_COLUMN) == 1);
|
||||
boolean answered = (cursor.getInt(ANSWERED_COLUMN) == 1);
|
||||
boolean forwarded = (cursor.getInt(FORWARDED_COLUMN) == 1);
|
||||
|
||||
boolean hasAttachments = (cursor.getInt(ATTACHMENT_COUNT_COLUMN) > 0);
|
||||
|
||||
MessageViewHolder holder = (MessageViewHolder) view.getTag();
|
||||
|
||||
int maybeBoldTypeface = (read) ? Typeface.NORMAL : Typeface.BOLD;
|
||||
|
||||
long uniqueId = cursor.getLong(fragment.uniqueIdColumn);
|
||||
boolean selected = fragment.selected.contains(uniqueId);
|
||||
|
||||
holder.chip.setBackgroundColor(account.getChipColor());
|
||||
if (fragment.checkboxes) {
|
||||
holder.selected.setChecked(selected);
|
||||
}
|
||||
if (fragment.stars) {
|
||||
holder.flagged.setChecked(flagged);
|
||||
}
|
||||
holder.position = cursor.getPosition();
|
||||
if (holder.contactBadge != null) {
|
||||
updateContactBadge(holder, counterpartyAddress);
|
||||
}
|
||||
setBackgroundColor(view, selected, read);
|
||||
if (fragment.activeMessage != null) {
|
||||
changeBackgroundColorIfActiveMessage(cursor, account, view);
|
||||
}
|
||||
updateWithThreadCount(holder, threadCount);
|
||||
CharSequence beforePreviewText = (fragment.senderAboveSubject) ? subject : displayName;
|
||||
String sigil = recipientSigil(toMe, ccMe);
|
||||
SpannableStringBuilder messageStringBuilder = new SpannableStringBuilder(sigil)
|
||||
.append(beforePreviewText);
|
||||
if (fragment.previewLines > 0) {
|
||||
String preview = getPreview(cursor);
|
||||
messageStringBuilder.append(" ").append(preview);
|
||||
}
|
||||
holder.preview.setText(messageStringBuilder, TextView.BufferType.SPANNABLE);
|
||||
|
||||
formatPreviewText(holder.preview, beforePreviewText, sigil);
|
||||
|
||||
if (holder.from != null ) {
|
||||
holder.from.setTypeface(Typeface.create(holder.from.getTypeface(), maybeBoldTypeface));
|
||||
if (fragment.senderAboveSubject) {
|
||||
holder.from.setText(displayName);
|
||||
} else {
|
||||
holder.from.setText(new SpannableStringBuilder(sigil).append(displayName));
|
||||
}
|
||||
}
|
||||
if (holder.subject != null ) {
|
||||
holder.subject.setTypeface(Typeface.create(holder.subject.getTypeface(), maybeBoldTypeface));
|
||||
holder.subject.setText(subject);
|
||||
}
|
||||
holder.date.setText(displayDate);
|
||||
holder.attachment.setVisibility(hasAttachments ? View.VISIBLE : View.GONE);
|
||||
|
||||
Drawable statusHolder = buildStatusHolder(forwarded, answered);
|
||||
if (statusHolder != null) {
|
||||
holder.status.setImageDrawable(statusHolder);
|
||||
holder.status.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
holder.status.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
private void formatPreviewText(TextView preview, CharSequence beforePreviewText, String sigil) {
|
||||
Spannable previewText = (Spannable)preview.getText();
|
||||
previewText.setSpan(buildSenderSpan(), 0, beforePreviewText.length() + sigil.length(),
|
||||
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
|
||||
// Set span (color) for preview message
|
||||
previewText.setSpan(new ForegroundColorSpan(previewTextColor), beforePreviewText.length() + sigil.length(),
|
||||
previewText.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a span section for the sender, and assign the correct font size and weight
|
||||
*/
|
||||
private AbsoluteSizeSpan buildSenderSpan() {
|
||||
int fontSize = (fragment.senderAboveSubject) ?
|
||||
fontSizes.getMessageListSubject():
|
||||
fontSizes.getMessageListSender();
|
||||
return new AbsoluteSizeSpan(fontSize, true);
|
||||
}
|
||||
|
||||
private Address fetchCounterPartyAddress(boolean fromMe, Address[] toAddrs, Address[] ccAddrs, Address[] fromAddrs) {
|
||||
if (fromMe) {
|
||||
if (toAddrs.length > 0) {
|
||||
return toAddrs[0];
|
||||
} else if (ccAddrs.length > 0) {
|
||||
return ccAddrs[0];
|
||||
}
|
||||
} else if (fromAddrs.length > 0) {
|
||||
return fromAddrs[0];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void updateContactBadge(MessageViewHolder holder, Address counterpartyAddress) {
|
||||
if (counterpartyAddress != null) {
|
||||
holder.contactBadge.setContact(counterpartyAddress);
|
||||
/*
|
||||
* At least in Android 2.2 a different background + padding is used when no
|
||||
* email address is available. ListView reuses the views but ContactBadge
|
||||
* doesn't reset the padding, so we do it ourselves.
|
||||
*/
|
||||
holder.contactBadge.setPadding(0, 0, 0, 0);
|
||||
fragment.contactsPictureLoader.setContactPicture(holder.contactBadge, counterpartyAddress);
|
||||
} else {
|
||||
holder.contactBadge.assignContactUri(null);
|
||||
holder.contactBadge.setImageResource(R.drawable.ic_contact_picture);
|
||||
}
|
||||
}
|
||||
|
||||
private void changeBackgroundColorIfActiveMessage(Cursor cursor, Account account, View view) {
|
||||
String uid = cursor.getString(UID_COLUMN);
|
||||
String folderServerId = cursor.getString(FOLDER_SERVER_ID_COLUMN);
|
||||
|
||||
if (account.getUuid().equals(fragment.activeMessage.getAccountUuid()) &&
|
||||
folderServerId.equals(fragment.activeMessage.getFolderServerId()) &&
|
||||
uid.equals(fragment.activeMessage.getUid())) {
|
||||
view.setBackgroundColor(activeItemBackgroundColor);
|
||||
}
|
||||
}
|
||||
|
||||
private Drawable buildStatusHolder(boolean forwarded, boolean answered) {
|
||||
if (forwarded && answered) {
|
||||
return mForwardedAnsweredIcon;
|
||||
} else if (answered) {
|
||||
return mAnsweredIcon;
|
||||
} else if (forwarded) {
|
||||
return mForwardedIcon;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void setBackgroundColor(View view, boolean selected, boolean read) {
|
||||
if (selected || K9.isUseBackgroundAsUnreadIndicator()) {
|
||||
int color;
|
||||
if (selected) {
|
||||
color = selectedItemBackgroundColor;
|
||||
} else if (read) {
|
||||
color = readItemBackgroundColor;
|
||||
} else {
|
||||
color = unreadItemBackgroundColor;
|
||||
}
|
||||
|
||||
view.setBackgroundColor(color);
|
||||
} else {
|
||||
view.setBackgroundColor(Color.TRANSPARENT);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateWithThreadCount(MessageViewHolder holder, int threadCount) {
|
||||
if (threadCount > 1) {
|
||||
holder.threadCount.setText(String.format("%d", threadCount));
|
||||
holder.threadCount.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
holder.threadCount.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
private String getPreview(Cursor cursor) {
|
||||
String previewTypeString = cursor.getString(PREVIEW_TYPE_COLUMN);
|
||||
DatabasePreviewType previewType = DatabasePreviewType.fromDatabaseValue(previewTypeString);
|
||||
|
||||
switch (previewType) {
|
||||
case NONE:
|
||||
case ERROR: {
|
||||
return "";
|
||||
}
|
||||
case ENCRYPTED: {
|
||||
return fragment.getString(R.string.preview_encrypted);
|
||||
}
|
||||
case TEXT: {
|
||||
return cursor.getString(PREVIEW_COLUMN);
|
||||
}
|
||||
}
|
||||
|
||||
throw new AssertionError("Unknown preview type: " + previewType);
|
||||
}
|
||||
}
|
421
app/ui/src/main/java/com/fsck/k9/fragment/MessageListAdapter.kt
Normal file
421
app/ui/src/main/java/com/fsck/k9/fragment/MessageListAdapter.kt
Normal file
|
@ -0,0 +1,421 @@
|
|||
package com.fsck.k9.fragment
|
||||
|
||||
|
||||
import android.content.Context
|
||||
import android.content.res.Resources
|
||||
import android.database.Cursor
|
||||
import android.graphics.Color
|
||||
import android.graphics.Typeface
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.text.Spannable
|
||||
import android.text.SpannableStringBuilder
|
||||
import android.text.format.DateUtils
|
||||
import android.text.style.AbsoluteSizeSpan
|
||||
import android.text.style.ForegroundColorSpan
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.CursorAdapter
|
||||
import android.widget.TextView
|
||||
|
||||
import com.fsck.k9.Account
|
||||
import com.fsck.k9.K9
|
||||
import com.fsck.k9.ui.R
|
||||
import com.fsck.k9.Preferences
|
||||
import com.fsck.k9.contacts.ContactPictureLoader
|
||||
import com.fsck.k9.controller.MessageReference
|
||||
import com.fsck.k9.helper.MessageHelper
|
||||
import com.fsck.k9.mail.Address
|
||||
import com.fsck.k9.mailstore.DatabasePreviewType
|
||||
import com.fsck.k9.ui.ContactBadge
|
||||
|
||||
import com.fsck.k9.fragment.MLFProjectionInfo.ACCOUNT_UUID_COLUMN
|
||||
import com.fsck.k9.fragment.MLFProjectionInfo.ANSWERED_COLUMN
|
||||
import com.fsck.k9.fragment.MLFProjectionInfo.ATTACHMENT_COUNT_COLUMN
|
||||
import com.fsck.k9.fragment.MLFProjectionInfo.CC_LIST_COLUMN
|
||||
import com.fsck.k9.fragment.MLFProjectionInfo.DATE_COLUMN
|
||||
import com.fsck.k9.fragment.MLFProjectionInfo.FLAGGED_COLUMN
|
||||
import com.fsck.k9.fragment.MLFProjectionInfo.FOLDER_SERVER_ID_COLUMN
|
||||
import com.fsck.k9.fragment.MLFProjectionInfo.FORWARDED_COLUMN
|
||||
import com.fsck.k9.fragment.MLFProjectionInfo.PREVIEW_COLUMN
|
||||
import com.fsck.k9.fragment.MLFProjectionInfo.PREVIEW_TYPE_COLUMN
|
||||
import com.fsck.k9.fragment.MLFProjectionInfo.READ_COLUMN
|
||||
import com.fsck.k9.fragment.MLFProjectionInfo.SENDER_LIST_COLUMN
|
||||
import com.fsck.k9.fragment.MLFProjectionInfo.SUBJECT_COLUMN
|
||||
import com.fsck.k9.fragment.MLFProjectionInfo.THREAD_COUNT_COLUMN
|
||||
import com.fsck.k9.fragment.MLFProjectionInfo.TO_LIST_COLUMN
|
||||
import com.fsck.k9.fragment.MLFProjectionInfo.UID_COLUMN
|
||||
|
||||
import kotlin.math.max
|
||||
|
||||
class MessageListAdapter internal constructor(
|
||||
context: Context,
|
||||
theme: Resources.Theme,
|
||||
private val res: Resources,
|
||||
private val layoutInflater: LayoutInflater,
|
||||
private val messageHelper: MessageHelper,
|
||||
private val contactsPictureLoader: ContactPictureLoader,
|
||||
private val preferences: Preferences,
|
||||
private val listItemListener: MessageListItemActionListener,
|
||||
private val showingThreadedList: Boolean = false
|
||||
) : CursorAdapter(context, null, 0) {
|
||||
|
||||
private val forwardedIcon: Drawable
|
||||
private val answeredIcon: Drawable
|
||||
private val forwardedAnsweredIcon: Drawable
|
||||
private val previewTextColor: Int
|
||||
private val activeItemBackgroundColor: Int
|
||||
private val selectedItemBackgroundColor: Int
|
||||
private val readItemBackgroundColor: Int
|
||||
private val unreadItemBackgroundColor: Int
|
||||
private val fontSizes = K9.fontSizes
|
||||
|
||||
init {
|
||||
|
||||
val attributes = intArrayOf(
|
||||
R.attr.messageListAnswered,
|
||||
R.attr.messageListForwarded,
|
||||
R.attr.messageListAnsweredForwarded,
|
||||
R.attr.messageListPreviewTextColor,
|
||||
R.attr.messageListActiveItemBackgroundColor,
|
||||
R.attr.messageListSelectedBackgroundColor,
|
||||
R.attr.messageListReadItemBackgroundColor,
|
||||
R.attr.messageListUnreadItemBackgroundColor
|
||||
)
|
||||
|
||||
val array = theme.obtainStyledAttributes(attributes)
|
||||
|
||||
answeredIcon = res.getDrawable(array.getResourceId(0, R.drawable.ic_messagelist_answered_dark))
|
||||
forwardedIcon = res.getDrawable(array.getResourceId(1, R.drawable.ic_messagelist_forwarded_dark))
|
||||
forwardedAnsweredIcon = res.getDrawable(array.getResourceId(2, R.drawable.ic_messagelist_answered_forwarded_dark))
|
||||
previewTextColor = array.getColor(3, Color.BLACK)
|
||||
activeItemBackgroundColor = array.getColor(4, Color.BLACK)
|
||||
selectedItemBackgroundColor = array.getColor(5, Color.BLACK)
|
||||
readItemBackgroundColor = array.getColor(6, Color.BLACK)
|
||||
unreadItemBackgroundColor = array.getColor(7, Color.BLACK)
|
||||
|
||||
array.recycle()
|
||||
}
|
||||
|
||||
private inline val previewLines: Int
|
||||
get() = K9.messageListPreviewLines
|
||||
|
||||
private val senderAboveSubject: Boolean
|
||||
get() = K9.isMessageListSenderAboveSubject
|
||||
|
||||
private val checkboxes: Boolean
|
||||
get() = K9.isShowMessageListCheckboxes
|
||||
|
||||
private val stars: Boolean
|
||||
get() = K9.isShowMessageListStars
|
||||
|
||||
private val showContactPicture: Boolean
|
||||
get() = K9.isShowContactPicture
|
||||
|
||||
var activeMessage: MessageReference? = null
|
||||
|
||||
private val activeAccountUuid: String?
|
||||
get() = activeMessage?.accountUuid
|
||||
|
||||
private val activeFolderServerId: String?
|
||||
get() = activeMessage?.folderServerId
|
||||
|
||||
private val activeUid: String?
|
||||
get() = activeMessage?.uid
|
||||
|
||||
var uniqueIdColumn: Int = 0
|
||||
|
||||
var selected: Set<Long> = emptySet()
|
||||
|
||||
|
||||
private fun recipientSigil(toMe: Boolean, ccMe: Boolean): String {
|
||||
return if (toMe) {
|
||||
res.getString(R.string.messagelist_sent_to_me_sigil)
|
||||
} else if (ccMe) {
|
||||
res.getString(R.string.messagelist_sent_cc_me_sigil)
|
||||
} else {
|
||||
""
|
||||
}
|
||||
}
|
||||
|
||||
override fun newView(context: Context, cursor: Cursor, parent: ViewGroup): View {
|
||||
val view = layoutInflater.inflate(R.layout.message_list_item, parent, false)
|
||||
|
||||
val holder = MessageViewHolder(listItemListener)
|
||||
holder.date = view.findViewById(R.id.date)
|
||||
holder.chip = view.findViewById(R.id.chip)
|
||||
holder.attachment = view.findViewById(R.id.attachment)
|
||||
holder.status = view.findViewById(R.id.status)
|
||||
holder.preview = view.findViewById(R.id.preview)
|
||||
holder.flagged = view.findViewById(R.id.star)
|
||||
|
||||
val contactBadge = view.findViewById<ContactBadge>(R.id.contact_badge)
|
||||
if (showContactPicture) {
|
||||
holder.contactBadge = contactBadge
|
||||
} else {
|
||||
contactBadge.visibility = View.GONE
|
||||
}
|
||||
|
||||
if (senderAboveSubject) {
|
||||
holder.from = view.findViewById(R.id.subject)
|
||||
fontSizes.setViewTextSize(holder.from, fontSizes.messageListSender)
|
||||
|
||||
} else {
|
||||
holder.subject = view.findViewById(R.id.subject)
|
||||
fontSizes.setViewTextSize(holder.subject, fontSizes.messageListSubject)
|
||||
|
||||
}
|
||||
|
||||
fontSizes.setViewTextSize(holder.date, fontSizes.messageListDate)
|
||||
|
||||
|
||||
// 1 preview line is needed even if it is set to 0, because subject is part of the same text view
|
||||
holder.preview.setLines(max(previewLines, 1))
|
||||
fontSizes.setViewTextSize(holder.preview, fontSizes.messageListPreview)
|
||||
holder.threadCount = view.findViewById(R.id.thread_count)
|
||||
fontSizes.setViewTextSize(holder.threadCount, fontSizes.messageListSubject) // thread count is next to subject
|
||||
view.findViewById<View>(R.id.selected_checkbox_wrapper).visibility = if (checkboxes) View.VISIBLE else View.GONE
|
||||
|
||||
holder.flagged.visibility = if (stars) View.VISIBLE else View.GONE
|
||||
holder.flagged.setOnClickListener(holder)
|
||||
|
||||
|
||||
holder.selected = view.findViewById(R.id.selected_checkbox)
|
||||
holder.selected.setOnClickListener(holder)
|
||||
|
||||
|
||||
view.tag = holder
|
||||
|
||||
return view
|
||||
}
|
||||
|
||||
override fun bindView(view: View, context: Context, cursor: Cursor) {
|
||||
val account = getAccount(cursor)
|
||||
|
||||
val fromList = cursor.getString(SENDER_LIST_COLUMN)
|
||||
val toList = cursor.getString(TO_LIST_COLUMN)
|
||||
val ccList = cursor.getString(CC_LIST_COLUMN)
|
||||
val fromAddrs = Address.unpack(fromList)
|
||||
val toAddrs = Address.unpack(toList)
|
||||
val ccAddrs = Address.unpack(ccList)
|
||||
|
||||
val fromMe = messageHelper.toMe(account, fromAddrs)
|
||||
val toMe = messageHelper.toMe(account, toAddrs)
|
||||
val ccMe = messageHelper.toMe(account, ccAddrs)
|
||||
|
||||
val displayName = messageHelper.getDisplayName(account, fromAddrs, toAddrs)
|
||||
val displayDate = DateUtils.getRelativeTimeSpanString(context, cursor.getLong(DATE_COLUMN))
|
||||
|
||||
val counterpartyAddress = fetchCounterPartyAddress(fromMe, toAddrs, ccAddrs, fromAddrs)
|
||||
|
||||
val threadCount = if (showingThreadedList) cursor.getInt(THREAD_COUNT_COLUMN) else 0
|
||||
|
||||
val subject = MlfUtils.buildSubject(cursor.getString(SUBJECT_COLUMN),
|
||||
res.getString(R.string.general_no_subject), threadCount)
|
||||
|
||||
val read = cursor.getInt(READ_COLUMN) == 1
|
||||
val flagged = cursor.getInt(FLAGGED_COLUMN) == 1
|
||||
val answered = cursor.getInt(ANSWERED_COLUMN) == 1
|
||||
val forwarded = cursor.getInt(FORWARDED_COLUMN) == 1
|
||||
|
||||
val hasAttachments = cursor.getInt(ATTACHMENT_COUNT_COLUMN) > 0
|
||||
|
||||
val holder = view.tag as MessageViewHolder
|
||||
|
||||
val maybeBoldTypeface = if (read) Typeface.NORMAL else Typeface.BOLD
|
||||
|
||||
val uniqueId = cursor.getLong(uniqueIdColumn)
|
||||
val selected = selected.contains(uniqueId)
|
||||
|
||||
holder.chip.setBackgroundColor(account.chipColor)
|
||||
if (checkboxes) {
|
||||
holder.selected.isChecked = selected
|
||||
}
|
||||
if (stars) {
|
||||
holder.flagged.isChecked = flagged
|
||||
}
|
||||
holder.position = cursor.position
|
||||
if (holder.contactBadge != null) {
|
||||
updateContactBadge(holder, counterpartyAddress)
|
||||
}
|
||||
setBackgroundColor(view, selected, read)
|
||||
if (activeMessage != null) {
|
||||
changeBackgroundColorIfActiveMessage(cursor, account, view)
|
||||
}
|
||||
updateWithThreadCount(holder, threadCount)
|
||||
val beforePreviewText = if (senderAboveSubject) subject else displayName
|
||||
val sigil = recipientSigil(toMe, ccMe)
|
||||
val messageStringBuilder = SpannableStringBuilder(sigil)
|
||||
.append(beforePreviewText)
|
||||
if (previewLines > 0) {
|
||||
val preview = getPreview(cursor)
|
||||
messageStringBuilder.append(" ").append(preview)
|
||||
}
|
||||
holder.preview.setText(messageStringBuilder, TextView.BufferType.SPANNABLE)
|
||||
|
||||
formatPreviewText(holder.preview, beforePreviewText, sigil)
|
||||
|
||||
if (holder.from != null) {
|
||||
holder.from.typeface = Typeface.create(holder.from.typeface, maybeBoldTypeface)
|
||||
if (senderAboveSubject) {
|
||||
holder.from.text = displayName
|
||||
} else {
|
||||
holder.from.text = SpannableStringBuilder(sigil).append(displayName)
|
||||
}
|
||||
}
|
||||
if (holder.subject != null) {
|
||||
holder.subject.typeface = Typeface.create(holder.subject.typeface, maybeBoldTypeface)
|
||||
holder.subject.text = subject
|
||||
}
|
||||
holder.date.text = displayDate
|
||||
holder.attachment.visibility = if (hasAttachments) View.VISIBLE else View.GONE
|
||||
|
||||
val statusHolder = buildStatusHolder(forwarded, answered)
|
||||
if (statusHolder != null) {
|
||||
holder.status.setImageDrawable(statusHolder)
|
||||
holder.status.visibility = View.VISIBLE
|
||||
} else {
|
||||
holder.status.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
private fun getAccount(cursor: Cursor): Account {
|
||||
val accountUuid = cursor.getString(ACCOUNT_UUID_COLUMN)
|
||||
return preferences.getAccount(accountUuid)
|
||||
}
|
||||
|
||||
private fun formatPreviewText(
|
||||
preview: TextView,
|
||||
beforePreviewText: CharSequence,
|
||||
sigil: String
|
||||
) {
|
||||
val previewText = preview.text as Spannable
|
||||
previewText.setSpan(buildSenderSpan(), 0, beforePreviewText.length + sigil.length,
|
||||
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
|
||||
// Set span (color) for preview message
|
||||
previewText.setSpan(
|
||||
ForegroundColorSpan(previewTextColor),
|
||||
beforePreviewText.length + sigil.length,
|
||||
previewText.length,
|
||||
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a span section for the sender, and assign the correct font size and weight
|
||||
*/
|
||||
private fun buildSenderSpan(): AbsoluteSizeSpan {
|
||||
val fontSize = if (senderAboveSubject)
|
||||
fontSizes.messageListSubject
|
||||
else
|
||||
fontSizes.messageListSender
|
||||
return AbsoluteSizeSpan(fontSize, true)
|
||||
}
|
||||
|
||||
private fun fetchCounterPartyAddress(
|
||||
fromMe: Boolean,
|
||||
toAddrs: Array<Address>,
|
||||
ccAddrs: Array<Address>,
|
||||
fromAddrs: Array<Address>
|
||||
): Address? {
|
||||
if (fromMe) {
|
||||
if (toAddrs.size > 0) {
|
||||
return toAddrs[0]
|
||||
} else if (ccAddrs.size > 0) {
|
||||
return ccAddrs[0]
|
||||
}
|
||||
} else if (fromAddrs.size > 0) {
|
||||
return fromAddrs[0]
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private fun updateContactBadge(holder: MessageViewHolder, counterpartyAddress: Address?) {
|
||||
if (counterpartyAddress != null) {
|
||||
holder.contactBadge.setContact(counterpartyAddress)
|
||||
/*
|
||||
* At least in Android 2.2 a different background + padding is used when no
|
||||
* email address is available. ListView reuses the views but ContactBadge
|
||||
* doesn't reset the padding, so we do it ourselves.
|
||||
*/
|
||||
holder.contactBadge.setPadding(0, 0, 0, 0)
|
||||
contactsPictureLoader.setContactPicture(holder.contactBadge, counterpartyAddress)
|
||||
} else {
|
||||
holder.contactBadge.assignContactUri(null)
|
||||
holder.contactBadge.setImageResource(R.drawable.ic_contact_picture)
|
||||
}
|
||||
}
|
||||
|
||||
private fun changeBackgroundColorIfActiveMessage(cursor: Cursor, account: Account, view: View) {
|
||||
val uid = cursor.getString(UID_COLUMN)
|
||||
val folderServerId = cursor.getString(FOLDER_SERVER_ID_COLUMN)
|
||||
|
||||
if (account.uuid == activeAccountUuid &&
|
||||
folderServerId == activeFolderServerId &&
|
||||
uid == activeUid) {
|
||||
view.setBackgroundColor(activeItemBackgroundColor)
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildStatusHolder(forwarded: Boolean, answered: Boolean): Drawable? {
|
||||
if (forwarded && answered) {
|
||||
return forwardedAnsweredIcon
|
||||
} else if (answered) {
|
||||
return answeredIcon
|
||||
} else if (forwarded) {
|
||||
return forwardedIcon
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private fun setBackgroundColor(view: View, selected: Boolean, read: Boolean) {
|
||||
if (selected || K9.isUseBackgroundAsUnreadIndicator) {
|
||||
val color: Int
|
||||
if (selected) {
|
||||
color = selectedItemBackgroundColor
|
||||
} else if (read) {
|
||||
color = readItemBackgroundColor
|
||||
} else {
|
||||
color = unreadItemBackgroundColor
|
||||
}
|
||||
|
||||
view.setBackgroundColor(color)
|
||||
} else {
|
||||
view.setBackgroundColor(Color.TRANSPARENT)
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateWithThreadCount(holder: MessageViewHolder, threadCount: Int) {
|
||||
if (threadCount > 1) {
|
||||
holder.threadCount.setText(String.format("%d", threadCount))
|
||||
holder.threadCount.visibility = View.VISIBLE
|
||||
} else {
|
||||
holder.threadCount.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
private fun getPreview(cursor: Cursor): String {
|
||||
val previewTypeString = cursor.getString(PREVIEW_TYPE_COLUMN)
|
||||
val previewType = DatabasePreviewType.fromDatabaseValue(previewTypeString)
|
||||
|
||||
when (previewType) {
|
||||
DatabasePreviewType.NONE, DatabasePreviewType.ERROR -> {
|
||||
return ""
|
||||
}
|
||||
DatabasePreviewType.ENCRYPTED -> {
|
||||
return res.getString(R.string.preview_encrypted)
|
||||
}
|
||||
DatabasePreviewType.TEXT -> {
|
||||
return cursor.getString(PREVIEW_COLUMN)
|
||||
}
|
||||
}
|
||||
|
||||
throw AssertionError("Unknown preview type: $previewType")
|
||||
}
|
||||
}
|
||||
|
||||
interface MessageListItemActionListener {
|
||||
fun toggleMessageSelectWithAdapterPosition(position: Int)
|
||||
fun toggleMessageFlagWithAdapterPosition(position: Int)
|
||||
}
|
|
@ -60,11 +60,9 @@ import com.fsck.k9.activity.ActivityListener;
|
|||
import com.fsck.k9.activity.ChooseFolder;
|
||||
import com.fsck.k9.activity.FolderInfoHolder;
|
||||
import com.fsck.k9.activity.misc.ContactPicture;
|
||||
import com.fsck.k9.contacts.ContactPictureLoader;
|
||||
import com.fsck.k9.cache.EmailProviderCache;
|
||||
import com.fsck.k9.controller.MessageReference;
|
||||
import com.fsck.k9.controller.MessagingController;
|
||||
import com.fsck.k9.core.BuildConfig;
|
||||
import com.fsck.k9.ui.R;
|
||||
import com.fsck.k9.fragment.ConfirmationDialogFragment.ConfirmationDialogFragmentListener;
|
||||
import com.fsck.k9.fragment.MessageListFragmentComparators.ArrivalComparator;
|
||||
|
@ -110,7 +108,7 @@ import static com.fsck.k9.fragment.MLFProjectionInfo.UID_COLUMN;
|
|||
|
||||
|
||||
public class MessageListFragment extends Fragment implements OnItemClickListener,
|
||||
ConfirmationDialogFragmentListener, LoaderCallbacks<Cursor> {
|
||||
ConfirmationDialogFragmentListener, LoaderCallbacks<Cursor>, MessageListItemActionListener {
|
||||
|
||||
public static MessageListFragment newInstance(
|
||||
LocalSearch search, boolean isThreadDisplay, boolean threadedList) {
|
||||
|
@ -163,9 +161,6 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
|
|||
private SwipeRefreshLayout swipeRefreshLayout;
|
||||
Parcelable savedListState;
|
||||
|
||||
int previewLines = 0;
|
||||
|
||||
|
||||
private MessageListAdapter adapter;
|
||||
private View footerView;
|
||||
private FolderInfoHolder currentFolder;
|
||||
|
@ -177,7 +172,7 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
|
|||
|
||||
private Cursor[] cursors;
|
||||
private boolean[] cursorValid;
|
||||
int uniqueIdColumn;
|
||||
private int uniqueIdColumn;
|
||||
|
||||
/**
|
||||
* Stores the server ID of the folder that we want to open as soon as possible after load.
|
||||
|
@ -199,12 +194,9 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
|
|||
private SortType sortType = SortType.SORT_DATE;
|
||||
private boolean sortAscending = true;
|
||||
private boolean sortDateAscending = false;
|
||||
boolean senderAboveSubject = false;
|
||||
boolean checkboxes = true;
|
||||
boolean stars = true;
|
||||
|
||||
private int selectedCount = 0;
|
||||
Set<Long> selected = new HashSet<>();
|
||||
private Set<Long> selected = new HashSet<>();
|
||||
private ActionMode actionMode;
|
||||
private Boolean hasConnectivity;
|
||||
/**
|
||||
|
@ -212,23 +204,20 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
|
|||
* between user interactions (e.g. selecting a folder for move operation).
|
||||
*/
|
||||
private List<MessageReference> activeMessages;
|
||||
/* package visibility for faster inner class access */
|
||||
MessageHelper messageHelper;
|
||||
private final ActionModeCallback actionModeCallback = new ActionModeCallback();
|
||||
MessageListFragmentListener fragmentListener;
|
||||
boolean showingThreadedList;
|
||||
private boolean showingThreadedList;
|
||||
private boolean isThreadDisplay;
|
||||
private Context context;
|
||||
private final ActivityListener activityListener = new MessageListActivityListener();
|
||||
private Preferences preferences;
|
||||
private boolean loaderJustInitialized;
|
||||
MessageReference activeMessage;
|
||||
private MessageReference activeMessage;
|
||||
/**
|
||||
* {@code true} after {@link #onCreate(Bundle)} was executed. Used in {@link #updateTitle()} to
|
||||
* make sure we don't access member variables before initialization is complete.
|
||||
*/
|
||||
private boolean initialized = false;
|
||||
ContactPictureLoader contactsPictureLoader;
|
||||
private LocalBroadcastManager localBroadcastManager;
|
||||
private BroadcastReceiver cacheBroadcastReceiver;
|
||||
private IntentFilter cacheIntentFilter;
|
||||
|
@ -413,14 +402,6 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
|
|||
preferences = Preferences.getPreferences(appContext);
|
||||
messagingController = MessagingController.getInstance(getActivity().getApplication());
|
||||
|
||||
previewLines = K9.getMessageListPreviewLines();
|
||||
checkboxes = K9.isShowMessageListCheckboxes();
|
||||
stars = K9.isShowMessageListStars();
|
||||
|
||||
if (K9.isShowContactPicture()) {
|
||||
contactsPictureLoader = ContactPicture.getContactPictureLoader();
|
||||
}
|
||||
|
||||
restoreInstanceState(savedInstanceState);
|
||||
decodeArguments();
|
||||
|
||||
|
@ -455,8 +436,6 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
|
|||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
|
||||
messageHelper = MessageHelper.getInstance(getActivity());
|
||||
|
||||
initializeMessageList();
|
||||
|
||||
// This needs to be done before initializing the cursor loader below
|
||||
|
@ -502,6 +481,7 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
|
|||
savedListState = savedInstanceState.getParcelable(STATE_MESSAGE_LIST);
|
||||
String messageReferenceString = savedInstanceState.getString(STATE_ACTIVE_MESSAGE);
|
||||
activeMessage = MessageReference.parse(messageReferenceString);
|
||||
if (adapter != null) adapter.setActiveMessage(activeMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -598,7 +578,17 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
|
|||
}
|
||||
|
||||
private void initializeMessageList() {
|
||||
adapter = new MessageListAdapter(this);
|
||||
adapter = new MessageListAdapter(
|
||||
requireContext(),
|
||||
requireActivity().getTheme(),
|
||||
getResources(),
|
||||
layoutInflater,
|
||||
MessageHelper.getInstance(getActivity()),
|
||||
ContactPicture.getContactPictureLoader(),
|
||||
preferences,
|
||||
this,
|
||||
showingThreadedList
|
||||
);
|
||||
|
||||
if (folderServerId != null) {
|
||||
currentFolder = getFolderInfoHolder(folderServerId, account);
|
||||
|
@ -652,8 +642,6 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
|
|||
public void onResume() {
|
||||
super.onResume();
|
||||
|
||||
senderAboveSubject = K9.isMessageListSenderAboveSubject();
|
||||
|
||||
if (!loaderJustInitialized) {
|
||||
restartLoader();
|
||||
} else {
|
||||
|
@ -1453,14 +1441,16 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
|
|||
toggleMessageSelectWithAdapterPosition(adapterPosition);
|
||||
}
|
||||
|
||||
void toggleMessageFlagWithAdapterPosition(int adapterPosition) {
|
||||
@Override
|
||||
public void toggleMessageFlagWithAdapterPosition(int adapterPosition) {
|
||||
Cursor cursor = (Cursor) adapter.getItem(adapterPosition);
|
||||
boolean flagged = (cursor.getInt(FLAGGED_COLUMN) == 1);
|
||||
|
||||
setFlag(adapterPosition,Flag.FLAGGED, !flagged);
|
||||
}
|
||||
|
||||
void toggleMessageSelectWithAdapterPosition(int adapterPosition) {
|
||||
@Override
|
||||
public void toggleMessageSelectWithAdapterPosition(int adapterPosition) {
|
||||
Cursor cursor = (Cursor) adapter.getItem(adapterPosition);
|
||||
long uniqueId = cursor.getLong(uniqueIdColumn);
|
||||
|
||||
|
@ -2105,6 +2095,7 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
|
|||
} else if (dialogId == R.id.dialog_confirm_delete) {
|
||||
onDeleteConfirmed(activeMessages);
|
||||
activeMessage = null;
|
||||
if (adapter != null) adapter.setActiveMessage(null);
|
||||
} else if (dialogId == R.id.dialog_confirm_mark_all_as_read) {
|
||||
markAllAsRead();
|
||||
} else if (dialogId == R.id.dialog_confirm_empty_trash) {
|
||||
|
@ -2589,6 +2580,7 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
|
|||
cursor = data;
|
||||
uniqueIdColumn = ID_COLUMN;
|
||||
}
|
||||
adapter.setUniqueIdColumn(uniqueIdColumn);
|
||||
|
||||
if (isThreadDisplay) {
|
||||
if (cursor.moveToFirst()) {
|
||||
|
@ -2606,6 +2598,8 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
|
|||
}
|
||||
|
||||
cleanupSelected(cursor);
|
||||
adapter.setSelected(selected);
|
||||
|
||||
updateContextMenu(cursor);
|
||||
|
||||
adapter.swapCursor(cursor);
|
||||
|
@ -2745,7 +2739,7 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
|
|||
adapter.swapCursor(null);
|
||||
}
|
||||
|
||||
Account getAccountFromCursor(Cursor cursor) {
|
||||
private Account getAccountFromCursor(Cursor cursor) {
|
||||
String accountUuid = cursor.getString(ACCOUNT_UUID_COLUMN);
|
||||
return preferences.getAccount(accountUuid);
|
||||
}
|
||||
|
@ -2775,6 +2769,7 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
|
|||
|
||||
// Redraw list immediately
|
||||
if (adapter != null) {
|
||||
adapter.setActiveMessage(activeMessage);
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
@ -2822,10 +2817,6 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
|
|||
return (isRemoteSearchAllowed() || isCheckMailAllowed());
|
||||
}
|
||||
|
||||
LayoutInflater getK9LayoutInflater() {
|
||||
return layoutInflater;
|
||||
}
|
||||
|
||||
public LocalSearch getLocalSearch() {
|
||||
return search;
|
||||
}
|
||||
|
|
|
@ -5,13 +5,12 @@ import android.view.View;
|
|||
import android.widget.CheckBox;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.fsck.k9.ui.R;
|
||||
import com.fsck.k9.ui.ContactBadge;
|
||||
import com.fsck.k9.ui.R;
|
||||
|
||||
|
||||
public class MessageViewHolder implements View.OnClickListener {
|
||||
private final MessageListFragment fragment;
|
||||
private final MessageListItemActionListener itemActionListener;
|
||||
public TextView subject;
|
||||
public TextView preview;
|
||||
public TextView from;
|
||||
|
@ -26,8 +25,8 @@ public class MessageViewHolder implements View.OnClickListener {
|
|||
public ImageView attachment;
|
||||
public ImageView status;
|
||||
|
||||
public MessageViewHolder(MessageListFragment fragment) {
|
||||
this.fragment = fragment;
|
||||
public MessageViewHolder(final MessageListItemActionListener itemActionListener) {
|
||||
this.itemActionListener = itemActionListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -35,9 +34,9 @@ public class MessageViewHolder implements View.OnClickListener {
|
|||
if (position != -1) {
|
||||
int id = view.getId();
|
||||
if (id == R.id.selected_checkbox) {
|
||||
fragment.toggleMessageSelectWithAdapterPosition(position);
|
||||
itemActionListener.toggleMessageSelectWithAdapterPosition(position);
|
||||
} else if (id == R.id.star) {
|
||||
fragment.toggleMessageFlagWithAdapterPosition(position);
|
||||
itemActionListener.toggleMessageFlagWithAdapterPosition(position);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue