package dev.inmo.micro_utils.pagination.compose import androidx.compose.runtime.* import dev.inmo.micro_utils.common.Optional import dev.inmo.micro_utils.common.dataOrThrow import dev.inmo.micro_utils.common.optional import dev.inmo.micro_utils.pagination.* class PagedComponentContext internal constructor( preset: PaginationResult? = null, initialPage: Int, size: Int ) { internal val iterationState: MutableState> = mutableStateOf(0 to SimplePagination(preset ?.page ?: initialPage, preset ?.size ?: size)) internal var dataOptional: PaginationResult? = preset private set internal val dataState: MutableState?> = mutableStateOf(dataOptional) fun loadNext() { iterationState.value = iterationState.value.let { if (dataState.value ?.isLastPage == true) return (it.first + 1) to it.second.nextPage() } } fun loadPrevious() { iterationState.value = iterationState.value.let { if (it.second.isFirstPage) return (it.first - 1) to SimplePagination( it.second.page - 1, it.second.size ) } } fun reload() { iterationState.value = iterationState.value.let { it.copy(it.first + 1) } } } @Composable internal fun PagedComponent( preload: PaginationResult?, initialPage: Int, size: Int, loader: suspend PagedComponentContext.(Pagination) -> PaginationResult, block: @Composable PagedComponentContext.(PaginationResult) -> Unit ) { val context = remember { PagedComponentContext(preload, initialPage, size) } LaunchedEffect(context.iterationState.value) { context.dataState.value = loader(context, context.iterationState.value.second) } context.dataState.value ?.let { context.block(it) } } @Composable fun PagedComponent( preload: PaginationResult, loader: suspend PagedComponentContext.(Pagination) -> PaginationResult, block: @Composable PagedComponentContext.(PaginationResult) -> Unit ) { PagedComponent( preload, preload.page, preload.size, loader, block ) } @Composable fun PagedComponent( pageInfo: Pagination, loader: suspend PagedComponentContext.(Pagination) -> PaginationResult, block: @Composable PagedComponentContext.(PaginationResult) -> Unit ) { PagedComponent( null, pageInfo.page, pageInfo.size, loader, block ) } @Composable fun PagedComponent( initialPage: Int, size: Int, loader: suspend PagedComponentContext.(Pagination) -> PaginationResult, block: @Composable PagedComponentContext.(PaginationResult) -> Unit ) { PagedComponent(null, initialPage, size, loader, block) } @Composable fun PagedComponent( size: Int, loader: suspend PagedComponentContext.(Pagination) -> PaginationResult, block: @Composable PagedComponentContext.(PaginationResult) -> Unit ) { PagedComponent(0, size, loader, block) }