diff --git a/app/src/main/java/kr/co/vividnext/sodalive/chat/talk/room/ChatRoomActivity.kt b/app/src/main/java/kr/co/vividnext/sodalive/chat/talk/room/ChatRoomActivity.kt index 215b19cf..1ecca2bc 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/chat/talk/room/ChatRoomActivity.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/chat/talk/room/ChatRoomActivity.kt @@ -429,7 +429,7 @@ class ChatRoomActivity : BaseActivity( .subscribe({ localList -> if (localList.isNotEmpty() && items.isEmpty()) { val localItems = localList - .sortedBy { it.createdAt } + .sortedWith(compareBy { it.createdAt }.thenBy { it.messageId }.thenBy { it.localId ?: "" }) .map { msg -> if (msg.mine) ChatListItem.UserMessage(msg) else ChatListItem.AiMessage(msg, characterInfo?.name) @@ -450,8 +450,8 @@ class ChatRoomActivity : BaseActivity( // 캐릭터 정보 바인딩 setCharacterInfo(response.character) - // 메시지 정렬(오래된 -> 최신) 후 도메인/UI 모델로 변환 - val sorted = response.messages.sortedBy { it.createdAt } + // 메시지 정렬(오래된 -> 최신) + 동시간대는 messageId 오름차순으로 안정화 + val sorted = response.messages.sortedWith(compareBy { it.createdAt }.thenBy { it.messageId }) val chatItems = sorted.map { serverMsg -> val domain = serverMsg.toDomain() if (domain.mine) { @@ -549,8 +549,8 @@ class ChatRoomActivity : BaseActivity( chatRepository.loadMoreMessages(token = token, roomId = roomId, cursor = cursor) .observeOn(io.reactivex.rxjava3.android.schedulers.AndroidSchedulers.mainThread()) .subscribe({ response -> - // 서버에서 받은 메시지(이전 것들)를 오래된 -> 최신 순으로 정렬 - val sorted = response.messages.sortedBy { it.createdAt } + // 서버에서 받은 메시지(이전 것들)를 오래된 -> 최신 + 동시간대는 messageId 오름차순으로 정렬 + val sorted = response.messages.sortedWith(compareBy { it.createdAt }.thenBy { it.messageId }) // 중복 제거: 기존 목록의 messageId 집합과 비교 val existingIds: Set = items.mapNotNull {