feat(chat-room): 7.1 초기 데이터 로딩 구현 및 ServerChatMessage 매퍼 추가
- enterChatRoom API 연동하여 캐릭터/메시지 초기 로딩 - ServerChatMessage -> ChatMessage 매퍼 추가(toDomain) - ChatRoomActivity에서 어댑터에 초기 메시지 세팅 및 헤더 갱신 - hasMore/nextCursor 상태 갱신 및 오류 처리
This commit is contained in:
@@ -45,3 +45,17 @@ fun ServerChatMessage.toEntity(roomId: Long): ChatMessageEntity {
|
|||||||
createdAt = createdAt
|
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
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import kr.co.vividnext.sodalive.R
|
|||||||
import kr.co.vividnext.sodalive.base.BaseActivity
|
import kr.co.vividnext.sodalive.base.BaseActivity
|
||||||
import kr.co.vividnext.sodalive.chat.character.detail.CharacterType
|
import kr.co.vividnext.sodalive.chat.character.detail.CharacterType
|
||||||
import kr.co.vividnext.sodalive.databinding.ActivityChatRoomBinding
|
import kr.co.vividnext.sodalive.databinding.ActivityChatRoomBinding
|
||||||
|
import org.koin.android.ext.android.inject
|
||||||
|
|
||||||
class ChatRoomActivity : BaseActivity<ActivityChatRoomBinding>(
|
class ChatRoomActivity : BaseActivity<ActivityChatRoomBinding>(
|
||||||
ActivityChatRoomBinding::inflate
|
ActivityChatRoomBinding::inflate
|
||||||
@@ -25,6 +26,9 @@ class ChatRoomActivity : BaseActivity<ActivityChatRoomBinding>(
|
|||||||
private lateinit var chatAdapter: ChatMessageAdapter
|
private lateinit var chatAdapter: ChatMessageAdapter
|
||||||
private lateinit var layoutManager: LinearLayoutManager
|
private lateinit var layoutManager: LinearLayoutManager
|
||||||
|
|
||||||
|
// Repository 주입 (7.1 초기 데이터 로딩)
|
||||||
|
private val chatRepository: ChatRepository by inject()
|
||||||
|
|
||||||
// 5.2 무한 스크롤/자동 스크롤 상태
|
// 5.2 무한 스크롤/자동 스크롤 상태
|
||||||
private val items: MutableList<ChatListItem> = mutableListOf()
|
private val items: MutableList<ChatListItem> = mutableListOf()
|
||||||
private var isLoading: Boolean = false
|
private var isLoading: Boolean = false
|
||||||
@@ -348,11 +352,44 @@ class ChatRoomActivity : BaseActivity<ActivityChatRoomBinding>(
|
|||||||
// endregion 6.2 Send flow
|
// endregion 6.2 Send flow
|
||||||
|
|
||||||
private fun loadInitialMessages() {
|
private fun loadInitialMessages() {
|
||||||
// 7.x에서 Repository 연동 및 초기 로딩 구현 예정
|
// 7.1 초기 데이터 로딩 구현: 통합 API 호출 + 로컬 동기화 결과를 UI에 반영
|
||||||
items.clear()
|
isLoading = true
|
||||||
chatAdapter.setItems(items)
|
val token = "Bearer ${kr.co.vividnext.sodalive.common.SharedPreferenceManager.token}"
|
||||||
// 초기 진입 시 최신 메시지로 스크롤 (하단)
|
|
||||||
scrollToBottom()
|
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
|
// region 5.2 helper methods
|
||||||
|
|||||||
Reference in New Issue
Block a user