feat(chat-room): 7.1 로컬 우선 표시 및 오프라인 대체 처리 추가

- 진입 시 로컬 최근 20개 메시지 즉시 표시
- enterChatRoom 응답으로 최신 상태로 전체 갱신
- 네트워크 실패 시 로컬 UI 유지 및 토스트 노출
This commit is contained in:
2025-08-13 23:46:45 +09:00
parent 7fc72da905
commit 1882139fac

View File

@@ -366,11 +366,31 @@ class ChatRoomActivity : BaseActivity<ActivityChatRoomBinding>(
// endregion 6.2 Send flow // endregion 6.2 Send flow
private fun loadInitialMessages() { private fun loadInitialMessages() {
// 7.1 초기 데이터 로딩 구현: 통합 API 호출 + 로컬 동기화 결과를 UI에 반영 // 7.1 보완: 로컬 우선 표시 + 서버 동기화
isLoading = true isLoading = true
val token = "Bearer ${kr.co.vividnext.sodalive.common.SharedPreferenceManager.token}"
val disposable = chatRepository.enterChatRoom(token = token, roomId = roomId) // 1) 로컬 최근 20개 즉시 표시 (있을 경우)
val localDisposable = chatRepository.getRecentMessagesFromLocal(roomId)
.observeOn(io.reactivex.rxjava3.android.schedulers.AndroidSchedulers.mainThread())
.subscribe({ localList ->
if (localList.isNotEmpty() && items.isEmpty()) {
val localItems = localList
.sortedBy { it.createdAt }
.map { msg ->
if (msg.mine) ChatListItem.UserMessage(msg)
else ChatListItem.AiMessage(msg, characterInfo?.name)
}
items.clear()
items.addAll(localItems)
chatAdapter.setItems(items)
scrollToBottom()
}
}, { /* 로컬 로드 실패는 무시하고 서버 로딩 진행 */ })
compositeDisposable.add(localDisposable)
// 2) 서버 통합 API로 동기화 및 UI 갱신
val token = "Bearer ${kr.co.vividnext.sodalive.common.SharedPreferenceManager.token}"
val networkDisposable = chatRepository.enterChatRoom(token = token, roomId = roomId)
.observeOn(io.reactivex.rxjava3.android.schedulers.AndroidSchedulers.mainThread()) .observeOn(io.reactivex.rxjava3.android.schedulers.AndroidSchedulers.mainThread())
.subscribe({ response -> .subscribe({ response ->
// 캐릭터 정보 바인딩 // 캐릭터 정보 바인딩
@@ -406,10 +426,10 @@ class ChatRoomActivity : BaseActivity<ActivityChatRoomBinding>(
) )
}, { error -> }, { error ->
isLoading = false isLoading = false
// 오프라인/실패 시: 로컬 데이터가 이미 표시되어 있으면 그대로 유지
showToast(error.message ?: "채팅방 데이터를 불러오지 못했습니다.") showToast(error.message ?: "채팅방 데이터를 불러오지 못했습니다.")
}) })
compositeDisposable.add(networkDisposable)
compositeDisposable.add(disposable)
} }
// region 5.2 helper methods // region 5.2 helper methods