Fix losing reading progress on reading mode change
This commit is contained in:
1 parent
9013778f58
commit
d6c36146ba
1 file changed
+41
-34
@@ -8,7 +8,6 @@ import androidx.compose.runtime.LaunchedEffect
|
|||||||
import androidx.compose.runtime.Stable
|
import androidx.compose.runtime.Stable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableIntStateOf
|
import androidx.compose.runtime.mutableIntStateOf
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.runtime.snapshotFlow
|
import androidx.compose.runtime.snapshotFlow
|
||||||
@@ -16,7 +15,7 @@ import com.hippo.ehviewer.Settings
|
|||||||
import com.hippo.ehviewer.gallery.PageLoader2
|
import com.hippo.ehviewer.gallery.PageLoader2
|
||||||
import kotlin.math.absoluteValue
|
import kotlin.math.absoluteValue
|
||||||
import kotlinx.coroutines.flow.collectLatest
|
import kotlinx.coroutines.flow.collectLatest
|
||||||
import kotlinx.coroutines.flow.mapNotNull
|
import kotlinx.coroutines.flow.filterNotNull
|
||||||
|
|
||||||
@Stable
|
@Stable
|
||||||
class SliderPagerDoubleSync(
|
class SliderPagerDoubleSync(
|
||||||
@@ -24,8 +23,10 @@ class SliderPagerDoubleSync(
|
|||||||
private val pagerState: PagerState,
|
private val pagerState: PagerState,
|
||||||
private val pageLoader: PageLoader2,
|
private val pageLoader: PageLoader2,
|
||||||
) {
|
) {
|
||||||
private var sliderFollowPager by mutableStateOf(true)
|
private var requestScroll = true
|
||||||
var sliderValue by mutableIntStateOf(1)
|
private var sliderFollowPager = true
|
||||||
|
var sliderValue by mutableIntStateOf(pageLoader.startPage + 1)
|
||||||
|
private set
|
||||||
|
|
||||||
fun sliderScrollTo(index: Int) {
|
fun sliderScrollTo(index: Int) {
|
||||||
sliderFollowPager = false
|
sliderFollowPager = false
|
||||||
@@ -37,52 +38,55 @@ class SliderPagerDoubleSync(
|
|||||||
val fling by lazyListState.interactionSource.collectIsDraggedAsState()
|
val fling by lazyListState.interactionSource.collectIsDraggedAsState()
|
||||||
val pagerFling by pagerState.interactionSource.collectIsDraggedAsState()
|
val pagerFling by pagerState.interactionSource.collectIsDraggedAsState()
|
||||||
if (fling || pagerFling) sliderFollowPager = true
|
if (fling || pagerFling) sliderFollowPager = true
|
||||||
val startPage = remember { pageLoader.startPage }
|
|
||||||
val currentIndexFlow = remember(webtoon) {
|
val currentIndexFlow = remember(webtoon) {
|
||||||
|
requestScroll = true
|
||||||
if (webtoon) {
|
if (webtoon) {
|
||||||
snapshotFlow { lazyListState.layoutInfo }.mapNotNull { info ->
|
snapshotFlow {
|
||||||
info.visibleItemsInfo.lastOrNull {
|
with(lazyListState.layoutInfo) {
|
||||||
it.offset <= maxOf(info.viewportStartOffset, info.viewportEndOffset - it.size)
|
visibleItemsInfo.lastOrNull {
|
||||||
}?.index
|
it.offset <= maxOf(viewportStartOffset, viewportEndOffset - it.size)
|
||||||
}
|
}?.index
|
||||||
|
}
|
||||||
|
}.filterNotNull()
|
||||||
} else {
|
} else {
|
||||||
snapshotFlow { pagerState.currentPage }
|
snapshotFlow { pagerState.currentPage }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sliderFollowPager) {
|
LaunchedEffect(currentIndexFlow) {
|
||||||
LaunchedEffect(currentIndexFlow) {
|
currentIndexFlow.collect { index ->
|
||||||
currentIndexFlow.collect { index ->
|
if (sliderFollowPager && !requestScroll) {
|
||||||
sliderValue = index + 1
|
sliderValue = index + 1
|
||||||
pageLoader.startPage = index
|
pageLoader.startPage = index
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
LaunchedEffect(webtoon) {
|
LaunchedEffect(webtoon) {
|
||||||
snapshotFlow { sliderValue - 1 }.collectLatest { index ->
|
snapshotFlow { sliderValue - 1 }.collectLatest { index ->
|
||||||
if (webtoon) {
|
if (sliderFollowPager && !requestScroll) return@collectLatest
|
||||||
val noAnim = (index - lazyListState.firstVisibleItemIndex).absoluteValue > SMOOTH_SCROLL_THRESHOLD || !Settings.pageTransitions.value
|
if (webtoon) {
|
||||||
if (noAnim) {
|
if (requestScroll) {
|
||||||
lazyListState.scrollToItem(index)
|
lazyListState.requestScrollToItem(index)
|
||||||
} else {
|
requestScroll = false
|
||||||
lazyListState.animateScrollToItem(index)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
val noAnim = (index - pagerState.currentPage).absoluteValue > SMOOTH_SCROLL_THRESHOLD || !Settings.pageTransitions.value
|
if (smoothScroll((index - lazyListState.firstVisibleItemIndex))) {
|
||||||
if (noAnim) {
|
lazyListState.animateScrollToItem(index)
|
||||||
pagerState.scrollToPage(index)
|
|
||||||
} else {
|
} else {
|
||||||
|
lazyListState.scrollToItem(index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (requestScroll) {
|
||||||
|
pagerState.requestScrollToPage(index)
|
||||||
|
requestScroll = false
|
||||||
|
} else {
|
||||||
|
if (smoothScroll((index - pagerState.currentPage))) {
|
||||||
pagerState.animateScrollToPage(index)
|
pagerState.animateScrollToPage(index)
|
||||||
|
} else {
|
||||||
|
pagerState.scrollToPage(index)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pageLoader.startPage = index
|
|
||||||
}
|
}
|
||||||
}
|
pageLoader.startPage = index
|
||||||
}
|
|
||||||
LaunchedEffect(Unit) {
|
|
||||||
if (webtoon) {
|
|
||||||
lazyListState.scrollToItem(startPage)
|
|
||||||
} else {
|
|
||||||
pagerState.scrollToPage(startPage)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -100,4 +104,7 @@ fun rememberSliderPagerDoubleSyncState(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun smoothScroll(distance: Int) =
|
||||||
|
distance.absoluteValue < SMOOTH_SCROLL_THRESHOLD && Settings.pageTransitions.value
|
||||||
|
|
||||||
private const val SMOOTH_SCROLL_THRESHOLD = 50
|
private const val SMOOTH_SCROLL_THRESHOLD = 50
|
||||||
Reference in new issue
Block a user