ref: add MXCImage

This commit is contained in:
2025-06-05 20:08:31 +03:00
parent 7a2567f019
commit 8ac9ccfaca
2 changed files with 86 additions and 25 deletions
@@ -0,0 +1,82 @@
/*
* Created by sweetbread
* Copyright (c) 2025. All rights reserved.
*/
package ru.risdeveau.pixeldragon.ui.item
import android.annotation.SuppressLint
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Warning
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import coil3.compose.AsyncImagePainter
import coil3.compose.rememberAsyncImagePainter
import coil3.network.NetworkHeaders
import coil3.network.httpHeaders
import coil3.request.ImageRequest
import ru.risdeveau.pixeldragon.api.mxcToUrl
import ru.risdeveau.pixeldragon.token
import splitties.init.appCtx
@SuppressLint("StateFlowValueCalledInComposition")
@Composable
fun MXCImage(
mxcUrl: String,
modifier: Modifier = Modifier,
contentDescription: String = ""
) {
data class ImageLoadState(
val isLoading: Boolean = false,
val isSuccess: Boolean = false,
val error: Throwable? = null
)
val loadState = remember { mutableStateOf(ImageLoadState()) }
val painter = rememberAsyncImagePainter(
model = ImageRequest.Builder(appCtx)
.data(mxcToUrl(mxcUrl))
.httpHeaders(
NetworkHeaders.Builder()
.set("Authorization", "Bearer $token")
.set("Cache-Control", "max-age=86400")
.build()
)
.build(),
onState = { state ->
loadState.value = when (state) {
is AsyncImagePainter.State.Loading -> ImageLoadState(isLoading = true)
is AsyncImagePainter.State.Success -> ImageLoadState(isSuccess = true)
is AsyncImagePainter.State.Error -> ImageLoadState(error = state.result.throwable)
else -> ImageLoadState()
}
}
)
Box(
modifier = modifier,
contentAlignment = Alignment.Center
) {
Image(
painter = painter,
contentDescription = contentDescription,
contentScale = ContentScale.Crop,
modifier = Modifier.fillMaxSize()
)
if (loadState.value.isLoading) {
CircularProgressIndicator()
} else if (loadState.value.error != null) {
Icon(Icons.Outlined.Warning, "Error")
}
}
}
@@ -18,7 +18,6 @@ import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.LinearProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
@@ -31,22 +30,15 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import coil3.compose.SubcomposeAsyncImage
import coil3.network.NetworkHeaders
import coil3.network.httpHeaders
import coil3.request.ImageRequest
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import ru.risdeveau.pixeldragon.api.getRoom
import ru.risdeveau.pixeldragon.api.getRooms
import ru.risdeveau.pixeldragon.api.mxcToUrl
import ru.risdeveau.pixeldragon.db.Room
import ru.risdeveau.pixeldragon.token
import splitties.init.appCtx
import ru.risdeveau.pixeldragon.ui.item.MXCImage
@Composable
fun RoomList(modifier: Modifier = Modifier, navController: NavController) {
@@ -111,7 +103,8 @@ fun RoomItem(modifier: Modifier = Modifier, rid: String, navController: NavContr
}
.padding(8.dp)
) {
SubcomposeAsyncImage(
MXCImage(
room!!.avatarUrl ?: "",
modifier = Modifier
.padding(end = 4.dp)
.height(52.dp)
@@ -121,21 +114,7 @@ fun RoomItem(modifier: Modifier = Modifier, rid: String, navController: NavContr
it.clip(RoundedCornerShape(12.dp))
else
it.clip(CircleShape)
},
model = ImageRequest.Builder(appCtx)
.data(mxcToUrl(room!!.avatarUrl ?: ""))
.httpHeaders(
NetworkHeaders.Builder()
.set("Authorization", "Bearer $token")
.set("Cache-Control", "max-age=86400")
.build()
)
.build(),
contentDescription = room!!.roomId,
contentScale = ContentScale.Crop,
loading = {
CircularProgressIndicator()
}
}
)
Column {
Text(