-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
85f1143
commit ea527b5
Showing
6 changed files
with
304 additions
and
0 deletions.
There are no files selected for viewing
74 changes: 74 additions & 0 deletions
74
...on/compose/src/commonMain/kotlin/dev/inmo/micro_utils/common/compose/LoadableComponent.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
package dev.inmo.micro_utils.common.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 | ||
|
||
class LoadableComponentContext<T> internal constructor( | ||
presetOptional: Optional<T>, | ||
) { | ||
internal val iterationState: MutableState<Int> = mutableStateOf(0) | ||
|
||
internal var dataOptional: Optional<T> = if (presetOptional.dataPresented) presetOptional else Optional.absent() | ||
private set | ||
internal val dataState: MutableState<Optional<T>> = mutableStateOf(dataOptional) | ||
|
||
fun reload() { | ||
iterationState.value++ | ||
} | ||
} | ||
|
||
/** | ||
* Showing data with ability to reload data | ||
* | ||
* [block] will be shown when [loader] will complete loading. If you want to reload data, just call | ||
* [LoadableComponentContext.reload] | ||
*/ | ||
@Composable | ||
fun <T> LoadableComponent( | ||
preload: Optional<T>, | ||
loader: suspend LoadableComponentContext<T>.() -> T, | ||
block: @Composable LoadableComponentContext<T>.(T) -> Unit | ||
) { | ||
val context = remember { LoadableComponentContext(preload) } | ||
|
||
LaunchedEffect(context.iterationState.value) { | ||
context.dataState.value = loader(context).optional | ||
} | ||
|
||
context.dataState.let { | ||
if (it.value.dataPresented) { | ||
context.block(it.value.dataOrThrow(IllegalStateException("Data must be presented, but optional has been changed by some way"))) | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Showing data with ability to reload data | ||
* | ||
* [block] will be shown when [loader] will complete loading. If you want to reload data, just call | ||
* [LoadableComponentContext.reload] | ||
*/ | ||
@Composable | ||
fun <T> LoadableComponent( | ||
preload: T, | ||
loader: suspend LoadableComponentContext<T>.() -> T, | ||
block: @Composable LoadableComponentContext<T>.(T) -> Unit | ||
) { | ||
LoadableComponent(preload.optional, loader, block) | ||
} | ||
|
||
/** | ||
* Showing data with ability to reload data | ||
* | ||
* [block] will be shown when [loader] will complete loading. If you want to reload data, just call | ||
* [LoadableComponentContext.reload] | ||
*/ | ||
@Composable | ||
fun <T> LoadableComponent( | ||
loader: suspend LoadableComponentContext<T>.() -> T, | ||
block: @Composable LoadableComponentContext<T>.(T) -> Unit | ||
) { | ||
LoadableComponent(Optional.absent(), loader, block) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
plugins { | ||
id "org.jetbrains.kotlin.multiplatform" | ||
id "org.jetbrains.kotlin.plugin.serialization" | ||
id "com.android.library" | ||
alias(libs.plugins.jb.compose) | ||
alias(libs.plugins.kt.jb.compose) | ||
} | ||
|
||
apply from: "$mppComposeJvmJsAndroidLinuxMingwLinuxArm64Project" | ||
|
||
kotlin { | ||
sourceSets { | ||
commonMain { | ||
dependencies { | ||
api project(":micro_utils.pagination.common") | ||
api project(":micro_utils.common.compose") | ||
} | ||
} | ||
} | ||
} |
99 changes: 99 additions & 0 deletions
99
pagination/compose/src/commonMain/kotlin/InfinityPagedComponent.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
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 InfinityPagedComponentContext<T> internal constructor( | ||
preset: List<T>? = null, | ||
initialPage: Int, | ||
size: Int | ||
) { | ||
internal val iterationState: MutableState<Pair<Int, Pagination>> = mutableStateOf(0 to SimplePagination(preset ?.page ?: initialPage, preset ?.size ?: size)) | ||
|
||
internal var dataOptional: List<T>? = preset | ||
private set | ||
internal val dataState: MutableState<List<T>?> = mutableStateOf(dataOptional) | ||
|
||
fun loadNext() { | ||
iterationState.value = iterationState.value.let { | ||
if ((dataState.value as? PaginationResult<*>) ?.isLastPage == true) return | ||
(it.first + 1) to it.second.nextPage() | ||
} | ||
} | ||
fun reload() { | ||
iterationState.value = iterationState.value.let { | ||
(it.first + 1) to (it.second.firstPage()) | ||
} | ||
} | ||
} | ||
|
||
@Composable | ||
internal fun <T> InfinityPagedComponent( | ||
preload: List<T>?, | ||
initialPage: Int, | ||
size: Int, | ||
loader: suspend PagedComponentContext<T>.(Pagination) -> PaginationResult<T>, | ||
block: @Composable PagedComponentContext<T>.(List<T>) -> Unit | ||
) { | ||
val context = remember { InfinityPagedComponentContext(preload, initialPage, size) } | ||
|
||
LaunchedEffect(context.iterationState.value) { | ||
context.dataState.value = loader(context, context.iterationState.value.second) | ||
} | ||
|
||
context.dataState.value ?.let { | ||
context.block() | ||
} | ||
} | ||
|
||
@Composable | ||
fun <T> InfinityPagedComponent( | ||
preload: PaginationResult<T>, | ||
loader: suspend PagedComponentContext<T>.(Pagination) -> PaginationResult<T>, | ||
block: @Composable PagedComponentContext<T>.(PaginationResult<T>) -> Unit | ||
) { | ||
PagedComponent( | ||
preload, | ||
preload.page, | ||
preload.size, | ||
loader, | ||
block | ||
) | ||
} | ||
|
||
@Composable | ||
fun <T> InfinityPagedComponent( | ||
pageInfo: Pagination, | ||
loader: suspend PagedComponentContext<T>.(Pagination) -> PaginationResult<T>, | ||
block: @Composable PagedComponentContext<T>.(PaginationResult<T>) -> Unit | ||
) { | ||
PagedComponent( | ||
null, | ||
pageInfo.page, | ||
pageInfo.size, | ||
loader, | ||
block | ||
) | ||
} | ||
|
||
@Composable | ||
fun <T> InfinityPagedComponent( | ||
initialPage: Int, | ||
size: Int, | ||
loader: suspend PagedComponentContext<T>.(Pagination) -> PaginationResult<T>, | ||
block: @Composable PagedComponentContext<T>.(PaginationResult<T>) -> Unit | ||
) { | ||
PagedComponent(null, initialPage, size, loader, block) | ||
} | ||
|
||
@Composable | ||
fun <T> InfinityPagedComponent( | ||
size: Int, | ||
loader: suspend PagedComponentContext<T>.(Pagination) -> PaginationResult<T>, | ||
block: @Composable PagedComponentContext<T>.(PaginationResult<T>) -> Unit | ||
) { | ||
PagedComponent(0, size, loader, block) | ||
} |
108 changes: 108 additions & 0 deletions
108
pagination/compose/src/commonMain/kotlin/PagedComponent.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
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<T> internal constructor( | ||
preset: PaginationResult<T>? = null, | ||
initialPage: Int, | ||
size: Int | ||
) { | ||
internal val iterationState: MutableState<Pair<Int, Pagination>> = mutableStateOf(0 to SimplePagination(preset ?.page ?: initialPage, preset ?.size ?: size)) | ||
|
||
internal var dataOptional: PaginationResult<T>? = preset | ||
private set | ||
internal val dataState: MutableState<PaginationResult<T>?> = 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 <T> PagedComponent( | ||
preload: PaginationResult<T>?, | ||
initialPage: Int, | ||
size: Int, | ||
loader: suspend PagedComponentContext<T>.(Pagination) -> PaginationResult<T>, | ||
block: @Composable PagedComponentContext<T>.(PaginationResult<T>) -> 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 <T> PagedComponent( | ||
preload: PaginationResult<T>, | ||
loader: suspend PagedComponentContext<T>.(Pagination) -> PaginationResult<T>, | ||
block: @Composable PagedComponentContext<T>.(PaginationResult<T>) -> Unit | ||
) { | ||
PagedComponent( | ||
preload, | ||
preload.page, | ||
preload.size, | ||
loader, | ||
block | ||
) | ||
} | ||
|
||
@Composable | ||
fun <T> PagedComponent( | ||
pageInfo: Pagination, | ||
loader: suspend PagedComponentContext<T>.(Pagination) -> PaginationResult<T>, | ||
block: @Composable PagedComponentContext<T>.(PaginationResult<T>) -> Unit | ||
) { | ||
PagedComponent( | ||
null, | ||
pageInfo.page, | ||
pageInfo.size, | ||
loader, | ||
block | ||
) | ||
} | ||
|
||
@Composable | ||
fun <T> PagedComponent( | ||
initialPage: Int, | ||
size: Int, | ||
loader: suspend PagedComponentContext<T>.(Pagination) -> PaginationResult<T>, | ||
block: @Composable PagedComponentContext<T>.(PaginationResult<T>) -> Unit | ||
) { | ||
PagedComponent(null, initialPage, size, loader, block) | ||
} | ||
|
||
@Composable | ||
fun <T> PagedComponent( | ||
size: Int, | ||
loader: suspend PagedComponentContext<T>.(Pagination) -> PaginationResult<T>, | ||
block: @Composable PagedComponentContext<T>.(PaginationResult<T>) -> Unit | ||
) { | ||
PagedComponent(0, size, loader, block) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters