Loading app/core/src/main/java/com/fsck/k9/KoinModule.kt +1 −1 Original line number Diff line number Diff line Loading @@ -28,7 +28,7 @@ val mainModule = module { single { get<Context>().resources } single { get<Context>().contentResolver } single { LocalStoreProvider() } single { Contacts(contactDataSource = get()) } single { Contacts() } single { LocalKeyStore(directoryProvider = get()) } single { TrustManagerFactory.createInstance(get()) } single { LocalKeyStoreManager(get()) } Loading app/core/src/main/java/com/fsck/k9/helper/ContactNameProvider.kt +5 −2 Original line number Diff line number Diff line package com.fsck.k9.helper import app.k9mail.core.android.common.contact.ContactRepository import app.k9mail.core.common.mail.EmailAddress interface ContactNameProvider { fun getNameForAddress(address: String): String? } class RealContactNameProvider(private val contacts: Contacts) : ContactNameProvider { class RealContactNameProvider( private val contactRepository: ContactRepository, ) : ContactNameProvider { override fun getNameForAddress(address: String): String? { return contacts.getNameFor(EmailAddress(address)) return contactRepository.getContactFor(EmailAddress(address))?.name } } app/core/src/main/java/com/fsck/k9/helper/Contacts.kt +1 −82 Original line number Diff line number Diff line package com.fsck.k9.helper import android.net.Uri import app.k9mail.core.android.common.contact.ContactDataSource import app.k9mail.core.common.mail.EmailAddress import com.fsck.k9.mail.Address import timber.log.Timber /** * Helper class to access the contacts stored on the device. */ open class Contacts( private val contactDataSource: ContactDataSource, ) { /** * Check whether the provided email address belongs to one of the contacts. * * @param emailAddress The email address to look for. * @return <tt>true</tt>, if the email address belongs to a contact. * <tt>false</tt>, otherwise. */ fun isInContacts(emailAddress: EmailAddress): Boolean = contactDataSource.hasContactFor(emailAddress) /** * Check whether one of the provided email addresses belongs to one of the contacts. * * @param emailAddresses The email addresses to search in contacts * @return <tt>true</tt>, if one of the email addresses belongs to a contact. * <tt>false</tt>, otherwise. */ fun isAnyInContacts(emailAddresses: List<EmailAddress>): Boolean = emailAddresses.any { emailAddress -> isInContacts(emailAddress) } fun getContactUri(emailAddress: EmailAddress): Uri? { val contact = contactDataSource.getContactFor(emailAddress) return contact?.uri } /** * Get the name of the contact an email address belongs to. * * @param emailAddress The email address to search for. * @return The name of the contact the email address belongs to. Or * <tt>null</tt> if there's no matching contact. */ open fun getNameFor(emailAddress: EmailAddress): String? { if (nameCache.containsKey(emailAddress)) { return nameCache[emailAddress] } val contact = contactDataSource.getContactFor(emailAddress) return if (contact != null) { nameCache[emailAddress] = contact.name contact.name } else { null } } class Contacts { /** * Mark contacts with the provided email addresses as contacted. */ Loading @@ -65,33 +13,4 @@ open class Contacts( // TODO: Keep track of this information in a local database. Then use this information when sorting contacts for // auto-completion. } /** * Get URI to the picture of the contact with the supplied email address. * * @param emailAddress An email address, the contact database is searched for. * * @return URI to the picture of the contact with the supplied email address. `null` if * no such contact could be found or the contact doesn't have a picture. */ fun getPhotoUri(emailAddress: EmailAddress): Uri? { return try { val contact = contactDataSource.getContactFor(emailAddress) contact?.photoUri } catch (e: Exception) { Timber.e(e, "Couldn't fetch photo for contact with email ${emailAddress.address}") null } } companion object { private val nameCache = HashMap<EmailAddress, String?>() /** * Clears the cache for names and photo uris */ fun clearCache() { nameCache.clear() } } } app/core/src/main/java/com/fsck/k9/helper/KoinModule.kt +2 −2 Original line number Diff line number Diff line Loading @@ -7,9 +7,9 @@ import org.koin.dsl.module val helperModule = module { single { ClipboardManager(get()) } single { MessageHelper(resourceProvider = get(), contacts = get()) } single { MessageHelper(resourceProvider = get(), contactRepository = get()) } factory<KeyStoreDirectoryProvider> { AndroidKeyStoreDirectoryProvider(context = get()) } factory { get<Context>().getSystemService(Context.ALARM_SERVICE) as AlarmManager } single { AlarmManagerCompat(alarmManager = get()) } factory<ContactNameProvider> { RealContactNameProvider(contacts = get()) } factory<ContactNameProvider> { RealContactNameProvider(contactRepository = get()) } } app/core/src/main/java/com/fsck/k9/helper/MessageHelper.kt +15 −14 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ import android.text.SpannableString import android.text.SpannableStringBuilder import android.text.TextUtils import android.text.style.ForegroundColorSpan import app.k9mail.core.android.common.contact.ContactRepository import app.k9mail.core.common.mail.EmailAddress import com.fsck.k9.CoreResourceProvider import com.fsck.k9.K9.contactNameColor Loading @@ -16,23 +17,23 @@ import java.util.regex.Pattern class MessageHelper( private val resourceProvider: CoreResourceProvider, private val contacts: Contacts, private val contactRepository: ContactRepository, ) { fun getSenderDisplayName(address: Address?): CharSequence { if (address == null) { return resourceProvider.contactUnknownSender() } val contactHelper = if (isShowContactName) contacts else null return toFriendly(address, contactHelper) val repository = if (isShowContactName) contactRepository else null return toFriendly(address, repository) } fun getRecipientDisplayNames(addresses: Array<Address>?): CharSequence { if (addresses == null || addresses.isEmpty()) { return resourceProvider.contactUnknownRecipient() } val contactHelper = if (isShowContactName) contacts else null val recipients = toFriendly(addresses, contactHelper) val repository = if (isShowContactName) contactRepository else null val recipients = toFriendly(addresses, repository) return SpannableStringBuilder(resourceProvider.contactDisplayNamePrefix()).append(recipients) } Loading @@ -59,28 +60,28 @@ class MessageHelper( * @param contacts A [Contacts] instance or `null`. * @return A "friendly" name for this [Address]. */ fun toFriendly(address: Address, contacts: Contacts?): CharSequence { fun toFriendly(address: Address, contactRepository: ContactRepository?): CharSequence { return toFriendly( address, contacts, contactRepository, isShowCorrespondentNames, isChangeContactNameColor, contactNameColor, ) } fun toFriendly(addresses: Array<Address>?, contacts: Contacts?): CharSequence? { var contacts = contacts fun toFriendly(addresses: Array<Address>?, contactRepository: ContactRepository?): CharSequence? { var repository = contactRepository if (addresses == null) { return null } if (addresses.size >= TOO_MANY_ADDRESSES) { // Don't look up contacts if the number of addresses is very high. contacts = null repository = null } val stringBuilder = SpannableStringBuilder() for (i in addresses.indices) { stringBuilder.append(toFriendly(addresses[i], contacts)) stringBuilder.append(toFriendly(addresses[i], repository)) if (i < addresses.size - 1) { stringBuilder.append(',') } Loading @@ -92,15 +93,15 @@ class MessageHelper( @JvmStatic fun toFriendly( address: Address, contacts: Contacts?, contactRepository: ContactRepository?, showCorrespondentNames: Boolean, changeContactNameColor: Boolean, contactNameColor: Int, ): CharSequence { if (!showCorrespondentNames) { return address.address } else if (contacts != null) { val name = contacts.getNameFor(EmailAddress(address.address)) } else if (contactRepository != null) { val name = contactRepository.getContactFor(EmailAddress(address.address))?.name if (name != null) { return if (changeContactNameColor) { val coloredName = SpannableString(name) Loading Loading
app/core/src/main/java/com/fsck/k9/KoinModule.kt +1 −1 Original line number Diff line number Diff line Loading @@ -28,7 +28,7 @@ val mainModule = module { single { get<Context>().resources } single { get<Context>().contentResolver } single { LocalStoreProvider() } single { Contacts(contactDataSource = get()) } single { Contacts() } single { LocalKeyStore(directoryProvider = get()) } single { TrustManagerFactory.createInstance(get()) } single { LocalKeyStoreManager(get()) } Loading
app/core/src/main/java/com/fsck/k9/helper/ContactNameProvider.kt +5 −2 Original line number Diff line number Diff line package com.fsck.k9.helper import app.k9mail.core.android.common.contact.ContactRepository import app.k9mail.core.common.mail.EmailAddress interface ContactNameProvider { fun getNameForAddress(address: String): String? } class RealContactNameProvider(private val contacts: Contacts) : ContactNameProvider { class RealContactNameProvider( private val contactRepository: ContactRepository, ) : ContactNameProvider { override fun getNameForAddress(address: String): String? { return contacts.getNameFor(EmailAddress(address)) return contactRepository.getContactFor(EmailAddress(address))?.name } }
app/core/src/main/java/com/fsck/k9/helper/Contacts.kt +1 −82 Original line number Diff line number Diff line package com.fsck.k9.helper import android.net.Uri import app.k9mail.core.android.common.contact.ContactDataSource import app.k9mail.core.common.mail.EmailAddress import com.fsck.k9.mail.Address import timber.log.Timber /** * Helper class to access the contacts stored on the device. */ open class Contacts( private val contactDataSource: ContactDataSource, ) { /** * Check whether the provided email address belongs to one of the contacts. * * @param emailAddress The email address to look for. * @return <tt>true</tt>, if the email address belongs to a contact. * <tt>false</tt>, otherwise. */ fun isInContacts(emailAddress: EmailAddress): Boolean = contactDataSource.hasContactFor(emailAddress) /** * Check whether one of the provided email addresses belongs to one of the contacts. * * @param emailAddresses The email addresses to search in contacts * @return <tt>true</tt>, if one of the email addresses belongs to a contact. * <tt>false</tt>, otherwise. */ fun isAnyInContacts(emailAddresses: List<EmailAddress>): Boolean = emailAddresses.any { emailAddress -> isInContacts(emailAddress) } fun getContactUri(emailAddress: EmailAddress): Uri? { val contact = contactDataSource.getContactFor(emailAddress) return contact?.uri } /** * Get the name of the contact an email address belongs to. * * @param emailAddress The email address to search for. * @return The name of the contact the email address belongs to. Or * <tt>null</tt> if there's no matching contact. */ open fun getNameFor(emailAddress: EmailAddress): String? { if (nameCache.containsKey(emailAddress)) { return nameCache[emailAddress] } val contact = contactDataSource.getContactFor(emailAddress) return if (contact != null) { nameCache[emailAddress] = contact.name contact.name } else { null } } class Contacts { /** * Mark contacts with the provided email addresses as contacted. */ Loading @@ -65,33 +13,4 @@ open class Contacts( // TODO: Keep track of this information in a local database. Then use this information when sorting contacts for // auto-completion. } /** * Get URI to the picture of the contact with the supplied email address. * * @param emailAddress An email address, the contact database is searched for. * * @return URI to the picture of the contact with the supplied email address. `null` if * no such contact could be found or the contact doesn't have a picture. */ fun getPhotoUri(emailAddress: EmailAddress): Uri? { return try { val contact = contactDataSource.getContactFor(emailAddress) contact?.photoUri } catch (e: Exception) { Timber.e(e, "Couldn't fetch photo for contact with email ${emailAddress.address}") null } } companion object { private val nameCache = HashMap<EmailAddress, String?>() /** * Clears the cache for names and photo uris */ fun clearCache() { nameCache.clear() } } }
app/core/src/main/java/com/fsck/k9/helper/KoinModule.kt +2 −2 Original line number Diff line number Diff line Loading @@ -7,9 +7,9 @@ import org.koin.dsl.module val helperModule = module { single { ClipboardManager(get()) } single { MessageHelper(resourceProvider = get(), contacts = get()) } single { MessageHelper(resourceProvider = get(), contactRepository = get()) } factory<KeyStoreDirectoryProvider> { AndroidKeyStoreDirectoryProvider(context = get()) } factory { get<Context>().getSystemService(Context.ALARM_SERVICE) as AlarmManager } single { AlarmManagerCompat(alarmManager = get()) } factory<ContactNameProvider> { RealContactNameProvider(contacts = get()) } factory<ContactNameProvider> { RealContactNameProvider(contactRepository = get()) } }
app/core/src/main/java/com/fsck/k9/helper/MessageHelper.kt +15 −14 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ import android.text.SpannableString import android.text.SpannableStringBuilder import android.text.TextUtils import android.text.style.ForegroundColorSpan import app.k9mail.core.android.common.contact.ContactRepository import app.k9mail.core.common.mail.EmailAddress import com.fsck.k9.CoreResourceProvider import com.fsck.k9.K9.contactNameColor Loading @@ -16,23 +17,23 @@ import java.util.regex.Pattern class MessageHelper( private val resourceProvider: CoreResourceProvider, private val contacts: Contacts, private val contactRepository: ContactRepository, ) { fun getSenderDisplayName(address: Address?): CharSequence { if (address == null) { return resourceProvider.contactUnknownSender() } val contactHelper = if (isShowContactName) contacts else null return toFriendly(address, contactHelper) val repository = if (isShowContactName) contactRepository else null return toFriendly(address, repository) } fun getRecipientDisplayNames(addresses: Array<Address>?): CharSequence { if (addresses == null || addresses.isEmpty()) { return resourceProvider.contactUnknownRecipient() } val contactHelper = if (isShowContactName) contacts else null val recipients = toFriendly(addresses, contactHelper) val repository = if (isShowContactName) contactRepository else null val recipients = toFriendly(addresses, repository) return SpannableStringBuilder(resourceProvider.contactDisplayNamePrefix()).append(recipients) } Loading @@ -59,28 +60,28 @@ class MessageHelper( * @param contacts A [Contacts] instance or `null`. * @return A "friendly" name for this [Address]. */ fun toFriendly(address: Address, contacts: Contacts?): CharSequence { fun toFriendly(address: Address, contactRepository: ContactRepository?): CharSequence { return toFriendly( address, contacts, contactRepository, isShowCorrespondentNames, isChangeContactNameColor, contactNameColor, ) } fun toFriendly(addresses: Array<Address>?, contacts: Contacts?): CharSequence? { var contacts = contacts fun toFriendly(addresses: Array<Address>?, contactRepository: ContactRepository?): CharSequence? { var repository = contactRepository if (addresses == null) { return null } if (addresses.size >= TOO_MANY_ADDRESSES) { // Don't look up contacts if the number of addresses is very high. contacts = null repository = null } val stringBuilder = SpannableStringBuilder() for (i in addresses.indices) { stringBuilder.append(toFriendly(addresses[i], contacts)) stringBuilder.append(toFriendly(addresses[i], repository)) if (i < addresses.size - 1) { stringBuilder.append(',') } Loading @@ -92,15 +93,15 @@ class MessageHelper( @JvmStatic fun toFriendly( address: Address, contacts: Contacts?, contactRepository: ContactRepository?, showCorrespondentNames: Boolean, changeContactNameColor: Boolean, contactNameColor: Int, ): CharSequence { if (!showCorrespondentNames) { return address.address } else if (contacts != null) { val name = contacts.getNameFor(EmailAddress(address.address)) } else if (contactRepository != null) { val name = contactRepository.getContactFor(EmailAddress(address.address))?.name if (name != null) { return if (changeContactNameColor) { val coloredName = SpannableString(name) Loading