Start/end the thread divider in the middle of the avatar (#3892)

Previously, the thread indicator would start at the top of the avatar
for the status at the start of the thread, and end at the top of the
avatar for the status at the end of the thread.

If these avatars were partially transparent the thread indicator could
either (a) poke out of the top of the avatar at the start of the thread,
(b) not properly connect with the avatar at the end of the thread, or
(c) both.

Partially fix this by making the divider start/stop in the middle of the
avatar. This assumes that this area will typically have opaque content,
even if some of the rest of the avatar is transparent. This is not
always true, but it's still better than the current behaviour.
This commit is contained in:
Nik Clayton 2023-08-10 19:25:33 +02:00 committed by GitHub
parent f5c7054b8c
commit 09d4f62004
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 20 additions and 19 deletions

View File

@ -24,36 +24,34 @@ import androidx.core.view.forEach
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.keylesspalace.tusky.R import com.keylesspalace.tusky.R
class ConversationLineItemDecoration(private val context: Context) : RecyclerView.ItemDecoration() { class ConversationLineItemDecoration(context: Context) : RecyclerView.ItemDecoration() {
private val divider: Drawable = ContextCompat.getDrawable(context, R.drawable.conversation_thread_line)!! private val divider: Drawable = ContextCompat.getDrawable(context, R.drawable.conversation_thread_line)!!
override fun onDraw(canvas: Canvas, parent: RecyclerView, state: RecyclerView.State) { private val avatarTopMargin = context.resources.getDimensionPixelSize(R.dimen.account_avatar_margin)
val dividerStart = parent.paddingStart + context.resources.getDimensionPixelSize(R.dimen.status_line_margin_start) private val halfAvatarHeight = context.resources.getDimensionPixelSize(R.dimen.timeline_status_avatar_height) / 2
val dividerEnd = dividerStart + divider.intrinsicWidth private val statusLineMarginStart = context.resources.getDimensionPixelSize(R.dimen.status_line_margin_start)
val avatarMargin = context.resources.getDimensionPixelSize(R.dimen.account_avatar_margin) override fun onDraw(canvas: Canvas, parent: RecyclerView, state: RecyclerView.State) {
val dividerStart = parent.paddingStart + statusLineMarginStart
val dividerEnd = dividerStart + divider.intrinsicWidth
val items = (parent.adapter as ThreadAdapter).currentList val items = (parent.adapter as ThreadAdapter).currentList
parent.forEach { child -> parent.forEach { statusItemView ->
val position = parent.getChildAdapterPosition(statusItemView)
val position = parent.getChildAdapterPosition(child) items.getOrNull(position)?.let { current ->
val current = items.getOrNull(position)
if (current != null) {
val above = items.getOrNull(position - 1) val above = items.getOrNull(position - 1)
val dividerTop = if (above != null && above.id == current.status.inReplyToId) { val dividerTop = if (above != null && above.id == current.status.inReplyToId) {
child.top statusItemView.top
} else { } else {
child.top + avatarMargin statusItemView.top + avatarTopMargin + halfAvatarHeight
} }
val below = items.getOrNull(position + 1) val below = items.getOrNull(position + 1)
val dividerBottom = if (below != null && current.id == below.status.inReplyToId && !current.isDetailed) { val dividerBottom = if (below != null && current.id == below.status.inReplyToId && !current.isDetailed) {
child.bottom statusItemView.bottom
} else { } else {
child.top + avatarMargin statusItemView.top + avatarTopMargin + halfAvatarHeight
} }
if (parent.layoutDirection == View.LAYOUT_DIRECTION_LTR) { if (parent.layoutDirection == View.LAYOUT_DIRECTION_LTR) {

View File

@ -33,10 +33,10 @@
<ImageView <ImageView
android:id="@+id/status_avatar" android:id="@+id/status_avatar"
android:layout_width="48dp" android:layout_width="@dimen/timeline_status_avatar_width"
android:layout_height="48dp" android:layout_height="@dimen/timeline_status_avatar_height"
android:layout_marginStart="14dp" android:layout_marginStart="14dp"
android:layout_marginTop="14dp" android:layout_marginTop="@dimen/account_avatar_margin"
android:contentDescription="@string/action_view_profile" android:contentDescription="@string/action_view_profile"
android:importantForAccessibility="no" android:importantForAccessibility="no"
android:scaleType="centerCrop" android:scaleType="centerCrop"

View File

@ -63,4 +63,7 @@
<dimen name="graph_line_thickness">1dp</dimen> <dimen name="graph_line_thickness">1dp</dimen>
<dimen name="minimum_touch_target">48dp</dimen> <dimen name="minimum_touch_target">48dp</dimen>
<dimen name="timeline_status_avatar_height">48dp</dimen>
<dimen name="timeline_status_avatar_width">48dp</dimen>
</resources> </resources>