feat(chat): 메시지 괄호 지문 색상을 회색으로 변경
This commit is contained in:
		@@ -6,8 +6,13 @@
 | 
				
			|||||||
package kr.co.vividnext.sodalive.chat.talk.room
 | 
					package kr.co.vividnext.sodalive.chat.talk.room
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import android.annotation.SuppressLint
 | 
					import android.annotation.SuppressLint
 | 
				
			||||||
 | 
					import android.graphics.Typeface
 | 
				
			||||||
import android.os.Bundle
 | 
					import android.os.Bundle
 | 
				
			||||||
 | 
					import android.text.SpannableStringBuilder
 | 
				
			||||||
 | 
					import android.text.Spanned
 | 
				
			||||||
import android.text.TextUtils
 | 
					import android.text.TextUtils
 | 
				
			||||||
 | 
					import android.text.style.ForegroundColorSpan
 | 
				
			||||||
 | 
					import android.text.style.StyleSpan
 | 
				
			||||||
import android.view.LayoutInflater
 | 
					import android.view.LayoutInflater
 | 
				
			||||||
import android.view.View
 | 
					import android.view.View
 | 
				
			||||||
import android.view.ViewGroup
 | 
					import android.view.ViewGroup
 | 
				
			||||||
@@ -16,6 +21,7 @@ import android.view.animation.AnimationUtils
 | 
				
			|||||||
import android.widget.TextView
 | 
					import android.widget.TextView
 | 
				
			||||||
import androidx.annotation.LayoutRes
 | 
					import androidx.annotation.LayoutRes
 | 
				
			||||||
import androidx.annotation.VisibleForTesting
 | 
					import androidx.annotation.VisibleForTesting
 | 
				
			||||||
 | 
					import androidx.core.content.ContextCompat
 | 
				
			||||||
import androidx.core.view.isVisible
 | 
					import androidx.core.view.isVisible
 | 
				
			||||||
import androidx.recyclerview.widget.DiffUtil
 | 
					import androidx.recyclerview.widget.DiffUtil
 | 
				
			||||||
import androidx.recyclerview.widget.RecyclerView
 | 
					import androidx.recyclerview.widget.RecyclerView
 | 
				
			||||||
