feat: show room avatar when is DM
This commit is contained in:
@@ -1,7 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Created by sweetbread
|
* Created by sweetbread
|
||||||
* Copyright (c) 2025. All rights reserved.
|
* Copyright (c) 2025. All rights reserved.
|
||||||
* Last modified 03.03.2025, 18:28
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ru.risdeveau.pixeldragon.api
|
package ru.risdeveau.pixeldragon.api
|
||||||
@@ -36,12 +35,28 @@ suspend fun getRooms(): List<String> {
|
|||||||
|
|
||||||
suspend fun getRoom(rid: String): Room {
|
suspend fun getRoom(rid: String): Room {
|
||||||
var room = db.roomDoa().getById(rid)
|
var room = db.roomDoa().getById(rid)
|
||||||
|
|
||||||
|
val direct = getAccountData(getMe()!!.userId, "m.direct")
|
||||||
|
var directWith = ""
|
||||||
|
direct?.let {
|
||||||
|
for (user in direct.keys()) {
|
||||||
|
val roomsWithUser = direct.getJSONArray(user)
|
||||||
|
for (i in 0 until roomsWithUser.length()) {
|
||||||
|
if (rid == roomsWithUser.getString(i)) {
|
||||||
|
directWith = user
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (directWith.isNotEmpty()) break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (room == null) {
|
if (room == null) {
|
||||||
val name = getState(rid, "m.room.name", "name")
|
val name = getState(rid, "m.room.name", "name")
|
||||||
val type = getState(rid, "m.room.create", "type") ?: "m.room"
|
val type = getState(rid, "m.room.create", "type") ?: "m.room"
|
||||||
val creator = getState(rid, "m.room.create", "creator")
|
val creator = getState(rid, "m.room.create", "creator")
|
||||||
val avatar = getState(rid, "m.room.avatar", "url")
|
val avatar = getState(rid, "m.room.avatar", "url")
|
||||||
room = Room(rid, name, type, creator, null, avatar, null, true)
|
room = Room(rid, name, type, creator, null, avatar, null, true, if (directWith.isNotEmpty()) directWith else null)
|
||||||
db.roomDoa().insert(room)
|
db.roomDoa().insert(room)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Created by sweetbread
|
* Created by sweetbread
|
||||||
* Copyright (c) 2025. All rights reserved.
|
* Copyright (c) 2025. All rights reserved.
|
||||||
* Last modified 03.03.2025, 15:40
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ru.risdeveau.pixeldragon.api
|
package ru.risdeveau.pixeldragon.api
|
||||||
@@ -28,9 +27,11 @@ suspend fun getHomeserver(url: String): String? {
|
|||||||
return homeserver
|
return homeserver
|
||||||
}
|
}
|
||||||
|
|
||||||
fun mxcToUrl(mxc: String): String {
|
fun mxcToUrl(mxc: String): String? {
|
||||||
val pattern = Regex("mxc://([-a-zA-Z0-9@:%._+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6})/([a-zA-Z]+)")
|
val pattern = Regex("mxc://([-a-zA-Z0-9@:%._+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6})/([a-zA-Z0-9]+)")
|
||||||
val match = pattern.find(mxc)
|
val match = pattern.find(mxc)
|
||||||
|
|
||||||
|
if ((match?.groupValues[1] == null) or (match?.groupValues[2] == null)) return null
|
||||||
|
|
||||||
return "$homeserver/_matrix/client/v1/media/download/${match?.groupValues[1]}/${match?.groupValues[2]}"
|
return "$homeserver/_matrix/client/v1/media/download/${match?.groupValues[1]}/${match?.groupValues[2]}"
|
||||||
}
|
}
|
||||||
@@ -25,6 +25,7 @@ import splitties.init.appCtx
|
|||||||
import splitties.preferences.edit
|
import splitties.preferences.edit
|
||||||
|
|
||||||
data class Me (val userId: String, val deviceId: String)
|
data class Me (val userId: String, val deviceId: String)
|
||||||
|
data class UserProfile (val displayName: String, val avatarUrl: String, val other: JSONObject)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This func is to validate the token
|
* This func is to validate the token
|
||||||
@@ -82,3 +83,18 @@ suspend fun login(server: String, login: String, pass: String): Boolean {
|
|||||||
|
|
||||||
return initCheck()
|
return initCheck()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun getAccountData(user: String, state: String): JSONObject? {
|
||||||
|
val r = client.get("$baseUrl/user/$user/account_data/$state") { bearerAuth(token) }
|
||||||
|
if (r.status != HttpStatusCode.OK) return null
|
||||||
|
return JSONObject(r.bodyAsText())
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun getUserProfile(userId: String): UserProfile? {
|
||||||
|
val r = client.get("$baseUrl/profile/$userId") { bearerAuth(token) }
|
||||||
|
if (r.status != HttpStatusCode.OK) return null
|
||||||
|
val json = JSONObject(r.bodyAsText())
|
||||||
|
val name = json.optString("displayname", ""); json.remove("displayname")
|
||||||
|
val avatar = json.optString("avatar_url", ""); json.remove("avatar_url")
|
||||||
|
return UserProfile(name, avatar, json)
|
||||||
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Created by sweetbread
|
* Created by sweetbread
|
||||||
* Copyright (c) 2025. All rights reserved.
|
* Copyright (c) 2025. All rights reserved.
|
||||||
* Last modified 22.02.2025, 19:49
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ru.risdeveau.pixeldragon.db
|
package ru.risdeveau.pixeldragon.db
|
||||||
@@ -27,7 +26,8 @@ data class Room(
|
|||||||
val createTime: Long?,
|
val createTime: Long?,
|
||||||
val avatarUrl: String?,
|
val avatarUrl: String?,
|
||||||
val members: Int?,
|
val members: Int?,
|
||||||
val joined: Boolean
|
val joined: Boolean,
|
||||||
|
val direct: String?,
|
||||||
)
|
)
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import androidx.compose.material3.Icon
|
|||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.layout.ContentScale
|
import androidx.compose.ui.layout.ContentScale
|
||||||
import coil3.compose.AsyncImagePainter
|
import coil3.compose.AsyncImagePainter
|
||||||
@@ -38,10 +39,11 @@ fun MXCImage(
|
|||||||
contentScale: ContentScale = ContentScale.Fit,
|
contentScale: ContentScale = ContentScale.Fit,
|
||||||
contentDescription: String = ""
|
contentDescription: String = ""
|
||||||
) {
|
) {
|
||||||
|
mxcToUrl(mxcUrl)?.let { url ->
|
||||||
val loadState = remember { mutableStateOf(ImageLoadState.Loading) }
|
val loadState = remember { mutableStateOf(ImageLoadState.Loading) }
|
||||||
val painter = rememberAsyncImagePainter(
|
val painter = rememberAsyncImagePainter(
|
||||||
model = ImageRequest.Builder(appCtx)
|
model = ImageRequest.Builder(appCtx)
|
||||||
.data(mxcToUrl(mxcUrl))
|
.data(url)
|
||||||
.httpHeaders(
|
.httpHeaders(
|
||||||
NetworkHeaders.Builder()
|
NetworkHeaders.Builder()
|
||||||
.set("Authorization", "Bearer $token")
|
.set("Authorization", "Bearer $token")
|
||||||
@@ -59,7 +61,8 @@ fun MXCImage(
|
|||||||
)
|
)
|
||||||
|
|
||||||
Box(
|
Box(
|
||||||
modifier = modifier.fillMaxSize()
|
modifier = modifier.fillMaxSize(),
|
||||||
|
contentAlignment = Alignment.Center
|
||||||
) {
|
) {
|
||||||
Image(
|
Image(
|
||||||
painter = painter,
|
painter = painter,
|
||||||
@@ -75,3 +78,4 @@ fun MXCImage(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
@@ -35,8 +35,10 @@ import androidx.navigation.NavController
|
|||||||
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.UserProfile
|
||||||
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.getUserProfile
|
||||||
import ru.risdeveau.pixeldragon.db.Room
|
import ru.risdeveau.pixeldragon.db.Room
|
||||||
import ru.risdeveau.pixeldragon.ui.item.MXCImage
|
import ru.risdeveau.pixeldragon.ui.item.MXCImage
|
||||||
|
|
||||||
@@ -77,6 +79,7 @@ fun RoomList(modifier: Modifier = Modifier, navController: NavController) {
|
|||||||
@Composable
|
@Composable
|
||||||
fun RoomItem(modifier: Modifier = Modifier, rid: String, navController: NavController) {
|
fun RoomItem(modifier: Modifier = Modifier, rid: String, navController: NavController) {
|
||||||
var room by remember { mutableStateOf<Room?>(null) }
|
var room by remember { mutableStateOf<Room?>(null) }
|
||||||
|
var directUser by remember { mutableStateOf<UserProfile?>(null) }
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
|
|
||||||
LaunchedEffect(true) {
|
LaunchedEffect(true) {
|
||||||
@@ -87,13 +90,28 @@ fun RoomItem(modifier: Modifier = Modifier, rid: String, navController: NavContr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LaunchedEffect(room?.direct) {
|
||||||
|
room?.let {
|
||||||
|
it.direct?.let { uid ->
|
||||||
|
scope.launch {
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
directUser = getUserProfile(uid)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (room != null) {
|
if (room != null) {
|
||||||
|
val avatarUrl = room!!.avatarUrl ?: (directUser?.avatarUrl ?: "")
|
||||||
|
|
||||||
Row(
|
Row(
|
||||||
modifier
|
modifier
|
||||||
.padding(8.dp)
|
.padding(8.dp)
|
||||||
.height((52 + 8 * 2).dp)
|
.height((52 + 8 * 2).dp)
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.background(color =
|
.background(
|
||||||
|
color =
|
||||||
if (room!!.type == "m.space")
|
if (room!!.type == "m.space")
|
||||||
MaterialTheme.colorScheme.tertiary
|
MaterialTheme.colorScheme.tertiary
|
||||||
else
|
else
|
||||||
@@ -109,7 +127,7 @@ fun RoomItem(modifier: Modifier = Modifier, rid: String, navController: NavContr
|
|||||||
.padding(8.dp)
|
.padding(8.dp)
|
||||||
) {
|
) {
|
||||||
MXCImage(
|
MXCImage(
|
||||||
room!!.avatarUrl ?: "",
|
avatarUrl,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(end = 4.dp)
|
.padding(end = 4.dp)
|
||||||
.height(52.dp)
|
.height(52.dp)
|
||||||
|
|||||||
Reference in New Issue
Block a user