Infinite scrolling for continuous vertical and webtoon

This commit is contained in:
Syer10
2023-01-16 12:49:57 -05:00
parent 7d9cf842d7
commit de99675969
7 changed files with 197 additions and 103 deletions

View File

@@ -30,6 +30,7 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.widthIn
import androidx.compose.material.CircularProgressIndicator
import androidx.compose.material.Icon
import androidx.compose.material.IconButton
import androidx.compose.material.ModalBottomSheetLayout
@@ -188,6 +189,7 @@ fun ReaderMenu(
retry = vm::retry,
progress = vm::progress,
updateLastPageReadOffset = vm::updateLastPageReadOffset,
requestPreloadChapter = vm::requestPreloadChapter,
sideMenuOpen = readerSettingsMenuOpen,
setSideMenuOpen = vm::setReaderSettingsMenuOpen,
setMangaReaderMode = vm::setMangaReaderMode,
@@ -217,6 +219,7 @@ fun ReaderMenu(
retry = vm::retry,
progress = vm::progress,
updateLastPageReadOffset = vm::updateLastPageReadOffset,
requestPreloadChapter = vm::requestPreloadChapter,
readerMenuOpen = readerSettingsMenuOpen,
setMangaReaderMode = vm::setMangaReaderMode,
movePrevChapter = vm::prevChapter,
@@ -266,6 +269,7 @@ fun WideReaderMenu(
retry: (ReaderPage) -> Unit,
progress: (ReaderItem) -> Unit,
updateLastPageReadOffset: (Int) -> Unit,
requestPreloadChapter: (ReaderChapter) -> Unit,
sideMenuOpen: Boolean,
setSideMenuOpen: (Boolean) -> Unit,
setMangaReaderMode: (String) -> Unit,
@@ -319,7 +323,8 @@ fun WideReaderMenu(
pageEmitterHolder = pageEmitterHolder,
retry = retry,
progress = progress,
updateLastPageReadOffset = updateLastPageReadOffset
updateLastPageReadOffset = updateLastPageReadOffset,
requestPreloadChapter = requestPreloadChapter
)
SideMenuButton(sideMenuOpen, onOpenSideMenuClicked = { setSideMenuOpen(true) })
}
@@ -348,6 +353,7 @@ fun ThinReaderMenu(
retry: (ReaderPage) -> Unit,
progress: (ReaderItem) -> Unit,
updateLastPageReadOffset: (Int) -> Unit,
requestPreloadChapter: (ReaderChapter) -> Unit,
readerMenuOpen: Boolean,
setMangaReaderMode: (String) -> Unit,
movePrevChapter: () -> Unit,
@@ -389,7 +395,8 @@ fun ThinReaderMenu(
pageEmitterHolder = pageEmitterHolder,
retry = retry,
progress = progress,
updateLastPageReadOffset = updateLastPageReadOffset
updateLastPageReadOffset = updateLastPageReadOffset,
requestPreloadChapter = requestPreloadChapter
)
AnimatedVisibility(
readerMenuOpen,
@@ -449,7 +456,8 @@ fun ReaderLayout(
pageEmitterHolder: StableHolder<SharedFlow<PageMove>>,
retry: (ReaderPage) -> Unit,
progress: (ReaderItem) -> Unit,
updateLastPageReadOffset: (Int) -> Unit
updateLastPageReadOffset: (Int) -> Unit,
requestPreloadChapter: (ReaderChapter) -> Unit
) {
val loadingModifier = Modifier.widthIn(max = 700.dp)
.fillMaxWidth()
@@ -491,7 +499,8 @@ fun ReaderLayout(
pageEmitterHolder = pageEmitterHolder,
retry = retry,
progress = progress,
updateLastPageReadOffset = updateLastPageReadOffset
updateLastPageReadOffset = updateLastPageReadOffset,
requestPreloadChapter = requestPreloadChapter
)
} else {
PagerReader(
@@ -503,7 +512,8 @@ fun ReaderLayout(
pageContentScale = imageScale.toContentScale(),
pageEmitterHolder = pageEmitterHolder,
retry = retry,
progress = progress
progress = progress,
requestPreloadChapter = requestPreloadChapter
)
}
}
@@ -577,18 +587,39 @@ fun ReaderImage(
@Composable
fun ChapterSeparator(
previousChapter: ReaderChapter?,
nextChapter: ReaderChapter?
nextChapter: ReaderChapter?,
requestPreloadChapter: (ReaderChapter) -> Unit
) {
Box(Modifier.fillMaxWidth().height(350.dp), contentAlignment = Alignment.Center) {
Column {
Column(horizontalAlignment = Alignment.CenterHorizontally) {
when {
previousChapter == null && nextChapter != null -> {
Text(stringResource(MR.strings.no_previous_chapter))
}
previousChapter != null && nextChapter != null -> {
val prevChapter by previousChapter.stateObserver.collectAsState()
when (prevChapter) {
ReaderChapter.State.Loading, ReaderChapter.State.Wait -> {
LaunchedEffect(Unit) {
requestPreloadChapter(previousChapter)
}
CircularProgressIndicator()
}
else -> Unit
}
Text(stringResource(MR.strings.previous_chapter, previousChapter.chapter.name))
Spacer(Modifier.height(8.dp))
Text(stringResource(MR.strings.next_chapter, nextChapter.chapter.name))
val nexChapter by previousChapter.stateObserver.collectAsState()
when (nexChapter) {
ReaderChapter.State.Loading, ReaderChapter.State.Wait -> {
LaunchedEffect(Unit) {
requestPreloadChapter(nextChapter)
}
CircularProgressIndicator()
}
else -> Unit
}
}
previousChapter != null && nextChapter == null -> {
Text(stringResource(MR.strings.no_next_chapter))

View File

@@ -37,7 +37,6 @@ import ca.gosyer.jui.ui.reader.model.ViewerChapters
import ca.gosyer.jui.uicore.vm.ContextWrapper
import ca.gosyer.jui.uicore.vm.ViewModel
import io.ktor.http.decodeURLQueryComponent
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.DelicateCoroutinesApi
@@ -53,15 +52,18 @@ import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.filterIsInstance
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.singleOrNull
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.flow.take
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import me.tatarka.inject.annotations.Inject
import org.lighthousegames.logging.logging
@@ -82,20 +84,41 @@ class ReaderMenuViewModel @Inject constructor(
) : ViewModel(contextWrapper) {
override val scope = MainScope()
private val _manga = MutableStateFlow<Manga?>(null)
private val viewerChapters = ViewerChapters(
MutableStateFlow(null),
MutableStateFlow(null),
MutableStateFlow(null)
)
val previousChapter = viewerChapters.prevChapter.asStateFlow()
val chapter = viewerChapters.currChapter.asStateFlow()
val nextChapter = viewerChapters.nextChapter.asStateFlow()
private val viewerChapters = MutableStateFlow(ViewerChapters(null, null, null))
val previousChapter = viewerChapters.map { it.prevChapter }.stateIn(scope, SharingStarted.Eagerly, null)
val chapter = viewerChapters.map { it.currChapter }.stateIn(scope, SharingStarted.Eagerly, null)
val nextChapter = viewerChapters.map { it.nextChapter }.stateIn(scope, SharingStarted.Eagerly, null)
private val _state = MutableStateFlow<ReaderChapter.State>(ReaderChapter.State.Wait)
val state = _state.asStateFlow()
private val _pages = MutableStateFlow<ImmutableList<ReaderItem>>(persistentListOf())
val pages = _pages.asStateFlow()
val pages = viewerChapters.flatMapLatest {
val previousChapterPages = it.prevChapter
?.pages
?.map { (it as? PagesState.Success)?.pages }
?: flowOf(null)
val chapterPages = it.currChapter
?.pages
?.map { (it as? PagesState.Success)?.pages }
?: flowOf(null)
val nextChapterPages = it.nextChapter
?.pages
?.map { (it as? PagesState.Success)?.pages }
?: flowOf(null)
combine(previousChapterPages, chapterPages, nextChapterPages, readerModeSettings.continuous) { prev, cur, next, cont ->
if (cont) {
(prev.orEmpty() +
ReaderPageSeparator(it.prevChapter, it.currChapter) +
cur.orEmpty() +
ReaderPageSeparator(it.currChapter, it.nextChapter) +
next.orEmpty()).toImmutableList()
} else {
(listOf(ReaderPageSeparator(it.prevChapter, it.currChapter)) +
cur.orEmpty() +
ReaderPageSeparator(it.currChapter, it.nextChapter)).toImmutableList()
}
}
}.stateIn(scope, SharingStarted.Eagerly, persistentListOf())
private val _currentPage = MutableStateFlow<ReaderItem?>(null)
val currentPage = _currentPage.asStateFlow()
@@ -148,6 +171,35 @@ class ReaderMenuViewModel @Inject constructor(
}
}
init {
scope.launchDefault {
currentPage
.filterIsInstance<ReaderPage>()
.collectLatest { page ->
page.chapter.pageLoader?.loadPage(page)
if (page.chapter == chapter.value) {
if ((page.index + 1) >= page.chapter.chapter.pageCount!!) {
markChapterRead(page.chapter)
}
val nextChapter = nextChapter.value
if (nextChapter != null && (page.index + 1) >= (page.chapter.chapter.pageCount!! - 5)) {
requestPreloadChapter(nextChapter)
}
} else {
val previousChapter = previousChapter.value
val nextChapter = nextChapter.value
if (page.chapter == previousChapter) {
viewerChapters.value = viewerChapters.value.movePrev()
initChapters(params.mangaId, page.chapter.chapter.index, fromMenuButton = false)
} else if (page.chapter == nextChapter) {
viewerChapters.value = viewerChapters.value.moveNext()
initChapters(params.mangaId, page.chapter.chapter.index, fromMenuButton = false)
}
}
}
}
}
fun navigate(navigationRegion: Navigation): Boolean {
scope.launch {
val moveTo = when (navigationRegion) {
@@ -198,12 +250,6 @@ class ReaderMenuViewModel @Inject constructor(
chapter.value?.pageLoader?.retryPage(page)
}
private fun resetValues() {
viewerChapters.recycle()
_pages.value = persistentListOf()
_currentPage.value = null
}
fun setMangaReaderMode(mode: String) {
scope.launchDefault {
_manga.value?.let {
@@ -223,7 +269,7 @@ class ReaderMenuViewModel @Inject constructor(
try {
_state.value = ReaderChapter.State.Wait
sendProgress()
viewerChapters.movePrev()
viewerChapters.value = viewerChapters.value.movePrev()
initChapters(params.mangaId, prevChapter.chapter.index, fromMenuButton = true)
} catch (e: Exception) {
log.warn(e) { "Error loading prev chapter" }
@@ -237,7 +283,7 @@ class ReaderMenuViewModel @Inject constructor(
try {
_state.value = ReaderChapter.State.Wait
sendProgress()
viewerChapters.moveNext()
viewerChapters.value = viewerChapters.value.moveNext()
initChapters(params.mangaId, nextChapter.chapter.index, fromMenuButton = true)
} catch (e: Exception) {
log.warn(e) { "Error loading next chapter" }
@@ -263,12 +309,12 @@ class ReaderMenuViewModel @Inject constructor(
chapterIndex: Int,
fromMenuButton: Boolean = true
) {
// resetValues()
log.debug { "Loading chapter index $chapterIndex" }
val (chapter, pages) = coroutineScope {
val getCurrentChapter = async {
val chapter = getReaderChapter(chapterIndex) ?: return@async null
val pages = loader.loadChapter(chapter)
viewerChapters.currChapter.value = chapter
viewerChapters.update { it.copy(currChapter = chapter) }
chapter to pages
}
@@ -279,22 +325,24 @@ class ReaderMenuViewModel @Inject constructor(
).orEmpty()
val nextChapter = async {
if (viewerChapters.nextChapter.value == null) {
if (viewerChapters.value.nextChapter == null) {
val nextChapter = chapters.find { it.index == chapterIndex + 1 }
if (nextChapter != null) {
viewerChapters.nextChapter.value = getReaderChapter(nextChapter.index)
val nextReaderChapter = getReaderChapter(nextChapter.index)
viewerChapters.update { it.copy(nextChapter = nextReaderChapter) }
} else {
viewerChapters.nextChapter.value = null
viewerChapters.update { it.copy(nextChapter = null) }
}
}
}
val prevChapter = async {
if (viewerChapters.prevChapter.value == null) {
if (viewerChapters.value.prevChapter == null) {
val prevChapter = chapters.find { it.index == chapterIndex - 1 }
if (prevChapter != null) {
viewerChapters.prevChapter.value = getReaderChapter(prevChapter.index)
val prevReaderChapter = getReaderChapter(prevChapter.index)
viewerChapters.update { it.copy(prevChapter = prevReaderChapter) }
} else {
viewerChapters.prevChapter.value = null
viewerChapters.update { it.copy(prevChapter = null) }
}
}
}
@@ -306,19 +354,16 @@ class ReaderMenuViewModel @Inject constructor(
getCurrentChapter.await()
} ?: return
chapter.stateObserver
.onEach {
_state.value = it
}
.launchIn(chapter.scope)
pages
.filterIsInstance<PagesState.Success>()
.onEach { (pageList) ->
val prevSeparator = ReaderPageSeparator(viewerChapters.prevChapter.value, chapter)
val nextSeparator = ReaderPageSeparator(chapter, viewerChapters.nextChapter.value)
_pages.value = (listOf(prevSeparator) + pageList + nextSeparator).toImmutableList()
if (fromMenuButton) {
chapter.stateObserver
.onEach {
_state.value = it
}
.launchIn(chapter.scope)
if (fromMenuButton) {
pages
.filterIsInstance<PagesState.Success>()
.onEach { (pageList) ->
val lastPageReadOffset = chapter.chapter.meta.juiPageOffset
if (lastPageReadOffset != 0) {
_currentPageOffset.value = lastPageReadOffset
@@ -330,19 +375,9 @@ class ReaderMenuViewModel @Inject constructor(
pageList.first()
}.also { chapter.pageLoader?.loadPage(it) }
}
}
.launchIn(chapter.scope)
.launchIn(chapter.scope)
}
_currentPage
.filterIsInstance<ReaderPage>()
.filter { it.chapter.chapter.index == chapterIndex }
.onEach { page ->
chapter.pageLoader?.loadPage(page)
if ((page.index + 1) >= chapter.chapter.pageCount!!) {
markChapterRead(chapter)
}
}
.launchIn(chapter.scope)
}
private suspend fun getReaderChapter(chapterIndex: Int): ReaderChapter? {
@@ -357,6 +392,14 @@ class ReaderMenuViewModel @Inject constructor(
)
}
fun requestPreloadChapter(chapter: ReaderChapter) {
if (chapter.state != ReaderChapter.State.Wait && chapter.state !is ReaderChapter.State.Error) {
return
}
log.debug { "Preloading ${chapter.chapter.index}" }
loader.loadChapter(chapter)
}
private fun markChapterRead(chapter: ReaderChapter) {
scope.launch {
updateChapterRead.await(chapter.chapter, read = true, onError = { toast(it.message.orEmpty()) })
@@ -391,7 +434,7 @@ class ReaderMenuViewModel @Inject constructor(
}
override fun onDispose() {
viewerChapters.recycle()
viewerChapters.value.recycle()
scope.cancel()
}

View File

@@ -161,7 +161,7 @@ class TachideskPageLoader(
*/
private fun preloadNextPages(currentPage: ReaderPage, amount: Int): List<PriorityPage> {
val pageIndex = currentPage.index
val pages = (currentPage.chapter.pages?.value as? PagesState.Success)?.pages ?: return emptyList()
val pages = (currentPage.chapter.pages.value as? PagesState.Success)?.pages ?: return emptyList()
if (pageIndex >= pages.lastIndex) return emptyList()
return pages

View File

@@ -15,8 +15,12 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.filterIsInstance
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.stateIn
import org.lighthousegames.logging.logging
@Immutable
@@ -31,10 +35,11 @@ data class ReaderChapter(val chapter: Chapter) {
_state.value = value
}
val stateObserver by lazy { _state.asStateFlow() }
val stateObserver = _state.asStateFlow()
val pages: StateFlow<PagesState>?
get() = (state as? State.Loaded)?.pages
val pages: StateFlow<PagesState> = _state.filterIsInstance<State.Loaded>()
.flatMapLatest { it.pages }
.stateIn(scope, SharingStarted.Eagerly, PagesState.Loading)
var pageLoader: PageLoader? = null

View File

@@ -6,33 +6,32 @@
package ca.gosyer.jui.ui.reader.model
import kotlinx.coroutines.flow.MutableStateFlow
data class ViewerChapters(
val currChapter: MutableStateFlow<ReaderChapter?>,
val prevChapter: MutableStateFlow<ReaderChapter?>,
val nextChapter: MutableStateFlow<ReaderChapter?>
val currChapter: ReaderChapter?,
val prevChapter: ReaderChapter?,
val nextChapter: ReaderChapter?
) {
fun recycle() {
currChapter.value?.recycle()
prevChapter.value?.recycle()
nextChapter.value?.recycle()
currChapter.value = null
prevChapter.value = null
nextChapter.value = null
currChapter?.recycle()
prevChapter?.recycle()
nextChapter?.recycle()
}
fun movePrev() {
nextChapter.value?.recycle()
nextChapter.value = currChapter.value
currChapter.value = prevChapter.value
prevChapter.value = null
fun movePrev(): ViewerChapters {
nextChapter?.recycle()
return ViewerChapters(
nextChapter = currChapter,
currChapter = prevChapter,
prevChapter = null
)
}
fun moveNext() {
prevChapter.value?.recycle()
prevChapter.value = currChapter.value
currChapter.value = nextChapter.value
nextChapter.value = null
fun moveNext(): ViewerChapters {
prevChapter?.recycle()
return ViewerChapters(
prevChapter = currChapter,
currChapter = nextChapter,
nextChapter = null
)
}
}

View File

@@ -25,7 +25,6 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
@@ -37,6 +36,7 @@ import ca.gosyer.jui.ui.reader.ChapterSeparator
import ca.gosyer.jui.ui.reader.ReaderImage
import ca.gosyer.jui.ui.reader.model.MoveTo
import ca.gosyer.jui.ui.reader.model.PageMove
import ca.gosyer.jui.ui.reader.model.ReaderChapter
import ca.gosyer.jui.ui.reader.model.ReaderItem
import ca.gosyer.jui.ui.reader.model.ReaderPage
import ca.gosyer.jui.ui.reader.model.ReaderPageSeparator
@@ -46,10 +46,8 @@ import ca.gosyer.jui.uicore.components.rememberScrollbarAdapter
import ca.gosyer.jui.uicore.components.scrollbarPadding
import kotlinx.collections.immutable.ImmutableList
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.mapLatest
import kotlinx.coroutines.flow.mapNotNull
@Composable
fun ContinuousReader(
@@ -65,7 +63,8 @@ fun ContinuousReader(
pageEmitterHolder: StableHolder<SharedFlow<PageMove>>,
retry: (ReaderPage) -> Unit,
progress: (ReaderItem) -> Unit,
updateLastPageReadOffset: (Int) -> Unit
updateLastPageReadOffset: (Int) -> Unit,
requestPreloadChapter: (ReaderChapter) -> Unit
) {
BoxWithConstraints(modifier then Modifier.fillMaxSize()) {
val state = rememberLazyListState(pages.indexOf(currentPage).coerceAtLeast(1), currentPageOffset)
@@ -102,11 +101,12 @@ fun ContinuousReader(
updateLastPageReadOffset(state.firstVisibleItemScrollOffset)
}
}
LaunchedEffect(state) {
snapshotFlow { state.layoutInfo.visibleItemsInfo.lastOrNull()?.index }
.filterNotNull()
.mapNotNull { pages.getOrNull(it) }
.collect(progress)
LaunchedEffect(state.layoutInfo.visibleItemsInfo.lastOrNull()?.index) {
val index = state.layoutInfo.visibleItemsInfo.lastOrNull()?.index
val page = index?.let { pages.getOrNull(it) }
if (page != null) {
progress(page)
}
}
val imageModifier = if (maxSize != 0) {
@@ -140,7 +140,8 @@ fun ContinuousReader(
imageModifier = imageModifier,
loadingModifier = loadingModifier,
pageContentScale = pageContentScale,
retry = ::retry
retry = ::retry,
requestPreloadChapter = requestPreloadChapter
)
}
VerticalScrollbar(
@@ -165,7 +166,8 @@ fun ContinuousReader(
imageModifier = imageModifier,
loadingModifier = loadingModifier,
pageContentScale = pageContentScale,
retry = ::retry
retry = ::retry,
requestPreloadChapter = requestPreloadChapter
)
}
HorizontalScrollbar(
@@ -185,7 +187,8 @@ private fun LazyListScope.items(
imageModifier: Modifier,
loadingModifier: Modifier,
pageContentScale: ContentScale,
retry: (Int) -> Unit
retry: (Int) -> Unit,
requestPreloadChapter: (ReaderChapter) -> Unit
) {
items(
pages,
@@ -211,7 +214,11 @@ private fun LazyListScope.items(
retry = retry
)
}
is ReaderPageSeparator -> ChapterSeparator(previousChapter = image.previousChapter, nextChapter = image.nextChapter)
is ReaderPageSeparator -> ChapterSeparator(
previousChapter = image.previousChapter,
nextChapter = image.nextChapter,
requestPreloadChapter = requestPreloadChapter
)
}
}
}

View File

@@ -19,6 +19,7 @@ import ca.gosyer.jui.ui.reader.ChapterSeparator
import ca.gosyer.jui.ui.reader.ReaderImage
import ca.gosyer.jui.ui.reader.model.MoveTo
import ca.gosyer.jui.ui.reader.model.PageMove
import ca.gosyer.jui.ui.reader.model.ReaderChapter
import ca.gosyer.jui.ui.reader.model.ReaderItem
import ca.gosyer.jui.ui.reader.model.ReaderPage
import ca.gosyer.jui.ui.reader.model.ReaderPageSeparator
@@ -40,7 +41,8 @@ fun PagerReader(
pageContentScale: ContentScale,
pageEmitterHolder: StableHolder<SharedFlow<PageMove>>,
retry: (ReaderPage) -> Unit,
progress: (ReaderItem) -> Unit
progress: (ReaderItem) -> Unit,
requestPreloadChapter: (ReaderChapter) -> Unit
) {
val state = rememberPagerState(initialPage = pages.indexOf(currentPage).coerceAtLeast(1))
val currentPageState = rememberUpdatedState(currentPage)
@@ -93,7 +95,8 @@ fun PagerReader(
page = it,
loadingModifier = loadingModifier,
pageContentScale = pageContentScale,
retry = ::retry
retry = ::retry,
requestPreloadChapter = requestPreloadChapter
)
}
} else {
@@ -108,7 +111,8 @@ fun PagerReader(
page = it,
loadingModifier = loadingModifier,
pageContentScale = pageContentScale,
retry = ::retry
retry = ::retry,
requestPreloadChapter = requestPreloadChapter
)
}
}
@@ -120,7 +124,8 @@ fun HandlePager(
page: Int,
loadingModifier: Modifier,
pageContentScale: ContentScale,
retry: (Int) -> Unit
retry: (Int) -> Unit,
requestPreloadChapter: (ReaderChapter) -> Unit
) {
when (val image = pages[page]) {
is ReaderPage -> {
@@ -136,6 +141,10 @@ fun HandlePager(
contentScale = pageContentScale
)
}
is ReaderPageSeparator -> ChapterSeparator(image.previousChapter, image.nextChapter)
is ReaderPageSeparator -> ChapterSeparator(
previousChapter = image.previousChapter,
nextChapter = image.nextChapter,
requestPreloadChapter = requestPreloadChapter
)
}
}