Merge pull request #5970 from ofalvai/feature/ofa/read-receipts-design
Make read receipt avatar list more compact
This commit is contained in:
commit
e6beb73e3d
|
@ -0,0 +1 @@
|
||||||
|
Make read receipt avatar list more compact
|
|
@ -28,8 +28,7 @@ import im.vector.app.features.home.AvatarRenderer
|
||||||
import im.vector.app.features.home.room.detail.timeline.item.ReadReceiptData
|
import im.vector.app.features.home.room.detail.timeline.item.ReadReceiptData
|
||||||
import im.vector.app.features.home.room.detail.timeline.item.toMatrixItem
|
import im.vector.app.features.home.room.detail.timeline.item.toMatrixItem
|
||||||
|
|
||||||
private const val MAX_RECEIPT_DISPLAYED = 5
|
private const val MAX_RECEIPT_DISPLAYED = 3
|
||||||
private const val MAX_RECEIPT_DESCRIBED = 3
|
|
||||||
|
|
||||||
class ReadReceiptsView @JvmOverloads constructor(
|
class ReadReceiptsView @JvmOverloads constructor(
|
||||||
context: Context,
|
context: Context,
|
||||||
|
@ -45,13 +44,7 @@ class ReadReceiptsView @JvmOverloads constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
private val receiptAvatars: List<ImageView> by lazy {
|
private val receiptAvatars: List<ImageView> by lazy {
|
||||||
listOf(
|
listOf(views.receiptAvatar1, views.receiptAvatar2, views.receiptAvatar3)
|
||||||
views.receiptAvatar1,
|
|
||||||
views.receiptAvatar2,
|
|
||||||
views.receiptAvatar3,
|
|
||||||
views.receiptAvatar4,
|
|
||||||
views.receiptAvatar5
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupView() {
|
private fun setupView() {
|
||||||
|
@ -60,66 +53,58 @@ class ReadReceiptsView @JvmOverloads constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun render(readReceipts: List<ReadReceiptData>, avatarRenderer: AvatarRenderer) {
|
fun render(readReceipts: List<ReadReceiptData>, avatarRenderer: AvatarRenderer) {
|
||||||
if (readReceipts.isNotEmpty()) {
|
receiptAvatars.forEach { it.isVisible = false }
|
||||||
isVisible = true
|
|
||||||
for (index in 0 until MAX_RECEIPT_DISPLAYED) {
|
|
||||||
val receiptData = readReceipts.getOrNull(index)
|
|
||||||
if (receiptData == null) {
|
|
||||||
receiptAvatars[index].visibility = View.INVISIBLE
|
|
||||||
} else {
|
|
||||||
receiptAvatars[index].visibility = View.VISIBLE
|
|
||||||
avatarRenderer.render(receiptData.toMatrixItem(), receiptAvatars[index])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val displayNames = readReceipts
|
readReceipts.take(MAX_RECEIPT_DISPLAYED).forEachIndexed { index, receiptData ->
|
||||||
.mapNotNull { it.displayName }
|
receiptAvatars[index].isVisible = true
|
||||||
.filter { it.isNotBlank() }
|
avatarRenderer.render(receiptData.toMatrixItem(), receiptAvatars[index])
|
||||||
.take(MAX_RECEIPT_DESCRIBED)
|
}
|
||||||
|
|
||||||
if (readReceipts.size > MAX_RECEIPT_DISPLAYED) {
|
val displayNames = readReceipts
|
||||||
views.receiptMore.visibility = View.VISIBLE
|
.mapNotNull { it.displayName }
|
||||||
views.receiptMore.text = context.getString(
|
.filter { it.isNotBlank() }
|
||||||
R.string.x_plus, readReceipts.size - MAX_RECEIPT_DISPLAYED
|
.take(MAX_RECEIPT_DISPLAYED)
|
||||||
)
|
|
||||||
} else {
|
if (readReceipts.size > MAX_RECEIPT_DISPLAYED) {
|
||||||
views.receiptMore.visibility = View.GONE
|
views.receiptMore.visibility = View.VISIBLE
|
||||||
}
|
views.receiptMore.text = context.getString(
|
||||||
contentDescription = when (readReceipts.size) {
|
R.string.x_plus, readReceipts.size - MAX_RECEIPT_DISPLAYED
|
||||||
1 ->
|
)
|
||||||
if (displayNames.size == 1) {
|
|
||||||
context.getString(R.string.one_user_read, displayNames[0])
|
|
||||||
} else {
|
|
||||||
context.resources.getQuantityString(R.plurals.fallback_users_read, readReceipts.size)
|
|
||||||
}
|
|
||||||
2 ->
|
|
||||||
if (displayNames.size == 2) {
|
|
||||||
context.getString(R.string.two_users_read, displayNames[0], displayNames[1])
|
|
||||||
} else {
|
|
||||||
context.resources.getQuantityString(R.plurals.fallback_users_read, readReceipts.size)
|
|
||||||
}
|
|
||||||
3 ->
|
|
||||||
if (displayNames.size == 3) {
|
|
||||||
context.getString(R.string.three_users_read, displayNames[0], displayNames[1], displayNames[2])
|
|
||||||
} else {
|
|
||||||
context.resources.getQuantityString(R.plurals.fallback_users_read, readReceipts.size)
|
|
||||||
}
|
|
||||||
else ->
|
|
||||||
if (displayNames.size >= 2) {
|
|
||||||
val qty = readReceipts.size - 2
|
|
||||||
context.resources.getQuantityString(
|
|
||||||
R.plurals.two_and_some_others_read,
|
|
||||||
qty,
|
|
||||||
displayNames[0],
|
|
||||||
displayNames[1],
|
|
||||||
qty
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
context.resources.getQuantityString(R.plurals.fallback_users_read, readReceipts.size)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
isVisible = false
|
views.receiptMore.visibility = View.GONE
|
||||||
|
}
|
||||||
|
contentDescription = when (readReceipts.size) {
|
||||||
|
1 ->
|
||||||
|
if (displayNames.size == 1) {
|
||||||
|
context.getString(R.string.one_user_read, displayNames[0])
|
||||||
|
} else {
|
||||||
|
context.resources.getQuantityString(R.plurals.fallback_users_read, readReceipts.size)
|
||||||
|
}
|
||||||
|
2 ->
|
||||||
|
if (displayNames.size == 2) {
|
||||||
|
context.getString(R.string.two_users_read, displayNames[0], displayNames[1])
|
||||||
|
} else {
|
||||||
|
context.resources.getQuantityString(R.plurals.fallback_users_read, readReceipts.size)
|
||||||
|
}
|
||||||
|
3 ->
|
||||||
|
if (displayNames.size == 3) {
|
||||||
|
context.getString(R.string.three_users_read, displayNames[0], displayNames[1], displayNames[2])
|
||||||
|
} else {
|
||||||
|
context.resources.getQuantityString(R.plurals.fallback_users_read, readReceipts.size)
|
||||||
|
}
|
||||||
|
else ->
|
||||||
|
if (displayNames.size >= 2) {
|
||||||
|
val qty = readReceipts.size - 2
|
||||||
|
context.resources.getQuantityString(
|
||||||
|
R.plurals.two_and_some_others_read,
|
||||||
|
qty,
|
||||||
|
displayNames[0],
|
||||||
|
displayNames[1],
|
||||||
|
qty
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
context.resources.getQuantityString(R.plurals.fallback_users_read, readReceipts.size)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="end"
|
||||||
tools:parentTag="android.widget.LinearLayout">
|
tools:parentTag="android.widget.LinearLayout">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
@ -18,53 +19,40 @@
|
||||||
android:textColor="?vctr_content_primary"
|
android:textColor="?vctr_content_primary"
|
||||||
tools:text="999+" />
|
tools:text="999+" />
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/receiptAvatar5"
|
|
||||||
android:layout_width="@dimen/item_event_message_state_size"
|
|
||||||
android:layout_height="@dimen/item_event_message_state_size"
|
|
||||||
android:layout_marginStart="2dp"
|
|
||||||
android:adjustViewBounds="true"
|
|
||||||
android:importantForAccessibility="no"
|
|
||||||
android:scaleType="centerCrop"
|
|
||||||
tools:src="@sample/user_round_avatars" />
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/receiptAvatar4"
|
|
||||||
android:layout_width="@dimen/item_event_message_state_size"
|
|
||||||
android:layout_height="@dimen/item_event_message_state_size"
|
|
||||||
android:layout_marginStart="2dp"
|
|
||||||
android:adjustViewBounds="true"
|
|
||||||
android:importantForAccessibility="no"
|
|
||||||
android:scaleType="centerCrop"
|
|
||||||
tools:src="@sample/user_round_avatars" />
|
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/receiptAvatar3"
|
android:id="@+id/receiptAvatar3"
|
||||||
android:layout_width="@dimen/item_event_message_state_size"
|
android:layout_width="@dimen/item_event_message_state_size"
|
||||||
android:layout_height="@dimen/item_event_message_state_size"
|
android:layout_height="@dimen/item_event_message_state_size"
|
||||||
android:layout_marginStart="2dp"
|
android:layout_marginStart="2dp"
|
||||||
|
android:layout_marginEnd="-6dp"
|
||||||
android:adjustViewBounds="true"
|
android:adjustViewBounds="true"
|
||||||
android:importantForAccessibility="no"
|
android:importantForAccessibility="no"
|
||||||
|
android:padding="1dp"
|
||||||
android:scaleType="centerCrop"
|
android:scaleType="centerCrop"
|
||||||
|
tools:ignore="NegativeMargin"
|
||||||
tools:src="@sample/user_round_avatars" />
|
tools:src="@sample/user_round_avatars" />
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/receiptAvatar2"
|
android:id="@+id/receiptAvatar2"
|
||||||
android:layout_width="@dimen/item_event_message_state_size"
|
android:layout_width="@dimen/item_event_message_state_size"
|
||||||
android:layout_height="@dimen/item_event_message_state_size"
|
android:layout_height="@dimen/item_event_message_state_size"
|
||||||
android:layout_marginStart="2dp"
|
android:layout_marginEnd="-6dp"
|
||||||
android:adjustViewBounds="true"
|
android:adjustViewBounds="true"
|
||||||
|
android:background="@drawable/pill_receipt"
|
||||||
android:importantForAccessibility="no"
|
android:importantForAccessibility="no"
|
||||||
|
android:padding="1dp"
|
||||||
android:scaleType="centerCrop"
|
android:scaleType="centerCrop"
|
||||||
|
tools:ignore="NegativeMargin"
|
||||||
tools:src="@sample/user_round_avatars" />
|
tools:src="@sample/user_round_avatars" />
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/receiptAvatar1"
|
android:id="@+id/receiptAvatar1"
|
||||||
android:layout_width="@dimen/item_event_message_state_size"
|
android:layout_width="@dimen/item_event_message_state_size"
|
||||||
android:layout_height="@dimen/item_event_message_state_size"
|
android:layout_height="@dimen/item_event_message_state_size"
|
||||||
android:layout_marginStart="2dp"
|
|
||||||
android:adjustViewBounds="true"
|
android:adjustViewBounds="true"
|
||||||
|
android:background="@drawable/pill_receipt"
|
||||||
android:importantForAccessibility="no"
|
android:importantForAccessibility="no"
|
||||||
|
android:padding="1dp"
|
||||||
android:scaleType="centerCrop"
|
android:scaleType="centerCrop"
|
||||||
tools:src="@sample/user_round_avatars" />
|
tools:src="@sample/user_round_avatars" />
|
||||||
|
|
||||||
|
|
|
@ -1424,7 +1424,7 @@
|
||||||
<string name="merged_events_collapse">collapse</string>
|
<string name="merged_events_collapse">collapse</string>
|
||||||
|
|
||||||
<string name="generic_label_and_value">%1$s: %2$s</string>
|
<string name="generic_label_and_value">%1$s: %2$s</string>
|
||||||
<string name="x_plus">%d+</string>
|
<string name="x_plus">+%d</string>
|
||||||
<string name="no_valid_google_play_services_apk">No valid Google Play Services APK found. Notifications may not work properly.</string>
|
<string name="no_valid_google_play_services_apk">No valid Google Play Services APK found. Notifications may not work properly.</string>
|
||||||
|
|
||||||
<!-- Passphrase -->
|
<!-- Passphrase -->
|
||||||
|
|
Loading…
Reference in New Issue