Implement retry on click for thumbnails
This commit is contained in:
1 parent
85b03d9d8a
commit
4052007de8
4 files changed
+108
-39
No files matched your search
@@ -1,6 +1,9 @@
|
||||
package com.hippo.ehviewer.ui.main
|
||||
|
||||
import androidx.compose.animation.SharedTransitionScope
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.ShapeDefaults
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.NonRestartableComposable
|
||||
@@ -12,8 +15,12 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import coil3.Image
|
||||
import coil3.Image as CoilImage
|
||||
import coil3.compose.AsyncImage
|
||||
import coil3.compose.AsyncImagePainter
|
||||
import coil3.compose.ConstraintsSizeResolver
|
||||
import coil3.compose.rememberAsyncImagePainter
|
||||
import coil3.compose.rememberConstraintsSizeResolver
|
||||
import coil3.request.ImageRequest
|
||||
import com.hippo.ehviewer.client.data.GalleryInfo
|
||||
import com.hippo.ehviewer.ktbuilder.imageRequest
|
||||
@@ -25,7 +32,25 @@ import com.hippo.ehviewer.ui.tools.shouldCrop
|
||||
@NonRestartableComposable
|
||||
fun requestOf(model: GalleryInfo): ImageRequest {
|
||||
val context = LocalContext.current
|
||||
return remember(model) { context.imageRequest(model) }
|
||||
return remember(model) { context.imageRequest(model) }.withSizeResolver()
|
||||
}
|
||||
|
||||
@Composable
|
||||
@NonRestartableComposable
|
||||
fun ImageRequest.withSizeResolver() = if (defined.sizeResolver != null) {
|
||||
this
|
||||
} else {
|
||||
val sizeResolver = rememberConstraintsSizeResolver()
|
||||
remember(this, sizeResolver) { newBuilder().size(sizeResolver).build() }
|
||||
}
|
||||
|
||||
fun Modifier.imageRequest(request: ImageRequest): Modifier {
|
||||
val sizeResolver = request.sizeResolver
|
||||
return if (sizeResolver is ConstraintsSizeResolver) {
|
||||
then(sizeResolver)
|
||||
} else {
|
||||
this
|
||||
}
|
||||
}
|
||||
|
||||
context(SharedTransitionScope, TransitionsVisibilityScope, SETNodeGenerator)
|
||||
@@ -34,7 +59,7 @@ context(SharedTransitionScope, TransitionsVisibilityScope, SETNodeGenerator)
|
||||
fun EhAsyncThumb(
|
||||
model: GalleryInfo,
|
||||
modifier: Modifier = Modifier,
|
||||
onSuccess: ((Image) -> Unit)? = null,
|
||||
onSuccess: ((CoilImage) -> Unit)? = null,
|
||||
contentScale: ContentScale = ContentScale.Fit,
|
||||
) = AsyncImage(
|
||||
model = requestOf(model),
|
||||
@@ -69,3 +94,35 @@ fun EhAsyncCropThumb(
|
||||
contentScale = contentScale,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun EhThumbCard(
|
||||
key: GalleryInfo,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
var contentScale by remember(key) { mutableStateOf(ContentScale.Fit) }
|
||||
val request = requestOf(key)
|
||||
val painter = rememberAsyncImagePainter(
|
||||
model = request,
|
||||
onSuccess = {
|
||||
if (it.result.image.shouldCrop) {
|
||||
contentScale = ContentScale.Crop
|
||||
}
|
||||
},
|
||||
)
|
||||
Card(
|
||||
onClick = {
|
||||
if (painter.state.value is AsyncImagePainter.State.Error) {
|
||||
painter.restart()
|
||||
}
|
||||
},
|
||||
modifier = modifier,
|
||||
) {
|
||||
Image(
|
||||
painter = painter,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.imageRequest(request).fillMaxSize().clip(ShapeDefaults.Medium),
|
||||
contentScale = contentScale,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -109,16 +109,14 @@ fun GalleryDetailHeaderCard(
|
||||
modifier: Modifier = Modifier,
|
||||
) = ElevatedCard(modifier = modifier) {
|
||||
Row {
|
||||
Card {
|
||||
with(detailThumbGenerator) {
|
||||
EhAsyncCropThumb(
|
||||
key = remember(info.gid) { info },
|
||||
modifier = Modifier.size(
|
||||
dimensionResource(id = R.dimen.gallery_detail_thumb_width),
|
||||
dimensionResource(id = R.dimen.gallery_detail_thumb_height),
|
||||
),
|
||||
)
|
||||
}
|
||||
with(detailThumbGenerator) {
|
||||
EhThumbCard(
|
||||
key = remember(info.gid) { info },
|
||||
modifier = Modifier.size(
|
||||
dimensionResource(id = R.dimen.gallery_detail_thumb_width),
|
||||
dimensionResource(id = R.dimen.gallery_detail_thumb_height),
|
||||
),
|
||||
)
|
||||
}
|
||||
Spacer(modifier = Modifier.weight(0.5F))
|
||||
Column(
|
||||
|
||||
@@ -18,7 +18,6 @@ import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Download
|
||||
import androidx.compose.material.icons.filled.Favorite
|
||||
import androidx.compose.material3.Badge
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.ProvideTextStyle
|
||||
@@ -108,13 +107,11 @@ fun GalleryInfoListItem(
|
||||
interactionSource = interactionSource,
|
||||
) {
|
||||
Row {
|
||||
Card {
|
||||
with(listThumbGenerator) {
|
||||
EhAsyncCropThumb(
|
||||
key = info,
|
||||
modifier = Modifier.aspectRatio(DEFAULT_RATIO).fillMaxSize(),
|
||||
)
|
||||
}
|
||||
with(listThumbGenerator) {
|
||||
EhThumbCard(
|
||||
key = info,
|
||||
modifier = Modifier.aspectRatio(DEFAULT_RATIO),
|
||||
)
|
||||
}
|
||||
ConstraintLayout(
|
||||
modifier = Modifier.padding(start = 8.dp, top = 2.dp, end = 4.dp, bottom = 4.dp).fillMaxSize(),
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.hippo.ehviewer.ui.main
|
||||
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.aspectRatio
|
||||
@@ -20,8 +21,8 @@ import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.unit.IntOffset
|
||||
import androidx.compose.ui.unit.IntSize
|
||||
import coil3.BitmapImage
|
||||
import coil3.compose.AsyncImage
|
||||
import coil3.compose.AsyncImagePainter.State
|
||||
import coil3.compose.rememberAsyncImagePainter
|
||||
import coil3.request.ImageRequest
|
||||
import com.hippo.ehviewer.client.data.GalleryPreview
|
||||
import com.hippo.ehviewer.client.data.V2GalleryPreview
|
||||
@@ -33,19 +34,19 @@ import com.hippo.ehviewer.ui.tools.shouldCrop
|
||||
@NonRestartableComposable
|
||||
fun requestOf(model: GalleryPreview): ImageRequest {
|
||||
val context = LocalContext.current
|
||||
return remember(model) { context.imageRequest(model) }
|
||||
return remember(model) { context.imageRequest(model) }.withSizeResolver()
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun EhAsyncPreview(
|
||||
fun EhPreviewCard(
|
||||
model: GalleryPreview,
|
||||
onClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
var contentScale by remember(model) { mutableStateOf(ContentScale.Fit) }
|
||||
AsyncImage(
|
||||
model = requestOf(model),
|
||||
contentDescription = null,
|
||||
modifier = modifier,
|
||||
val request = requestOf(model)
|
||||
val painter = rememberAsyncImagePainter(
|
||||
model = request,
|
||||
transform = {
|
||||
if (it is State.Success && model is V2GalleryPreview) {
|
||||
with(model) {
|
||||
@@ -74,8 +75,23 @@ fun EhAsyncPreview(
|
||||
}
|
||||
}
|
||||
},
|
||||
contentScale = contentScale,
|
||||
)
|
||||
CrystalCard(
|
||||
onClick = onClick,
|
||||
onLongClick = {
|
||||
if (painter.state.value is State.Error) {
|
||||
painter.restart()
|
||||
}
|
||||
},
|
||||
modifier = modifier,
|
||||
) {
|
||||
Image(
|
||||
painter = painter,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.imageRequest(request).fillMaxSize(),
|
||||
contentScale = contentScale,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@@ -86,16 +102,17 @@ fun EhPreviewItem(
|
||||
onClick: () -> Unit,
|
||||
) = Column(horizontalAlignment = Alignment.CenterHorizontally) {
|
||||
Box(contentAlignment = Alignment.Center) {
|
||||
CrystalCard(
|
||||
onClick = onClick,
|
||||
modifier = Modifier.aspectRatio(DEFAULT_RATIO),
|
||||
) {
|
||||
if (galleryPreview != null) {
|
||||
EhAsyncPreview(
|
||||
model = galleryPreview,
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
)
|
||||
}
|
||||
if (galleryPreview != null) {
|
||||
EhPreviewCard(
|
||||
model = galleryPreview,
|
||||
onClick = onClick,
|
||||
modifier = Modifier.aspectRatio(DEFAULT_RATIO),
|
||||
)
|
||||
} else {
|
||||
CrystalCard(
|
||||
onClick = onClick,
|
||||
modifier = Modifier.aspectRatio(DEFAULT_RATIO),
|
||||
) {}
|
||||
}
|
||||
}
|
||||
Text(text = "${position + 1}")
|
||||
|
||||
Reference in new issue
Block a user