fix(creator): 라이브 더보기 상태 보존을 보정한다
This commit is contained in:
@@ -58,8 +58,11 @@ class CreatorChannelLiveViewModel(
|
|||||||
val data = response.data
|
val data = response.data
|
||||||
val current = _liveStateLiveData.value as? CreatorChannelLiveUiState.Content ?: content
|
val current = _liveStateLiveData.value as? CreatorChannelLiveUiState.Content ?: content
|
||||||
if (response.success && data != null) {
|
if (response.success && data != null) {
|
||||||
_liveStateLiveData.value = data.toContentState(
|
_liveStateLiveData.value = current.copy(
|
||||||
liveReplayContents = current.liveReplayContents + data.liveReplayContents,
|
liveReplayContents = current.liveReplayContents + data.liveReplayContents,
|
||||||
|
page = data.page,
|
||||||
|
size = data.size,
|
||||||
|
hasNext = data.hasNext,
|
||||||
isLoadingMore = false
|
isLoadingMore = false
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
@@ -71,6 +74,13 @@ class CreatorChannelLiveViewModel(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun consumePaginationErrorMessage() {
|
||||||
|
val content = _liveStateLiveData.value as? CreatorChannelLiveUiState.Content ?: return
|
||||||
|
if (content.paginationErrorMessage == null) return
|
||||||
|
|
||||||
|
_liveStateLiveData.value = content.copy(paginationErrorMessage = null)
|
||||||
|
}
|
||||||
|
|
||||||
private fun loadFirstPage(sort: ContentSort) {
|
private fun loadFirstPage(sort: ContentSort) {
|
||||||
val generation = ++requestGeneration
|
val generation = ++requestGeneration
|
||||||
_liveStateLiveData.value = CreatorChannelLiveUiState.Loading
|
_liveStateLiveData.value = CreatorChannelLiveUiState.Loading
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import kr.co.vividnext.sodalive.common.ApiResponse
|
|||||||
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
||||||
import kr.co.vividnext.sodalive.v2.common.data.ContentSort
|
import kr.co.vividnext.sodalive.v2.common.data.ContentSort
|
||||||
import kr.co.vividnext.sodalive.v2.creator.channel.data.CreatorChannelAudioContentResponse
|
import kr.co.vividnext.sodalive.v2.creator.channel.data.CreatorChannelAudioContentResponse
|
||||||
|
import kr.co.vividnext.sodalive.v2.creator.channel.data.CreatorChannelLiveResponse
|
||||||
import kr.co.vividnext.sodalive.v2.creator.channel.data.CreatorChannelRepository
|
import kr.co.vividnext.sodalive.v2.creator.channel.data.CreatorChannelRepository
|
||||||
import kr.co.vividnext.sodalive.v2.creator.channel.live.data.CreatorChannelLiveTabResponse
|
import kr.co.vividnext.sodalive.v2.creator.channel.live.data.CreatorChannelLiveTabResponse
|
||||||
import org.junit.After
|
import org.junit.After
|
||||||
@@ -76,6 +77,62 @@ class CreatorChannelLivePaginationTest {
|
|||||||
verifyGetLive(page = 1)
|
verifyGetLive(page = 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `다음 페이지 성공은 첫 페이지 현재 라이브 count sort를 보존하고 page와 hasNext만 갱신한다`() {
|
||||||
|
val currentLive = CreatorChannelLiveResponse(
|
||||||
|
liveId = 10L,
|
||||||
|
title = "현재 라이브",
|
||||||
|
coverImageUrl = null,
|
||||||
|
beginDateTimeUtc = "2026-06-17T01:00:00Z",
|
||||||
|
price = 100,
|
||||||
|
isAdult = false
|
||||||
|
)
|
||||||
|
stubGetLive(
|
||||||
|
page = 0,
|
||||||
|
response = Single.just(
|
||||||
|
ApiResponse(
|
||||||
|
true,
|
||||||
|
liveResponse(
|
||||||
|
page = 0,
|
||||||
|
ids = listOf(1L),
|
||||||
|
hasNext = true,
|
||||||
|
liveReplayContentCount = 99,
|
||||||
|
currentLive = currentLive
|
||||||
|
),
|
||||||
|
null
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
stubGetLive(
|
||||||
|
page = 1,
|
||||||
|
response = Single.just(
|
||||||
|
ApiResponse(
|
||||||
|
true,
|
||||||
|
liveResponse(
|
||||||
|
page = 1,
|
||||||
|
sort = ContentSort.POPULAR,
|
||||||
|
ids = listOf(2L),
|
||||||
|
hasNext = false,
|
||||||
|
liveReplayContentCount = 1,
|
||||||
|
currentLive = null
|
||||||
|
),
|
||||||
|
null
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
viewModel.loadLive(100L)
|
||||||
|
|
||||||
|
viewModel.loadMore()
|
||||||
|
|
||||||
|
val state = viewModel.liveStateLiveData.requireValue() as CreatorChannelLiveUiState.Content
|
||||||
|
assertEquals(currentLive, state.currentLive)
|
||||||
|
assertEquals(99, state.liveReplayContentCount)
|
||||||
|
assertEquals(ContentSort.LATEST, state.selectedSort)
|
||||||
|
assertEquals(1, state.page)
|
||||||
|
assertEquals(listOf(1L, 2L), state.liveReplayContents.map { it.audioContentId })
|
||||||
|
assertFalse(state.hasNext)
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `다음 페이지 로딩 중 중복 load-more 요청은 막는다`() {
|
fun `다음 페이지 로딩 중 중복 load-more 요청은 막는다`() {
|
||||||
val pending = SingleSubject.create<ApiResponse<CreatorChannelLiveTabResponse>>()
|
val pending = SingleSubject.create<ApiResponse<CreatorChannelLiveTabResponse>>()
|
||||||
@@ -114,6 +171,27 @@ class CreatorChannelLivePaginationTest {
|
|||||||
assertEquals("failed", state.paginationErrorMessage)
|
assertEquals("failed", state.paginationErrorMessage)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `pagination error message는 표시 후 clear되어 다시 표시되지 않는다`() {
|
||||||
|
stubGetLive(
|
||||||
|
page = 0,
|
||||||
|
response = Single.just(ApiResponse(true, liveResponse(page = 0, ids = listOf(1L), hasNext = true), null))
|
||||||
|
)
|
||||||
|
stubGetLive(page = 1, response = Single.just(ApiResponse(false, null, "failed")))
|
||||||
|
viewModel.loadLive(100L)
|
||||||
|
viewModel.loadMore()
|
||||||
|
|
||||||
|
val state = viewModel.liveStateLiveData.requireValue() as CreatorChannelLiveUiState.Content
|
||||||
|
|
||||||
|
assertEquals("failed", state.paginationErrorMessage)
|
||||||
|
|
||||||
|
viewModel.consumePaginationErrorMessage()
|
||||||
|
|
||||||
|
val consumedState = viewModel.liveStateLiveData.requireValue() as CreatorChannelLiveUiState.Content
|
||||||
|
assertEquals(null, consumedState.paginationErrorMessage)
|
||||||
|
assertEquals(listOf(1L), consumedState.liveReplayContents.map { it.audioContentId })
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `이전 load-more 응답은 이후 정렬 변경 목록에 append되지 않는다`() {
|
fun `이전 load-more 응답은 이후 정렬 변경 목록에 append되지 않는다`() {
|
||||||
val nextPagePending = SingleSubject.create<ApiResponse<CreatorChannelLiveTabResponse>>()
|
val nextPagePending = SingleSubject.create<ApiResponse<CreatorChannelLiveTabResponse>>()
|
||||||
@@ -186,10 +264,12 @@ class CreatorChannelLivePaginationTest {
|
|||||||
page: Int,
|
page: Int,
|
||||||
sort: ContentSort = ContentSort.LATEST,
|
sort: ContentSort = ContentSort.LATEST,
|
||||||
ids: List<Long>,
|
ids: List<Long>,
|
||||||
hasNext: Boolean
|
hasNext: Boolean,
|
||||||
|
liveReplayContentCount: Int = ids.size,
|
||||||
|
currentLive: CreatorChannelLiveResponse? = null
|
||||||
) = CreatorChannelLiveTabResponse(
|
) = CreatorChannelLiveTabResponse(
|
||||||
liveReplayContentCount = ids.size,
|
liveReplayContentCount = liveReplayContentCount,
|
||||||
currentLive = null,
|
currentLive = currentLive,
|
||||||
liveReplayContents = ids.map { audioContent(it) },
|
liveReplayContents = ids.map { audioContent(it) },
|
||||||
sort = sort,
|
sort = sort,
|
||||||
page = page,
|
page = page,
|
||||||
|
|||||||
Reference in New Issue
Block a user