diff --git a/app/src/main/kotlin/com/hippo/ehviewer/client/data/BaseGalleryInfo.kt b/app/src/main/kotlin/com/hippo/ehviewer/client/data/BaseGalleryInfo.kt index 18e632cc4..67390b0d3 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/client/data/BaseGalleryInfo.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/client/data/BaseGalleryInfo.kt @@ -23,7 +23,6 @@ import androidx.room.PrimaryKey import androidx.room.TypeConverter import androidx.room.TypeConverters import com.hippo.ehviewer.client.data.GalleryInfo.Companion.NOT_FAVORITED -import kotlinx.parcelize.IgnoredOnParcel import kotlinx.parcelize.Parcelize import kotlinx.serialization.Serializable @@ -91,9 +90,6 @@ data class BaseGalleryInfo( override var favoriteNote: String? = null, ) : GalleryInfo, Parcelable { - @IgnoredOnParcel - override val hasAds by lazy { simpleTags?.any { "extraneous ads" in it } == true } - constructor() : this(0, "") } diff --git a/app/src/main/kotlin/com/hippo/ehviewer/client/data/GalleryInfo.kt b/app/src/main/kotlin/com/hippo/ehviewer/client/data/GalleryInfo.kt index cde4ed643..6b9c5a854 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/client/data/GalleryInfo.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/client/data/GalleryInfo.kt @@ -37,7 +37,6 @@ interface GalleryInfo { var favoriteSlot: Int var favoriteName: String? var favoriteNote: String? - val hasAds: Boolean fun generateSLang() { simpleLanguage = simpleTags?.let { generateSLangFromTags(it) } @@ -142,3 +141,6 @@ fun GalleryInfo.findBaseInfo(): BaseGalleryInfo = when (this) { } fun GalleryInfo.asGalleryDetail(): GalleryDetail? = this as? GalleryDetail + +val GalleryInfo.hasAds + get() = simpleTags?.any { "extraneous ads" in it } ?: false diff --git a/app/src/main/kotlin/com/hippo/ehviewer/coil/Extensions.kt b/app/src/main/kotlin/com/hippo/ehviewer/coil/Extensions.kt index 9daf43c69..d5558387a 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/coil/Extensions.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/coil/Extensions.kt @@ -9,16 +9,12 @@ import coil3.network.NetworkHeaders import coil3.network.httpHeaders import coil3.request.CachePolicy import coil3.request.ImageRequest -import coil3.request.allowHardware import coil3.size.Size -import com.hippo.ehviewer.BuildConfig import com.hippo.ehviewer.Settings import com.hippo.ehviewer.client.CHROME_ACCEPT import com.hippo.ehviewer.client.CHROME_ACCEPT_LANGUAGE -import com.hippo.ehviewer.client.data.GalleryDetail import com.hippo.ehviewer.client.data.GalleryInfo import com.hippo.ehviewer.client.data.GalleryPreview -import com.hippo.ehviewer.client.data.LargeGalleryPreview import com.hippo.ehviewer.client.data.NormalGalleryPreview import com.hippo.ehviewer.spider.DownloadInfoMagics.encodeMagicRequestOrUrl import io.ktor.http.HttpHeaders @@ -37,24 +33,11 @@ fun ImageRequest.Builder.ehUrl(info: GalleryInfo) = apply { httpHeaders(header) } -context(GalleryDetail) -fun ImageRequest.Builder.ehPreview( - preview: GalleryPreview, -) = with(preview) { +fun ImageRequest.Builder.ehPreview(preview: GalleryPreview) = with(preview) { data(url) memoryCacheKey(imageKey) diskCacheKey(imageKey) - when (preview) { - is NormalGalleryPreview -> size(Size.ORIGINAL) - is LargeGalleryPreview -> { - if (hasAds && detectAds(position, pages, BuildConfig.DEBUG)) { - size(Size.ORIGINAL) - detectQrCode(true) - allowHardware(false) - hardwareThreshold(0) - } - } - } + if (preview is NormalGalleryPreview) size(Size.ORIGINAL) httpHeaders(header) } diff --git a/app/src/main/kotlin/com/hippo/ehviewer/coil/QrCodeInterceptor.kt b/app/src/main/kotlin/com/hippo/ehviewer/coil/QrCodeInterceptor.kt index c704c032d..0385e4029 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/coil/QrCodeInterceptor.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/coil/QrCodeInterceptor.kt @@ -1,21 +1,13 @@ package com.hippo.ehviewer.coil -import androidx.collection.SieveCache import coil3.Extras -import coil3.Image import coil3.getExtra import coil3.intercept.Interceptor -import coil3.memory.MemoryCache import coil3.request.ImageRequest import coil3.request.ImageResult import coil3.request.SuccessResult import com.hippo.ehviewer.Settings import com.hippo.ehviewer.image.hasQrCode -import eu.kanade.tachiyomi.util.system.logcat -import java.util.concurrent.locks.ReentrantReadWriteLock -import kotlin.concurrent.read -import kotlin.concurrent.write -import moe.tarsin.coroutines.runSuspendCatching private val detectQrCodeKey = Extras.Key(default = false) @@ -23,9 +15,6 @@ fun ImageRequest.Builder.detectQrCode(enable: Boolean) = apply { extras[detectQrCodeKey] = enable } -private val cache = SieveCache(50) -private val lock = ReentrantReadWriteLock() - val ImageRequest.detectQrCode: Boolean get() = getExtra(detectQrCodeKey) @@ -35,11 +24,7 @@ object QrCodeInterceptor : Interceptor { if (chain.request.detectQrCode && result is SuccessResult) { val image = result.image if (image is BitmapImageWithExtraInfo) { - fun compute() = runSuspendCatching { hasQrCode(image.image.bitmap) }.onFailure { logcat(it) }.getOrThrow() - val hasQrCode = when (val key = result.memoryCacheKey) { - is MemoryCache.Key -> lock.read { cache[key] } ?: compute().also { lock.write { cache[key] = it } } - null -> compute() - } + val hasQrCode = hasQrCode(image.image.bitmap) val new = image.copy(hasQrCode = hasQrCode) return result.copy(image = new) } @@ -48,10 +33,4 @@ object QrCodeInterceptor : Interceptor { } } -val Image.hasQrCode - get() = when (this) { - is BitmapImageWithExtraInfo -> hasQrCode - else -> false - } - -fun detectAds(index: Int, size: Int, enable: Boolean = true) = index > size - 10 && Settings.stripExtraneousAds.value && enable +fun detectAds(index: Int, size: Int) = index > size - 10 && Settings.stripExtraneousAds.value diff --git a/app/src/main/kotlin/com/hippo/ehviewer/image/Image.kt b/app/src/main/kotlin/com/hippo/ehviewer/image/Image.kt index 1df8620b9..c39b6d5e5 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/image/Image.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/image/Image.kt @@ -37,7 +37,6 @@ import com.hippo.ehviewer.Settings import com.hippo.ehviewer.coil.BitmapImageWithExtraInfo import com.hippo.ehviewer.coil.detectQrCode import com.hippo.ehviewer.coil.hardwareThreshold -import com.hippo.ehviewer.coil.hasQrCode import com.hippo.ehviewer.coil.maybeCropBorder import com.hippo.ehviewer.jni.isGif import com.hippo.ehviewer.jni.mmap @@ -56,7 +55,10 @@ import splitties.init.appCtx class Image private constructor(image: CoilImage, private val src: ImageSource) { val intrinsicSize = with(image) { IntSize(width, height) } val allocationSize = image.size - val hasQrCode = image.hasQrCode + val hasQrCode = when (image) { + is BitmapImageWithExtraInfo -> image.hasQrCode + else -> false + } var innerImage: CoilImage? = when (image) { is BitmapImageWithExtraInfo -> image.image diff --git a/app/src/main/kotlin/com/hippo/ehviewer/ktbuilder/Coil.kt b/app/src/main/kotlin/com/hippo/ehviewer/ktbuilder/Coil.kt index e8ba89747..7d534b31e 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/ktbuilder/Coil.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/ktbuilder/Coil.kt @@ -5,7 +5,6 @@ import coil3.ImageLoader import coil3.disk.DiskCache import coil3.imageLoader import coil3.request.ImageRequest -import com.hippo.ehviewer.client.data.GalleryDetail import com.hippo.ehviewer.client.data.GalleryInfo import com.hippo.ehviewer.client.data.GalleryPreview import com.hippo.ehviewer.coil.ehPreview @@ -13,7 +12,6 @@ import com.hippo.ehviewer.coil.ehUrl import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch -context(GalleryDetail) inline fun Context.imageRequest(preview: GalleryPreview, builder: ImageRequest.Builder.() -> Unit = {}) = ImageRequest.Builder(this).ehPreview(preview).apply(builder).build() inline fun Context.imageRequest(info: GalleryInfo, builder: ImageRequest.Builder.() -> Unit = {}) = ImageRequest.Builder(this).ehUrl(info).apply(builder).build() inline fun Context.imageRequest(builder: ImageRequest.Builder.() -> Unit = {}) = ImageRequest.Builder(this).apply(builder).build() diff --git a/app/src/main/kotlin/com/hippo/ehviewer/spider/SpiderQueen.kt b/app/src/main/kotlin/com/hippo/ehviewer/spider/SpiderQueen.kt index 9e541cc0d..867d5d093 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/spider/SpiderQueen.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/spider/SpiderQueen.kt @@ -26,6 +26,7 @@ import com.hippo.ehviewer.client.EhUrl.getGalleryDetailUrl import com.hippo.ehviewer.client.EhUrl.getGalleryMultiPageViewerUrl import com.hippo.ehviewer.client.EhUrl.referer import com.hippo.ehviewer.client.data.GalleryInfo +import com.hippo.ehviewer.client.data.hasAds import com.hippo.ehviewer.client.ehRequest import com.hippo.ehviewer.client.exception.QuotaExceededException import com.hippo.ehviewer.client.fetchUsingAsText diff --git a/app/src/main/kotlin/com/hippo/ehviewer/ui/main/GalleryPreview.kt b/app/src/main/kotlin/com/hippo/ehviewer/ui/main/GalleryPreview.kt index 35c6c998a..5ef050587 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/ui/main/GalleryPreview.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/ui/main/GalleryPreview.kt @@ -10,7 +10,6 @@ import androidx.compose.runtime.NonRestartableComposable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember -import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -22,18 +21,14 @@ import androidx.compose.ui.unit.IntOffset import androidx.compose.ui.unit.IntSize import coil3.BitmapImage import coil3.compose.AsyncImage -import coil3.compose.AsyncImagePainter +import coil3.compose.AsyncImagePainter.State import coil3.request.ImageRequest -import com.hippo.ehviewer.client.data.GalleryDetail import com.hippo.ehviewer.client.data.GalleryPreview import com.hippo.ehviewer.client.data.NormalGalleryPreview -import com.hippo.ehviewer.coil.hasQrCode import com.hippo.ehviewer.ktbuilder.imageRequest -import com.hippo.ehviewer.ui.reader.AdsPlaceholder import com.hippo.ehviewer.ui.tools.CrystalCard import com.hippo.ehviewer.ui.tools.shouldCrop -context(GalleryDetail) @Composable @NonRestartableComposable fun requestOf(model: GalleryPreview): ImageRequest { @@ -41,60 +36,48 @@ fun requestOf(model: GalleryPreview): ImageRequest { return remember(model) { context.imageRequest(model) } } -context(GalleryDetail) @Composable fun EhAsyncPreview( model: GalleryPreview, modifier: Modifier = Modifier, ) { var contentScale by remember(model) { mutableStateOf(ContentScale.Fit) } - var blocked by rememberSaveable(model) { mutableStateOf(false) } - if (blocked) { - AdsPlaceholder( - modifier = modifier, - contentScale = ContentScale.Fit, - ) - } else { - AsyncImage( - model = requestOf(model), - contentDescription = null, - modifier = modifier, - transform = { + AsyncImage( + model = requestOf(model), + contentDescription = null, + modifier = modifier, + transform = { + if (it is State.Success && model is NormalGalleryPreview) { with(model) { - when (it) { - is AsyncImagePainter.State.Success if it.result.image.hasQrCode -> it.also { blocked = true } - is AsyncImagePainter.State.Success if this is NormalGalleryPreview -> it.copy( - painter = BitmapPainter( - (it.result.image as BitmapImage).bitmap.asImageBitmap(), - IntOffset(offsetX, 0), - IntSize(clipWidth - 1, clipHeight - 1), - ), - ) - else -> it + it.copy( + painter = BitmapPainter( + (it.result.image as BitmapImage).bitmap.asImageBitmap(), + IntOffset(offsetX, 0), + IntSize(clipWidth - 1, clipHeight - 1), + ), + ) + } + } else { + it + } + }, + onState = { + if (it is State.Success) { + if (model is NormalGalleryPreview) { + if (model.shouldCrop) { + contentScale = ContentScale.Crop + } + } else { + if (it.result.image.shouldCrop) { + contentScale = ContentScale.Crop } } - }, - onState = { - if (it is AsyncImagePainter.State.Success) { - with(model) { - if (this is NormalGalleryPreview) { - if (shouldCrop) { - contentScale = ContentScale.Crop - } - } else { - if (it.result.image.shouldCrop) { - contentScale = ContentScale.Crop - } - } - } - } - }, - contentScale = contentScale, - ) - } + } + }, + contentScale = contentScale, + ) } -context(GalleryDetail) @Composable @NonRestartableComposable fun EhPreviewItem( diff --git a/app/src/main/kotlin/com/hippo/ehviewer/ui/reader/ReaderScreen.kt b/app/src/main/kotlin/com/hippo/ehviewer/ui/reader/ReaderScreen.kt index d432db98f..6ba9880ef 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/ui/reader/ReaderScreen.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/ui/reader/ReaderScreen.kt @@ -57,6 +57,7 @@ import com.google.accompanist.systemuicontroller.rememberSystemUiController import com.hippo.ehviewer.R import com.hippo.ehviewer.Settings import com.hippo.ehviewer.client.data.BaseGalleryInfo +import com.hippo.ehviewer.client.data.hasAds import com.hippo.ehviewer.collectAsState import com.hippo.ehviewer.download.DownloadManager import com.hippo.ehviewer.download.archiveFile diff --git a/app/src/main/kotlin/com/hippo/ehviewer/ui/screen/GalleryDetailContent.kt b/app/src/main/kotlin/com/hippo/ehviewer/ui/screen/GalleryDetailContent.kt index 43287a93d..2cda55430 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/ui/screen/GalleryDetailContent.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/ui/screen/GalleryDetailContent.kt @@ -298,7 +298,7 @@ fun GalleryDetailContent( } } if (galleryDetail != null) { - galleryPreview(galleryDetail, previews) { navToReader(galleryDetail.galleryInfo, it) } + galleryPreview(previews) { navToReader(galleryDetail.galleryInfo, it) } } } @@ -366,7 +366,7 @@ fun GalleryDetailContent( } } if (galleryDetail != null) { - galleryPreview(galleryDetail, previews) { navToReader(galleryDetail.galleryInfo, it) } + galleryPreview(previews) { navToReader(galleryDetail.galleryInfo, it) } } } } @@ -775,19 +775,13 @@ private fun GalleryDetail?.collectPreviewItems(prefetchDistance: Int) = remember }.flow.cachedIn(viewModelScope) }.collectAsLazyPagingItems() -private fun LazyGridScope.galleryPreview( - detail: GalleryDetail, - data: LazyPagingItems, - onClick: (Int) -> Unit, -) { +private fun LazyGridScope.galleryPreview(data: LazyPagingItems, onClick: (Int) -> Unit) { items( count = data.itemCount, key = data.itemKey(key = { item -> item.position }), contentType = { "preview" }, ) { index -> val item = data[index] - with(detail) { - EhPreviewItem(item, index) { onClick(index) } - } + EhPreviewItem(item, index) { onClick(index) } } } diff --git a/app/src/main/kotlin/com/hippo/ehviewer/ui/screen/GalleryDetailScreen.kt b/app/src/main/kotlin/com/hippo/ehviewer/ui/screen/GalleryDetailScreen.kt index 5300d264a..5dd08711d 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/ui/screen/GalleryDetailScreen.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/ui/screen/GalleryDetailScreen.kt @@ -138,10 +138,8 @@ fun AnimatedVisibilityScope.GalleryDetailScreen(args: GalleryDetailScreenArgs, n detailCache[galleryDetail.gid] = galleryDetail if (Settings.preloadThumbAggressively) { launchIO { - with(galleryDetail) { - previewList.forEach { - imageLoader.enqueue(imageRequest(it) { justDownload() }) - } + galleryDetail.previewList.forEach { + imageLoader.enqueue(imageRequest(it) { justDownload() }) } } }