Restore jumpToCertainPage ability

This commit is contained in:
tarsin committed 2023-05-10 23:12:15 +08:00
1 parent 577286eb56
commit c786ff0087
3 files changed
+64 -87

No files matched your search

@@ -15,7 +15,6 @@
*/
package com.hippo.ehviewer.ui.scene
import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
@@ -23,9 +22,13 @@ import android.view.ViewGroup
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
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.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.rememberLazyGridState
@@ -35,12 +38,17 @@ import androidx.compose.material.icons.filled.CallMissedOutgoing
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Slider
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll
@@ -48,6 +56,7 @@ import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import androidx.paging.Pager
@@ -60,7 +69,6 @@ import androidx.paging.compose.itemContentType
import androidx.paging.compose.itemKey
import arrow.core.partially1
import coil.imageLoader
import com.hippo.app.BaseDialogBuilder
import com.hippo.ehviewer.R
import com.hippo.ehviewer.Settings
import com.hippo.ehviewer.client.EhEngine
@@ -68,17 +76,19 @@ import com.hippo.ehviewer.client.EhUrl
import com.hippo.ehviewer.client.data.GalleryDetail
import com.hippo.ehviewer.client.data.GalleryPreview
import com.hippo.ehviewer.coil.imageRequest
import com.hippo.ehviewer.databinding.DialogGoToBinding
import com.hippo.ehviewer.ui.widget.CrystalCard
import com.hippo.ehviewer.ui.widget.EhAsyncPreview
import com.hippo.ehviewer.ui.widget.rememberDialogState
import com.hippo.ehviewer.ui.widget.setMD3Content
import com.hippo.util.getParcelableCompat
import com.hippo.widget.recyclerview.getSpanCountForSuitableSize
import eu.kanade.tachiyomi.util.lang.launchIO
import eu.kanade.tachiyomi.util.lang.withIOContext
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import moe.tarsin.coroutines.runSuspendCatching
import java.util.Locale
import kotlin.math.roundToInt
class GalleryPreviewsScene : BaseScene() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
@@ -91,10 +101,34 @@ class GalleryPreviewsScene : BaseScene() {
// Padding is not subtracted here to have the same column count as gallery list and preview
val totalSpace = LocalConfiguration.current.screenWidthDp
val columnCount = getSpanCountForSuitableSize(totalSpace, Settings.thumbSizeDp)
val state = rememberLazyGridState()
val dialogState = rememberDialogState()
dialogState.Handler()
val coroutineScope = rememberCoroutineScope()
val pages = galleryDetail.pages
val pgSize = galleryDetail.previewList.size
suspend fun showGoToDialog() {
val goto = dialogState.show(initial = 1, title = R.string.go_to) {
var jumpTo by remember { mutableStateOf(1f) }
Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier.padding(top = 18.dp)) {
Text(text = String.format(Locale.US, "%d", 1), modifier = Modifier.padding(12.dp))
Slider(
value = jumpTo,
onValueChange = { jumpTo = it },
modifier = Modifier.height(48.dp).width(0.dp).weight(1F).align(Alignment.CenterVertically),
valueRange = 1f..galleryDetail.previewPages.toFloat(),
steps = galleryDetail.previewPages - 2,
onValueChangeFinished = {
this@show shouldReturn jumpTo.roundToInt()
},
)
Text(text = String.format(Locale.US, "%d", pages), modifier = Modifier.padding(12.dp))
}
}
state.scrollToItem((goto - 1) * pgSize)
}
// No Refresh support
val source = remember {
object : PagingSource<Int, GalleryPreview>() {
@@ -126,7 +160,9 @@ class GalleryPreviewsScene : BaseScene() {
},
actions = {
if (galleryDetail.previewPages > 1) {
IconButton(onClick = ::showGoto) {
IconButton(onClick = {
coroutineScope.launch { showGoToDialog() }
}) {
Icon(imageVector = Icons.Default.CallMissedOutgoing, contentDescription = null)
}
}
@@ -135,7 +171,6 @@ class GalleryPreviewsScene : BaseScene() {
)
},
) { paddingValues ->
val state = rememberLazyGridState()
LaunchedEffect(toNextPage) {
delay(500) // Should we wait this animation?
if (toNextPage) state.scrollToItem(pgSize)
@@ -176,16 +211,6 @@ class GalleryPreviewsScene : BaseScene() {
}
}
private fun showGoto() {
/*
val pages = mHelper!!.pages
if (pages > 1 && mHelper!!.canGoTo()) {
showGoToDialog(requireContext(), pages, mHelper!!.pageForBottom)
}
*/
}
private suspend fun getPreviewListByPage(galleryDetail: GalleryDetail, page: Int): List<GalleryPreview> {
galleryDetail.run {
val url = EhUrl.getGalleryDetailUrl(gid, token, page, false)
@@ -197,23 +222,6 @@ class GalleryPreviewsScene : BaseScene() {
}
}
private fun showGoToDialog(context: Context, pages: Int, currentPage: Int) {
val dialogBinding = DialogGoToBinding.inflate(layoutInflater)
dialogBinding.start.text = String.format(Locale.US, "%d", 1)
dialogBinding.end.text = String.format(Locale.US, "%d", pages)
dialogBinding.slider.valueTo = pages.toFloat()
dialogBinding.slider.value = (currentPage + 1).toFloat()
val dialog = BaseDialogBuilder(context)
.setTitle(R.string.go_to)
.setView(dialogBinding.root)
.setPositiveButton(android.R.string.ok) { _, _ ->
val page = (dialogBinding.slider.value - 1).toInt()
// mHelper!!.goTo(page)
}
.create()
dialog.show()
}
companion object {
const val KEY_GALLERY_DETAIL = "gallery_detail"
const val KEY_NEXT_PAGE = "next_page"
@@ -13,30 +13,46 @@ import androidx.compose.ui.res.stringResource
import kotlinx.coroutines.suspendCancellableCoroutine
import kotlin.coroutines.resume
interface DialogScope {
fun dismiss()
interface DialogScope<R> {
infix fun shouldReturn(value: R)
}
class DialogState : DialogScope {
class DialogState {
private var content: (@Composable () -> Unit)? by mutableStateOf(null)
@Composable
fun Handler() = content?.invoke()
override fun dismiss() {
fun dismiss() {
content = null
}
suspend fun show(block: @Composable DialogScope.() -> Unit) {
suspend fun <R> show(initial: R, @StringRes title: Int? = null, block: @Composable DialogScope<R>.() -> Unit): R {
return suspendCancellableCoroutine { cont ->
cont.invokeOnCancellation { dismiss() }
content = {
var result by remember { mutableStateOf(initial) }
AlertDialog(
onDismissRequest = {
cont.cancel()
dismiss()
cont.resume(Unit)
},
content = { block() },
confirmButton = {
TextButton(onClick = {
dismiss()
cont.resume(result)
}) {
Text(text = stringResource(id = android.R.string.ok))
}
},
title = title?.let { { Text(text = stringResource(id = title)) } },
text = {
block(object : DialogScope<R> {
override infix fun shouldReturn(value: R) {
result = value
}
})
},
)
}
}
-47
View File
@@ -1,47 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ Copyright 2015 Hippo Seven
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:paddingHorizontal="?attr/dialogPreferredPadding"
android:paddingTop="@dimen/abc_dialog_padding_top_material">
<TextView
android:id="@+id/start"
android:layout_width="32dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:gravity="center_horizontal" />
<com.hippo.app.HapticSlider
android:id="@+id/slider"
android:layout_width="0dp"
android:layout_height="48dp"
android:layout_gravity="center_horizontal"
android:layout_weight="1"
android:stepSize="1"
android:valueFrom="1" />
<TextView
android:id="@+id/end"
android:layout_width="32dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:gravity="center_horizontal" />
</LinearLayout>