From b9977527b238aaebabcb7dcae7e0b6d2cd916602 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Tue, 4 Mar 2025 09:23:33 +0600 Subject: [PATCH] rework InfinityPagedComponent --- .../kotlin/InfinityPagedComponent.kt | 39 +++++++++---------- .../kotlin/InfinityPagedComponentTests.kt | 4 +- 2 files changed, 19 insertions(+), 24 deletions(-) diff --git a/pagination/compose/src/commonMain/kotlin/InfinityPagedComponent.kt b/pagination/compose/src/commonMain/kotlin/InfinityPagedComponent.kt index 6ac79e351a2..377fe15a6c2 100644 --- a/pagination/compose/src/commonMain/kotlin/InfinityPagedComponent.kt +++ b/pagination/compose/src/commonMain/kotlin/InfinityPagedComponent.kt @@ -1,6 +1,7 @@ package dev.inmo.micro_utils.pagination.compose import androidx.compose.runtime.* +import dev.inmo.micro_utils.coroutines.SpecialMutableStateFlow import dev.inmo.micro_utils.pagination.* /** @@ -18,32 +19,27 @@ class InfinityPagedComponentContext internal constructor( size: Int ) { internal val startPage = SimplePagination(page, size) - internal val iterationState: MutableState = mutableStateOf(null) - internal val dataState: MutableState?> = mutableStateOf(null) - internal var lastPageLoaded = false + internal val currentlyLoadingPage = SpecialMutableStateFlow(startPage) + internal val latestLoadedPage = SpecialMutableStateFlow?>(null) + internal val dataState = SpecialMutableStateFlow?>(null) /** * Loads the next page of data. If the current page is the last one, the function returns early. */ fun loadNext() { - if (lastPageLoaded) return - if (iterationState.value is SimplePagination) return // Data loading has been inited but not loaded yet + if (latestLoadedPage.value ?.isLastPage == true) return + if (currentlyLoadingPage.value != null) return // Data loading has been inited but not loaded yet - iterationState.value = iterationState.value.let { - if ((it as? PaginationResult<*>) ?.isLastPage == true) return - (it ?: startPage).nextPage() - } + currentlyLoadingPage.value = latestLoadedPage.value ?.nextPage() ?: startPage } /** * Reloads the pagination from the first page, clearing previously loaded data. */ fun reload() { - dataState.value = null - lastPageLoaded = false - iterationState.value = iterationState.value.let { - null - } + latestLoadedPage.value = null + currentlyLoadingPage.value = null + loadNext() } } @@ -66,16 +62,17 @@ internal fun InfinityPagedComponent( ) { val context = remember { InfinityPagedComponentContext(page, size) } - LaunchedEffect(context.iterationState.value ?.page) { - val paginationResult = loader(context, context.iterationState.value ?: context.startPage) - if (paginationResult.isLastPage) { - context.lastPageLoaded = true - } - context.iterationState.value = paginationResult + val currentlyLoadingState = context.currentlyLoadingPage.collectAsState() + LaunchedEffect(currentlyLoadingState.value) { + val paginationResult = loader(context, currentlyLoadingState.value ?: return@LaunchedEffect) + context.latestLoadedPage.value = paginationResult + context.currentlyLoadingPage.value = null + context.dataState.value = (context.dataState.value ?: emptyList()) + paginationResult.results } - context.block(context.dataState.value) + val dataState = context.dataState.collectAsState() + context.block(dataState.value) } /** diff --git a/pagination/compose/src/jvmTest/kotlin/InfinityPagedComponentTests.kt b/pagination/compose/src/jvmTest/kotlin/InfinityPagedComponentTests.kt index 62600116fdb..daabfeca6ac 100644 --- a/pagination/compose/src/jvmTest/kotlin/InfinityPagedComponentTests.kt +++ b/pagination/compose/src/jvmTest/kotlin/InfinityPagedComponentTests.kt @@ -30,9 +30,7 @@ class InfinityPagedComponentTests { } ) { if (it == null) { - if (this.iterationState.value != null) { - assertEquals(0, (this.iterationState.value as? SimplePagination) ?.page) - } + assertEquals(0, this.currentlyLoadingPage.value ?.page) } else { assertEquals(expectedList, it) }