refactor: Avatar function
This commit is contained in:
@@ -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,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user