From 620f7e0918d53fe880101dba9d6dff11ff0a9d28 Mon Sep 17 00:00:00 2001 From: Ren Amamiya Date: Thu, 14 May 2026 17:52:46 +0700 Subject: [PATCH] refactor avatar component --- .../composeResources/drawable/avatar.png | Bin 0 -> 12163 bytes .../kotlin/su/reya/coop/screens/ChatScreen.kt | 26 ++------ .../kotlin/su/reya/coop/screens/HomeScreen.kt | 59 ++++-------------- .../kotlin/su/reya/coop/shared/Avatar.kt | 38 +++++++++++ 4 files changed, 56 insertions(+), 67 deletions(-) create mode 100644 composeApp/src/androidMain/composeResources/drawable/avatar.png create mode 100644 composeApp/src/androidMain/kotlin/su/reya/coop/shared/Avatar.kt diff --git a/composeApp/src/androidMain/composeResources/drawable/avatar.png b/composeApp/src/androidMain/composeResources/drawable/avatar.png new file mode 100644 index 0000000000000000000000000000000000000000..8805020677ad23a68bddda772ccb90b87652bf42 GIT binary patch literal 12163 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 literal 0 HcmV?d00001 diff --git a/composeApp/src/androidMain/kotlin/su/reya/coop/screens/ChatScreen.kt b/composeApp/src/androidMain/kotlin/su/reya/coop/screens/ChatScreen.kt index a8fb6d5..a907668 100644 --- a/composeApp/src/androidMain/kotlin/su/reya/coop/screens/ChatScreen.kt +++ b/composeApp/src/androidMain/kotlin/su/reya/coop/screens/ChatScreen.kt @@ -16,7 +16,6 @@ import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.widthIn import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items -import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.FilledTonalIconButton import androidx.compose.material3.Icon @@ -42,15 +41,11 @@ import androidx.compose.runtime.remember 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.graphics.Color -import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp -import coil3.compose.AsyncImage import coop.composeapp.generated.resources.Res import coop.composeapp.generated.resources.ic_arrow_back -import coop.composeapp.generated.resources.ic_avatar import coop.composeapp.generated.resources.ic_send import org.jetbrains.compose.resources.painterResource import rust.nostr.sdk.UnsignedEvent @@ -58,6 +53,7 @@ import su.reya.coop.LocalNostrViewModel import su.reya.coop.LocalSnackbarHostState import su.reya.coop.humanReadable import su.reya.coop.roomId +import su.reya.coop.shared.Avatar import su.reya.coop.shared.displayNameFlow import su.reya.coop.shared.pictureFlow @@ -113,21 +109,11 @@ fun ChatScreen( title = { Row(verticalAlignment = Alignment.CenterVertically) { Box { - if (!picture.isNullOrBlank()) { - AsyncImage( - model = picture, - contentDescription = "Room Avatar", - modifier = Modifier - .size(32.dp) - .clip(CircleShape), - contentScale = ContentScale.Crop - ) - } else { - Icon( - painter = painterResource(Res.drawable.ic_avatar), - contentDescription = "User" - ) - } + Avatar( + picture = picture, + description = displayName, + size = 32.dp, + ) } Spacer(modifier = Modifier.size(8.dp)) Text( diff --git a/composeApp/src/androidMain/kotlin/su/reya/coop/screens/HomeScreen.kt b/composeApp/src/androidMain/kotlin/su/reya/coop/screens/HomeScreen.kt index 05a71cb..da90657 100644 --- a/composeApp/src/androidMain/kotlin/su/reya/coop/screens/HomeScreen.kt +++ b/composeApp/src/androidMain/kotlin/su/reya/coop/screens/HomeScreen.kt @@ -13,7 +13,6 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items -import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi @@ -44,13 +43,10 @@ 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.platform.LocalClipboard import androidx.compose.ui.platform.toClipEntry import androidx.compose.ui.unit.dp -import coil3.compose.AsyncImage import coop.composeapp.generated.resources.Res -import coop.composeapp.generated.resources.ic_avatar import coop.composeapp.generated.resources.ic_search import kotlinx.coroutines.launch import org.jetbrains.compose.resources.painterResource @@ -58,6 +54,7 @@ import su.reya.coop.LocalNostrViewModel import su.reya.coop.LocalSnackbarHostState import su.reya.coop.Room import su.reya.coop.ago +import su.reya.coop.shared.Avatar import su.reya.coop.shared.displayNameFlow import su.reya.coop.shared.pictureFlow import su.reya.coop.short @@ -103,21 +100,11 @@ fun HomeScreen(onOpenChat: (Long) -> Unit) { } // User IconButton(onClick = { showBottomSheet = true }) { - if (userProfile?.asRecord()?.picture != null) { - AsyncImage( - model = userProfile?.asRecord()?.picture, - contentDescription = "User Avatar", - modifier = Modifier - .size(32.dp) - .clip(CircleShape), - contentScale = ContentScale.Crop - ) - } else { - Icon( - painter = painterResource(Res.drawable.ic_avatar), - contentDescription = "User" - ) - } + Avatar( + picture = userProfile?.asRecord()?.picture, + description = userProfile?.asRecord()?.displayName, + size = 32.dp, + ) } } ) @@ -188,19 +175,11 @@ fun HomeScreen(onOpenChat: (Long) -> Unit) { .clip(MaterialShapes.Cookie9Sided.toShape()), contentAlignment = Alignment.Center ) { - if (userProfile?.asRecord()?.picture != null) { - AsyncImage( - model = userProfile?.asRecord()?.picture, - contentDescription = "User Avatar", - modifier = Modifier.fillMaxSize(), - contentScale = ContentScale.Crop - ) - } else { - Icon( - painter = painterResource(Res.drawable.ic_avatar), - contentDescription = "User" - ) - } + Avatar( + picture = userProfile?.asRecord()?.picture, + description = userProfile?.asRecord()?.displayName, + shape = MaterialShapes.Cookie9Sided.toShape(), + ) } Spacer(modifier = Modifier.size(8.dp)) Box( @@ -250,21 +229,7 @@ fun ChatRoom(room: Room, onClick: () -> Unit) { ListItem( modifier = Modifier.clickable(onClick = onClick), leadingContent = { - if (!picture.isNullOrBlank()) { - AsyncImage( - model = picture, - contentDescription = "Room Avatar", - modifier = Modifier - .size(48.dp) - .clip(CircleShape), - contentScale = ContentScale.Crop, - ) - } else { - Icon( - painter = painterResource(Res.drawable.ic_avatar), - contentDescription = "User" - ) - } + Avatar(picture = picture, description = displayName) }, headlineContent = { Row( diff --git a/composeApp/src/androidMain/kotlin/su/reya/coop/shared/Avatar.kt b/composeApp/src/androidMain/kotlin/su/reya/coop/shared/Avatar.kt new file mode 100644 index 0000000..023f871 --- /dev/null +++ b/composeApp/src/androidMain/kotlin/su/reya/coop/shared/Avatar.kt @@ -0,0 +1,38 @@ +package su.reya.coop.shared + +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Shape +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import coil3.compose.AsyncImage +import coop.composeapp.generated.resources.Res +import coop.composeapp.generated.resources.avatar +import org.jetbrains.compose.resources.painterResource + +@Composable +fun Avatar( + picture: String?, + description: String?, + modifier: Modifier = Modifier, + size: Dp = 48.dp, + shape: Shape = CircleShape +) { + val placeholder = painterResource(Res.drawable.avatar) + + AsyncImage( + model = picture, + contentDescription = description, + modifier = modifier + .size(size) + .clip(shape), + contentScale = ContentScale.Crop, + fallback = placeholder, + error = placeholder, + placeholder = placeholder + ) +}