fix(live-room): 종료 경합의 중복 재조회와 오류 토스트를 막는다

This commit is contained in:
2026-04-13 13:41:17 +09:00
parent c5411899bc
commit 9654c41fb9
7 changed files with 215 additions and 5 deletions

View File

@@ -170,6 +170,7 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
private var isSpeakerMute = false
private var isMicrophoneMute = false
private var isSpeaker = false
private var hasKnownHostAbsence = false
private var isCapturePrivacyMuted = false
private var isScreenRecordingActive = false
@@ -2304,13 +2305,26 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
override fun onUserOffline(uid: Int, reason: Int) {
super.onUserOffline(uid, reason)
Logger.e("onUserOffline - uid: $uid")
if (viewModel.isEqualToHostId(uid)) {
val offlineAction = resolveLiveRoomOfflineAction(
isHostOffline = viewModel.isEqualToHostId(uid),
hasKnownHostAbsence = hasKnownHostAbsence
)
if (offlineAction.shouldMarkHostAbsence) {
hasKnownHostAbsence = true
}
if (offlineAction.shouldFinishRoom) {
handler.post {
showToast(getString(R.string.screen_live_room_closed))
finish()
}
} else {
viewModel.getRoomInfo(roomId)
return
}
if (offlineAction.shouldRefreshRoomInfo) {
viewModel.getRoomInfo(roomId, suppressRoomNotFoundError = true)
speakerListAdapter.muteSpeakers.remove(uid)
}
}
@@ -2669,7 +2683,7 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
}
} else if (eventType == RtmConstants.RtmPresenceEventType.REMOTE_LEAVE) {
if (!viewModel.isEqualToHostId(memberId.toInt())) {
viewModel.getRoomInfo(roomId)
viewModel.getRoomInfo(roomId, suppressRoomNotFoundError = true)
}
}
}

View File

@@ -0,0 +1,34 @@
package kr.co.vividnext.sodalive.live.room
internal data class LiveRoomOfflineAction(
val shouldMarkHostAbsence: Boolean,
val shouldFinishRoom: Boolean,
val shouldRefreshRoomInfo: Boolean
)
internal fun resolveLiveRoomOfflineAction(
isHostOffline: Boolean,
hasKnownHostAbsence: Boolean
): LiveRoomOfflineAction {
if (hasKnownHostAbsence) {
return LiveRoomOfflineAction(
shouldMarkHostAbsence = false,
shouldFinishRoom = false,
shouldRefreshRoomInfo = false
)
}
if (isHostOffline) {
return LiveRoomOfflineAction(
shouldMarkHostAbsence = true,
shouldFinishRoom = true,
shouldRefreshRoomInfo = false
)
}
return LiveRoomOfflineAction(
shouldMarkHostAbsence = false,
shouldFinishRoom = false,
shouldRefreshRoomInfo = true
)
}

View File

@@ -0,0 +1,24 @@
package kr.co.vividnext.sodalive.live.room
private val ignorableLiveRoomNotFoundMessages = setOf(
"라이브 정보가 없습니다.",
"해당하는 라이브의 정보가 없습니다.",
"Live session information not found.",
"該当するライブの情報がありません。"
)
internal fun shouldSuppressLiveRoomInfoError(
message: String?,
suppressRoomNotFoundError: Boolean
): Boolean {
if (!suppressRoomNotFoundError) {
return false
}
val normalizedMessage = message?.trim().orEmpty()
if (normalizedMessage.isBlank()) {
return false
}
return normalizedMessage in ignorableLiveRoomNotFoundMessages
}

View File

@@ -232,7 +232,12 @@ class LiveRoomViewModel(
)
}
fun getRoomInfo(roomId: Long, userId: Int = 0, onSuccess: (String) -> Unit = {}) {
fun getRoomInfo(
roomId: Long,
userId: Int = 0,
suppressRoomNotFoundError: Boolean = false,
onSuccess: (String) -> Unit = {}
) {
compositeDisposable.add(
repository.getRoomInfo(roomId, "Bearer ${SharedPreferenceManager.token}")
.subscribeOn(Schedulers.io())
@@ -266,6 +271,10 @@ class LiveRoomViewModel(
onSuccess(nickname)
}
} else {
if (shouldSuppressLiveRoomInfoError(it.message, suppressRoomNotFoundError)) {
return@subscribe
}
if (it.message != null) {
_toastLiveData.postValue(it.message)
} else {