diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/activity/MessageListActivityConfig.kt b/app/ui/legacy/src/main/java/com/fsck/k9/activity/MessageListActivityConfig.kt index ba099bca5..7ef6d9e3c 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/activity/MessageListActivityConfig.kt +++ b/app/ui/legacy/src/main/java/com/fsck/k9/activity/MessageListActivityConfig.kt @@ -2,6 +2,7 @@ package com.fsck.k9.activity import com.fsck.k9.K9 import com.fsck.k9.SwipeAction +import com.fsck.k9.UiDensity import com.fsck.k9.preferences.AppTheme import com.fsck.k9.preferences.GeneralSettingsManager import com.fsck.k9.preferences.SubTheme @@ -21,6 +22,7 @@ data class MessageListActivityConfig( val contactNameColor: Int, val messageViewTheme: SubTheme, val messageListPreviewLines: Int, + val messageListDensity: UiDensity, val splitViewMode: K9.SplitViewMode, val fontSizeMessageListSubject: Int, val fontSizeMessageListSender: Int, @@ -53,6 +55,7 @@ data class MessageListActivityConfig( contactNameColor = K9.contactNameColor, messageViewTheme = settings.messageViewTheme, messageListPreviewLines = K9.messageListPreviewLines, + messageListDensity = K9.messageListDensity, splitViewMode = K9.splitViewMode, fontSizeMessageListSubject = K9.fontSizes.messageListSubject, fontSizeMessageListSender = K9.fontSizes.messageListSender, diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/ui/messagelist/MessageListAdapter.kt b/app/ui/legacy/src/main/java/com/fsck/k9/ui/messagelist/MessageListAdapter.kt index d209b1f5a..a693d7859 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/ui/messagelist/MessageListAdapter.kt +++ b/app/ui/legacy/src/main/java/com/fsck/k9/ui/messagelist/MessageListAdapter.kt @@ -17,12 +17,16 @@ import android.view.View.OnLongClickListener import android.view.ViewGroup import android.widget.ImageView import android.widget.TextView +import androidx.annotation.DimenRes +import androidx.constraintlayout.widget.Guideline +import androidx.core.content.res.ResourcesCompat import androidx.core.graphics.drawable.DrawableCompat import androidx.core.view.isVisible import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView.NO_POSITION import com.fsck.k9.FontSizes +import com.fsck.k9.UiDensity import com.fsck.k9.contacts.ContactPictureLoader import com.fsck.k9.controller.MessageReference import com.fsck.k9.mail.Address @@ -69,6 +73,16 @@ class MessageListAdapter internal constructor( private val unreadItemBackgroundColor: Int = theme.resolveColorAttribute(R.attr.messageListUnreadItemBackgroundColor) + private val compactVerticalPadding = res.getDimensionPixelSize(R.dimen.messageListCompactVerticalPadding) + private val compactTextViewMarginTop = res.getDimensionPixelSize(R.dimen.messageListCompactTextViewMargin) + private val compactLineSpacingMultiplier = res.getFloatCompat(R.dimen.messageListCompactLineSpacingMultiplier) + private val defaultVerticalPadding = res.getDimensionPixelSize(R.dimen.messageListDefaultVerticalPadding) + private val defaultTextViewMarginTop = res.getDimensionPixelSize(R.dimen.messageListDefaultTextViewMargin) + private val defaultLineSpacingMultiplier = res.getFloatCompat(R.dimen.messageListDefaultLineSpacingMultiplier) + private val relaxedVerticalPadding = res.getDimensionPixelSize(R.dimen.messageListRelaxedVerticalPadding) + private val relaxedTextViewMarginTop = res.getDimensionPixelSize(R.dimen.messageListRelaxedTextViewMargin) + private val relaxedLineSpacingMultiplier = res.getFloatCompat(R.dimen.messageListRelaxedLineSpacingMultiplier) + var messages: List = emptyList() @SuppressLint("NotifyDataSetChanged") set(value) { @@ -260,9 +274,14 @@ class MessageListAdapter internal constructor( val holder = MessageViewHolder(view) - val contactPictureContainer = view.findViewById(R.id.contact_picture_container) - contactPictureContainer.isVisible = appearance.showContactPicture - contactPictureContainer.setOnClickListener(contactPictureContainerClickListener) + val contactPictureClickArea = view.findViewById(R.id.contact_picture_click_area) + if (appearance.showContactPicture) { + contactPictureClickArea.setOnClickListener(contactPictureContainerClickListener) + } else { + contactPictureClickArea.isVisible = false + holder.selected.isVisible = false + holder.contactPicture.isVisible = false + } holder.chip.isVisible = appearance.showAccountChip @@ -281,11 +300,43 @@ class MessageListAdapter internal constructor( holder.starClickArea.isVisible = appearance.stars holder.starClickArea.setOnClickListener(starClickListener) + applyDensityValue(holder, appearance.density) + view.tag = holder return holder } + private fun applyDensityValue(holder: MessageViewHolder, density: UiDensity) { + val verticalPadding: Int + val textViewMarginTop: Int + val lineSpacingMultiplier: Float + when (density) { + UiDensity.Compact -> { + verticalPadding = compactVerticalPadding + textViewMarginTop = compactTextViewMarginTop + lineSpacingMultiplier = compactLineSpacingMultiplier + } + UiDensity.Default -> { + verticalPadding = defaultVerticalPadding + textViewMarginTop = defaultTextViewMarginTop + lineSpacingMultiplier = defaultLineSpacingMultiplier + } + UiDensity.Relaxed -> { + verticalPadding = relaxedVerticalPadding + textViewMarginTop = relaxedTextViewMarginTop + lineSpacingMultiplier = relaxedLineSpacingMultiplier + } + } + + holder.itemView.findViewById(R.id.top_guideline).setGuidelineBegin(verticalPadding) + holder.itemView.findViewById(R.id.bottom_guideline).setGuidelineEnd(verticalPadding) + holder.preview.apply { + setMarginTop(textViewMarginTop) + setLineSpacing(lineSpacingExtra, lineSpacingMultiplier) + } + } + private fun createFooterViewHolder(parent: ViewGroup): MessageListViewHolder { val view = layoutInflater.inflate(R.layout.message_list_item_footer, parent, false) view.setOnClickListener(footerClickListener) @@ -537,6 +588,12 @@ class MessageListAdapter internal constructor( } } +private fun Resources.getFloatCompat(@DimenRes resId: Int) = ResourcesCompat.getFloat(this, resId) + +private fun View.setMarginTop(margin: Int) { + (layoutParams as? ViewGroup.MarginLayoutParams)?.topMargin = margin +} + private class MessageListDiffCallback( private val oldMessageList: List, private val newMessageList: List, diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/ui/messagelist/MessageListAppearance.kt b/app/ui/legacy/src/main/java/com/fsck/k9/ui/messagelist/MessageListAppearance.kt index f3638cf4b..9958682d0 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/ui/messagelist/MessageListAppearance.kt +++ b/app/ui/legacy/src/main/java/com/fsck/k9/ui/messagelist/MessageListAppearance.kt @@ -1,6 +1,7 @@ package com.fsck.k9.ui.messagelist import com.fsck.k9.FontSizes +import com.fsck.k9.UiDensity data class MessageListAppearance( val fontSizes: FontSizes, @@ -11,4 +12,5 @@ data class MessageListAppearance( val showingThreadedList: Boolean, val backGroundAsReadIndicator: Boolean, val showAccountChip: Boolean, + val density: UiDensity, ) diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/ui/messagelist/MessageListFragment.kt b/app/ui/legacy/src/main/java/com/fsck/k9/ui/messagelist/MessageListFragment.kt index b78aa47f8..99182918d 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/ui/messagelist/MessageListFragment.kt +++ b/app/ui/legacy/src/main/java/com/fsck/k9/ui/messagelist/MessageListFragment.kt @@ -573,6 +573,7 @@ class MessageListFragment : showingThreadedList = showingThreadedList, backGroundAsReadIndicator = K9.isUseBackgroundAsUnreadIndicator, showAccountChip = isShowAccountChip, + density = K9.messageListDensity, ) private fun getFolderInfoHolder(folderId: Long, account: Account): FolderInfoHolder { diff --git a/app/ui/legacy/src/main/res/layout/message_list_item.xml b/app/ui/legacy/src/main/res/layout/message_list_item.xml index 373c8b3da..5f0feb9f9 100644 --- a/app/ui/legacy/src/main/res/layout/message_list_item.xml +++ b/app/ui/legacy/src/main/res/layout/message_list_item.xml @@ -8,54 +8,55 @@ - + app:layout_constraintTop_toTopOf="@+id/top_guideline" + app:layout_constraintVertical_bias="0.0" + app:srcCompat="@drawable/ic_check_circle_large" /> - - - - - + + app:srcCompat="?attr/messageListAnswered" /> + + + app:layout_constraintGuide_begin="@dimen/messageListDefaultVerticalPadding" /> + app:layout_constraintGuide_end="@dimen/messageListDefaultVerticalPadding" /> + app:constraint_referenced_ids="margin_start,contact_picture_click_area" /> + app:layout_constraintStart_toEndOf="@+id/contact_picture_click_area" /> + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + + diff --git a/app/ui/legacy/src/main/res/values/dimensions.xml b/app/ui/legacy/src/main/res/values/dimensions.xml index 8f5f3d1dd..e97ed506f 100644 --- a/app/ui/legacy/src/main/res/values/dimensions.xml +++ b/app/ui/legacy/src/main/res/values/dimensions.xml @@ -13,6 +13,27 @@ 24dp 12dp + 72dp + 40dp + 16dp + + + 4dp + 0dp + 1.0 + + + 12dp + 2dp + 1.1 + + + 4dp + 16dp + 1.2 + + 4dp + 16dp 80dp diff --git a/app/ui/legacy/src/test/java/com/fsck/k9/ui/messagelist/MessageListAdapterTest.kt b/app/ui/legacy/src/test/java/com/fsck/k9/ui/messagelist/MessageListAdapterTest.kt index d3ed1221a..f2af4b87c 100644 --- a/app/ui/legacy/src/test/java/com/fsck/k9/ui/messagelist/MessageListAdapterTest.kt +++ b/app/ui/legacy/src/test/java/com/fsck/k9/ui/messagelist/MessageListAdapterTest.kt @@ -17,6 +17,7 @@ import com.fsck.k9.FontSizes.FONT_DEFAULT import com.fsck.k9.FontSizes.LARGE import com.fsck.k9.RobolectricTest import com.fsck.k9.TestClock +import com.fsck.k9.UiDensity import com.fsck.k9.contacts.ContactPictureLoader import com.fsck.k9.mail.Address import com.fsck.k9.textString @@ -398,6 +399,7 @@ class MessageListAdapterTest : RobolectricTest() { showingThreadedList: Boolean = true, backGroundAsReadIndicator: Boolean = false, showAccountChip: Boolean = false, + density: UiDensity = UiDensity.Default, ): MessageListAdapter { val appearance = MessageListAppearance( fontSizes, @@ -408,6 +410,7 @@ class MessageListAdapterTest : RobolectricTest() { showingThreadedList, backGroundAsReadIndicator, showAccountChip, + density, ) return MessageListAdapter( @@ -476,7 +479,7 @@ class MessageListAdapterTest : RobolectricTest() { val View.accountChipView: View get() = findViewById(R.id.account_color_chip) val View.starView: View get() = findViewById(R.id.star) - val View.contactPictureContainerView: View get() = findViewById(R.id.contact_picture_container) + val View.contactPictureContainerView: View get() = findViewById(R.id.contact_picture_click_area) val View.threadCountView: TextView get() = findViewById(R.id.thread_count) val View.firstLineView: TextView get() = findViewById(R.id.subject) val View.secondLineView: TextView get() = findViewById(R.id.preview)