@@ -106,6 +112,41 @@ class ChatMessageAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
 | 
				
			|||||||
            val isLast = !isSameSender(curr, next)
 | 
					            val isLast = !isSameSender(curr, next)
 | 
				
			||||||
            return grouped to isLast
 | 
					            return grouped to isLast
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // 소괄호 텍스트 스타일링 유틸: 회색 + 기울임꼴
 | 
				
			||||||
 | 
					        private val PAREN_REGEX = Regex("\\([^()]*\\)")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        fun applyParentheticalStyle(tv: TextView, raw: CharSequence?, color: Int? = null) {
 | 
				
			||||||
 | 
					            if (raw.isNullOrEmpty()) {
 | 
				
			||||||
 | 
					                tv.text = raw ?: ""
 | 
				
			||||||
 | 
					                return
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            val text = raw.toString()
 | 
				
			||||||
 | 
					            val builder = SpannableStringBuilder(text)
 | 
				
			||||||
 | 
					            val targetColor = color ?: ContextCompat.getColor(
 | 
				
			||||||
 | 
					                tv.context,
 | 
				
			||||||
 | 
					                R.color.color_7fe2e2e2
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					            PAREN_REGEX.findAll(text).forEach { match ->
 | 
				
			||||||
 | 
					                val start = match.range.first
 | 
				
			||||||
 | 
					                val end = match.range.last + 1
 | 
				
			||||||
 | 
					                if (start in 0 until end && end <= builder.length) {
 | 
				
			||||||
 | 
					                    builder.setSpan(
 | 
				
			||||||
 | 
					                        ForegroundColorSpan(targetColor),
 | 
				
			||||||
 | 
					                        start,
 | 
				
			||||||
 | 
					                        end,
 | 
				
			||||||
 | 
					                        Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
 | 
				
			||||||
 | 
					                    )
 | 
				
			||||||
 | 
					                    builder.setSpan(
 | 
				
			||||||
 | 
					                        StyleSpan(Typeface.ITALIC),
 | 
				
			||||||
 | 
					                        start,
 | 
				
			||||||
 | 
					                        end,
 | 
				
			||||||
 | 
					                        Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
 | 
				
			||||||
 | 
					                    )
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            tv.text = builder
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private val items: MutableList<ChatListItem> = mutableListOf()
 | 
					    private val items: MutableList<ChatListItem> = mutableListOf()
 | 
				
			||||||
@@ -414,7 +455,14 @@ class ChatMessageAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
 | 
				
			|||||||
        private val binding: ItemChatUserMessageBinding
 | 
					        private val binding: ItemChatUserMessageBinding
 | 
				
			||||||
    ) : RecyclerView.ViewHolder(binding.root) {
 | 
					    ) : RecyclerView.ViewHolder(binding.root) {
 | 
				
			||||||
        fun bind(data: ChatMessage, showTime: Boolean, isGrouped: Boolean) {
 | 
					        fun bind(data: ChatMessage, showTime: Boolean, isGrouped: Boolean) {
 | 
				
			||||||
            binding.tvMessage.text = data.message
 | 
					            applyParentheticalStyle(
 | 
				
			||||||
 | 
					                binding.tvMessage,
 | 
				
			||||||
 | 
					                data.message,
 | 
				
			||||||
 | 
					                ContextCompat.getColor(
 | 
				
			||||||
 | 
					                    binding.root.context,
 | 
				
			||||||
 | 
					                    R.color.color_333333
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
            // 화면 너비의 65%를 최대 폭으로 적용
 | 
					            // 화면 너비의 65%를 최대 폭으로 적용
 | 
				
			||||||
            binding.tvMessage.maxWidth =
 | 
					            binding.tvMessage.maxWidth =
 | 
				
			||||||
                (itemView.resources.displayMetrics.widthPixels * 0.65f).toInt()
 | 
					                (itemView.resources.displayMetrics.widthPixels * 0.65f).toInt()
 | 
				
			||||||
@@ -542,7 +590,7 @@ class ChatMessageAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
 | 
				
			|||||||
                // 텍스트 메시지
 | 
					                // 텍스트 메시지
 | 
				
			||||||
                binding.imageContainer.visibility = View.GONE
 | 
					                binding.imageContainer.visibility = View.GONE
 | 
				
			||||||
                binding.messageContainer.visibility = View.VISIBLE
 | 
					                binding.messageContainer.visibility = View.VISIBLE
 | 
				
			||||||
                binding.tvMessage.text = data.message
 | 
					                applyParentheticalStyle(binding.tvMessage, data.message)
 | 
				
			||||||
                binding.tvMessage.maxWidth =
 | 
					                binding.tvMessage.maxWidth =
 | 
				
			||||||
                    (itemView.resources.displayMetrics.widthPixels * 0.90f).toInt()
 | 
					                    (itemView.resources.displayMetrics.widthPixels * 0.90f).toInt()
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -96,6 +96,8 @@ class ChatRoomActivity : BaseActivity<ActivityChatRoomBinding>(
 | 
				
			|||||||
            binding.tvName.text = ""
 | 
					            binding.tvName.text = ""
 | 
				
			||||||
            binding.ivProfile.setImageResource(R.drawable.ic_placeholder_profile)
 | 
					            binding.ivProfile.setImageResource(R.drawable.ic_placeholder_profile)
 | 
				
			||||||
            binding.ivBackgroundProfile.setImageResource(R.drawable.ic_placeholder_profile)
 | 
					            binding.ivBackgroundProfile.setImageResource(R.drawable.ic_placeholder_profile)
 | 
				
			||||||
 | 
					            // 저장된 배경이 있으면 즉시 적용 (네트워크 응답 전 초기 진입에서도 반영)
 | 
				
			||||||
 | 
					            applyBackgroundFromPrefsOrProfile("")
 | 
				
			||||||
            // 배지는 기본 Clone으로 둔다가 실제 값으로 갱신 (디자인 기본 배경도 clone)
 | 
					            // 배지는 기본 Clone으로 둔다가 실제 값으로 갱신 (디자인 기본 배경도 clone)
 | 
				
			||||||
            binding.tvCharacterTypeBadge.text = "Clone"
 | 
					            binding.tvCharacterTypeBadge.text = "Clone"
 | 
				
			||||||
            binding.tvCharacterTypeBadge.setBackgroundResource(R.drawable.bg_character_status_clone)
 | 
					            binding.tvCharacterTypeBadge.setBackgroundResource(R.drawable.bg_character_status_clone)
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user