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 b03359d7..1d53ef75 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 @@ -366,11 +366,31 @@ class ChatRoomActivity : BaseActivity( // endregion 6.2 Send flow private fun loadInitialMessages() { - // 7.1 초기 데이터 로딩 구현: 통합 API 호출 + 로컬 동기화 결과를 UI에 반영 + // 7.1 보완: 로컬 우선 표시 + 서버 동기화 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()) .subscribe({ response -> // 캐릭터 정보 바인딩 @@ -406,10 +426,10 @@ class ChatRoomActivity : BaseActivity( ) }, { error -> isLoading = false + // 오프라인/실패 시: 로컬 데이터가 이미 표시되어 있으면 그대로 유지 showToast(error.message ?: "채팅방 데이터를 불러오지 못했습니다.") }) - - compositeDisposable.add(disposable) + compositeDisposable.add(networkDisposable) } // region 5.2 helper methods