archive-97f2350/app/src/main/java/uk/orllewin/sianel/data/VideoPagingSource.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package uk.orllewin.sianel.data
import androidx.paging.PagingSource
import androidx.paging.PagingState
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
/**
* Offset-keyed paging over [SianelService.listPage]. The key is the row offset into
* the newest-first list; [SianelService.Page.total] tells us when to stop.
*/
class VideoPagingSource(
private val client: SianelService,
) : PagingSource<Int, SianelService.VideoItem>() {
override suspend fun load(
params: LoadParams<Int>,
): LoadResult<Int, SianelService.VideoItem> {
val offset = params.key ?: 0
val count = params.loadSize
return try {
val page = withContext(Dispatchers.IO) { client.listPage(offset, count) }
val nextOffset = offset + page.items.size
LoadResult.Page(
data = page.items,
prevKey = if (offset == 0) null else (offset - count).coerceAtLeast(0),
nextKey = if (nextOffset >= page.total || page.items.isEmpty()) null else nextOffset,
)
} catch (e: Throwable) {
LoadResult.Error(e)
}
}
// Recompute a sensible reload key around the user's current position.
override fun getRefreshKey(state: PagingState<Int, SianelService.VideoItem>): Int? {
val anchor = state.anchorPosition ?: return null
val page = state.closestPageToPosition(anchor) ?: return null
return page.prevKey?.plus(state.config.pageSize) ?: page.nextKey?.minus(state.config.pageSize)
}
}