mirror of
https://github.com/Suwayomi/TachideskJUI.git
synced 2026-01-25 04:54:04 +01:00
Reader improvements, hotkey support, mark as read when finished, a lot more
This commit is contained in:
@@ -15,20 +15,16 @@ import androidx.compose.foundation.layout.aspectRatio
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.material.Surface
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.ImageBitmap
|
||||
import androidx.compose.ui.input.key.Key
|
||||
import androidx.compose.ui.input.key.KeysSet
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.unit.IntOffset
|
||||
import androidx.compose.ui.unit.dp
|
||||
@@ -42,12 +38,12 @@ import ca.gosyer.ui.base.components.LoadingScreen
|
||||
import ca.gosyer.ui.base.components.mangaAspectRatio
|
||||
import ca.gosyer.ui.base.theme.AppTheme
|
||||
import ca.gosyer.ui.base.vm.viewModel
|
||||
import ca.gosyer.ui.reader.model.MoveTo
|
||||
import ca.gosyer.ui.reader.model.ReaderChapter
|
||||
import ca.gosyer.ui.reader.model.ReaderPage
|
||||
import ca.gosyer.ui.reader.viewer.ContinuousReader
|
||||
import ca.gosyer.ui.reader.viewer.PagerReader
|
||||
import ca.gosyer.util.lang.launchUI
|
||||
import com.google.accompanist.pager.HorizontalPager
|
||||
import com.google.accompanist.pager.VerticalPager
|
||||
import com.google.accompanist.pager.rememberPagerState
|
||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||
|
||||
@OptIn(DelicateCoroutinesApi::class)
|
||||
@@ -113,14 +109,52 @@ fun ReaderMenu(chapterIndex: Int, mangaId: Long, setHotkeys: (List<KeyboardShort
|
||||
val direction by vm.readerModeSettings.direction.collectAsState()
|
||||
val padding by vm.readerModeSettings.padding.collectAsState()
|
||||
val currentPage by vm.currentPage.collectAsState()
|
||||
remember {
|
||||
LaunchedEffect(Unit) {
|
||||
setHotkeys(
|
||||
listOf(
|
||||
KeyboardShortcut(KeysSet(setOf(Key.W, Key.DirectionUp))) {
|
||||
vm.progress(currentPage + 1)
|
||||
KeyboardShortcut(Key.W) {
|
||||
vm.moveDirection(MoveTo.Previous)
|
||||
},
|
||||
KeyboardShortcut(KeysSet(setOf(Key.S, Key.DirectionDown))) {
|
||||
vm.progress(currentPage - 1)
|
||||
KeyboardShortcut(Key.DirectionUp) {
|
||||
vm.moveDirection(MoveTo.Previous)
|
||||
},
|
||||
KeyboardShortcut(Key.S) {
|
||||
vm.moveDirection(MoveTo.Next)
|
||||
},
|
||||
KeyboardShortcut(Key.DirectionDown) {
|
||||
vm.moveDirection(MoveTo.Next)
|
||||
},
|
||||
KeyboardShortcut(Key.A) {
|
||||
vm.moveDirection(
|
||||
when (direction) {
|
||||
Direction.Left -> MoveTo.Next
|
||||
else -> MoveTo.Previous
|
||||
}
|
||||
)
|
||||
},
|
||||
KeyboardShortcut(Key.DirectionLeft) {
|
||||
vm.moveDirection(
|
||||
when (direction) {
|
||||
Direction.Left -> MoveTo.Next
|
||||
else -> MoveTo.Previous
|
||||
}
|
||||
)
|
||||
},
|
||||
KeyboardShortcut(Key.D) {
|
||||
vm.moveDirection(
|
||||
when (direction) {
|
||||
Direction.Left -> MoveTo.Previous
|
||||
else -> MoveTo.Next
|
||||
}
|
||||
)
|
||||
},
|
||||
KeyboardShortcut(Key.DirectionRight) {
|
||||
vm.moveDirection(
|
||||
when (direction) {
|
||||
Direction.Left -> MoveTo.Previous
|
||||
else -> MoveTo.Next
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
)
|
||||
@@ -132,9 +166,13 @@ fun ReaderMenu(chapterIndex: Int, mangaId: Long, setHotkeys: (List<KeyboardShort
|
||||
val pageModifier = Modifier.fillMaxWidth().aspectRatio(mangaAspectRatio)
|
||||
if (pages.isNotEmpty()) {
|
||||
if (continuous) {
|
||||
ContinuesReader(
|
||||
ContinuousReader(
|
||||
pages,
|
||||
previousChapter,
|
||||
chapter,
|
||||
nextChapter,
|
||||
pageModifier,
|
||||
vm.pageEmitter,
|
||||
vm::retry,
|
||||
vm::progress
|
||||
)
|
||||
@@ -147,6 +185,7 @@ fun ReaderMenu(chapterIndex: Int, mangaId: Long, setHotkeys: (List<KeyboardShort
|
||||
chapter,
|
||||
nextChapter,
|
||||
pageModifier,
|
||||
vm.pageEmitter,
|
||||
vm::retry,
|
||||
vm::progress
|
||||
)
|
||||
@@ -187,88 +226,12 @@ fun ReaderImage(
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun PagerReader(
|
||||
direction: Direction,
|
||||
currentPage: Int,
|
||||
pages: List<ReaderPage>,
|
||||
previousChapter: ReaderChapter?,
|
||||
currentChapter: ReaderChapter,
|
||||
nextChapter: ReaderChapter?,
|
||||
pageModifier: Modifier,
|
||||
retry: (ReaderPage) -> Unit,
|
||||
progress: (Int) -> Unit
|
||||
) {
|
||||
val state = rememberPagerState(pages.size + 1, initialPage = currentPage)
|
||||
|
||||
LaunchedEffect(state.currentPage) {
|
||||
if (state.currentPage != currentPage) {
|
||||
progress(state.currentPage)
|
||||
}
|
||||
}
|
||||
|
||||
if (direction == Direction.Down || direction == Direction.Up) {
|
||||
VerticalPager(state, reverseLayout = direction == Direction.Up) {
|
||||
HandlePager(
|
||||
pages,
|
||||
it,
|
||||
previousChapter,
|
||||
currentChapter,
|
||||
nextChapter,
|
||||
pageModifier,
|
||||
retry
|
||||
)
|
||||
}
|
||||
} else {
|
||||
HorizontalPager(state, reverseLayout = direction == Direction.Left) {
|
||||
HandlePager(
|
||||
pages,
|
||||
it,
|
||||
previousChapter,
|
||||
currentChapter,
|
||||
nextChapter,
|
||||
pageModifier,
|
||||
retry
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun HandlePager(
|
||||
pages: List<ReaderPage>,
|
||||
page: Int,
|
||||
previousChapter: ReaderChapter?,
|
||||
currentChapter: ReaderChapter,
|
||||
nextChapter: ReaderChapter?,
|
||||
pageModifier: Modifier,
|
||||
retry: (ReaderPage) -> Unit,
|
||||
) {
|
||||
when (page) {
|
||||
0 -> ChapterSeperator(previousChapter, currentChapter)
|
||||
pages.size -> ChapterSeperator(currentChapter, nextChapter)
|
||||
else -> {
|
||||
val image = pages[page - 1]
|
||||
ReaderImage(
|
||||
image.index,
|
||||
image.bitmap.collectAsState().value,
|
||||
image.status.collectAsState().value,
|
||||
image.error.collectAsState().value,
|
||||
loadingModifier = pageModifier,
|
||||
retry = { pageIndex ->
|
||||
pages.find { it.index == pageIndex }?.let { retry(it) }
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ChapterSeperator(
|
||||
previousChapter: ReaderChapter?,
|
||||
nextChapter: ReaderChapter?
|
||||
) {
|
||||
Box(contentAlignment = Alignment.Center) {
|
||||
Box(Modifier.fillMaxWidth().height(350.dp), contentAlignment = Alignment.Center) {
|
||||
Column {
|
||||
when {
|
||||
previousChapter == null && nextChapter != null -> {
|
||||
@@ -286,29 +249,3 @@ fun ChapterSeperator(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ContinuesReader(
|
||||
pages: List<ReaderPage>,
|
||||
pageModifier: Modifier,
|
||||
retry: (ReaderPage) -> Unit,
|
||||
progress: (Int) -> Unit
|
||||
) {
|
||||
LazyColumn {
|
||||
items(pages) { image ->
|
||||
LaunchedEffect(image.index) {
|
||||
progress(image.index)
|
||||
}
|
||||
ReaderImage(
|
||||
image.index,
|
||||
image.bitmap.collectAsState().value,
|
||||
image.status.collectAsState().value,
|
||||
image.error.collectAsState().value,
|
||||
loadingModifier = pageModifier,
|
||||
retry = { pageIndex ->
|
||||
pages.find { it.index == pageIndex }?.let { retry(it) }
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,14 +10,15 @@ import ca.gosyer.data.reader.ReaderModeWatch
|
||||
import ca.gosyer.data.reader.ReaderPreferences
|
||||
import ca.gosyer.data.server.interactions.ChapterInteractionHandler
|
||||
import ca.gosyer.ui.base.vm.ViewModel
|
||||
import ca.gosyer.ui.reader.model.MoveTo
|
||||
import ca.gosyer.ui.reader.model.ReaderChapter
|
||||
import ca.gosyer.ui.reader.model.ReaderPage
|
||||
import ca.gosyer.ui.reader.model.ViewerChapters
|
||||
import ca.gosyer.util.lang.throwIfCancellation
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.awaitAll
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asSharedFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
@@ -47,6 +48,9 @@ class ReaderMenuViewModel @Inject constructor(
|
||||
private val _currentPage = MutableStateFlow(1)
|
||||
val currentPage = _currentPage.asStateFlow()
|
||||
|
||||
private val _pageEmitter = MutableSharedFlow<Pair<MoveTo, Int>>()
|
||||
val pageEmitter = _pageEmitter.asSharedFlow()
|
||||
|
||||
val readerModeSettings = ReaderModeWatch(readerPreferences, scope)
|
||||
|
||||
private val loader = ChapterLoader(scope.coroutineContext, readerPreferences, chapterHandler)
|
||||
@@ -57,6 +61,12 @@ class ReaderMenuViewModel @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
fun moveDirection(direction: MoveTo) {
|
||||
scope.launch {
|
||||
_pageEmitter.emit(direction to currentPage.value)
|
||||
}
|
||||
}
|
||||
|
||||
fun progress(index: Int) {
|
||||
_currentPage.value = index
|
||||
}
|
||||
@@ -76,46 +86,68 @@ class ReaderMenuViewModel @Inject constructor(
|
||||
resetValues()
|
||||
val chapter = ReaderChapter(
|
||||
scope.coroutineContext + Dispatchers.Default,
|
||||
chapterHandler.getChapter(mangaId, chapterIndex)
|
||||
try {
|
||||
chapterHandler.getChapter(mangaId, chapterIndex)
|
||||
} catch (e: Exception) {
|
||||
e.throwIfCancellation()
|
||||
_state.value = ReaderChapter.State.Error(e)
|
||||
throw e
|
||||
}
|
||||
)
|
||||
val pages = loader.loadChapter(chapter)
|
||||
viewerChapters.currChapter.value = chapter
|
||||
scope.launch(Dispatchers.Default) {
|
||||
listOf(
|
||||
async {
|
||||
try {
|
||||
viewerChapters.nextChapter.value = ReaderChapter(
|
||||
scope.coroutineContext + Dispatchers.Default,
|
||||
chapterHandler.getChapter(mangaId, chapterIndex + 1)
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
e.throwIfCancellation()
|
||||
}
|
||||
},
|
||||
async {
|
||||
if (chapterIndex != 0) {
|
||||
try {
|
||||
viewerChapters.prevChapter.value = ReaderChapter(
|
||||
scope.coroutineContext + Dispatchers.Default,
|
||||
chapterHandler.getChapter(mangaId, chapterIndex - 1)
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
e.throwIfCancellation()
|
||||
}
|
||||
}
|
||||
}
|
||||
).awaitAll()
|
||||
val chapters = try {
|
||||
chapterHandler.getChapters(mangaId)
|
||||
} catch (e: Exception) {
|
||||
e.throwIfCancellation()
|
||||
emptyList()
|
||||
}
|
||||
val nextChapter = chapters.find { it.index == chapterIndex + 1 }
|
||||
if (nextChapter != null) {
|
||||
viewerChapters.nextChapter.value = ReaderChapter(
|
||||
scope.coroutineContext + Dispatchers.Default,
|
||||
nextChapter
|
||||
)
|
||||
}
|
||||
val prevChapter = chapters.find { it.index == chapterIndex - 1 }
|
||||
if (prevChapter != null) {
|
||||
viewerChapters.prevChapter.value = ReaderChapter(
|
||||
scope.coroutineContext + Dispatchers.Default,
|
||||
prevChapter
|
||||
)
|
||||
}
|
||||
}
|
||||
chapter.stateObserver.onEach {
|
||||
_state.value = it
|
||||
}.launchIn(chapter.scope)
|
||||
pages.onEach { pageList ->
|
||||
pageList.forEach { it.chapter = chapter }
|
||||
_pages.value = pageList
|
||||
}.launchIn(chapter.scope)
|
||||
_currentPage.onEach { index ->
|
||||
pages.value.getOrNull(index - 1)?.let { chapter.pageLoader?.loadPage(it) }
|
||||
}.launchIn(chapter.scope)
|
||||
val lastPageRead = chapter.chapter.lastPageRead
|
||||
if (lastPageRead != 0) {
|
||||
_currentPage.value = chapter.chapter.lastPageRead
|
||||
}
|
||||
|
||||
chapter.stateObserver
|
||||
.onEach {
|
||||
_state.value = it
|
||||
}
|
||||
.launchIn(chapter.scope)
|
||||
pages
|
||||
.onEach { pageList ->
|
||||
pageList.forEach { it.chapter = chapter }
|
||||
_pages.value = pageList
|
||||
}
|
||||
.launchIn(chapter.scope)
|
||||
|
||||
_currentPage
|
||||
.onEach { index ->
|
||||
if (index == pages.value.size) {
|
||||
markChapterRead(mangaId, chapter)
|
||||
} else {
|
||||
pages.value.getOrNull(index - 1)?.let { chapter.pageLoader?.loadPage(it) }
|
||||
}
|
||||
}
|
||||
.launchIn(chapter.scope)
|
||||
}
|
||||
|
||||
private suspend fun markChapterRead(mangaId: Long, chapter: ReaderChapter) {
|
||||
chapterHandler.updateChapter(mangaId, chapter.chapter.index, true)
|
||||
}
|
||||
|
||||
data class Params(val chapterIndex: Int, val mangaId: Long)
|
||||
|
||||
12
src/main/kotlin/ca/gosyer/ui/reader/model/MoveTo.kt
Normal file
12
src/main/kotlin/ca/gosyer/ui/reader/model/MoveTo.kt
Normal file
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package ca.gosyer.ui.reader.model
|
||||
|
||||
enum class MoveTo {
|
||||
Previous,
|
||||
Next
|
||||
}
|
||||
82
src/main/kotlin/ca/gosyer/ui/reader/viewer/Continuous.kt
Normal file
82
src/main/kotlin/ca/gosyer/ui/reader/viewer/Continuous.kt
Normal file
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package ca.gosyer.ui.reader.viewer
|
||||
|
||||
import androidx.compose.foundation.gestures.animateScrollBy
|
||||
import androidx.compose.foundation.layout.BoxWithConstraints
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.ui.Modifier
|
||||
import ca.gosyer.ui.reader.ChapterSeperator
|
||||
import ca.gosyer.ui.reader.ReaderImage
|
||||
import ca.gosyer.ui.reader.model.MoveTo
|
||||
import ca.gosyer.ui.reader.model.ReaderChapter
|
||||
import ca.gosyer.ui.reader.model.ReaderPage
|
||||
import kotlinx.coroutines.flow.SharedFlow
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.mapLatest
|
||||
|
||||
@Composable
|
||||
fun ContinuousReader(
|
||||
pages: List<ReaderPage>,
|
||||
previousChapter: ReaderChapter?,
|
||||
currentChapter: ReaderChapter,
|
||||
nextChapter: ReaderChapter?,
|
||||
pageModifier: Modifier,
|
||||
pageEmitter: SharedFlow<Pair<MoveTo, Int>>,
|
||||
retry: (ReaderPage) -> Unit,
|
||||
progress: (Int) -> Unit
|
||||
) {
|
||||
BoxWithConstraints {
|
||||
val state = rememberLazyListState(1)
|
||||
LaunchedEffect(Unit) {
|
||||
pageEmitter
|
||||
.mapLatest { (moveTo) ->
|
||||
val by = when (moveTo) {
|
||||
MoveTo.Previous -> -maxHeight
|
||||
MoveTo.Next -> maxHeight
|
||||
}
|
||||
state.animateScrollBy(by.value)
|
||||
}
|
||||
.launchIn(this)
|
||||
}
|
||||
|
||||
LazyColumn(state = state) {
|
||||
item {
|
||||
LaunchedEffect(Unit) {
|
||||
progress(0)
|
||||
}
|
||||
ChapterSeperator(previousChapter, currentChapter)
|
||||
}
|
||||
items(pages) { image ->
|
||||
LaunchedEffect(image.index) {
|
||||
progress(image.index)
|
||||
}
|
||||
ReaderImage(
|
||||
image.index,
|
||||
image.bitmap.collectAsState().value,
|
||||
image.status.collectAsState().value,
|
||||
image.error.collectAsState().value,
|
||||
loadingModifier = pageModifier,
|
||||
retry = { pageIndex ->
|
||||
pages.find { it.index == pageIndex }?.let { retry(it) }
|
||||
}
|
||||
)
|
||||
}
|
||||
item {
|
||||
LaunchedEffect(Unit) {
|
||||
progress(pages.size)
|
||||
}
|
||||
ChapterSeperator(currentChapter, nextChapter)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
113
src/main/kotlin/ca/gosyer/ui/reader/viewer/Pager.kt
Normal file
113
src/main/kotlin/ca/gosyer/ui/reader/viewer/Pager.kt
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package ca.gosyer.ui.reader.viewer
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.ui.Modifier
|
||||
import ca.gosyer.data.reader.model.Direction
|
||||
import ca.gosyer.ui.reader.ChapterSeperator
|
||||
import ca.gosyer.ui.reader.ReaderImage
|
||||
import ca.gosyer.ui.reader.model.MoveTo
|
||||
import ca.gosyer.ui.reader.model.ReaderChapter
|
||||
import ca.gosyer.ui.reader.model.ReaderPage
|
||||
import com.google.accompanist.pager.HorizontalPager
|
||||
import com.google.accompanist.pager.VerticalPager
|
||||
import com.google.accompanist.pager.rememberPagerState
|
||||
import kotlinx.coroutines.flow.SharedFlow
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.mapLatest
|
||||
|
||||
@Composable
|
||||
fun PagerReader(
|
||||
direction: Direction,
|
||||
currentPage: Int,
|
||||
pages: List<ReaderPage>,
|
||||
previousChapter: ReaderChapter?,
|
||||
currentChapter: ReaderChapter,
|
||||
nextChapter: ReaderChapter?,
|
||||
pageModifier: Modifier,
|
||||
pageEmitter: SharedFlow<Pair<MoveTo, Int>>,
|
||||
retry: (ReaderPage) -> Unit,
|
||||
progress: (Int) -> Unit
|
||||
) {
|
||||
val state = rememberPagerState(pages.size + 1, initialPage = currentPage)
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
pageEmitter
|
||||
.mapLatest { (moveTo, currentPage) ->
|
||||
val page = when (moveTo) {
|
||||
MoveTo.Previous -> currentPage - 1
|
||||
MoveTo.Next -> currentPage + 1
|
||||
}
|
||||
state.animateScrollToPage(page)
|
||||
}
|
||||
.launchIn(this)
|
||||
}
|
||||
|
||||
LaunchedEffect(state.currentPage) {
|
||||
if (state.currentPage != currentPage) {
|
||||
progress(state.currentPage)
|
||||
}
|
||||
}
|
||||
|
||||
if (direction == Direction.Down || direction == Direction.Up) {
|
||||
VerticalPager(state, reverseLayout = direction == Direction.Up) {
|
||||
HandlePager(
|
||||
pages,
|
||||
it,
|
||||
previousChapter,
|
||||
currentChapter,
|
||||
nextChapter,
|
||||
pageModifier,
|
||||
retry
|
||||
)
|
||||
}
|
||||
} else {
|
||||
HorizontalPager(state, reverseLayout = direction == Direction.Left) {
|
||||
HandlePager(
|
||||
pages,
|
||||
it,
|
||||
previousChapter,
|
||||
currentChapter,
|
||||
nextChapter,
|
||||
pageModifier,
|
||||
retry
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun HandlePager(
|
||||
pages: List<ReaderPage>,
|
||||
page: Int,
|
||||
previousChapter: ReaderChapter?,
|
||||
currentChapter: ReaderChapter,
|
||||
nextChapter: ReaderChapter?,
|
||||
pageModifier: Modifier,
|
||||
retry: (ReaderPage) -> Unit,
|
||||
) {
|
||||
when (page) {
|
||||
0 -> ChapterSeperator(previousChapter, currentChapter)
|
||||
pages.size -> ChapterSeperator(currentChapter, nextChapter)
|
||||
else -> {
|
||||
val image = pages[page - 1]
|
||||
ReaderImage(
|
||||
image.index,
|
||||
image.bitmap.collectAsState().value,
|
||||
image.status.collectAsState().value,
|
||||
image.error.collectAsState().value,
|
||||
loadingModifier = pageModifier,
|
||||
retry = { pageIndex ->
|
||||
pages.find { it.index == pageIndex }?.let { retry(it) }
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user