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.lazy.rememberLazyListState
|
||||||
import androidx.compose.foundation.shape.CircleShape
|
import androidx.compose.foundation.shape.CircleShape
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.material3.CircularProgressIndicator
|
|
||||||
import androidx.compose.material3.LinearProgressIndicator
|
import androidx.compose.material3.LinearProgressIndicator
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
@@ -31,22 +30,15 @@ import androidx.compose.runtime.rememberCoroutineScope
|
|||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.layout.ContentScale
|
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.navigation.NavController
|
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.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import ru.risdeveau.pixeldragon.api.getRoom
|
import ru.risdeveau.pixeldragon.api.getRoom
|
||||||
import ru.risdeveau.pixeldragon.api.getRooms
|
import ru.risdeveau.pixeldragon.api.getRooms
|
||||||
import ru.risdeveau.pixeldragon.api.mxcToUrl
|
|
||||||
import ru.risdeveau.pixeldragon.db.Room
|
import ru.risdeveau.pixeldragon.db.Room
|
||||||
import ru.risdeveau.pixeldragon.token
|
import ru.risdeveau.pixeldragon.ui.item.MXCImage
|
||||||
import splitties.init.appCtx
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun RoomList(modifier: Modifier = Modifier, navController: NavController) {
|
fun RoomList(modifier: Modifier = Modifier, navController: NavController) {
|
||||||
@@ -111,7 +103,8 @@ fun RoomItem(modifier: Modifier = Modifier, rid: String, navController: NavContr
|
|||||||
}
|
}
|
||||||
.padding(8.dp)
|
.padding(8.dp)
|
||||||
) {
|
) {
|
||||||
SubcomposeAsyncImage(
|
MXCImage(
|
||||||
|
room!!.avatarUrl ?: "",
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(end = 4.dp)
|
.padding(end = 4.dp)
|
||||||
.height(52.dp)
|
.height(52.dp)
|
||||||
@@ -121,21 +114,7 @@ fun RoomItem(modifier: Modifier = Modifier, rid: String, navController: NavContr
|
|||||||
it.clip(RoundedCornerShape(12.dp))
|
it.clip(RoundedCornerShape(12.dp))
|
||||||
else
|
else
|
||||||
it.clip(CircleShape)
|
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 {
|
Column {
|
||||||
Text(
|
Text(
|
||||||
|
|||||||
Reference in New Issue
Block a user