Skip to content
This repository was archived by the owner on May 11, 2026. It is now read-only.

Commit 5e1858b

Browse files
committed
refactor (feat): Implement animated GIF / WEBP images
1 parent 1c81c0e commit 5e1858b

5 files changed

Lines changed: 7 additions & 29 deletions

File tree

app/src/main/kotlin/org/dokiteam/doki/core/util/ext/Coil.kt

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -82,25 +82,3 @@ fun SourceFetchResult.copyWithNewSource(): SourceFetchResult = SourceFetchResult
8282
mimeType = mimeType,
8383
dataSource = dataSource,
8484
)
85-
86-
fun String.isAnimatedWebP(): Boolean = runCatching {
87-
val client = okhttp3.OkHttpClient.Builder()
88-
.connectTimeout(2, java.util.concurrent.TimeUnit.SECONDS)
89-
.readTimeout(2, java.util.concurrent.TimeUnit.SECONDS)
90-
.build()
91-
92-
val request = okhttp3.Request.Builder()
93-
.url(this)
94-
.header("Range", "bytes=0-20")
95-
.build()
96-
97-
client.newCall(request).execute().use { response ->
98-
val bytes = response.body.bytes()
99-
100-
bytes.size >= 21 &&
101-
bytes[0] == 0x52.toByte() && bytes[3] == 0x46.toByte() &&
102-
bytes[8] == 0x57.toByte() && bytes[11] == 0x50.toByte() &&
103-
bytes[12] == 0x56.toByte() && bytes[15] == 0x58.toByte() &&
104-
(bytes[20].toInt() and 0x02) != 0
105-
}
106-
}.getOrDefault(false)

app/src/main/kotlin/org/dokiteam/doki/core/util/ext/String.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ fun <T> Collection<T>.joinToStringWithLimit(context: Context, limit: Int, transf
7272

7373
fun String.isHttpUrl() = startsWith("https://", ignoreCase = true) || startsWith("http://", ignoreCase = true)
7474

75-
fun String.isAnimatedImage() = contains(".gif", ignoreCase = true) || contains(".webp", ignoreCase = true) && isAnimatedWebP()
75+
fun String.isSupportedAnimatedImage() = contains(".gif", ignoreCase = true) || contains(".webp", ignoreCase = true)
7676

7777
fun concatStrings(context: Context, a: String?, b: String?): String? = when {
7878
a.isNullOrEmpty() && b.isNullOrEmpty() -> null

app/src/main/kotlin/org/dokiteam/doki/image/ui/CoverImageView.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ import org.dokiteam.doki.core.ui.image.TrimTransformation
3434
import org.dokiteam.doki.core.util.ext.bookmarkExtra
3535
import org.dokiteam.doki.core.util.ext.decodeRegion
3636
import org.dokiteam.doki.core.util.ext.getThemeColor
37-
import org.dokiteam.doki.core.util.ext.isAnimatedImage
37+
import org.dokiteam.doki.core.util.ext.isSupportedAnimatedImage
3838
import org.dokiteam.doki.core.util.ext.isNetworkError
3939
import org.dokiteam.doki.core.util.ext.mangaExtra
4040
import org.dokiteam.doki.core.util.ext.mangaSourceExtra
@@ -106,7 +106,7 @@ class CoverImageView @JvmOverloads constructor(
106106
}
107107
}
108108

109-
private fun isAnimatedUrl(url: String?): Boolean = url?.isAnimatedImage() == true
109+
private fun isAnimatedUrl(url: String?): Boolean = url?.isSupportedAnimatedImage() == true
110110

111111
private fun newRequestBuilder(applyTrim: Boolean) = super.newRequestBuilder().apply {
112112
if (trimImage && applyTrim) {

app/src/main/kotlin/org/dokiteam/doki/image/ui/ImageActivity.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ import org.dokiteam.doki.core.util.ext.getDisplayIcon
3838
import org.dokiteam.doki.core.util.ext.getDisplayMessage
3939
import org.dokiteam.doki.core.util.ext.getParcelableExtraCompat
4040
import org.dokiteam.doki.core.util.ext.getThemeColor
41-
import org.dokiteam.doki.core.util.ext.isAnimatedImage
41+
import org.dokiteam.doki.core.util.ext.isSupportedAnimatedImage
4242
import org.dokiteam.doki.core.util.ext.mangaSourceExtra
4343
import org.dokiteam.doki.core.util.ext.observe
4444
import org.dokiteam.doki.core.util.ext.observeEvent
@@ -125,7 +125,7 @@ class ImageActivity : BaseActivity<ActivityImageBinding>(),
125125

126126
private fun loadImage() {
127127
val url = intent.data?.toString()
128-
val isAnimated = url?.isAnimatedImage() == true
128+
val isAnimated = url?.isSupportedAnimatedImage() == true
129129

130130
if (isAnimated) {
131131
viewBinding.ssiv.isVisible = false

app/src/main/kotlin/org/dokiteam/doki/reader/ui/pager/BasePageHolder.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import org.dokiteam.doki.core.image.CoilImageView
2323
import org.dokiteam.doki.core.os.NetworkState
2424
import org.dokiteam.doki.core.ui.list.lifecycle.LifecycleAwareViewHolder
2525
import org.dokiteam.doki.core.util.ext.getDisplayMessage
26-
import org.dokiteam.doki.core.util.ext.isAnimatedImage
26+
import org.dokiteam.doki.core.util.ext.isSupportedAnimatedImage
2727
import org.dokiteam.doki.core.util.ext.isLowRamDevice
2828
import org.dokiteam.doki.core.util.ext.isSerializable
2929
import org.dokiteam.doki.core.util.ext.observe
@@ -173,7 +173,7 @@ abstract class BasePageHolder<B : ViewBinding>(
173173
bindingInfo.progressBar.isIndeterminate = true
174174
bindingInfo.textViewStatus.setText(R.string.loading_)
175175
}
176-
val isAnimated = boundData?.url?.isAnimatedImage() == true
176+
val isAnimated = boundData?.url?.isSupportedAnimatedImage() == true
177177
when (state) {
178178
is PageState.Converting -> {
179179
bindingInfo.textViewStatus.setText(R.string.processing_)

0 commit comments

Comments
 (0)