Improve page previews
This commit is contained in:
parent
c36d2794bb
commit
cbb743f995
@ -34,6 +34,7 @@ import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableIntStateOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
@ -44,6 +45,7 @@ import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.platform.LocalHapticFeedback
|
||||
import androidx.compose.ui.platform.LocalLayoutDirection
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.util.fastAll
|
||||
import androidx.compose.ui.util.fastAny
|
||||
import androidx.compose.ui.util.fastMap
|
||||
@ -57,6 +59,7 @@ import eu.kanade.presentation.manga.components.MangaInfoBox
|
||||
import eu.kanade.presentation.manga.components.MangaInfoButtons
|
||||
import eu.kanade.presentation.manga.components.MangaToolbar
|
||||
import eu.kanade.presentation.manga.components.MissingChapterCountListItem
|
||||
import eu.kanade.presentation.manga.components.PagePreviewItems
|
||||
import eu.kanade.presentation.manga.components.PagePreviews
|
||||
import eu.kanade.presentation.manga.components.SearchMetadataChips
|
||||
import eu.kanade.presentation.util.formatChapterNumber
|
||||
@ -339,6 +342,9 @@ private fun MangaScreenSmallImpl(
|
||||
}
|
||||
// SY -->
|
||||
val metadataDescription = metadataDescription(state.source)
|
||||
var maxWidth by remember {
|
||||
mutableStateOf(Dp.Hairline)
|
||||
}
|
||||
// SY <--
|
||||
|
||||
val internalOnBackPressed = {
|
||||
@ -546,16 +552,13 @@ private fun MangaScreenSmallImpl(
|
||||
}
|
||||
|
||||
if (state.pagePreviewsState !is PagePreviewState.Unused) {
|
||||
item(
|
||||
key = MangaScreenItem.CHAPTER_PREVIEW,
|
||||
contentType = MangaScreenItem.CHAPTER_PREVIEW,
|
||||
) {
|
||||
PagePreviews(
|
||||
pagePreviewState = state.pagePreviewsState,
|
||||
onOpenPage = onOpenPagePreview,
|
||||
onMorePreviewsClicked = onMorePreviewsClicked,
|
||||
)
|
||||
}
|
||||
PagePreviewItems(
|
||||
pagePreviewState = state.pagePreviewsState,
|
||||
onOpenPage = onOpenPagePreview,
|
||||
onMorePreviewsClicked = onMorePreviewsClicked,
|
||||
maxWidth = maxWidth,
|
||||
setMaxWidth = { maxWidth = it }
|
||||
)
|
||||
}
|
||||
// SY <--
|
||||
|
||||
|
@ -25,7 +25,9 @@ enum class MangaScreenItem {
|
||||
|
||||
// SY -->
|
||||
INFO_BUTTONS,
|
||||
CHAPTER_PREVIEW,
|
||||
CHAPTER_PREVIEW_LOADING,
|
||||
CHAPTER_PREVIEW_ROW,
|
||||
CHAPTER_PREVIEW_MORE,
|
||||
|
||||
// SY <--
|
||||
CHAPTER_HEADER,
|
||||
|
@ -10,6 +10,8 @@ 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.LazyListScope
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.material3.CircularProgressIndicator
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
@ -31,69 +33,132 @@ import androidx.compose.ui.unit.dp
|
||||
import coil.compose.SubcomposeAsyncImage
|
||||
import coil.compose.SubcomposeAsyncImageContent
|
||||
import eu.kanade.domain.manga.model.PagePreview
|
||||
import eu.kanade.presentation.manga.MangaScreenItem
|
||||
import eu.kanade.tachiyomi.ui.manga.PagePreviewState
|
||||
import exh.util.floor
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import tachiyomi.i18n.sy.SYMR
|
||||
import tachiyomi.presentation.core.components.material.padding
|
||||
import tachiyomi.presentation.core.i18n.stringResource
|
||||
|
||||
@Composable
|
||||
private fun PagePreviewLoading(
|
||||
setMaxWidth: (Dp) -> Unit
|
||||
) {
|
||||
val density = LocalDensity.current
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.height(60.dp)
|
||||
.fillMaxWidth()
|
||||
.onGloballyPositioned {
|
||||
setMaxWidth(with(density) { it.size.width.toDp() })
|
||||
},
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
CircularProgressIndicator()
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun PagePreviewRow(
|
||||
onOpenPage: (Int) -> Unit,
|
||||
items: ImmutableList<PagePreview>
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 8.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.padding.medium),
|
||||
) {
|
||||
items.forEach { page ->
|
||||
PagePreview(
|
||||
modifier = Modifier.weight(1F),
|
||||
page = page,
|
||||
onOpenPage = onOpenPage,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun PagePreviewMore(
|
||||
onMorePreviewsClicked: () -> Unit,
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
TextButton(onClick = onMorePreviewsClicked) {
|
||||
Text(stringResource(SYMR.strings.more_previews))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun PagePreviews(
|
||||
pagePreviewState: PagePreviewState,
|
||||
onOpenPage: (Int) -> Unit,
|
||||
onMorePreviewsClicked: () -> Unit,
|
||||
) {
|
||||
when (pagePreviewState) {
|
||||
PagePreviewState.Loading -> {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.height(60.dp)
|
||||
.fillMaxWidth(),
|
||||
contentAlignment = Alignment.Center,
|
||||
Column(Modifier.fillMaxWidth()) {
|
||||
var maxWidth by remember {
|
||||
mutableStateOf(Dp.Hairline)
|
||||
}
|
||||
when {
|
||||
pagePreviewState is PagePreviewState.Loading || maxWidth == Dp.Hairline -> {
|
||||
PagePreviewLoading(setMaxWidth = { maxWidth = it })
|
||||
}
|
||||
pagePreviewState is PagePreviewState.Success -> {
|
||||
val itemPerRowCount = (maxWidth / 120.dp).floor()
|
||||
pagePreviewState.pagePreviews.take(4 * itemPerRowCount).chunked(itemPerRowCount).forEach {
|
||||
PagePreviewRow(
|
||||
onOpenPage = onOpenPage,
|
||||
items = remember(it) { it.toImmutableList() }
|
||||
)
|
||||
}
|
||||
|
||||
PagePreviewMore(onMorePreviewsClicked)
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun LazyListScope.PagePreviewItems(
|
||||
pagePreviewState: PagePreviewState,
|
||||
onOpenPage: (Int) -> Unit,
|
||||
onMorePreviewsClicked: () -> Unit,
|
||||
maxWidth: Dp,
|
||||
setMaxWidth: (Dp) -> Unit
|
||||
) {
|
||||
when {
|
||||
pagePreviewState is PagePreviewState.Loading || maxWidth == Dp.Hairline -> {
|
||||
item(
|
||||
key = MangaScreenItem.CHAPTER_PREVIEW_LOADING,
|
||||
contentType = MangaScreenItem.CHAPTER_PREVIEW_LOADING,
|
||||
) {
|
||||
CircularProgressIndicator()
|
||||
PagePreviewLoading(setMaxWidth = setMaxWidth)
|
||||
}
|
||||
}
|
||||
is PagePreviewState.Success -> {
|
||||
var maxWidth by remember {
|
||||
mutableStateOf(Dp.Hairline)
|
||||
}
|
||||
val density = LocalDensity.current
|
||||
Box(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.onGloballyPositioned {
|
||||
maxWidth = with(density) { it.size.width.toDp() }
|
||||
},
|
||||
pagePreviewState is PagePreviewState.Success -> {
|
||||
val itemPerRowCount = (maxWidth / 120.dp).floor()
|
||||
items(
|
||||
key = { "${MangaScreenItem.CHAPTER_PREVIEW_ROW}-$it" },
|
||||
contentType = { MangaScreenItem.CHAPTER_PREVIEW_ROW },
|
||||
items = pagePreviewState.pagePreviews.take(4 * itemPerRowCount).chunked(itemPerRowCount),
|
||||
) {
|
||||
if (maxWidth == Dp.Hairline) return@Box
|
||||
val itemPerRowCount = (maxWidth / 120.dp).floor()
|
||||
Column(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.spacedBy(MaterialTheme.padding.small),
|
||||
) {
|
||||
pagePreviewState.pagePreviews.take(4 * itemPerRowCount).chunked(itemPerRowCount).forEach {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 8.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.padding.medium),
|
||||
) {
|
||||
it.forEach { page ->
|
||||
PagePreview(
|
||||
modifier = Modifier.weight(1F),
|
||||
page = page,
|
||||
onOpenPage = onOpenPage,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
TextButton(onClick = onMorePreviewsClicked) {
|
||||
Text(stringResource(SYMR.strings.more_previews))
|
||||
}
|
||||
}
|
||||
PagePreviewRow(
|
||||
onOpenPage = onOpenPage,
|
||||
items = remember(it) { it.toImmutableList() }
|
||||
)
|
||||
}
|
||||
item(
|
||||
key = MangaScreenItem.CHAPTER_PREVIEW_MORE,
|
||||
contentType = MangaScreenItem.CHAPTER_PREVIEW_MORE,
|
||||
) {
|
||||
PagePreviewMore(onMorePreviewsClicked)
|
||||
}
|
||||
}
|
||||
else -> {}
|
||||
|
@ -406,7 +406,6 @@ class EHentai(
|
||||
@Suppress("DEPRECATION")
|
||||
override fun fetchChapterList(manga: SManga) = fetchChapterList(manga) {}
|
||||
|
||||
@Suppress("DeprecatedCallableAddReplaceWith")
|
||||
@Deprecated("Use the 1.x API instead", replaceWith = ReplaceWith("getChapterList"))
|
||||
fun fetchChapterList(manga: SManga, throttleFunc: suspend () -> Unit) = runAsObservable {
|
||||
getChapterList(manga, throttleFunc)
|
||||
@ -476,6 +475,7 @@ class EHentai(
|
||||
|
||||
@Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getLatestUpdates"))
|
||||
override fun fetchLatestUpdates(page: Int): Observable<MangasPage> {
|
||||
@Suppress("DEPRECATION")
|
||||
return super<HttpSource>.fetchLatestUpdates(page).checkValid()
|
||||
}
|
||||
|
||||
@ -485,6 +485,7 @@ class EHentai(
|
||||
|
||||
@Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getPopularManga"))
|
||||
override fun fetchPopularManga(page: Int): Observable<MangasPage> {
|
||||
@Suppress("DEPRECATION")
|
||||
return super<HttpSource>.fetchPopularManga(page).checkValid()
|
||||
}
|
||||
|
||||
@ -496,6 +497,7 @@ class EHentai(
|
||||
@Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getSearchManga"))
|
||||
override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable<MangasPage> =
|
||||
urlImportFetchSearchManga(context, query) {
|
||||
@Suppress("DEPRECATION")
|
||||
super<HttpSource>.fetchSearchManga(page, query, filters).checkValid()
|
||||
}
|
||||
|
||||
@ -506,7 +508,7 @@ class EHentai(
|
||||
}
|
||||
|
||||
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
||||
val toplist = ToplistOption.values()[filters.firstNotNullOfOrNull { (it as? ToplistOptions)?.state } ?: 0]
|
||||
val toplist = ToplistOption.entries[filters.firstNotNullOfOrNull { (it as? ToplistOptions)?.state } ?: 0]
|
||||
if (toplist != ToplistOption.NONE) {
|
||||
val uri = "https://e-hentai.org".toUri().buildUpon()
|
||||
uri.appendPath("toplist.php")
|
||||
@ -794,6 +796,7 @@ class EHentai(
|
||||
override fun pageListParse(response: Response) =
|
||||
throw UnsupportedOperationException("Unused method was called somehow!")
|
||||
|
||||
@Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getImageUrl"))
|
||||
override fun fetchImageUrl(page: Page): Observable<String> {
|
||||
return client.newCall(imageUrlRequest(page))
|
||||
.asObservableSuccess()
|
||||
@ -957,7 +960,7 @@ class EHentai(
|
||||
|
||||
class ToplistOptions : Filter.Select<ToplistOption>(
|
||||
"Toplists",
|
||||
ToplistOption.values(),
|
||||
ToplistOption.entries.toTypedArray(),
|
||||
)
|
||||
|
||||
class GenreOption(name: String, val genreId: Int) : Filter.CheckBox(name, false)
|
||||
|
Loading…
x
Reference in New Issue
Block a user