diff --git a/app/src/main/java/kr/co/vividnext/sodalive/chat/talk/TalkApi.kt b/app/src/main/java/kr/co/vividnext/sodalive/chat/talk/TalkApi.kt index 70b713fa..a3ea6740 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/chat/talk/TalkApi.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/chat/talk/TalkApi.kt @@ -40,7 +40,7 @@ interface TalkApi { @Header("Authorization") authHeader: String, @Path("roomId") roomId: Long, @Body request: SendMessageRequest - ): Single> + ): Single>> // 점진적 메시지 로딩 API @GET("/api/chat/rooms/{roomId}/messages") diff --git a/app/src/main/java/kr/co/vividnext/sodalive/chat/talk/room/ChatRepository.kt b/app/src/main/java/kr/co/vividnext/sodalive/chat/talk/room/ChatRepository.kt index 6c4d0da9..80ae23f8 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/chat/talk/room/ChatRepository.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/chat/talk/room/ChatRepository.kt @@ -30,7 +30,7 @@ class ChatRepository( roomId: Long, localId: String, content: String - ): Single { + ): Single> { return talkApi.sendMessage( authHeader = token, roomId = roomId, @@ -38,18 +38,18 @@ class ChatRepository( ) .subscribeOn(Schedulers.io()) .map { ensureSuccess(it) } - .flatMap { serverMsg -> + .flatMap { serverMsgs -> // 1) 로컬에 사용자 메시지 상태를 SENT로 업데이트 val updateStatus = Completable.fromAction { kotlinx.coroutines.runBlocking { chatDao.updateStatusByLocalId(roomId, localId, MessageStatus.SENT.name) } } - // 2) 서버 응답 메시지를 로컬 DB에 저장(중복 방지: 동일 ID는 REPLACE) - val insertServer = Completable.fromAction { - val entity = serverMsg.toEntity(roomId) - kotlinx.coroutines.runBlocking { chatDao.insertMessage(entity) } + // 2) 서버 응답 메시지들을 로컬 DB에 저장(중복 방지: 동일 ID는 REPLACE) + val insertServers = Completable.fromAction { + val entities = serverMsgs.map { it.toEntity(roomId) } + kotlinx.coroutines.runBlocking { chatDao.insertMessages(entities) } } - updateStatus.andThen(insertServer) - .andThen(Single.just(serverMsg)) + updateStatus.andThen(insertServers) + .andThen(Single.just(serverMsgs)) .subscribeOn(Schedulers.io()) } } 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 1d8214b4..0c07d066 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 @@ -285,15 +285,17 @@ class ChatRoomActivity : BaseActivity( content = content ) .observeOn(io.reactivex.rxjava3.android.schedulers.AndroidSchedulers.mainThread()) - .subscribe({ serverMsg -> + .subscribe({ serverMsgs -> // 성공: 타이핑 인디케이터 제거 및 상태 업데이트 chatAdapter.hideTypingIndicator() updateUserMessageStatus(localId, MessageStatus.SENT) - // 서버 응답이 AI 메시지인 경우 리스트에 추가 - val domain = serverMsg.toDomain() - if (!domain.mine) { - appendMessage(ChatListItem.AiMessage(domain, characterInfo?.name)) + // 서버 응답이 여러 개인 경우, mine == false(AI)만 순서대로 추가 + serverMsgs.forEach { msg -> + val domain = msg.toDomain() + if (!domain.mine) { + appendMessage(ChatListItem.AiMessage(domain, characterInfo?.name)) + } } }, { error -> // 실패: 타이핑 인디케이터 제거 및 FAILED로 업데이트