fix(chat): 대화 초기화 성공 시 로컬 데이터 삭제 및 로딩 다이얼로그 적용
- ChatMessageDao: deleteMessagesByRoomId(roomId) 추가 - ChatRepository: clearMessagesByRoom(roomId) 추가 - ChatRoomActivity: - clearLocalPrefsForRoom(roomId) 구현 - reset 플로우에 Prefs/DB 삭제 체인 연결 - onResetChatRequested()에서 LoadingDialog 표시 및 doFinally로 닫힘 보장
This commit is contained in:
@@ -4,6 +4,7 @@ import io.reactivex.rxjava3.core.Single
|
||||
import kr.co.vividnext.sodalive.chat.talk.room.ChatMessagePurchaseRequest
|
||||
import kr.co.vividnext.sodalive.chat.talk.room.ChatMessagesResponse
|
||||
import kr.co.vividnext.sodalive.chat.talk.room.ChatRoomEnterResponse
|
||||
import kr.co.vividnext.sodalive.chat.talk.room.ChatRoomResetRequest
|
||||
import kr.co.vividnext.sodalive.chat.talk.room.CreateChatRoomRequest
|
||||
import kr.co.vividnext.sodalive.chat.talk.room.CreateChatRoomResponse
|
||||
import kr.co.vividnext.sodalive.chat.talk.room.SendChatMessageResponse
|
||||
@@ -35,7 +36,8 @@ interface TalkApi {
|
||||
@POST("/api/chat/room/{roomId}/reset")
|
||||
fun resetChatRoom(
|
||||
@Header("Authorization") authHeader: String,
|
||||
@Path("roomId") roomId: Long
|
||||
@Path("roomId") roomId: Long,
|
||||
@Body request: ChatRoomResetRequest
|
||||
): Single<ApiResponse<CreateChatRoomResponse>>
|
||||
|
||||
// 통합 채팅방 입장 API
|
||||
|
||||
@@ -43,7 +43,13 @@ class ChatRepository(
|
||||
.flatMap { response ->
|
||||
// 1) 로컬에 사용자 메시지 상태를 SENT로 업데이트
|
||||
val updateStatus = Completable.fromAction {
|
||||
kotlinx.coroutines.runBlocking { chatDao.updateStatusByLocalId(roomId, localId, MessageStatus.SENT.name) }
|
||||
kotlinx.coroutines.runBlocking {
|
||||
chatDao.updateStatusByLocalId(
|
||||
roomId,
|
||||
localId,
|
||||
MessageStatus.SENT.name
|
||||
)
|
||||
}
|
||||
}
|
||||
// 2) 서버 응답 메시지들을 로컬 DB에 저장(중복 방지: 동일 ID는 REPLACE)
|
||||
val insertServers = Completable.fromAction {
|
||||
@@ -86,8 +92,16 @@ class ChatRepository(
|
||||
* 통합 채팅방 입장: 서버 캐릭터 정보 + 최신 메시지 수신 후 로컬 DB 업데이트
|
||||
* - 로컬 데이터가 없더라도 서버 응답을 기준으로 동기화
|
||||
*/
|
||||
fun enterChatRoom(token: String, roomId: Long, characterImageId: Long?): Single<ChatRoomEnterResponse> {
|
||||
return talkApi.enterChatRoom(authHeader = token, roomId = roomId, characterImageId = characterImageId)
|
||||
fun enterChatRoom(
|
||||
token: String,
|
||||
roomId: Long,
|
||||
characterImageId: Long?
|
||||
): Single<ChatRoomEnterResponse> {
|
||||
return talkApi.enterChatRoom(
|
||||
authHeader = token,
|
||||
roomId = roomId,
|
||||
characterImageId = characterImageId
|
||||
)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.flatMap { response ->
|
||||
val data = ensureSuccess(response)
|
||||
@@ -106,7 +120,12 @@ class ChatRepository(
|
||||
* 점진적 메시지 로딩: 커서 기반으로 이전 메시지를 조회
|
||||
*/
|
||||
fun loadMoreMessages(token: String, roomId: Long, cursor: Long?): Single<ChatMessagesResponse> {
|
||||
return talkApi.getChatRoomMessages(authHeader = token, roomId = roomId, cursor = cursor, limit = 20)
|
||||
return talkApi.getChatRoomMessages(
|
||||
authHeader = token,
|
||||
roomId = roomId,
|
||||
cursor = cursor,
|
||||
limit = 20
|
||||
)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.flatMap { response ->
|
||||
val data = ensureMessagesSuccess(response)
|
||||
@@ -132,10 +151,20 @@ class ChatRepository(
|
||||
/**
|
||||
* localId 기반 상태 업데이트(SENDING→SENT/FAILED)
|
||||
*/
|
||||
fun updateMessageStatusByLocalId(roomId: Long, localId: String, newStatus: MessageStatus): Completable {
|
||||
fun updateMessageStatusByLocalId(
|
||||
roomId: Long,
|
||||
localId: String,
|
||||
newStatus: MessageStatus
|
||||
): Completable {
|
||||
return Completable.fromAction {
|
||||
// enum을 문자열로 변환하여 쿼리 파라미터로 전달
|
||||
kotlinx.coroutines.runBlocking { chatDao.updateStatusByLocalId(roomId, localId, newStatus.name) }
|
||||
kotlinx.coroutines.runBlocking {
|
||||
chatDao.updateStatusByLocalId(
|
||||
roomId,
|
||||
localId,
|
||||
newStatus.name
|
||||
)
|
||||
}
|
||||
}.subscribeOn(Schedulers.io())
|
||||
}
|
||||
|
||||
@@ -206,7 +235,11 @@ class ChatRepository(
|
||||
* 대화 초기화: 서버에 리셋 요청 → 새 채팅방 ID 반환
|
||||
*/
|
||||
fun resetChatRoom(token: String, roomId: Long): Single<CreateChatRoomResponse> {
|
||||
return talkApi.resetChatRoom(authHeader = token, roomId = roomId)
|
||||
return talkApi.resetChatRoom(
|
||||
authHeader = token,
|
||||
roomId = roomId,
|
||||
request = ChatRoomResetRequest()
|
||||
)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.map { ensureSuccess(it) }
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import kr.co.vividnext.sodalive.R
|
||||
import kr.co.vividnext.sodalive.base.BaseActivity
|
||||
import kr.co.vividnext.sodalive.base.SodaDialog
|
||||
import kr.co.vividnext.sodalive.chat.character.detail.detail.CharacterType
|
||||
import kr.co.vividnext.sodalive.common.LoadingDialog
|
||||
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
||||
import kr.co.vividnext.sodalive.databinding.ActivityChatRoomBinding
|
||||
import kr.co.vividnext.sodalive.extensions.dpToPx
|
||||
@@ -890,6 +891,12 @@ class ChatRoomActivity : BaseActivity<ActivityChatRoomBinding>(
|
||||
desc = desc,
|
||||
confirmButtonTitle = "초기화",
|
||||
confirmButtonClick = {
|
||||
val loadingDialog = LoadingDialog(this, layoutInflater)
|
||||
loadingDialog.show(
|
||||
screenWidth,
|
||||
"대화 초기화 중..."
|
||||
)
|
||||
|
||||
val token = "Bearer ${SharedPreferenceManager.token}"
|
||||
val disposable = chatRepository.resetChatRoom(token = token, roomId = roomId)
|
||||
.flatMap { response ->
|
||||
@@ -899,6 +906,7 @@ class ChatRoomActivity : BaseActivity<ActivityChatRoomBinding>(
|
||||
.andThen(io.reactivex.rxjava3.core.Single.just(response))
|
||||
}
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.doFinally { loadingDialog.dismiss() }
|
||||
.subscribe({ response ->
|
||||
val intent = newIntent(this, response.chatRoomId)
|
||||
startActivity(intent)
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
package kr.co.vividnext.sodalive.chat.talk.room
|
||||
|
||||
import androidx.annotation.Keep
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
@Keep
|
||||
data class ChatRoomResetRequest(
|
||||
@SerializedName("container") val container: String = "aos"
|
||||
)
|
||||
Reference in New Issue
Block a user