refactor: Avatar function

This commit is contained in:
2026-04-23 05:41:30 +03:00
parent 52ca540bca
commit f2ab63887a
2 changed files with 97 additions and 48 deletions
@@ -11,7 +11,6 @@ import android.util.Log
import androidx.activity.ComponentActivity import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
@@ -40,7 +39,6 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
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.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
@@ -59,6 +57,8 @@ import de.connect2x.trixnity.client.flattenValues
import de.connect2x.trixnity.client.room import de.connect2x.trixnity.client.room
import de.connect2x.trixnity.client.store.type import de.connect2x.trixnity.client.store.type
import de.connect2x.trixnity.clientserverapi.client.SyncState import de.connect2x.trixnity.clientserverapi.client.SyncState
import de.connect2x.trixnity.clientserverapi.model.user.avatarUrl
import de.connect2x.trixnity.clientserverapi.model.user.displayName
import de.connect2x.trixnity.core.model.events.m.room.CreateEventContent import de.connect2x.trixnity.core.model.events.m.room.CreateEventContent
import io.github.rabehx.iconsax.Iconsax import io.github.rabehx.iconsax.Iconsax
import io.github.rabehx.iconsax.automirrored.outline.ArrowLeft2 import io.github.rabehx.iconsax.automirrored.outline.ArrowLeft2
@@ -68,7 +68,7 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import ru.risdeveau.pixeldragon.R import ru.risdeveau.pixeldragon.R
import ru.risdeveau.pixeldragon.client import ru.risdeveau.pixeldragon.client
import ru.risdeveau.pixeldragon.ui.item.MXCImage import ru.risdeveau.pixeldragon.ui.item.Avatar
import ru.risdeveau.pixeldragon.ui.layout.Room import ru.risdeveau.pixeldragon.ui.layout.Room
import ru.risdeveau.pixeldragon.ui.layout.RoomList import ru.risdeveau.pixeldragon.ui.layout.RoomList
import ru.risdeveau.pixeldragon.ui.theme.PixelDragonTheme import ru.risdeveau.pixeldragon.ui.theme.PixelDragonTheme
@@ -212,6 +212,28 @@ private fun HomeTopBar(syncState: SyncState) {
title = { title = {
Text(syncState.toStatusTitle() ?: stringResource(R.string.app_name)) Text(syncState.toStatusTitle() ?: stringResource(R.string.app_name))
}, },
actions = {
val client = client!!
var userName by remember { mutableStateOf("?") }
var userAvatar: String? by remember { mutableStateOf(null) }
LaunchedEffect(client, syncState) {
val profile = client.api.user
.getProfile(client.userId)
.getOrNull()
userName = profile?.displayName ?: "?"
userAvatar = profile?.avatarUrl
}
Avatar(
Modifier.size(32.dp).clip(CircleShape),
userAvatar,
userName,
MaterialTheme.colorScheme.background
)
}
) )
} }
@@ -260,23 +282,13 @@ private fun RoomTopBarTitle(room: TrixnityRoom) {
Row( Row(
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
) { ) {
if (room.avatarUrl != null) { Avatar(
MXCImage( Modifier
mxcUrl = room.avatarUrl!!, .size(36.dp)
modifier = Modifier .clip(avatarShape),
.size(36.dp) room.avatarUrl,
.clip(avatarShape), title
contentScale = ContentScale.Crop, )
contentDescription = title,
showProgress = false,
)
} else {
RoomAvatarPlaceholder(
title = title,
modifier = Modifier.size(36.dp),
isSpace = isSpace,
)
}
Spacer(Modifier.width(10.dp)) Spacer(Modifier.width(10.dp))
@@ -289,34 +301,6 @@ private fun RoomTopBarTitle(room: TrixnityRoom) {
} }
} }
@Composable
private fun RoomAvatarPlaceholder(
title: String,
modifier: Modifier = Modifier,
isSpace: Boolean = false,
) {
val shape = if (isSpace) RoundedCornerShape(8.dp) else CircleShape
val initial = title
.trim()
.firstOrNull()
?.uppercaseChar()
?.toString()
?: "?"
Box(
modifier = modifier
.clip(shape)
.background(MaterialTheme.colorScheme.secondaryContainer),
contentAlignment = Alignment.Center,
) {
Text(
text = initial,
color = MaterialTheme.colorScheme.onSecondaryContainer,
style = MaterialTheme.typography.titleMedium,
)
}
}
private fun TrixnityRoom.displayName(): String { private fun TrixnityRoom.displayName(): String {
return name?.explicitName return name?.explicitName
?: name?.heroes?.firstNotNullOfOrNull { it.localpart } ?: name?.heroes?.firstNotNullOfOrNull { it.localpart }
@@ -0,0 +1,65 @@
/*
* Created by sweetbread
* Copyright (c) 2026. All rights reserved.
*/
package ru.risdeveau.pixeldragon.ui.item
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
@Composable
fun Avatar(
modifier: Modifier,
url: String?,
fallbackName: String,
fallbackColor: Color = MaterialTheme.colorScheme.secondaryContainer,
) {
if (url != null) {
MXCImage(
mxcUrl = url,
modifier = modifier,
contentScale = ContentScale.Crop,
contentDescription = fallbackName,
showProgress = false,
)
} else {
AvatarPlaceholder(
modifier,
fallbackName,
fallbackColor,
)
}
}
@Composable
private fun AvatarPlaceholder(
modifier: Modifier = Modifier,
fallbackName: String,
fallbackColor: Color,
) {
val initial = fallbackName
.trim()
.firstOrNull()
?.uppercaseChar()
?.toString()
?: "?"
Box(
modifier = modifier.background(fallbackColor),
contentAlignment = Alignment.Center,
) {
Text(
text = initial,
color = MaterialTheme.colorScheme.onSecondaryContainer,
style = MaterialTheme.typography.titleMedium,
)
}
}