Loading core/android/common/src/main/kotlin/app/k9mail/core/android/common/contact/ContactRepository.kt +10 −0 Original line number Diff line number Diff line package app.k9mail.core.android.common.contact import android.net.Uri import net.thunderbird.core.common.cache.Cache import net.thunderbird.core.common.mail.EmailAddress import net.thunderbird.core.common.mail.toEmailAddressOrNull interface ContactRepository { Loading @@ -10,6 +12,8 @@ interface ContactRepository { fun hasContactFor(emailAddress: EmailAddress): Boolean fun hasAnyContactFor(emailAddresses: List<EmailAddress>): Boolean fun getPhotoUri(emailAddress: String): Uri? } interface CachingRepository { Loading Loading @@ -42,6 +46,12 @@ internal class CachingContactRepository( override fun hasAnyContactFor(emailAddresses: List<EmailAddress>): Boolean = emailAddresses.any { emailAddress -> hasContactFor(emailAddress) } override fun getPhotoUri(emailAddress: String): Uri? { return emailAddress.toEmailAddressOrNull()?.let { emailAddress -> getContactFor(emailAddress)?.photoUri } } override fun clearCache() { cache.clear() } Loading legacy/ui/legacy/build.gradle.kts +2 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,8 @@ dependencies { implementation(projects.feature.notification.api) // TODO: Remove AccountOauth dependency implementation(projects.feature.account.oauth) implementation(projects.feature.account.avatar.api) implementation(projects.feature.account.avatar.impl) implementation(projects.feature.funding.api) implementation(projects.feature.search.implLegacy) implementation(projects.feature.settings.import) Loading legacy/ui/legacy/src/debug/kotlin/com/fsck/k9/ui/messagelist/item/MessageItemContentPreview.kt +26 −0 Original line number Diff line number Diff line Loading @@ -2,6 +2,8 @@ package com.fsck.k9.ui.messagelist.item import androidx.compose.runtime.Composable import androidx.compose.ui.tooling.preview.PreviewLightDark import app.k9mail.core.android.common.contact.Contact import app.k9mail.core.android.common.contact.ContactRepository import app.k9mail.core.ui.compose.designsystem.PreviewWithThemesLightDark import com.fsck.k9.FontSizes import com.fsck.k9.UiDensity Loading @@ -12,7 +14,9 @@ import com.fsck.k9.ui.messagelist.MessageListAppearance import com.fsck.k9.ui.messagelist.MessageListItem import net.thunderbird.core.android.account.Identity import net.thunderbird.core.android.account.LegacyAccount import net.thunderbird.core.common.mail.EmailAddress import net.thunderbird.feature.account.AccountIdFactory import net.thunderbird.feature.account.avatar.AvatarMonogramCreator import net.thunderbird.feature.account.storage.profile.AvatarDto import net.thunderbird.feature.account.storage.profile.AvatarTypeDto import net.thunderbird.feature.account.storage.profile.ProfileDto Loading @@ -25,6 +29,8 @@ internal fun MessageItemContentPreview() { item = fakeMessageListItem, isActive = true, isSelected = false, contactRepository = fakeContactRepository, avatarMonogramCreator = fakeAvatarMonogramCreator, onClick = {}, onLongClick = {}, onAvatarClick = {}, Loading Loading @@ -97,3 +103,23 @@ private val fakeMessageListAppearance = MessageListAppearance( showAccountIndicator = true, density = UiDensity.Default, ) private val fakeContactRepository = object : ContactRepository { override fun getContactFor(emailAddress: EmailAddress): Contact? { error("Not implemented") } override fun hasContactFor(emailAddress: EmailAddress): Boolean { error("Not implemented") } override fun hasAnyContactFor(emailAddresses: List<EmailAddress>): Boolean { error("Not implemented") } override fun getPhotoUri(emailAddress: String) = null } private val fakeAvatarMonogramCreator = object : AvatarMonogramCreator { override fun create(name: String?, email: String?) = "SE" } legacy/ui/legacy/src/main/java/com/fsck/k9/contacts/ContactPhotoLoader.kt +1 −9 Original line number Diff line number Diff line Loading @@ -3,9 +3,7 @@ package com.fsck.k9.contacts import android.content.ContentResolver import android.graphics.Bitmap import android.graphics.BitmapFactory import android.net.Uri import app.k9mail.core.android.common.contact.ContactRepository import net.thunderbird.core.common.mail.toEmailAddressOrNull import net.thunderbird.core.logging.legacy.Log internal class ContactPhotoLoader( Loading @@ -13,7 +11,7 @@ internal class ContactPhotoLoader( private val contactRepository: ContactRepository, ) { fun loadContactPhoto(emailAddress: String): Bitmap? { val photoUri = getPhotoUri(emailAddress) ?: return null val photoUri = contactRepository.getPhotoUri(emailAddress = emailAddress) ?: return null return try { contentResolver.openInputStream(photoUri).use { inputStream -> BitmapFactory.decodeStream(inputStream) Loading @@ -23,10 +21,4 @@ internal class ContactPhotoLoader( null } } private fun getPhotoUri(email: String): Uri? { return email.toEmailAddressOrNull()?.let { emailAddress -> contactRepository.getContactFor(emailAddress)?.photoUri } } } legacy/ui/legacy/src/main/java/com/fsck/k9/ui/messagelist/MessageListAdapter.kt +6 −0 Original line number Diff line number Diff line Loading @@ -11,6 +11,7 @@ import android.view.ViewGroup import androidx.compose.ui.platform.ComposeView import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.RecyclerView import app.k9mail.core.android.common.contact.ContactRepository import app.k9mail.feature.launcher.FeatureLauncherActivity import app.k9mail.feature.launcher.FeatureLauncherTarget import app.k9mail.legacy.message.controller.MessageReference Loading @@ -27,6 +28,7 @@ import net.thunderbird.core.featureflag.FeatureFlagKey import net.thunderbird.core.featureflag.FeatureFlagProvider import net.thunderbird.core.featureflag.FeatureFlagResult import net.thunderbird.core.ui.theme.api.FeatureThemeProvider import net.thunderbird.feature.account.avatar.AvatarMonogramCreator import net.thunderbird.feature.notification.api.ui.action.NotificationAction private const val FOOTER_ID = 1L Loading @@ -47,6 +49,8 @@ class MessageListAdapter internal constructor( private val relativeDateTimeFormatter: RelativeDateTimeFormatter, private val themeProvider: FeatureThemeProvider, private val featureFlagProvider: FeatureFlagProvider, private val contactRepository: ContactRepository, private val avatarMonogramCreator: AvatarMonogramCreator, ) : RecyclerView.Adapter<MessageListViewHolder>() { val colors: MessageViewHolderColors = MessageViewHolderColors.resolveColors(theme) Loading Loading @@ -266,6 +270,8 @@ class MessageListAdapter internal constructor( ComposableMessageViewHolder.create( context = parent.context, themeProvider = themeProvider, contactRepository = contactRepository, avatarMonogramCreator = avatarMonogramCreator, onClick = { listItemListener.onMessageClicked(it) }, onLongClick = { listItemListener.onToggleMessageSelection(it) }, onFavouriteClick = { listItemListener.onToggleMessageFlag(it) }, Loading Loading
core/android/common/src/main/kotlin/app/k9mail/core/android/common/contact/ContactRepository.kt +10 −0 Original line number Diff line number Diff line package app.k9mail.core.android.common.contact import android.net.Uri import net.thunderbird.core.common.cache.Cache import net.thunderbird.core.common.mail.EmailAddress import net.thunderbird.core.common.mail.toEmailAddressOrNull interface ContactRepository { Loading @@ -10,6 +12,8 @@ interface ContactRepository { fun hasContactFor(emailAddress: EmailAddress): Boolean fun hasAnyContactFor(emailAddresses: List<EmailAddress>): Boolean fun getPhotoUri(emailAddress: String): Uri? } interface CachingRepository { Loading Loading @@ -42,6 +46,12 @@ internal class CachingContactRepository( override fun hasAnyContactFor(emailAddresses: List<EmailAddress>): Boolean = emailAddresses.any { emailAddress -> hasContactFor(emailAddress) } override fun getPhotoUri(emailAddress: String): Uri? { return emailAddress.toEmailAddressOrNull()?.let { emailAddress -> getContactFor(emailAddress)?.photoUri } } override fun clearCache() { cache.clear() } Loading
legacy/ui/legacy/build.gradle.kts +2 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,8 @@ dependencies { implementation(projects.feature.notification.api) // TODO: Remove AccountOauth dependency implementation(projects.feature.account.oauth) implementation(projects.feature.account.avatar.api) implementation(projects.feature.account.avatar.impl) implementation(projects.feature.funding.api) implementation(projects.feature.search.implLegacy) implementation(projects.feature.settings.import) Loading
legacy/ui/legacy/src/debug/kotlin/com/fsck/k9/ui/messagelist/item/MessageItemContentPreview.kt +26 −0 Original line number Diff line number Diff line Loading @@ -2,6 +2,8 @@ package com.fsck.k9.ui.messagelist.item import androidx.compose.runtime.Composable import androidx.compose.ui.tooling.preview.PreviewLightDark import app.k9mail.core.android.common.contact.Contact import app.k9mail.core.android.common.contact.ContactRepository import app.k9mail.core.ui.compose.designsystem.PreviewWithThemesLightDark import com.fsck.k9.FontSizes import com.fsck.k9.UiDensity Loading @@ -12,7 +14,9 @@ import com.fsck.k9.ui.messagelist.MessageListAppearance import com.fsck.k9.ui.messagelist.MessageListItem import net.thunderbird.core.android.account.Identity import net.thunderbird.core.android.account.LegacyAccount import net.thunderbird.core.common.mail.EmailAddress import net.thunderbird.feature.account.AccountIdFactory import net.thunderbird.feature.account.avatar.AvatarMonogramCreator import net.thunderbird.feature.account.storage.profile.AvatarDto import net.thunderbird.feature.account.storage.profile.AvatarTypeDto import net.thunderbird.feature.account.storage.profile.ProfileDto Loading @@ -25,6 +29,8 @@ internal fun MessageItemContentPreview() { item = fakeMessageListItem, isActive = true, isSelected = false, contactRepository = fakeContactRepository, avatarMonogramCreator = fakeAvatarMonogramCreator, onClick = {}, onLongClick = {}, onAvatarClick = {}, Loading Loading @@ -97,3 +103,23 @@ private val fakeMessageListAppearance = MessageListAppearance( showAccountIndicator = true, density = UiDensity.Default, ) private val fakeContactRepository = object : ContactRepository { override fun getContactFor(emailAddress: EmailAddress): Contact? { error("Not implemented") } override fun hasContactFor(emailAddress: EmailAddress): Boolean { error("Not implemented") } override fun hasAnyContactFor(emailAddresses: List<EmailAddress>): Boolean { error("Not implemented") } override fun getPhotoUri(emailAddress: String) = null } private val fakeAvatarMonogramCreator = object : AvatarMonogramCreator { override fun create(name: String?, email: String?) = "SE" }
legacy/ui/legacy/src/main/java/com/fsck/k9/contacts/ContactPhotoLoader.kt +1 −9 Original line number Diff line number Diff line Loading @@ -3,9 +3,7 @@ package com.fsck.k9.contacts import android.content.ContentResolver import android.graphics.Bitmap import android.graphics.BitmapFactory import android.net.Uri import app.k9mail.core.android.common.contact.ContactRepository import net.thunderbird.core.common.mail.toEmailAddressOrNull import net.thunderbird.core.logging.legacy.Log internal class ContactPhotoLoader( Loading @@ -13,7 +11,7 @@ internal class ContactPhotoLoader( private val contactRepository: ContactRepository, ) { fun loadContactPhoto(emailAddress: String): Bitmap? { val photoUri = getPhotoUri(emailAddress) ?: return null val photoUri = contactRepository.getPhotoUri(emailAddress = emailAddress) ?: return null return try { contentResolver.openInputStream(photoUri).use { inputStream -> BitmapFactory.decodeStream(inputStream) Loading @@ -23,10 +21,4 @@ internal class ContactPhotoLoader( null } } private fun getPhotoUri(email: String): Uri? { return email.toEmailAddressOrNull()?.let { emailAddress -> contactRepository.getContactFor(emailAddress)?.photoUri } } }
legacy/ui/legacy/src/main/java/com/fsck/k9/ui/messagelist/MessageListAdapter.kt +6 −0 Original line number Diff line number Diff line Loading @@ -11,6 +11,7 @@ import android.view.ViewGroup import androidx.compose.ui.platform.ComposeView import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.RecyclerView import app.k9mail.core.android.common.contact.ContactRepository import app.k9mail.feature.launcher.FeatureLauncherActivity import app.k9mail.feature.launcher.FeatureLauncherTarget import app.k9mail.legacy.message.controller.MessageReference Loading @@ -27,6 +28,7 @@ import net.thunderbird.core.featureflag.FeatureFlagKey import net.thunderbird.core.featureflag.FeatureFlagProvider import net.thunderbird.core.featureflag.FeatureFlagResult import net.thunderbird.core.ui.theme.api.FeatureThemeProvider import net.thunderbird.feature.account.avatar.AvatarMonogramCreator import net.thunderbird.feature.notification.api.ui.action.NotificationAction private const val FOOTER_ID = 1L Loading @@ -47,6 +49,8 @@ class MessageListAdapter internal constructor( private val relativeDateTimeFormatter: RelativeDateTimeFormatter, private val themeProvider: FeatureThemeProvider, private val featureFlagProvider: FeatureFlagProvider, private val contactRepository: ContactRepository, private val avatarMonogramCreator: AvatarMonogramCreator, ) : RecyclerView.Adapter<MessageListViewHolder>() { val colors: MessageViewHolderColors = MessageViewHolderColors.resolveColors(theme) Loading Loading @@ -266,6 +270,8 @@ class MessageListAdapter internal constructor( ComposableMessageViewHolder.create( context = parent.context, themeProvider = themeProvider, contactRepository = contactRepository, avatarMonogramCreator = avatarMonogramCreator, onClick = { listItemListener.onMessageClicked(it) }, onLongClick = { listItemListener.onToggleMessageSelection(it) }, onFavouriteClick = { listItemListener.onToggleMessageFlag(it) }, Loading