feat(chat-room): sendMessage 응답 다건 변경 반영
- TalkApi.sendMessage: ApiResponse<List<ServerChatMessage>>로 변경 - ChatRepository.sendMessage: Single<List<ServerChatMessage>>로 변경. 로컬 SENDING→SENT 업데이트 후, 응답 메시지 전체를 DB에 저장 - ChatRoomActivity: 구독부에서 List를 처리하며 mine == false(AI) 메시지들만 순서대로 append. 타이핑 인디케이터는 성공/실패 시 동일하게 제거
This commit is contained in:
		@@ -40,7 +40,7 @@ interface TalkApi {
 | 
			
		||||
        @Header("Authorization") authHeader: String,
 | 
			
		||||
        @Path("roomId") roomId: Long,
 | 
			
		||||
        @Body request: SendMessageRequest
 | 
			
		||||
    ): Single<ApiResponse<ServerChatMessage>>
 | 
			
		||||
    ): Single<ApiResponse<List<ServerChatMessage>>>
 | 
			
		||||
 | 
			
		||||
    // 점진적 메시지 로딩 API
 | 
			
		||||
    @GET("/api/chat/rooms/{roomId}/messages")
 | 
			
		||||
 
 | 
			
		||||
@@ -30,7 +30,7 @@ class ChatRepository(
 | 
			
		||||
        roomId: Long,
 | 
			
		||||
        localId: String,
 | 
			
		||||
        content: String
 | 
			
		||||
    ): Single<ServerChatMessage> {
 | 
			
		||||
    ): Single<List<ServerChatMessage>> {
 | 
			
		||||
        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())
 | 
			
		||||
            }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -285,16 +285,18 @@ class ChatRoomActivity : BaseActivity<ActivityChatRoomBinding>(
 | 
			
		||||
            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()
 | 
			
		||||
                // 서버 응답이 여러 개인 경우, mine == false(AI)만 순서대로 추가
 | 
			
		||||
                serverMsgs.forEach { msg ->
 | 
			
		||||
                    val domain = msg.toDomain()
 | 
			
		||||
                    if (!domain.mine) {
 | 
			
		||||
                        appendMessage(ChatListItem.AiMessage(domain, characterInfo?.name))
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }, { error ->
 | 
			
		||||
                // 실패: 타이핑 인디케이터 제거 및 FAILED로 업데이트
 | 
			
		||||
                chatAdapter.hideTypingIndicator()
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user