Updated on 2026-08-14
This commit is contained in:
parent
4ec02d0447
commit
f426a1f922
26 changed files with 748 additions and 247 deletions
|
|
@ -68,4 +68,10 @@ sealed class BatchAction<out TKey, out TRequestParams, out TUpdate> {
|
|||
class CancelUpdates<TKey, TUpdate>(
|
||||
val predicate: (UpdateBatches<TKey, TUpdate>) -> Boolean,
|
||||
) : BatchAction<TKey, Nothing, TUpdate>()
|
||||
|
||||
/**
|
||||
* Clears the state and stops all current batch loading and updates
|
||||
* After this status becomes [PaginationStatus.None]
|
||||
*/
|
||||
data object Reset : BatchAction<Nothing, Nothing, Nothing>()
|
||||
}
|
||||
|
|
@ -12,10 +12,12 @@ sealed class BatchFetchResult<out TData> {
|
|||
* Represents a successful result of a batch fetch request.
|
||||
*
|
||||
* @param data fetched data.
|
||||
* @param empty indicates that data is empty and [BatchListSource] shouldn't create new batch for this result
|
||||
* @param last indicates if this is the last batch for the request.
|
||||
*/
|
||||
data class Success<TData>(
|
||||
val data: TData,
|
||||
val empty: Boolean,
|
||||
val last: Boolean,
|
||||
) : BatchFetchResult<TData>()
|
||||
|
||||
|
|
|
|||
|
|
@ -92,11 +92,7 @@ private class DefaultBatchListSource<TKey, TData, TRequestParams : Any, TUpdate>
|
|||
awaitCancellation()
|
||||
} finally {
|
||||
withContext(NonCancellable) {
|
||||
stopAllUpdates()
|
||||
loadMoreActionJob = null
|
||||
loadMoreActionJob = null
|
||||
lastRequestResult.value = null
|
||||
state.value = BatchListState(emptyList(), PaginationStatus.None)
|
||||
resetState()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -110,6 +106,7 @@ private class DefaultBatchListSource<TKey, TData, TRequestParams : Any, TUpdate>
|
|||
}
|
||||
}
|
||||
|
||||
@Suppress("CyclomaticComplexMethod")
|
||||
private fun collectActions(action: BatchAction<TKey, TRequestParams, TUpdate>) {
|
||||
when (action) {
|
||||
is BatchAction.Reload -> {
|
||||
|
|
@ -165,6 +162,9 @@ private class DefaultBatchListSource<TKey, TData, TRequestParams : Any, TUpdate>
|
|||
loadMoreActionJob?.cancel()
|
||||
reloadActionJob?.cancel()
|
||||
}
|
||||
BatchAction.Reset -> {
|
||||
resetState()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -237,13 +237,17 @@ private class DefaultBatchListSource<TKey, TData, TRequestParams : Any, TUpdate>
|
|||
|
||||
state.value = when (res) {
|
||||
is BatchFetchResult.Success -> {
|
||||
val key = generateNewKey(listOf())
|
||||
val batch = Batch(
|
||||
key = key,
|
||||
data = res.data,
|
||||
)
|
||||
val batch = if (res.empty.not()) {
|
||||
Batch(
|
||||
key = generateNewKey(listOf()),
|
||||
data = res.data,
|
||||
)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
BatchListState(
|
||||
data = listOf(batch),
|
||||
data = batch?.let { listOf(it) } ?: emptyList(),
|
||||
status = if (res.last) {
|
||||
PaginationStatus.EndOfPagination
|
||||
} else {
|
||||
|
|
@ -289,13 +293,17 @@ private class DefaultBatchListSource<TKey, TData, TRequestParams : Any, TUpdate>
|
|||
state.update { currentState ->
|
||||
when (res) {
|
||||
is BatchFetchResult.Success -> {
|
||||
val newBatch = Batch(
|
||||
key = generateNewKey(currentState.data.map { it.key }),
|
||||
data = res.data,
|
||||
)
|
||||
val newBatch = if (res.empty.not()) {
|
||||
Batch(
|
||||
key = generateNewKey(currentState.data.map { it.key }),
|
||||
data = res.data,
|
||||
)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
currentState.copy(
|
||||
data = currentState.data + newBatch,
|
||||
data = newBatch?.let { currentState.data + it } ?: currentState.data,
|
||||
status = if (res.last) {
|
||||
PaginationStatus.EndOfPagination
|
||||
} else {
|
||||
|
|
@ -400,6 +408,18 @@ private class DefaultBatchListSource<TKey, TData, TRequestParams : Any, TUpdate>
|
|||
waitingUpdateJobs.value.any { it.first.operationId == operationId }
|
||||
}
|
||||
|
||||
private fun resetState() {
|
||||
if (updateFetcher != null) {
|
||||
stopAllUpdates()
|
||||
}
|
||||
loadMoreActionJob?.cancel()
|
||||
loadMoreActionJob = null
|
||||
reloadActionJob?.cancel()
|
||||
reloadActionJob = null
|
||||
lastRequestResult.value = null
|
||||
state.value = BatchListState(emptyList(), PaginationStatus.None)
|
||||
}
|
||||
|
||||
private fun stopAllUpdates() {
|
||||
updateAsyncJobs.update { actionAsyncJobs ->
|
||||
actionAsyncJobs.forEach {
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ class LimitOffsetBatchFetcher<TRequestParams : Any, TData>(
|
|||
suspend fun fetch(
|
||||
request: Request<TRequestParams>,
|
||||
lastResult: BatchFetchResult<TData>?,
|
||||
isFirstBatchFetching: Boolean,
|
||||
): BatchFetchResult<TData>
|
||||
}
|
||||
|
||||
|
|
@ -45,7 +46,7 @@ class LimitOffsetBatchFetcher<TRequestParams : Any, TData>(
|
|||
)
|
||||
|
||||
val res = runCatching {
|
||||
subFetcher.fetch(req, null)
|
||||
subFetcher.fetch(request = req, lastResult = null, isFirstBatchFetching = true)
|
||||
}.getOrElse {
|
||||
currentCoroutineContext().ensureActive()
|
||||
BatchFetchResult.Error(it)
|
||||
|
|
@ -77,7 +78,7 @@ class LimitOffsetBatchFetcher<TRequestParams : Any, TData>(
|
|||
}
|
||||
|
||||
val res = runCatching {
|
||||
subFetcher.fetch(req, lastResult)
|
||||
subFetcher.fetch(request = req, lastResult = lastResult, isFirstBatchFetching = false)
|
||||
}.getOrElse {
|
||||
currentCoroutineContext().ensureActive()
|
||||
BatchFetchResult.Error(it)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue