Fix corner rounding issue

This commit is contained in:
Niels Andriesse 2021-06-25 14:06:53 +10:00
parent cc98ab5c9f
commit 40317d9834
6 changed files with 69 additions and 8 deletions

View File

@ -1,11 +1,14 @@
package org.thoughtcrime.securesms.conversation.v2.messages package org.thoughtcrime.securesms.conversation.v2.messages
import android.content.Context import android.content.Context
import android.content.res.Resources
import android.util.AttributeSet import android.util.AttributeSet
import android.view.Gravity
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.widget.LinearLayout import android.widget.LinearLayout
import androidx.core.content.res.ResourcesCompat import androidx.core.content.res.ResourcesCompat
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.view_control_message.view.* import kotlinx.android.synthetic.main.view_control_message.view.*
import network.loki.messenger.R import network.loki.messenger.R
import org.thoughtcrime.securesms.database.model.MessageRecord import org.thoughtcrime.securesms.database.model.MessageRecord
@ -19,6 +22,7 @@ class ControlMessageView : LinearLayout {
private fun initialize() { private fun initialize() {
LayoutInflater.from(context).inflate(R.layout.view_control_message, this) LayoutInflater.from(context).inflate(R.layout.view_control_message, this)
layoutParams = RecyclerView.LayoutParams(RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.WRAP_CONTENT)
} }
// endregion // endregion

View File

@ -1,6 +1,7 @@
package org.thoughtcrime.securesms.conversation.v2.messages package org.thoughtcrime.securesms.conversation.v2.messages
import android.content.Context import android.content.Context
import android.graphics.Canvas
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.util.AttributeSet import android.util.AttributeSet
import android.view.LayoutInflater import android.view.LayoutInflater
@ -9,12 +10,15 @@ import android.widget.LinearLayout
import androidx.core.content.res.ResourcesCompat import androidx.core.content.res.ResourcesCompat
import kotlinx.android.synthetic.main.view_link_preview.view.* import kotlinx.android.synthetic.main.view_link_preview.view.*
import network.loki.messenger.R import network.loki.messenger.R
import org.thoughtcrime.securesms.components.CornerMask
import org.thoughtcrime.securesms.conversation.v2.utilities.MessageBubbleUtilities
import org.thoughtcrime.securesms.database.model.MmsMessageRecord import org.thoughtcrime.securesms.database.model.MmsMessageRecord
import org.thoughtcrime.securesms.loki.utilities.UiModeUtilities import org.thoughtcrime.securesms.loki.utilities.UiModeUtilities
import org.thoughtcrime.securesms.mms.GlideRequests import org.thoughtcrime.securesms.mms.GlideRequests
import org.thoughtcrime.securesms.mms.ImageSlide import org.thoughtcrime.securesms.mms.ImageSlide
class LinkPreviewView : LinearLayout { class LinkPreviewView : LinearLayout {
private val cornerMask by lazy { CornerMask(this) }
// region Lifecycle // region Lifecycle
constructor(context: Context) : super(context) { initialize() } constructor(context: Context) : super(context) { initialize() }
@ -27,7 +31,7 @@ class LinkPreviewView : LinearLayout {
// endregion // endregion
// region Updating // region Updating
fun bind(message: MmsMessageRecord, glide: GlideRequests, background: Drawable) { fun bind(message: MmsMessageRecord, glide: GlideRequests, isStartOfMessageCluster: Boolean, isEndOfMessageCluster: Boolean) {
mainLinkPreviewContainer.background = background mainLinkPreviewContainer.background = background
mainLinkPreviewContainer.outlineProvider = ViewOutlineProvider.BACKGROUND mainLinkPreviewContainer.outlineProvider = ViewOutlineProvider.BACKGROUND
mainLinkPreviewContainer.clipToOutline = true mainLinkPreviewContainer.clipToOutline = true
@ -48,6 +52,17 @@ class LinkPreviewView : LinearLayout {
// Body // Body
val bodyTextView = VisibleMessageContentView.getBodyTextView(context, message) val bodyTextView = VisibleMessageContentView.getBodyTextView(context, message)
mainLinkPreviewContainer.addView(bodyTextView) mainLinkPreviewContainer.addView(bodyTextView)
// Corner radii
val cornerRadii = MessageBubbleUtilities.calculateRadii(context, isStartOfMessageCluster, isEndOfMessageCluster, message.isOutgoing)
cornerMask.setTopLeftRadius(cornerRadii[0])
cornerMask.setTopRightRadius(cornerRadii[1])
cornerMask.setBottomRightRadius(cornerRadii[2])
cornerMask.setBottomLeftRadius(cornerRadii[3])
}
override fun dispatchDraw(canvas: Canvas) {
super.dispatchDraw(canvas)
cornerMask.mask(canvas)
} }
fun recycle() { fun recycle() {

View File

@ -59,7 +59,7 @@ class VisibleMessageContentView : LinearLayout {
onContentClick = null onContentClick = null
if (message is MmsMessageRecord && message.linkPreviews.isNotEmpty()) { if (message is MmsMessageRecord && message.linkPreviews.isNotEmpty()) {
val linkPreviewView = LinkPreviewView(context) val linkPreviewView = LinkPreviewView(context)
linkPreviewView.bind(message, glide, background) linkPreviewView.bind(message, glide, isStartOfMessageCluster, isEndOfMessageCluster)
mainContainer.addView(linkPreviewView) mainContainer.addView(linkPreviewView)
// Body text view is inside the link preview for layout convenience // Body text view is inside the link preview for layout convenience
} else if (message is MmsMessageRecord && message.quote != null) { } else if (message is MmsMessageRecord && message.quote != null) {
@ -77,7 +77,7 @@ class VisibleMessageContentView : LinearLayout {
mainContainer.addView(bodyTextView) mainContainer.addView(bodyTextView)
} else if (message is MmsMessageRecord && message.slideDeck.audioSlide != null) { } else if (message is MmsMessageRecord && message.slideDeck.audioSlide != null) {
val voiceMessageView = VoiceMessageView(context) val voiceMessageView = VoiceMessageView(context)
voiceMessageView.bind(message, background) voiceMessageView.bind(message, isStartOfMessageCluster, isEndOfMessageCluster)
mainContainer.addView(voiceMessageView) mainContainer.addView(voiceMessageView)
// We have to use onContentClick (rather than a click listener directly on the voice // We have to use onContentClick (rather than a click listener directly on the voice
// message view) so as to not interfere with all the other gestures. // message view) so as to not interfere with all the other gestures.

View File

@ -1,6 +1,7 @@
package org.thoughtcrime.securesms.conversation.v2.messages package org.thoughtcrime.securesms.conversation.v2.messages
import android.content.Context import android.content.Context
import android.graphics.Canvas
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.os.Handler import android.os.Handler
import android.os.Looper import android.os.Looper
@ -12,12 +13,15 @@ import android.widget.RelativeLayout
import androidx.core.view.isVisible import androidx.core.view.isVisible
import kotlinx.android.synthetic.main.view_voice_message.view.* import kotlinx.android.synthetic.main.view_voice_message.view.*
import network.loki.messenger.R import network.loki.messenger.R
import org.thoughtcrime.securesms.components.CornerMask
import org.thoughtcrime.securesms.conversation.v2.utilities.MessageBubbleUtilities
import org.thoughtcrime.securesms.database.model.MmsMessageRecord import org.thoughtcrime.securesms.database.model.MmsMessageRecord
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import kotlin.math.roundToInt import kotlin.math.roundToInt
class VoiceMessageView : LinearLayout { class VoiceMessageView : LinearLayout {
private val snHandler = Handler(Looper.getMainLooper()) private val snHandler = Handler(Looper.getMainLooper())
private val cornerMask by lazy { CornerMask(this) }
private var runnable: Runnable? = null private var runnable: Runnable? = null
private var mockIsPlaying = false private var mockIsPlaying = false
private var mockProgress = 0L private var mockProgress = 0L
@ -38,12 +42,14 @@ class VoiceMessageView : LinearLayout {
// endregion // endregion
// region Updating // region Updating
fun bind(message: MmsMessageRecord, background: Drawable) { fun bind(message: MmsMessageRecord, isStartOfMessageCluster: Boolean, isEndOfMessageCluster: Boolean) {
val audio = message.slideDeck.audioSlide!! val audio = message.slideDeck.audioSlide!!
voiceMessageViewLoader.isVisible = audio.isPendingDownload voiceMessageViewLoader.isVisible = audio.isPendingDownload
mainVoiceMessageViewContainer.background = background val cornerRadii = MessageBubbleUtilities.calculateRadii(context, isStartOfMessageCluster, isEndOfMessageCluster, message.isOutgoing)
mainVoiceMessageViewContainer.outlineProvider = ViewOutlineProvider.BACKGROUND cornerMask.setTopLeftRadius(cornerRadii[0])
mainVoiceMessageViewContainer.clipToOutline = true cornerMask.setTopRightRadius(cornerRadii[1])
cornerMask.setBottomRightRadius(cornerRadii[2])
cornerMask.setBottomLeftRadius(cornerRadii[3])
} }
private fun handleProgressChanged() { private fun handleProgressChanged() {
@ -56,6 +62,11 @@ class VoiceMessageView : LinearLayout {
progressView.layoutParams = layoutParams progressView.layoutParams = layoutParams
} }
override fun dispatchDraw(canvas: Canvas) {
super.dispatchDraw(canvas)
cornerMask.mask(canvas)
}
fun recycle() { fun recycle() {
// TODO: Implement // TODO: Implement
} }

View File

@ -0,0 +1,31 @@
package org.thoughtcrime.securesms.conversation.v2.utilities
import android.content.Context
import network.loki.messenger.R
import kotlin.math.roundToInt
object MessageBubbleUtilities {
fun calculateRadii(context: Context, isStartOfMessageCluster: Boolean, isEndOfMessageCluster: Boolean, isOutgoing: Boolean): IntArray {
val roundedDimen = context.resources.getDimension(R.dimen.message_corner_radius).roundToInt()
val collapsedDimen = context.resources.getDimension(R.dimen.message_corner_collapse_radius).roundToInt()
val (tl, tr, bl, br) = when {
// Single message
isStartOfMessageCluster && isEndOfMessageCluster -> intArrayOf(roundedDimen, roundedDimen, roundedDimen, roundedDimen)
// Start of message cluster; collapsed BL
isStartOfMessageCluster -> intArrayOf(roundedDimen, roundedDimen, collapsedDimen, roundedDimen)
// End of message cluster; collapsed TL
isEndOfMessageCluster -> intArrayOf(collapsedDimen, roundedDimen, roundedDimen, roundedDimen)
// In the middle; no rounding on the left
else -> intArrayOf(collapsedDimen, roundedDimen, collapsedDimen, roundedDimen)
}
// TL, TR, BR, BL (CW direction)
// Flip if the message is outgoing
return intArrayOf(
if (!isOutgoing) tl else tr, // TL
if (!isOutgoing) tr else tl, // TR
if (!isOutgoing) br else bl, // BR
if (!isOutgoing) bl else br // BL
)
}
}

View File

@ -16,7 +16,7 @@
<TextView <TextView
android:id="@+id/textView" android:id="@+id/textView"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textSize="@dimen/very_small_font_size" android:textSize="@dimen/very_small_font_size"
android:textColor="@color/text" android:textColor="@color/text"