From 70d9db6cbf9d673ec15ed0efedc60b87feadfc73 Mon Sep 17 00:00:00 2001 From: Sweetbread Date: Tue, 4 Nov 2025 23:24:20 +0300 Subject: [PATCH] ref: caching joined rooms --- .../java/ru/risdeveau/pixeldragon/api/Room.kt | 17 ++- .../ru/risdeveau/pixeldragon/repo/Room.kt | 9 ++ .../risdeveau/pixeldragon/ui/layout/Room.kt | 7 +- .../risdeveau/pixeldragon/ui/layout/Rooms.kt | 114 ++++++++---------- 4 files changed, 74 insertions(+), 73 deletions(-) diff --git a/app/src/main/java/ru/risdeveau/pixeldragon/api/Room.kt b/app/src/main/java/ru/risdeveau/pixeldragon/api/Room.kt index 273c8eb..09c166b 100755 --- a/app/src/main/java/ru/risdeveau/pixeldragon/api/Room.kt +++ b/app/src/main/java/ru/risdeveau/pixeldragon/api/Room.kt @@ -24,16 +24,25 @@ import ru.risdeveau.pixeldragon.token // //} -suspend fun getRooms(): List { +suspend fun getJoinedRooms(): List { + val r = client.get("$baseUrl/joined_rooms") + { bearerAuth(token) } + val rooms = JSONObject(r.bodyAsText()).getJSONArray("joined_rooms") + return List( + rooms.length() + ) { i -> getRoom(rooms.getString(i), true) } +} + +suspend fun isJoined(id: String): Boolean { val r = client.get("$baseUrl/joined_rooms") { bearerAuth(token) } val rooms = JSONObject(r.bodyAsText()).getJSONArray("joined_rooms") return List( rooms.length() - ) { i -> rooms.getString(i) } + ) { i -> rooms.getString(i) }.contains(id) } -suspend fun getRoom(rid: String): Room { +suspend fun getRoom(rid: String, joined: Boolean? = null): Room { val direct = getAccountData(getMe()!!.userId, "m.direct") var directWith = "" direct?.let { @@ -61,7 +70,7 @@ suspend fun getRoom(rid: String): Room { null, avatar, null, - true, // TODO: insert actual value + joined ?: isJoined(rid), if (directWith.isNotEmpty()) User.getById(directWith) else null ) } diff --git a/app/src/main/java/ru/risdeveau/pixeldragon/repo/Room.kt b/app/src/main/java/ru/risdeveau/pixeldragon/repo/Room.kt index 471712b..4c57611 100755 --- a/app/src/main/java/ru/risdeveau/pixeldragon/repo/Room.kt +++ b/app/src/main/java/ru/risdeveau/pixeldragon/repo/Room.kt @@ -5,6 +5,7 @@ package ru.risdeveau.pixeldragon.repo +import ru.risdeveau.pixeldragon.api.getJoinedRooms import ru.risdeveau.pixeldragon.api.getRoom import ru.risdeveau.pixeldragon.db.cacheDb import ru.risdeveau.pixeldragon.db.isExpired @@ -34,5 +35,13 @@ class Room ( } return cachedRoom!!.toDomain() } + + suspend fun getJoined(cached: Boolean = true): List { + val cacheJoined = cacheDb.roomDoa().getAllJoined() + if (cacheJoined.isEmpty()) { + return getJoinedRooms() + } + return List(cacheJoined.size) { i -> cacheJoined[i].toDomain() } + } } } \ No newline at end of file diff --git a/app/src/main/java/ru/risdeveau/pixeldragon/ui/layout/Room.kt b/app/src/main/java/ru/risdeveau/pixeldragon/ui/layout/Room.kt index 3079b46..a5259be 100755 --- a/app/src/main/java/ru/risdeveau/pixeldragon/ui/layout/Room.kt +++ b/app/src/main/java/ru/risdeveau/pixeldragon/ui/layout/Room.kt @@ -86,7 +86,7 @@ fun EventItem(event: Event) { "m.room.message" -> Column( Modifier .fillMaxSize() - .then ( + .then( if (event.sender != ME!!.userId) Modifier.padding(end = 16.dp) else @@ -106,8 +106,11 @@ fun EventItem(event: Event) { when (val msgtype = event.content.optString("msgtype", null)) { "m.text" -> when (event.content.optString("format")) { - "org.matrix.custom.html" -> + "org.matrix.custom.html" -> { + if (event.content.getString("body") == event.content.getString("formatted_body")) + Text(event.content.getString("body")) HtmlRenderer(event.content.getString("formatted_body")) + } else -> Text(event.content.getString("body")) } diff --git a/app/src/main/java/ru/risdeveau/pixeldragon/ui/layout/Rooms.kt b/app/src/main/java/ru/risdeveau/pixeldragon/ui/layout/Rooms.kt index e05deaa..5ef7c2f 100755 --- a/app/src/main/java/ru/risdeveau/pixeldragon/ui/layout/Rooms.kt +++ b/app/src/main/java/ru/risdeveau/pixeldragon/ui/layout/Rooms.kt @@ -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.LinearProgressIndicator import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -29,17 +28,17 @@ import androidx.compose.runtime.remember 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 kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext -import ru.risdeveau.pixeldragon.api.getRooms import ru.risdeveau.pixeldragon.repo.Room import ru.risdeveau.pixeldragon.ui.item.MXCImage @Composable fun RoomList(modifier: Modifier = Modifier, navController: NavController) { - var list by remember { mutableStateOf(listOf()) } + var list by remember { mutableStateOf(listOf()) } val listState = rememberLazyListState() // if (itemState.scrollToTop) { @@ -50,12 +49,12 @@ fun RoomList(modifier: Modifier = Modifier, navController: NavController) { // } LaunchedEffect(Unit) { - list = withContext(Dispatchers.IO) { getRooms() } + list = withContext(Dispatchers.IO) { Room.getJoined() } } LazyColumn(modifier = modifier, state = listState) { - items(list) { rid -> - RoomItem(rid = rid, navController = navController ) + items(list) { room -> + RoomItem(room = room, navController = navController ) } item { @@ -67,72 +66,53 @@ fun RoomList(modifier: Modifier = Modifier, navController: NavController) { } @Composable -fun RoomItem(modifier: Modifier = Modifier, rid: String, navController: NavController) { - var room by remember { mutableStateOf(null) } +fun RoomItem(modifier: Modifier = Modifier, room: Room, navController: NavController) { + val avatarUrl = room.avatarUrl ?: (room.direct?.avatarUrl ?: "") + val name = room.name ?: (room.direct?.name ?: "Unnamed") - LaunchedEffect(Unit) { - room = withContext(Dispatchers.IO) { Room.getById(rid) } - } - - if (room != null) { - val room = room!! - val avatarUrl = room.avatarUrl ?: (room.direct?.avatarUrl ?: "") - - Row( - modifier - .padding(8.dp) - .height((52 + 8 * 2).dp) - .fillMaxWidth() - .background( - color = - if (room.type == "m.space") - MaterialTheme.colorScheme.tertiary - else - MaterialTheme.colorScheme.background - ) - .clip(RoundedCornerShape(12.dp)) - .clickable { + Row( + modifier + .padding(8.dp) + .height((52 + 8 * 2).dp) + .fillMaxWidth() + .background( + color = if (room.type == "m.space") - navController.navigate("space/$rid") + MaterialTheme.colorScheme.tertiary else - navController.navigate("room/$rid") - } - .padding(8.dp) - ) { - MXCImage( - avatarUrl, - modifier = Modifier - .padding(end = 4.dp) - .height(52.dp) - .width(52.dp) - .let { - if (room.type == "m.space") - it.clip(RoundedCornerShape(12.dp)) - else - it.clip(CircleShape) - } + MaterialTheme.colorScheme.background ) - Column { - Text(room.type) - Text( - room.name ?: "Unnamed", - maxLines = 1, - color = MaterialTheme.colorScheme.primary, - fontSize = MaterialTheme.typography.titleLarge.fontSize - ) + .clip(RoundedCornerShape(12.dp)) + .clickable { + if (room.type == "m.space") + navController.navigate("space/${room.id}") + else + navController.navigate("room/${room.id}") } - } - } else { - Row( - modifier - .padding(8.dp) - .height(80.dp) - .fillMaxWidth() - .background(MaterialTheme.colorScheme.background) - .clip(RoundedCornerShape(16.dp)) - .padding(8.dp) - ) { - LinearProgressIndicator(Modifier.fillMaxWidth()) + .padding(8.dp) + ) { + MXCImage( + avatarUrl, + modifier = Modifier + .padding(end = 4.dp) + .height(52.dp) + .width(52.dp) + .let { + if (room.type == "m.space") + it.clip(RoundedCornerShape(12.dp)) + else + it.clip(CircleShape) + }, + ContentScale.Crop + ) + Column { + Text(room.type) + Text( + name, + maxLines = 1, + color = MaterialTheme.colorScheme.primary, + fontSize = MaterialTheme.typography.titleLarge.fontSize + ) } } } \ No newline at end of file