Skip to content

Commit

Permalink
perf: update libs, coil v3
Browse files Browse the repository at this point in the history
  • Loading branch information
lisonge committed Dec 7, 2024
1 parent bcc89fa commit f7d8d4a
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 41 deletions.
6 changes: 4 additions & 2 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -183,9 +183,10 @@ configurations.configureEach {
}

composeCompiler {
// featureFlags.addAll(ComposeFeatureFlag.StrongSkipping) // default StrongSkipping
reportsDestination = layout.buildDirectory.dir("compose_compiler")
stabilityConfigurationFile = rootProject.layout.projectDirectory.file("stability_config.conf")
stabilityConfigurationFiles.addAll(
project.layout.projectDirectory.file("stability_config.conf"),
)
}

dependencies {
Expand Down Expand Up @@ -254,6 +255,7 @@ dependencies {
implementation(libs.androidx.splashscreen)

implementation(libs.coil.compose)
implementation(libs.coil.network)
implementation(libs.coil.gif)

implementation(libs.exp4j)
Expand Down
86 changes: 68 additions & 18 deletions app/src/main/kotlin/li/songe/gkd/ui/ImagePreviewPage.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package li.songe.gkd.ui

import android.webkit.URLUtil
import androidx.compose.animation.core.AnimationConstants.DefaultDurationMillis
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
Expand All @@ -11,8 +14,11 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.automirrored.outlined.OpenInNew
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
Expand All @@ -21,19 +27,27 @@ import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import androidx.compose.ui.zIndex
import coil.compose.SubcomposeAsyncImage
import coil.request.ImageRequest
import coil3.compose.AsyncImagePainter
import coil3.compose.rememberAsyncImagePainter
import coil3.request.ImageRequest
import coil3.request.crossfade
import com.ramcosta.composedestinations.annotation.Destination
import com.ramcosta.composedestinations.annotation.RootGraph
import li.songe.gkd.app
import li.songe.gkd.util.LocalNavController
import li.songe.gkd.util.ProfileTransitions
import li.songe.gkd.util.imageLoader
import li.songe.gkd.util.openUri
import li.songe.gkd.util.throttle

@Destination<RootGraph>(style = ProfileTransitions::class)
@Composable
Expand All @@ -48,6 +62,8 @@ fun ImagePreviewPage(
.background(MaterialTheme.colorScheme.background)
.fillMaxSize()
) {
val showUri = uri ?: if (uris.size == 1) uris.first() else null
val state = rememberPagerState { uris.size }
TopAppBar(
modifier = Modifier
.zIndex(1f)
Expand All @@ -67,22 +83,35 @@ fun ImagePreviewPage(
Text(text = title)
}
},
actions = {
val currentUri = showUri ?: uris.getOrNull(state.currentPage)
if (currentUri != null && URLUtil.isNetworkUrl(currentUri)) {
IconButton(onClick = throttle(fn = {
app.openUri(currentUri)
})) {
Icon(
imageVector = Icons.AutoMirrored.Outlined.OpenInNew,
contentDescription = null,
)
}
}
},
colors = TopAppBarDefaults.topAppBarColors(
containerColor = MaterialTheme.colorScheme.background.copy(alpha = 0.5f)
containerColor = MaterialTheme.colorScheme.background.copy(alpha = 0.3f)
)
)
val showUri = uri ?: if (uris.size == 1) uris.first() else null
if (showUri != null) {
UriImage(showUri)
} else if (uris.isNotEmpty()) {
val state = rememberPagerState { uris.size }
Box(
modifier = Modifier.fillMaxSize()
) {
HorizontalPager(
modifier = Modifier.fillMaxSize(),
state = state,
pageContent = { UriImage(uris[it]) }
pageContent = {
UriImage(uris[it])
}
)
Box(
Modifier
Expand All @@ -106,34 +135,55 @@ private fun UriImage(uri: String) {
val context = LocalContext.current
val model = remember(uri) {
ImageRequest.Builder(context).data(uri)
.crossfade(DefaultDurationMillis).build()
.crossfade(DefaultDurationMillis)
.build().apply {
imageLoader.enqueue(this)
}
}
SubcomposeAsyncImage(
modifier = Modifier.fillMaxWidth(),
model = model,
contentDescription = null,
loading = {
val painter = rememberAsyncImagePainter(model)
val state by painter.state.collectAsState()
when (state) {
AsyncImagePainter.State.Empty -> {}
is AsyncImagePainter.State.Loading -> {
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center,
) {
CircularProgressIndicator(modifier = Modifier.size(40.dp))
}
},
error = {
}

is AsyncImagePainter.State.Success -> {
Column(
modifier = Modifier
.fillMaxSize()
.verticalScroll(rememberScrollState()),
verticalArrangement = Arrangement.Center,
) {
Image(
painter = painter,
contentDescription = null,
modifier = Modifier.fillMaxWidth(),
contentScale = ContentScale.FillWidth,
alignment = Alignment.Center,
)
}
}

is AsyncImagePainter.State.Error -> {
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center,
) {
Text(
text = "加载失败",
modifier = Modifier.clickable(onClick = throttle { painter.restart() }),
text = "加载失败, 点击重试",
color = MaterialTheme.colorScheme.error,
style = MaterialTheme.typography.bodyMedium
)
}
},
imageLoader = imageLoader
)
}
}
}
37 changes: 23 additions & 14 deletions app/src/main/kotlin/li/songe/gkd/util/Singleton.kt
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package li.songe.gkd.util

import android.os.Build
import coil.ImageLoader
import coil.decode.GifDecoder
import coil.decode.ImageDecoderDecoder
import coil.disk.DiskCache
import coil3.ImageLoader
import coil3.disk.DiskCache
import coil3.gif.AnimatedImageDecoder
import coil3.gif.GifDecoder
import coil3.network.okhttp.OkHttpNetworkFetcherFactory
import com.tencent.mmkv.MMKV
import io.ktor.client.HttpClient
import io.ktor.client.engine.okhttp.OkHttp
Expand All @@ -14,6 +15,7 @@ import io.ktor.serialization.kotlinx.json.json
import kotlinx.serialization.json.Json
import li.songe.gkd.app
import okhttp3.OkHttpClient
import okio.Path.Companion.toOkioPath
import java.text.Collator
import java.util.Locale
import kotlin.time.Duration.Companion.seconds
Expand Down Expand Up @@ -49,22 +51,29 @@ val client by lazy {

val imageLoader by lazy {
ImageLoader.Builder(app)
.okHttpClient(
OkHttpClient.Builder()
.connectTimeout(30.seconds.toJavaDuration())
.readTimeout(30.seconds.toJavaDuration())
.writeTimeout(30.seconds.toJavaDuration())
.diskCache {
DiskCache.Builder()
.directory(imageCacheDir.toOkioPath())
.maxSizePercent(0.1)
.build()
)
}
.components {
if (Build.VERSION.SDK_INT >= 28) {
add(ImageDecoderDecoder.Factory())
add(AnimatedImageDecoder.Factory())
} else {
add(GifDecoder.Factory())
}
}.diskCache {
DiskCache.Builder().directory(imageCacheDir).build()
}.build()
add(OkHttpNetworkFetcherFactory(
callFactory = {
OkHttpClient.Builder()
.connectTimeout(30.seconds.toJavaDuration())
.readTimeout(30.seconds.toJavaDuration())
.writeTimeout(30.seconds.toJavaDuration())
.build()
}
))
}
.build()
}


Expand Down
15 changes: 8 additions & 7 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
[versions]
kotlin = "2.0.21"
ksp = "2.0.21-1.0.25"
android = "8.7.2"
kotlin = "2.1.0"
ksp = "2.1.0-1.0.29"
android = "8.7.3"
compose = "1.7.5"
rikka = "4.4.0"
room = "2.6.1"
paging = "3.3.4"
ktor = "3.0.1"
ktor = "3.0.2"
destinations = "2.1.0-beta14"
coil = "2.7.0"
coil = "3.0.4"
shizuku = "13.1.5"

[libraries]
Expand Down Expand Up @@ -55,8 +55,9 @@ rikka_shizuku_provider = { module = "dev.rikka.shizuku:provider", version.ref =
lsposed_hiddenapibypass = { module = "org.lsposed.hiddenapibypass:hiddenapibypass", version = "4.3" }
destinations_core = { module = "io.github.raamcosta.compose-destinations:core", version.ref = "destinations" }
destinations_ksp = { module = "io.github.raamcosta.compose-destinations:ksp", version.ref = "destinations" }
coil_compose = { module = "io.coil-kt:coil-compose", version.ref = "coil" }
coil_gif = { module = "io.coil-kt:coil-gif", version.ref = "coil" }
coil_compose = { module = "io.coil-kt.coil3:coil-compose", version.ref = "coil" }
coil_network = { module = "io.coil-kt.coil3:coil-network-okhttp", version.ref = "coil" }
coil_gif = { module = "io.coil-kt.coil3:coil-gif", version.ref = "coil" }
reorderable = { module = "sh.calvin.reorderable:reorderable", version = "2.4.0" }
exp4j = { module = "net.objecthunter:exp4j", version = "0.4.8" } # deprecated, replaced by kotlin
toaster = { module = "com.github.getActivity:Toaster", version = "12.6" }
Expand Down

0 comments on commit f7d8d4a

Please sign in to comment.