Loading app/core/build.gradle +1 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ dependencies { implementation libs.moshi implementation libs.timber implementation libs.mime4j.core implementation libs.mime4j.dom testImplementation project(':mail:testing') testImplementation project(":backend:imap") Loading app/core/src/main/java/com/fsck/k9/FontSizes.java +9 −48 Original line number Diff line number Diff line Loading @@ -16,10 +16,7 @@ public class FontSizes { private static final String MESSAGE_LIST_DATE = "fontSizeMessageListDate"; private static final String MESSAGE_LIST_PREVIEW = "fontSizeMessageListPreview"; private static final String MESSAGE_VIEW_SENDER = "fontSizeMessageViewSender"; private static final String MESSAGE_VIEW_TO = "fontSizeMessageViewTo"; private static final String MESSAGE_VIEW_CC = "fontSizeMessageViewCC"; private static final String MESSAGE_VIEW_BCC = "fontSizeMessageViewBCC"; private static final String MESSAGE_VIEW_ADDITIONAL_HEADERS = "fontSizeMessageViewAdditionalHeaders"; private static final String MESSAGE_VIEW_RECIPIENTS = "fontSizeMessageViewTo"; private static final String MESSAGE_VIEW_SUBJECT = "fontSizeMessageViewSubject"; private static final String MESSAGE_VIEW_DATE = "fontSizeMessageViewDate"; private static final String MESSAGE_VIEW_CONTENT_PERCENT = "fontSizeMessageViewContentPercent"; Loading @@ -40,10 +37,7 @@ public class FontSizes { private int messageListDate; private int messageListPreview; private int messageViewSender; private int messageViewTo; private int messageViewCC; private int messageViewBCC; private int messageViewAdditionalHeaders; private int messageViewRecipients; private int messageViewSubject; private int messageViewDate; private int messageViewContentPercent; Loading @@ -57,10 +51,7 @@ public class FontSizes { messageListPreview = FONT_DEFAULT; messageViewSender = FONT_DEFAULT; messageViewTo = FONT_DEFAULT; messageViewCC = FONT_DEFAULT; messageViewBCC = FONT_DEFAULT; messageViewAdditionalHeaders = FONT_DEFAULT; messageViewRecipients = FONT_DEFAULT; messageViewSubject = FONT_DEFAULT; messageViewDate = FONT_DEFAULT; messageViewContentPercent = 100; Loading @@ -75,10 +66,7 @@ public class FontSizes { editor.putInt(MESSAGE_LIST_PREVIEW, messageListPreview); editor.putInt(MESSAGE_VIEW_SENDER, messageViewSender); editor.putInt(MESSAGE_VIEW_TO, messageViewTo); editor.putInt(MESSAGE_VIEW_CC, messageViewCC); editor.putInt(MESSAGE_VIEW_BCC, messageViewBCC); editor.putInt(MESSAGE_VIEW_ADDITIONAL_HEADERS, messageViewAdditionalHeaders); editor.putInt(MESSAGE_VIEW_RECIPIENTS, messageViewRecipients); editor.putInt(MESSAGE_VIEW_SUBJECT, messageViewSubject); editor.putInt(MESSAGE_VIEW_DATE, messageViewDate); editor.putInt(MESSAGE_VIEW_CONTENT_PERCENT, getMessageViewContentAsPercent()); Loading @@ -93,10 +81,7 @@ public class FontSizes { messageListPreview = storage.getInt(MESSAGE_LIST_PREVIEW, messageListPreview); messageViewSender = storage.getInt(MESSAGE_VIEW_SENDER, messageViewSender); messageViewTo = storage.getInt(MESSAGE_VIEW_TO, messageViewTo); messageViewCC = storage.getInt(MESSAGE_VIEW_CC, messageViewCC); messageViewBCC = storage.getInt(MESSAGE_VIEW_BCC, messageViewBCC); messageViewAdditionalHeaders = storage.getInt(MESSAGE_VIEW_ADDITIONAL_HEADERS, messageViewAdditionalHeaders); messageViewRecipients = storage.getInt(MESSAGE_VIEW_RECIPIENTS, messageViewRecipients); messageViewSubject = storage.getInt(MESSAGE_VIEW_SUBJECT, messageViewSubject); messageViewDate = storage.getInt(MESSAGE_VIEW_DATE, messageViewDate); Loading Loading @@ -149,36 +134,12 @@ public class FontSizes { this.messageViewSender = messageViewSender; } public int getMessageViewTo() { return messageViewTo; public int getMessageViewRecipients() { return messageViewRecipients; } public void setMessageViewTo(int messageViewTo) { this.messageViewTo = messageViewTo; } public int getMessageViewCC() { return messageViewCC; } public void setMessageViewCC(int messageViewCC) { this.messageViewCC = messageViewCC; } public int getMessageViewBCC() { return messageViewBCC; } public void setMessageViewBCC(int messageViewBCC) { this.messageViewBCC = messageViewBCC; } public int getMessageViewAdditionalHeaders() { return messageViewAdditionalHeaders; } public void setMessageViewAdditionalHeaders(int messageViewAdditionalHeaders) { this.messageViewAdditionalHeaders = messageViewAdditionalHeaders; public void setMessageViewRecipients(int messageViewRecipients) { this.messageViewRecipients = messageViewRecipients; } public int getMessageViewSubject() { Loading app/core/src/main/java/com/fsck/k9/helper/AddressFormatter.kt 0 → 100644 +74 −0 Original line number Diff line number Diff line package com.fsck.k9.helper import android.text.Spannable.SPAN_EXCLUSIVE_EXCLUSIVE import android.text.SpannableString import android.text.style.ForegroundColorSpan import com.fsck.k9.Account import com.fsck.k9.Identity import com.fsck.k9.mail.Address /** * Get the display name for an email address. */ interface AddressFormatter { fun getDisplayName(address: Address): CharSequence } class RealAddressFormatter( private val contactNameProvider: ContactNameProvider, private val account: Account, private val showCorrespondentNames: Boolean, private val showContactNames: Boolean, private val contactNameColor: Int?, private val meText: String ) : AddressFormatter { override fun getDisplayName(address: Address): CharSequence { val identity = account.findIdentity(address) if (identity != null) { return getIdentityName(identity) } return if (!showCorrespondentNames) { address.address } else if (showContactNames) { getContactName(address) } else { buildDisplayName(address) } } private fun getIdentityName(identity: Identity): String { return if (account.identities.size == 1) { meText } else { identity.description ?: identity.name ?: identity.email ?: meText } } private fun getContactName(address: Address): CharSequence { val contactName = contactNameProvider.getNameForAddress(address.address) ?: return buildDisplayName(address) return if (contactNameColor != null) { SpannableString(contactName).apply { setSpan(ForegroundColorSpan(contactNameColor), 0, contactName.length, SPAN_EXCLUSIVE_EXCLUSIVE) } } else { contactName } } private fun buildDisplayName(address: Address): CharSequence { return address.personal?.takeIf { it.isNotBlank() && !it.equals(meText, ignoreCase = true) && !isSpoofAddress(it) } ?: address.address } private fun isSpoofAddress(displayName: String): Boolean { val atIndex = displayName.indexOf('@') return if (atIndex > 0) { displayName[atIndex - 1] != '(' } else { false } } } app/core/src/main/java/com/fsck/k9/helper/ContactNameProvider.kt 0 → 100644 +11 −0 Original line number Diff line number Diff line package com.fsck.k9.helper interface ContactNameProvider { fun getNameForAddress(address: String): String? } class RealContactNameProvider(private val contacts: Contacts) : ContactNameProvider { override fun getNameForAddress(address: String): String? { return contacts.getNameForAddress(address) } } app/core/src/main/java/com/fsck/k9/helper/Contacts.java +27 −5 Original line number Diff line number Diff line package com.fsck.k9.helper; import java.util.HashMap; import android.Manifest; import android.content.ContentResolver; import android.content.Context; Loading @@ -9,13 +11,12 @@ import android.content.pm.PackageManager; import android.database.Cursor; import android.net.Uri; import android.provider.ContactsContract; import timber.log.Timber; import android.provider.ContactsContract.CommonDataKinds.Photo; import androidx.core.content.ContextCompat; import androidx.annotation.Nullable; import androidx.core.content.ContextCompat; import com.fsck.k9.mail.Address; import java.util.HashMap; import timber.log.Timber; /** * Helper class to access the contacts stored on the device. Loading @@ -37,7 +38,8 @@ public class Contacts { ContactsContract.CommonDataKinds.Email._ID, ContactsContract.Contacts.DISPLAY_NAME, ContactsContract.CommonDataKinds.Email.CONTACT_ID, Photo.PHOTO_URI Photo.PHOTO_URI, ContactsContract.Contacts.LOOKUP_KEY }; /** Loading @@ -52,6 +54,8 @@ public class Contacts { */ protected static final int CONTACT_ID_INDEX = 2; protected static final int LOOKUP_KEY_INDEX = 4; /** * Get instance of the Contacts class. Loading Loading @@ -169,6 +173,24 @@ public class Contacts { return false; } @Nullable public Uri getContactUri(String emailAddress) { Cursor cursor = getContactByAddress(emailAddress); if (cursor == null) { return null; } try (cursor) { if (!cursor.moveToFirst()) { return null; } long contactId = cursor.getLong(CONTACT_ID_INDEX); String lookupKey = cursor.getString(LOOKUP_KEY_INDEX); return ContactsContract.Contacts.getLookupUri(contactId, lookupKey); } } /** * Get the name of the contact an email address belongs to. * Loading Loading
app/core/build.gradle +1 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ dependencies { implementation libs.moshi implementation libs.timber implementation libs.mime4j.core implementation libs.mime4j.dom testImplementation project(':mail:testing') testImplementation project(":backend:imap") Loading
app/core/src/main/java/com/fsck/k9/FontSizes.java +9 −48 Original line number Diff line number Diff line Loading @@ -16,10 +16,7 @@ public class FontSizes { private static final String MESSAGE_LIST_DATE = "fontSizeMessageListDate"; private static final String MESSAGE_LIST_PREVIEW = "fontSizeMessageListPreview"; private static final String MESSAGE_VIEW_SENDER = "fontSizeMessageViewSender"; private static final String MESSAGE_VIEW_TO = "fontSizeMessageViewTo"; private static final String MESSAGE_VIEW_CC = "fontSizeMessageViewCC"; private static final String MESSAGE_VIEW_BCC = "fontSizeMessageViewBCC"; private static final String MESSAGE_VIEW_ADDITIONAL_HEADERS = "fontSizeMessageViewAdditionalHeaders"; private static final String MESSAGE_VIEW_RECIPIENTS = "fontSizeMessageViewTo"; private static final String MESSAGE_VIEW_SUBJECT = "fontSizeMessageViewSubject"; private static final String MESSAGE_VIEW_DATE = "fontSizeMessageViewDate"; private static final String MESSAGE_VIEW_CONTENT_PERCENT = "fontSizeMessageViewContentPercent"; Loading @@ -40,10 +37,7 @@ public class FontSizes { private int messageListDate; private int messageListPreview; private int messageViewSender; private int messageViewTo; private int messageViewCC; private int messageViewBCC; private int messageViewAdditionalHeaders; private int messageViewRecipients; private int messageViewSubject; private int messageViewDate; private int messageViewContentPercent; Loading @@ -57,10 +51,7 @@ public class FontSizes { messageListPreview = FONT_DEFAULT; messageViewSender = FONT_DEFAULT; messageViewTo = FONT_DEFAULT; messageViewCC = FONT_DEFAULT; messageViewBCC = FONT_DEFAULT; messageViewAdditionalHeaders = FONT_DEFAULT; messageViewRecipients = FONT_DEFAULT; messageViewSubject = FONT_DEFAULT; messageViewDate = FONT_DEFAULT; messageViewContentPercent = 100; Loading @@ -75,10 +66,7 @@ public class FontSizes { editor.putInt(MESSAGE_LIST_PREVIEW, messageListPreview); editor.putInt(MESSAGE_VIEW_SENDER, messageViewSender); editor.putInt(MESSAGE_VIEW_TO, messageViewTo); editor.putInt(MESSAGE_VIEW_CC, messageViewCC); editor.putInt(MESSAGE_VIEW_BCC, messageViewBCC); editor.putInt(MESSAGE_VIEW_ADDITIONAL_HEADERS, messageViewAdditionalHeaders); editor.putInt(MESSAGE_VIEW_RECIPIENTS, messageViewRecipients); editor.putInt(MESSAGE_VIEW_SUBJECT, messageViewSubject); editor.putInt(MESSAGE_VIEW_DATE, messageViewDate); editor.putInt(MESSAGE_VIEW_CONTENT_PERCENT, getMessageViewContentAsPercent()); Loading @@ -93,10 +81,7 @@ public class FontSizes { messageListPreview = storage.getInt(MESSAGE_LIST_PREVIEW, messageListPreview); messageViewSender = storage.getInt(MESSAGE_VIEW_SENDER, messageViewSender); messageViewTo = storage.getInt(MESSAGE_VIEW_TO, messageViewTo); messageViewCC = storage.getInt(MESSAGE_VIEW_CC, messageViewCC); messageViewBCC = storage.getInt(MESSAGE_VIEW_BCC, messageViewBCC); messageViewAdditionalHeaders = storage.getInt(MESSAGE_VIEW_ADDITIONAL_HEADERS, messageViewAdditionalHeaders); messageViewRecipients = storage.getInt(MESSAGE_VIEW_RECIPIENTS, messageViewRecipients); messageViewSubject = storage.getInt(MESSAGE_VIEW_SUBJECT, messageViewSubject); messageViewDate = storage.getInt(MESSAGE_VIEW_DATE, messageViewDate); Loading Loading @@ -149,36 +134,12 @@ public class FontSizes { this.messageViewSender = messageViewSender; } public int getMessageViewTo() { return messageViewTo; public int getMessageViewRecipients() { return messageViewRecipients; } public void setMessageViewTo(int messageViewTo) { this.messageViewTo = messageViewTo; } public int getMessageViewCC() { return messageViewCC; } public void setMessageViewCC(int messageViewCC) { this.messageViewCC = messageViewCC; } public int getMessageViewBCC() { return messageViewBCC; } public void setMessageViewBCC(int messageViewBCC) { this.messageViewBCC = messageViewBCC; } public int getMessageViewAdditionalHeaders() { return messageViewAdditionalHeaders; } public void setMessageViewAdditionalHeaders(int messageViewAdditionalHeaders) { this.messageViewAdditionalHeaders = messageViewAdditionalHeaders; public void setMessageViewRecipients(int messageViewRecipients) { this.messageViewRecipients = messageViewRecipients; } public int getMessageViewSubject() { Loading
app/core/src/main/java/com/fsck/k9/helper/AddressFormatter.kt 0 → 100644 +74 −0 Original line number Diff line number Diff line package com.fsck.k9.helper import android.text.Spannable.SPAN_EXCLUSIVE_EXCLUSIVE import android.text.SpannableString import android.text.style.ForegroundColorSpan import com.fsck.k9.Account import com.fsck.k9.Identity import com.fsck.k9.mail.Address /** * Get the display name for an email address. */ interface AddressFormatter { fun getDisplayName(address: Address): CharSequence } class RealAddressFormatter( private val contactNameProvider: ContactNameProvider, private val account: Account, private val showCorrespondentNames: Boolean, private val showContactNames: Boolean, private val contactNameColor: Int?, private val meText: String ) : AddressFormatter { override fun getDisplayName(address: Address): CharSequence { val identity = account.findIdentity(address) if (identity != null) { return getIdentityName(identity) } return if (!showCorrespondentNames) { address.address } else if (showContactNames) { getContactName(address) } else { buildDisplayName(address) } } private fun getIdentityName(identity: Identity): String { return if (account.identities.size == 1) { meText } else { identity.description ?: identity.name ?: identity.email ?: meText } } private fun getContactName(address: Address): CharSequence { val contactName = contactNameProvider.getNameForAddress(address.address) ?: return buildDisplayName(address) return if (contactNameColor != null) { SpannableString(contactName).apply { setSpan(ForegroundColorSpan(contactNameColor), 0, contactName.length, SPAN_EXCLUSIVE_EXCLUSIVE) } } else { contactName } } private fun buildDisplayName(address: Address): CharSequence { return address.personal?.takeIf { it.isNotBlank() && !it.equals(meText, ignoreCase = true) && !isSpoofAddress(it) } ?: address.address } private fun isSpoofAddress(displayName: String): Boolean { val atIndex = displayName.indexOf('@') return if (atIndex > 0) { displayName[atIndex - 1] != '(' } else { false } } }
app/core/src/main/java/com/fsck/k9/helper/ContactNameProvider.kt 0 → 100644 +11 −0 Original line number Diff line number Diff line package com.fsck.k9.helper interface ContactNameProvider { fun getNameForAddress(address: String): String? } class RealContactNameProvider(private val contacts: Contacts) : ContactNameProvider { override fun getNameForAddress(address: String): String? { return contacts.getNameForAddress(address) } }
app/core/src/main/java/com/fsck/k9/helper/Contacts.java +27 −5 Original line number Diff line number Diff line package com.fsck.k9.helper; import java.util.HashMap; import android.Manifest; import android.content.ContentResolver; import android.content.Context; Loading @@ -9,13 +11,12 @@ import android.content.pm.PackageManager; import android.database.Cursor; import android.net.Uri; import android.provider.ContactsContract; import timber.log.Timber; import android.provider.ContactsContract.CommonDataKinds.Photo; import androidx.core.content.ContextCompat; import androidx.annotation.Nullable; import androidx.core.content.ContextCompat; import com.fsck.k9.mail.Address; import java.util.HashMap; import timber.log.Timber; /** * Helper class to access the contacts stored on the device. Loading @@ -37,7 +38,8 @@ public class Contacts { ContactsContract.CommonDataKinds.Email._ID, ContactsContract.Contacts.DISPLAY_NAME, ContactsContract.CommonDataKinds.Email.CONTACT_ID, Photo.PHOTO_URI Photo.PHOTO_URI, ContactsContract.Contacts.LOOKUP_KEY }; /** Loading @@ -52,6 +54,8 @@ public class Contacts { */ protected static final int CONTACT_ID_INDEX = 2; protected static final int LOOKUP_KEY_INDEX = 4; /** * Get instance of the Contacts class. Loading Loading @@ -169,6 +173,24 @@ public class Contacts { return false; } @Nullable public Uri getContactUri(String emailAddress) { Cursor cursor = getContactByAddress(emailAddress); if (cursor == null) { return null; } try (cursor) { if (!cursor.moveToFirst()) { return null; } long contactId = cursor.getLong(CONTACT_ID_INDEX); String lookupKey = cursor.getString(LOOKUP_KEY_INDEX); return ContactsContract.Contacts.getLookupUri(contactId, lookupKey); } } /** * Get the name of the contact an email address belongs to. * Loading