rework InfinityPagedComponent

This commit is contained in:
2025-03-04 09:23:33 +06:00
parent c216dba69d
commit b9977527b2
2 changed files with 19 additions and 24 deletions

View File

@@ -1,6 +1,7 @@
package dev.inmo.micro_utils.pagination.compose package dev.inmo.micro_utils.pagination.compose
import androidx.compose.runtime.* import androidx.compose.runtime.*
import dev.inmo.micro_utils.coroutines.SpecialMutableStateFlow
import dev.inmo.micro_utils.pagination.* import dev.inmo.micro_utils.pagination.*
/** /**
@@ -18,32 +19,27 @@ class InfinityPagedComponentContext<T> internal constructor(
size: Int size: Int
) { ) {
internal val startPage = SimplePagination(page, size) internal val startPage = SimplePagination(page, size)
internal val iterationState: MutableState<Pagination?> = mutableStateOf(null) internal val currentlyLoadingPage = SpecialMutableStateFlow<Pagination?>(startPage)
internal val dataState: MutableState<List<T>?> = mutableStateOf(null) internal val latestLoadedPage = SpecialMutableStateFlow<PaginationResult<T>?>(null)
internal var lastPageLoaded = false internal val dataState = SpecialMutableStateFlow<List<T>?>(null)
/** /**
* Loads the next page of data. If the current page is the last one, the function returns early. * Loads the next page of data. If the current page is the last one, the function returns early.
*/ */
fun loadNext() { fun loadNext() {
if (lastPageLoaded) return if (latestLoadedPage.value ?.isLastPage == true) return
if (iterationState.value is SimplePagination) return // Data loading has been inited but not loaded yet if (currentlyLoadingPage.value != null) return // Data loading has been inited but not loaded yet
iterationState.value = iterationState.value.let { currentlyLoadingPage.value = latestLoadedPage.value ?.nextPage() ?: startPage
if ((it as? PaginationResult<*>) ?.isLastPage == true) return
(it ?: startPage).nextPage()
}
} }
/** /**
* Reloads the pagination from the first page, clearing previously loaded data. * Reloads the pagination from the first page, clearing previously loaded data.
*/ */
fun reload() { fun reload() {
dataState.value = null latestLoadedPage.value = null
lastPageLoaded = false currentlyLoadingPage.value = null
iterationState.value = iterationState.value.let { loadNext()
null
}
} }
} }
@@ -66,16 +62,17 @@ internal fun <T> InfinityPagedComponent(
) { ) {
val context = remember { InfinityPagedComponentContext<T>(page, size) } val context = remember { InfinityPagedComponentContext<T>(page, size) }
LaunchedEffect(context.iterationState.value ?.page) { val currentlyLoadingState = context.currentlyLoadingPage.collectAsState()
val paginationResult = loader(context, context.iterationState.value ?: context.startPage) LaunchedEffect(currentlyLoadingState.value) {
if (paginationResult.isLastPage) { val paginationResult = loader(context, currentlyLoadingState.value ?: return@LaunchedEffect)
context.lastPageLoaded = true context.latestLoadedPage.value = paginationResult
} context.currentlyLoadingPage.value = null
context.iterationState.value = paginationResult
context.dataState.value = (context.dataState.value ?: emptyList()) + paginationResult.results context.dataState.value = (context.dataState.value ?: emptyList()) + paginationResult.results
} }
context.block(context.dataState.value) val dataState = context.dataState.collectAsState()
context.block(dataState.value)
} }
/** /**

View File

@@ -30,9 +30,7 @@ class InfinityPagedComponentTests {
} }
) { ) {
if (it == null) { if (it == null) {
if (this.iterationState.value != null) { assertEquals(0, this.currentlyLoadingPage.value ?.page)
assertEquals(0, (this.iterationState.value as? SimplePagination) ?.page)
}
} else { } else {
assertEquals(expectedList, it) assertEquals(expectedList, it)
} }