ref: add MXCImage
This commit is contained in:
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user