feat(chat-ui): 메시지 그룹화, 시간 포맷팅, Repository 테스트 추가

This commit is contained in:
2025-08-14 18:08:01 +09:00
parent ec60d4f143
commit d662bd0b65
5 changed files with 207 additions and 0 deletions

View File

@@ -14,6 +14,7 @@ import android.view.animation.Animation
import android.view.animation.AnimationUtils
import android.widget.TextView
import androidx.annotation.LayoutRes
import androidx.annotation.VisibleForTesting
import androidx.core.view.isVisible
import androidx.recyclerview.widget.RecyclerView
import kr.co.vividnext.sodalive.R
@@ -48,6 +49,34 @@ class ChatMessageAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
const val VIEW_TYPE_AI_MESSAGE = 2
const val VIEW_TYPE_NOTICE = 3
const val VIEW_TYPE_TYPING_INDICATOR = 4
/**
* [list]와 [position]을 기준으로 그룹화 여부와 해당 아이템이 그룹의 마지막인지 계산한다.
* 테스트를 위해 노출된 유틸 함수이며, onBindViewHolder의 로직과 동일한 판정을 수행한다.
*/
@VisibleForTesting
internal fun computeGroupingFlags(list: List<ChatListItem>, position: Int): Pair<Boolean, Boolean> {
fun isSameSender(prev: ChatListItem?, curr: ChatListItem?): Boolean {
if (prev == null || curr == null) return false
val p = when (prev) {
is ChatListItem.UserMessage -> prev.data.mine
is ChatListItem.AiMessage -> prev.data.mine
else -> return false
}
val c = when (curr) {
is ChatListItem.UserMessage -> curr.data.mine
is ChatListItem.AiMessage -> curr.data.mine
else -> return false
}
return p == c
}
val curr = list.getOrNull(position)
val prev = if (position > 0) list.getOrNull(position - 1) else null
val next = if (position < list.lastIndex) list.getOrNull(position + 1) else null
val grouped = isSameSender(prev, curr)
val isLast = !isSameSender(curr, next)
return grouped to isLast
}
}
private val items: MutableList<ChatListItem> = mutableListOf()
@@ -93,6 +122,15 @@ class ChatMessageAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
notifyDataSetChanged()
}
/**
* 테스트 전용: RecyclerView 프레임워크 없이 내부 리스트만 채우고 알림을 보내지 않는다.
*/
@VisibleForTesting
internal fun setItemsForTest(newItems: List<ChatListItem>) {
items.clear()
items.addAll(newItems)
}
fun addItem(item: ChatListItem) {
items.add(item)
notifyItemInserted(items.lastIndex)