diff --git a/app/src/main/java/ru/risdeveau/pixeldragon/ui/activity/MainActivity.kt b/app/src/main/java/ru/risdeveau/pixeldragon/ui/activity/MainActivity.kt index 05acde1..a009dc0 100755 --- a/app/src/main/java/ru/risdeveau/pixeldragon/ui/activity/MainActivity.kt +++ b/app/src/main/java/ru/risdeveau/pixeldragon/ui/activity/MainActivity.kt @@ -11,7 +11,6 @@ import android.util.Log import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge -import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer @@ -40,7 +39,6 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip -import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextOverflow 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.store.type 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 io.github.rabehx.iconsax.Iconsax import io.github.rabehx.iconsax.automirrored.outline.ArrowLeft2 @@ -68,7 +68,7 @@ import kotlinx.coroutines.flow.map import kotlinx.coroutines.launch import ru.risdeveau.pixeldragon.R 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.RoomList import ru.risdeveau.pixeldragon.ui.theme.PixelDragonTheme @@ -212,6 +212,28 @@ private fun HomeTopBar(syncState: SyncState) { title = { 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) { + val profile = client.api.user + .getProfile(client.userId) + .getOrThrow() + + 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( verticalAlignment = Alignment.CenterVertically, ) { - if (room.avatarUrl != null) { - MXCImage( - mxcUrl = room.avatarUrl!!, - modifier = Modifier - .size(36.dp) - .clip(avatarShape), - contentScale = ContentScale.Crop, - contentDescription = title, - showProgress = false, - ) - } else { - RoomAvatarPlaceholder( - title = title, - modifier = Modifier.size(36.dp), - isSpace = isSpace, - ) - } + Avatar( + Modifier + .size(36.dp) + .clip(avatarShape), + room.avatarUrl, + title + ) 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 { return name?.explicitName ?: name?.heroes?.firstNotNullOfOrNull { it.localpart } diff --git a/app/src/main/java/ru/risdeveau/pixeldragon/ui/item/Avatar.kt b/app/src/main/java/ru/risdeveau/pixeldragon/ui/item/Avatar.kt new file mode 100755 index 0000000..93fb0bf --- /dev/null +++ b/app/src/main/java/ru/risdeveau/pixeldragon/ui/item/Avatar.kt @@ -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, + ) + } +} \ No newline at end of file