feat(chat-room): 7.1 초기 데이터 로딩 구현 및 ServerChatMessage 매퍼 추가

- enterChatRoom API 연동하여 캐릭터/메시지 초기 로딩
- ServerChatMessage -> ChatMessage 매퍼 추가(toDomain)
- ChatRoomActivity에서 어댑터에 초기 메시지 세팅 및 헤더 갱신
- hasMore/nextCursor 상태 갱신 및 오류 처리
This commit is contained in:
2025-08-13 23:26:01 +09:00
parent ceae25ea06
commit 637595e8cd
2 changed files with 56 additions and 5 deletions

View File

@@ -45,3 +45,17 @@ fun ServerChatMessage.toEntity(roomId: Long): ChatMessageEntity {
createdAt = createdAt
)
}
@Keep
fun ServerChatMessage.toDomain(): ChatMessage {
return ChatMessage(
messageId = messageId,
message = message,
profileImageUrl = profileImageUrl,
mine = mine,
createdAt = createdAt,
status = MessageStatus.SENT,
localId = null,
isGrouped = false
)
}

View File

@@ -17,6 +17,7 @@ import kr.co.vividnext.sodalive.R
import kr.co.vividnext.sodalive.base.BaseActivity
import kr.co.vividnext.sodalive.chat.character.detail.CharacterType
import kr.co.vividnext.sodalive.databinding.ActivityChatRoomBinding
import org.koin.android.ext.android.inject
class ChatRoomActivity : BaseActivity<ActivityChatRoomBinding>(
ActivityChatRoomBinding::inflate
@@ -25,6 +26,9 @@ class ChatRoomActivity : BaseActivity<ActivityChatRoomBinding>(
private lateinit var chatAdapter: ChatMessageAdapter
private lateinit var layoutManager: LinearLayoutManager
// Repository 주입 (7.1 초기 데이터 로딩)
private val chatRepository: ChatRepository by inject()
// 5.2 무한 스크롤/자동 스크롤 상태
private val items: MutableList<ChatListItem> = mutableListOf()
private var isLoading: Boolean = false
@@ -348,11 +352,44 @@ class ChatRoomActivity : BaseActivity<ActivityChatRoomBinding>(
// endregion 6.2 Send flow
private fun loadInitialMessages() {
// 7.x에서 Repository 연동 및 초기 로딩 구현 예정
items.clear()
chatAdapter.setItems(items)
// 초기 진입 시 최신 메시지로 스크롤 (하단)
scrollToBottom()
// 7.1 초기 데이터 로딩 구현: 통합 API 호출 + 로컬 동기화 결과를 UI에 반영
isLoading = true
val token = "Bearer ${kr.co.vividnext.sodalive.common.SharedPreferenceManager.token}"
val disposable = chatRepository.enterChatRoom(token = token, roomId = roomId)
.observeOn(io.reactivex.rxjava3.android.schedulers.AndroidSchedulers.mainThread())
.subscribe({ response ->
// 캐릭터 정보 바인딩
setCharacterInfo(response.character)
// 메시지 정렬(오래된 -> 최신) 후 도메인/UI 모델로 변환
val sorted = response.messages.sortedBy { it.createdAt }
val chatItems = sorted.map { serverMsg ->
val domain = serverMsg.toDomain()
if (domain.mine) {
ChatListItem.UserMessage(domain)
} else {
ChatListItem.AiMessage(domain, response.character.name)
}
}
items.clear()
items.addAll(chatItems)
chatAdapter.setItems(items)
// 페이지 상태 갱신
hasMoreMessages = response.hasMoreMessages
nextCursor = sorted.firstOrNull()?.createdAt
// 최신 메시지 위치로
scrollToBottom()
isLoading = false
}, { error ->
isLoading = false
showToast(error.message ?: "채팅방 데이터를 불러오지 못했습니다.")
})
compositeDisposable.add(disposable)
}
// region 5.2 helper methods