Fix issue with chat colors not updating properly.
This commit is contained in:
parent
eafa1eabee
commit
5cc85cc860
3 changed files with 76 additions and 56 deletions
|
@ -394,6 +394,8 @@ class ConversationFragment :
|
|||
_binding.conversationItemRecycler.adapter = null
|
||||
|
||||
textDraftSaveDebouncer.clear()
|
||||
|
||||
ChatColorsDrawable.clearGlobalChatColors(_binding.conversationItemRecycler)
|
||||
}
|
||||
|
||||
private val viewModel: ConversationViewModel by viewModel {
|
||||
|
@ -1372,6 +1374,7 @@ class ConversationFragment :
|
|||
colorFilter = PorterDuffColorFilter(chatColors.asSingleColor(), PorterDuff.Mode.MULTIPLY)
|
||||
invalidateSelf()
|
||||
}
|
||||
ChatColorsDrawable.setGlobalChatColors(binding.conversationItemRecycler, chatColors)
|
||||
}
|
||||
|
||||
private fun presentScrollButtons(scrollButtonState: ConversationScrollButtonState) {
|
||||
|
|
|
@ -19,9 +19,9 @@ import androidx.core.graphics.toRectF
|
|||
import androidx.core.graphics.withClip
|
||||
import androidx.core.graphics.withTranslation
|
||||
import androidx.core.view.children
|
||||
import androidx.core.view.doOnDetach
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import org.thoughtcrime.securesms.conversation.colors.ChatColors
|
||||
import org.thoughtcrime.securesms.conversation.v2.items.ChatColorsDrawable.ChatColorsItemDecoration
|
||||
import org.thoughtcrime.securesms.util.Projection
|
||||
import org.thoughtcrime.securesms.util.Projection.Corners
|
||||
|
||||
|
@ -32,7 +32,8 @@ import org.thoughtcrime.securesms.util.Projection.Corners
|
|||
class ChatColorsDrawable : Drawable() {
|
||||
|
||||
companion object {
|
||||
private var maskDrawable: Drawable? = null
|
||||
private var globalChatColors: ChatColors? = null
|
||||
private var globalMask: Drawable? = null
|
||||
private var latestBounds: Rect? = null
|
||||
|
||||
/**
|
||||
|
@ -44,14 +45,34 @@ class ChatColorsDrawable : Drawable() {
|
|||
}
|
||||
|
||||
recyclerView.addItemDecoration(ChatColorsItemDecoration)
|
||||
recyclerView.doOnDetach {
|
||||
maskDrawable = null
|
||||
}
|
||||
|
||||
fun setGlobalChatColors(recyclerView: RecyclerView, chatColors: ChatColors) {
|
||||
if (globalChatColors == chatColors) {
|
||||
return
|
||||
}
|
||||
|
||||
globalChatColors = chatColors
|
||||
|
||||
globalMask = if (chatColors.isGradient()) {
|
||||
chatColors.chatBubbleMask
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
recyclerView.invalidateItemDecorations()
|
||||
}
|
||||
|
||||
fun clearGlobalChatColors(recyclerView: RecyclerView) {
|
||||
globalChatColors = null
|
||||
globalMask = null
|
||||
|
||||
recyclerView.invalidateItemDecorations()
|
||||
}
|
||||
|
||||
private fun applyBounds(bounds: Rect) {
|
||||
latestBounds = bounds
|
||||
maskDrawable?.bounds = bounds
|
||||
globalMask?.bounds = bounds
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -65,20 +86,18 @@ class ChatColorsDrawable : Drawable() {
|
|||
* Clipping path that includes the dimensions and corners for this view.
|
||||
*/
|
||||
private val path = Path()
|
||||
|
||||
private val rect = RectF()
|
||||
|
||||
private var gradientColors: ChatColors? = null
|
||||
private var corners: FloatArray = floatArrayOf(0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f)
|
||||
private var fillColor: Int = 0
|
||||
|
||||
private var localChatColors: ChatColors? = null
|
||||
private var localMask: Drawable? = null
|
||||
|
||||
override fun draw(canvas: Canvas) {
|
||||
if (gradientColors == null && fillColor == 0) {
|
||||
return
|
||||
}
|
||||
val chatColors = getChatColors() ?: return
|
||||
|
||||
val mask = maskDrawable
|
||||
if (gradientColors != null && mask != null) {
|
||||
val mask = getMask()
|
||||
if (chatColors.isGradient() && mask != null) {
|
||||
canvas.withTranslation(-maskOffset.x, -maskOffset.y) {
|
||||
canvas.withClip(path) {
|
||||
mask.draw(canvas)
|
||||
|
@ -89,7 +108,7 @@ class ChatColorsDrawable : Drawable() {
|
|||
rect.set(bounds)
|
||||
path.addRoundRect(rect, corners, Path.Direction.CW)
|
||||
canvas.withClip(path) {
|
||||
canvas.drawColor(fillColor)
|
||||
canvas.drawColor(chatColors.asSingleColor())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -139,7 +158,7 @@ class ChatColorsDrawable : Drawable() {
|
|||
}
|
||||
|
||||
fun isSolidColor(): Boolean {
|
||||
return gradientColors == null
|
||||
return getChatColors()?.isGradient() == false
|
||||
}
|
||||
|
||||
fun setCorners(corners: FloatArray) {
|
||||
|
@ -150,38 +169,41 @@ class ChatColorsDrawable : Drawable() {
|
|||
}
|
||||
|
||||
/**
|
||||
* Sets the chat color and shape as specified. If the colors are a gradient,
|
||||
* Sets the shape as specified. If the colors are a gradient,
|
||||
* we will use masking to draw, and we will draw every time we're told to by
|
||||
* the decorator.
|
||||
*
|
||||
* If a solid color is set, we can skip drawing as we move, since we haven't changed.
|
||||
*/
|
||||
fun setChatColors(
|
||||
chatColors: ChatColors,
|
||||
fun setCorners(
|
||||
corners: Corners
|
||||
) {
|
||||
this.corners = corners.toRadii()
|
||||
setCorners(corners.toRadii())
|
||||
}
|
||||
|
||||
if (chatColors.isGradient()) {
|
||||
if (maskDrawable == null) {
|
||||
maskDrawable = chatColors.chatBubbleMask
|
||||
fun setLocalChatColors(
|
||||
chatColors: ChatColors
|
||||
) {
|
||||
localChatColors = chatColors
|
||||
|
||||
val maskBounds = latestBounds
|
||||
if (maskBounds != null) {
|
||||
maskDrawable?.bounds = maskBounds
|
||||
}
|
||||
}
|
||||
|
||||
this.fillColor = 0
|
||||
this.gradientColors = chatColors
|
||||
localMask = if (chatColors.isGradient()) {
|
||||
chatColors.chatBubbleMask
|
||||
} else {
|
||||
this.fillColor = chatColors.asSingleColor()
|
||||
this.gradientColors = null
|
||||
null
|
||||
}
|
||||
|
||||
invalidateSelf()
|
||||
}
|
||||
|
||||
fun clearLocalChatColors() {
|
||||
localChatColors = null
|
||||
localMask = null
|
||||
|
||||
invalidateSelf()
|
||||
}
|
||||
|
||||
private fun getChatColors(): ChatColors? = localChatColors ?: globalChatColors
|
||||
|
||||
private fun getMask(): Drawable? = localMask ?: globalMask
|
||||
|
||||
private object ChatColorsItemDecoration : RecyclerView.ItemDecoration() {
|
||||
override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
|
||||
parent.children.map { parent.getChildViewHolder(it) }.filterIsInstance<ChatColorsDrawableInvalidator>().forEach { element ->
|
||||
|
|
|
@ -230,16 +230,14 @@ open class V2ConversationItemTextOnlyViewHolder<Model : MappingModel<Model>>(
|
|||
presentSenderNameBackground()
|
||||
presentReactions()
|
||||
|
||||
bodyBubbleDrawable.setChatColors(
|
||||
if (binding.body.isJumbomoji) {
|
||||
transparentChatColors
|
||||
} else if (binding.isIncoming) {
|
||||
ChatColors.forColor(ChatColors.Id.NotSet, themeDelegate.getBodyBubbleColor(conversationMessage))
|
||||
} else {
|
||||
conversationMessage.threadRecipient.chatColors
|
||||
},
|
||||
shapeDelegate.cornersLTR
|
||||
)
|
||||
bodyBubbleDrawable.setCorners(shapeDelegate.cornersLTR)
|
||||
if (binding.body.isJumbomoji) {
|
||||
bodyBubbleDrawable.setLocalChatColors(transparentChatColors)
|
||||
} else if (binding.isIncoming) {
|
||||
bodyBubbleDrawable.setLocalChatColors(ChatColors.forColor(ChatColors.Id.NotSet, themeDelegate.getBodyBubbleColor(conversationMessage)))
|
||||
} else {
|
||||
bodyBubbleDrawable.clearLocalChatColors()
|
||||
}
|
||||
|
||||
binding.reply.setBackgroundColor(themeDelegate.getReplyIconBackgroundColor())
|
||||
|
||||
|
@ -506,10 +504,8 @@ open class V2ConversationItemTextOnlyViewHolder<Model : MappingModel<Model>>(
|
|||
}
|
||||
|
||||
if (conversationContext.hasWallpaper()) {
|
||||
senderDrawable.setChatColors(
|
||||
ChatColors.forColor(ChatColors.Id.BuiltIn, themeDelegate.getFooterBubbleColor(conversationMessage)),
|
||||
footerCorners
|
||||
)
|
||||
senderDrawable.setCorners(footerCorners)
|
||||
senderDrawable.setLocalChatColors(ChatColors.forColor(ChatColors.Id.BuiltIn, themeDelegate.getFooterBubbleColor(conversationMessage)))
|
||||
|
||||
binding.senderName.background = senderDrawable
|
||||
} else {
|
||||
|
@ -606,14 +602,13 @@ open class V2ConversationItemTextOnlyViewHolder<Model : MappingModel<Model>>(
|
|||
}
|
||||
|
||||
binding.footerBackground.visible = true
|
||||
footerDrawable.setChatColors(
|
||||
if (binding.isIncoming) {
|
||||
ChatColors.forColor(ChatColors.Id.NotSet, themeDelegate.getFooterBubbleColor(conversationMessage))
|
||||
} else {
|
||||
conversationMessage.threadRecipient.chatColors
|
||||
},
|
||||
footerCorners
|
||||
)
|
||||
footerDrawable.setCorners(footerCorners)
|
||||
|
||||
if (binding.isIncoming) {
|
||||
footerDrawable.setLocalChatColors(ChatColors.forColor(ChatColors.Id.NotSet, themeDelegate.getFooterBubbleColor(conversationMessage)))
|
||||
} else {
|
||||
footerDrawable.clearLocalChatColors()
|
||||
}
|
||||
}
|
||||
|
||||
private fun presentDate() {
|
||||
|
|
Loading…
Add table
Reference in a new issue