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:
parent
f5c7054b8c
commit
09d4f62004
|
@ -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) {
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Loading…
Reference in New Issue