Implement V4 labels for Mailbox

MessagesListItemView.kt and MessagesRecyclerViewAdapter.kt

MAILAND-1502
This commit is contained in:
Davide Farella 2021-05-13 15:07:26 +02:00 committed by Davide Giuseppe Farella
parent 60875fcd24
commit 10b355e425
6 changed files with 87 additions and 109 deletions

View File

@ -120,7 +120,7 @@ class SingleLineLabelChipGroupViewTest : ViewTest<SingleLineLabelChipGroupView>(
chipGroupView.setLabels(labels)
// then
onMoreView().check(matches(withText("${labels.size - 1}+")))
onMoreView().check(matches(withText("+${labels.size - 1}")))
}
private fun onLabelView(): ViewInteraction =

View File

@ -19,18 +19,24 @@
package ch.protonmail.android.adapters.messages
import android.content.Context
import android.graphics.Color
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import ch.protonmail.android.core.Constants
import ch.protonmail.android.data.local.model.Label
import ch.protonmail.android.data.local.model.PendingSend
import ch.protonmail.android.data.local.model.PendingUpload
import ch.protonmail.android.domain.entity.Id
import ch.protonmail.android.domain.entity.Name
import ch.protonmail.android.mailbox.presentation.model.MailboxUiItem
import ch.protonmail.android.ui.view.LabelChipUiModel
import ch.protonmail.android.utils.UiUtil
import ch.protonmail.android.utils.ui.selection.SelectionModeEnum
import ch.protonmail.android.views.messagesList.MailboxItemFooterView
import ch.protonmail.android.views.messagesList.MailboxItemView
import kotlinx.android.synthetic.main.layout_sender_initial.view.*
import kotlinx.android.synthetic.main.list_item_mailbox.view.*
import me.proton.core.util.kotlin.takeIfNotBlank
class MailboxRecyclerViewAdapter(
private val context: Context,
@ -63,7 +69,8 @@ class MailboxRecyclerViewAdapter(
}
val checkedMailboxItems get() = selectedMailboxItemsIds.mapNotNull { mailboxItems.find { message -> message.itemId == it } }
val checkedMailboxItems get() =
selectedMailboxItemsIds.mapNotNull { mailboxItems.find { message -> message.itemId == it } }
fun getItem(position: Int) = mailboxItems[position]
@ -160,7 +167,7 @@ class MailboxRecyclerViewAdapter(
this.view.bind(
mailboxItem,
itemLabels,
itemLabels.toLabelChipUiModels(),
selectedMailboxItemsIds.isNotEmpty(),
mMailboxLocation,
isBeingSent,
@ -226,4 +233,13 @@ class MailboxRecyclerViewAdapter(
}
return lastItemTimeMs / 1000
}
private fun List<Label>.toLabelChipUiModels(): List<LabelChipUiModel> =
filterNot { it.exclusive }.map { label ->
val labelColor = label.color.takeIfNotBlank()
?.let { Color.parseColor(UiUtil.normalizeColor(it)) }
?: 0
LabelChipUiModel(Id(label.id), Name(label.name), labelColor)
}
}

View File

@ -51,7 +51,7 @@ class LabelChipView @JvmOverloads constructor(
setPadding(horizontalPadding, verticalPadding, horizontalPadding, verticalPadding)
// Text
setTextAppearance(R.style.Proton_Text_Caption_Strong)
setTextAppearance(R.style.Proton_Text_Overline_Strong)
setTextColor(context.getColor(R.color.text_inverted))
ellipsize = TextUtils.TruncateAt.END
maxLines = 1

View File

@ -66,5 +66,5 @@ class SingleLineLabelChipGroupView @JvmOverloads constructor (
}
private fun getMoreLabelsText(labelsCount: Int): String =
"${labelsCount - 1}+"
"+${labelsCount - 1}"
}

View File

@ -19,27 +19,23 @@
package ch.protonmail.android.views.messagesList
import android.content.Context
import android.graphics.Color
import android.util.AttributeSet
import android.util.TypedValue
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.LinearLayout
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat
import androidx.core.view.isVisible
import androidx.recyclerview.widget.RecyclerView
import ch.protonmail.android.R
import ch.protonmail.android.core.Constants
import ch.protonmail.android.data.local.model.Label
import ch.protonmail.android.databinding.ListItemMailboxBinding
import ch.protonmail.android.mailbox.presentation.model.MailboxUiItem
import ch.protonmail.android.ui.view.LabelChipUiModel
import ch.protonmail.android.ui.view.SingleLineLabelChipGroupView
import ch.protonmail.android.utils.DateUtil
import ch.protonmail.android.utils.UiUtil
import kotlinx.android.synthetic.main.list_item_mailbox.view.*
import me.proton.core.presentation.utils.inflate
private const val MAX_LABELS_WITH_TEXT = 1
class MailboxItemView @JvmOverloads constructor(
context: Context,
@ -47,30 +43,31 @@ class MailboxItemView @JvmOverloads constructor(
defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr) {
private val replyImageView: ImageView
private val replyAllImageView: ImageView
private val labelsLayout: SingleLineLabelChipGroupView
init {
inflate(R.layout.list_item_mailbox, true)
val binding = ListItemMailboxBinding.inflate(
LayoutInflater.from(context),
this,
true
)
replyImageView = binding.replyImageView
replyAllImageView = binding.replyAllImageView
labelsLayout = binding.mailboxLabelChipGroup
layoutParams = RecyclerView.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
}
private var allFolders = HashMap<String, Label>()
private val strokeWidth by lazy {
TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
1f,
context
.resources.displayMetrics
).toInt()
}
private fun setIconsTint(isRead: Boolean) {
val iconTint = if (isRead) context.getColor(R.color.icon_weak) else context.getColor(R.color.icon_norm)
reply_image_view.setColorFilter(iconTint)
reply_all_image_view.setColorFilter(iconTint)
replyImageView.setColorFilter(iconTint)
replyAllImageView.setColorFilter(iconTint)
forward_image_view.setColorFilter(iconTint)
first_location_image_view.setColorFilter(iconTint)
@ -119,7 +116,7 @@ class MailboxItemView @JvmOverloads constructor(
fun bind(
mailboxUiItem: MailboxUiItem,
labels: List<Label>,
labels: List<LabelChipUiModel>,
isMultiSelectionMode: Boolean,
mailboxLocation: Constants.MessageLocationType,
isBeingSent: Boolean,
@ -150,9 +147,9 @@ class MailboxItemView @JvmOverloads constructor(
time_date_text_view.text = context.getString(R.string.draft_label_message_uploading)
}
reply_image_view.isVisible = mailboxUiItem.messageData?.isReplied == true &&
replyImageView.isVisible = mailboxUiItem.messageData?.isReplied == true &&
!mailboxUiItem.messageData.isRepliedAll
reply_all_image_view.isVisible = mailboxUiItem.messageData?.isRepliedAll == true
replyAllImageView.isVisible = mailboxUiItem.messageData?.isRepliedAll == true
forward_image_view.isVisible = mailboxUiItem.messageData?.isForwarded == true
draft_image_view.isVisible = mailboxLocation in arrayOf(
@ -186,45 +183,7 @@ class MailboxItemView @JvmOverloads constructor(
expiration_image_view.isVisible = mailboxUiItem.expirationTime > 0
showLabels(labels)
labelsLayout.setLabels(labels)
}
private fun showLabels(labels: List<Label>) {
// TODO: This is the old labels logic and it should be changed with MAILAND-1502
labelsLayout.removeAllViews()
labelsLayout.visibility = View.GONE
labels.forEach { allFolders[it.id] = it }
val nonExclusiveLabels = labels.filter { !it.exclusive }
var commonHeight = 20
nonExclusiveLabels.forEachIndexed { i, (_, name, colorString) ->
val labelItemView = ItemLabelMarginlessSmallView(context)
val color = if (colorString.isNotEmpty()) {
val normalizedColor = UiUtil.normalizeColor(colorString)
Color.parseColor(normalizedColor)
} else 0
if (i < MAX_LABELS_WITH_TEXT) {
labelItemView.bind(name, color, strokeWidth)
labelsLayout.visibility = View.VISIBLE
labelsLayout.addView(labelItemView)
labelItemView.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED)
commonHeight = labelItemView.measuredHeight
} else {
val imageView = ImageView(context)
val lp = LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT
)
lp.setMargins(0, 0, 0, 0)
imageView.layoutParams = lp
imageView.setImageResource(R.drawable.mail_label_collapsed)
imageView.setColorFilter(color)
imageView.layoutParams.height = commonHeight
labelsLayout.visibility = View.VISIBLE
labelsLayout.addView(imageView)
}
labelItemView.requestLayout()
}
}
}

View File

@ -33,8 +33,8 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/sender_initial_view_margin_end"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@id/sender_initial_barrier"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/sender_initial_barrier"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.Barrier
@ -42,7 +42,8 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintLeft_toRightOf="@id/sender_initial_view"
app:barrierDirection="end"
app:layout_constraintStart_toEndOf="@id/sender_initial_view"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
@ -51,8 +52,8 @@
android:layout_width="@dimen/mailbox_list_item_icon_size"
android:layout_height="@dimen/mailbox_list_item_icon_size"
android:layout_marginEnd="@dimen/mailbox_list_item_views_margin"
app:layout_constraintLeft_toRightOf="@id/sender_initial_barrier"
app:layout_constraintRight_toLeftOf="@id/reply_all_image_view"
app:layout_constraintStart_toEndOf="@id/sender_initial_barrier"
app:layout_constraintEnd_toStartOf="@id/reply_all_image_view"
app:layout_constraintTop_toTopOf="@id/reply_all_image_view"
app:layout_constraintBottom_toBottomOf="@id/reply_all_image_view"
android:src="@drawable/ic_reply"
@ -64,8 +65,8 @@
android:layout_width="@dimen/mailbox_list_item_icon_size"
android:layout_height="@dimen/mailbox_list_item_icon_size"
android:layout_marginEnd="@dimen/mailbox_list_item_views_margin"
app:layout_constraintLeft_toRightOf="@id/reply_image_view"
app:layout_constraintRight_toLeftOf="@id/forward_image_view"
app:layout_constraintStart_toEndOf="@id/reply_image_view"
app:layout_constraintEnd_toStartOf="@id/forward_image_view"
app:layout_constraintTop_toTopOf="@id/forward_image_view"
app:layout_constraintBottom_toBottomOf="@id/forward_image_view"
android:src="@drawable/ic_reply_all"
@ -77,8 +78,8 @@
android:layout_width="@dimen/mailbox_list_item_icon_size"
android:layout_height="@dimen/mailbox_list_item_icon_size"
android:layout_marginEnd="@dimen/mailbox_list_item_views_margin"
app:layout_constraintLeft_toRightOf="@id/reply_all_image_view"
app:layout_constraintRight_toLeftOf="@id/draft_image_view"
app:layout_constraintStart_toEndOf="@id/reply_all_image_view"
app:layout_constraintEnd_toStartOf="@id/draft_image_view"
app:layout_constraintTop_toTopOf="@id/draft_image_view"
app:layout_constraintBottom_toBottomOf="@id/draft_image_view"
android:src="@drawable/ic_forward"
@ -90,8 +91,8 @@
android:layout_width="@dimen/mailbox_list_item_icon_size"
android:layout_height="@dimen/mailbox_list_item_icon_size"
android:layout_marginEnd="@dimen/mailbox_list_item_views_margin"
app:layout_constraintLeft_toRightOf="@id/forward_image_view"
app:layout_constraintRight_toLeftOf="@id/sender_text_view"
app:layout_constraintStart_toEndOf="@id/forward_image_view"
app:layout_constraintEnd_toStartOf="@id/sender_text_view"
app:layout_constraintTop_toTopOf="@id/sender_text_view"
app:layout_constraintBottom_toBottomOf="@id/sender_text_view"
android:src="@drawable/ic_pencil" />
@ -101,8 +102,8 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/mailbox_list_item_views_margin"
app:layout_constraintLeft_toRightOf="@id/draft_image_view"
app:layout_constraintRight_toLeftOf="@id/time_date_text_view"
app:layout_constraintStart_toEndOf="@id/draft_image_view"
app:layout_constraintEnd_toStartOf="@id/time_date_text_view"
app:layout_constraintTop_toTopOf="parent"
android:maxLines="1"
android:ellipsize="end"
@ -113,8 +114,8 @@
android:id="@+id/time_date_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintLeft_toRightOf="@id/sender_text_view"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintStart_toEndOf="@id/sender_text_view"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/sender_text_view"
app:layout_constraintBottom_toBottomOf="@id/sender_text_view"
android:textAppearance="@style/Proton.Text.Caption.Weak"
@ -125,8 +126,8 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintLeft_toRightOf="@id/sender_initial_barrier"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintStart_toEndOf="@id/sender_initial_barrier"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/sender_text_view" />
<ImageView
@ -134,8 +135,8 @@
android:layout_width="@dimen/mailbox_list_item_icon_size"
android:layout_height="@dimen/mailbox_list_item_icon_size"
android:layout_marginEnd="@dimen/mailbox_list_item_views_margin"
app:layout_constraintLeft_toRightOf="@id/sender_initial_barrier"
app:layout_constraintRight_toLeftOf="@id/second_location_image_view"
app:layout_constraintStart_toEndOf="@id/sender_initial_barrier"
app:layout_constraintEnd_toStartOf="@id/second_location_image_view"
app:layout_constraintTop_toTopOf="@id/second_location_image_view"
app:layout_constraintBottom_toBottomOf="@id/second_location_image_view"
app:layout_constraintHorizontal_chainStyle="packed"
@ -150,8 +151,8 @@
android:layout_width="@dimen/mailbox_list_item_icon_size"
android:layout_height="@dimen/mailbox_list_item_icon_size"
android:layout_marginEnd="@dimen/mailbox_list_item_views_margin"
app:layout_constraintLeft_toRightOf="@id/first_location_image_view"
app:layout_constraintRight_toLeftOf="@id/third_location_image_view"
app:layout_constraintStart_toEndOf="@id/first_location_image_view"
app:layout_constraintEnd_toStartOf="@id/third_location_image_view"
app:layout_constraintTop_toTopOf="@id/third_location_image_view"
app:layout_constraintBottom_toBottomOf="@id/third_location_image_view"
app:tint="@color/icon_weak"
@ -164,8 +165,8 @@
android:layout_width="@dimen/mailbox_list_item_icon_size"
android:layout_height="@dimen/mailbox_list_item_icon_size"
android:layout_marginEnd="@dimen/mailbox_list_item_views_margin"
app:layout_constraintLeft_toRightOf="@id/second_location_image_view"
app:layout_constraintRight_toLeftOf="@id/subject_text_view"
app:layout_constraintStart_toEndOf="@id/second_location_image_view"
app:layout_constraintEnd_toStartOf="@id/subject_text_view"
app:layout_constraintTop_toTopOf="@id/subject_text_view"
app:layout_constraintBottom_toBottomOf="@id/subject_text_view"
app:tint="@color/icon_weak"
@ -177,9 +178,10 @@
android:id="@+id/subject_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintLeft_toRightOf="@id/third_location_image_view"
app:layout_constraintRight_toLeftOf="@id/messages_number_text_view"
app:layout_constraintStart_toEndOf="@id/third_location_image_view"
app:layout_constraintEnd_toStartOf="@id/messages_number_text_view"
app:layout_constraintTop_toBottomOf="@id/first_row_barrier"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constrainedWidth="true"
android:maxLines="1"
android:ellipsize="end"
@ -193,8 +195,8 @@
android:layout_marginStart="@dimen/mailbox_list_item_views_margin"
android:paddingHorizontal="@dimen/message_number_view_padding_horizontal"
android:paddingVertical="@dimen/message_number_view_padding_vertical"
app:layout_constraintLeft_toRightOf="@id/subject_text_view"
app:layout_constraintRight_toLeftOf="@id/empty_space_view"
app:layout_constraintStart_toEndOf="@id/subject_text_view"
app:layout_constraintEnd_toStartOf="@id/empty_space_view"
app:layout_constraintTop_toTopOf="@id/subject_text_view"
app:layout_constraintBottom_toBottomOf="@id/subject_text_view"
android:background="@drawable/background_messages_number"
@ -207,8 +209,8 @@
android:id="@+id/empty_space_view"
android:layout_width="@dimen/mailbox_list_item_views_margin"
android:layout_height="1dp"
app:layout_constraintLeft_toRightOf="@id/messages_number_text_view"
app:layout_constraintRight_toLeftOf="@id/sending_uploading_progress_bar"
app:layout_constraintStart_toEndOf="@id/messages_number_text_view"
app:layout_constraintEnd_toStartOf="@id/sending_uploading_progress_bar"
app:layout_constraintTop_toTopOf="@id/messages_number_text_view"
app:layout_constraintBottom_toBottomOf="@id/messages_number_text_view" />
@ -216,7 +218,7 @@
android:id="@+id/sending_uploading_progress_bar"
android:layout_width="@dimen/mailbox_list_item_icon_size"
android:layout_height="@dimen/mailbox_list_item_icon_size"
app:layout_constraintRight_toLeftOf="@id/attachment_image_view"
app:layout_constraintEnd_toStartOf="@id/attachment_image_view"
app:layout_constraintTop_toTopOf="@id/attachment_image_view"
app:layout_constraintBottom_toBottomOf="@id/attachment_image_view" />
@ -224,7 +226,7 @@
android:id="@+id/attachment_image_view"
android:layout_width="@dimen/mailbox_list_item_icon_size"
android:layout_height="@dimen/mailbox_list_item_icon_size"
app:layout_constraintRight_toLeftOf="@id/star_image_view"
app:layout_constraintEnd_toStartOf="@id/star_image_view"
app:layout_constraintTop_toTopOf="@id/star_image_view"
app:layout_constraintBottom_toBottomOf="@id/star_image_view"
android:src="@drawable/ic_paper_clip"
@ -234,7 +236,7 @@
android:id="@+id/star_image_view"
android:layout_width="@dimen/mailbox_list_item_icon_size"
android:layout_height="@dimen/mailbox_list_item_icon_size"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/subject_text_view"
app:layout_constraintBottom_toBottomOf="@id/subject_text_view"
android:src="@drawable/ic_star_filled"
@ -246,8 +248,8 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintLeft_toRightOf="@id/sender_initial_barrier"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintStart_toEndOf="@id/sender_initial_barrier"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/subject_text_view" />
<ImageView
@ -256,21 +258,22 @@
android:layout_height="@dimen/mailbox_list_item_icon_size"
android:padding="@dimen/mailbox_list_item_expiration_icon_padding"
android:layout_marginTop="@dimen/mailbox_list_item_views_margin"
app:layout_constraintLeft_toRightOf="@id/sender_initial_barrier"
app:layout_constraintStart_toEndOf="@id/sender_initial_barrier"
app:layout_constraintTop_toBottomOf="@id/second_row_barrier"
android:src="@drawable/ic_hourglass"
android:background="@drawable/circle_background_interaction_weak" />
<!-- TODO: Should be replaced in MAILAND-1502 -->
<LinearLayout
android:id="@+id/labelsLayout"
<ch.protonmail.android.ui.view.SingleLineLabelChipGroupView
android:id="@+id/mailbox_label_chip_group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constrainedWidth="true"
android:layout_marginTop="@dimen/mailbox_list_item_views_margin"
android:layout_marginStart="@dimen/mailbox_list_item_views_margin"
app:layout_goneMarginStart="0dp"
app:layout_constraintLeft_toRightOf="@id/expiration_image_view"
app:layout_constraintStart_toEndOf="@id/expiration_image_view"
app:layout_constraintTop_toBottomOf="@id/second_row_barrier"
android:orientation="horizontal" />
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"/>
</androidx.constraintlayout.widget.ConstraintLayout>