Render profile list item.
This commit is contained in:
@@ -6,6 +6,25 @@ import ac.cord.auxiliary.compose.database.model.traits.NostrEventEntity
|
||||
import ac.cord.auxiliary.compose.database.model.traits.SoftDeletableEntity
|
||||
import ac.cord.auxiliary.compose.database.model.traits.TimestampedEntity
|
||||
import ac.cord.auxiliary.compose.database.model.traits.UserViewableEntity
|
||||
import ac.cord.auxiliary.compose.ui.composable.navigation.routes.NostrEventDetailRoute
|
||||
import ac.cord.auxiliary.compose.ui.composable.navigation.routes.Route
|
||||
import ac.cord.auxiliary.compose.ui.composable.widgets.profile.ProfileAvatar
|
||||
import ac.cord.auxiliary.compose.ui.theme.AuxTheme
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.room.Entity
|
||||
import androidx.room.ForeignKey
|
||||
import androidx.room.Index
|
||||
@@ -56,4 +75,74 @@ data class Profile(
|
||||
fun humanReadableNameOrPubkey(): String {
|
||||
return displayName ?: userName ?: nip05 ?: twitter ?: publicKey
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun RenderAsListItem(
|
||||
onNavigateToEvent: (Route) -> Unit
|
||||
) {
|
||||
Card(
|
||||
modifier = Modifier.fillMaxWidth().padding(
|
||||
horizontal = 6.dp,
|
||||
vertical = 3.dp
|
||||
),
|
||||
onClick = {
|
||||
onNavigateToEvent.invoke(
|
||||
NostrEventDetailRoute(
|
||||
nostrEventId
|
||||
)
|
||||
)
|
||||
}
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(
|
||||
space = 4.dp,
|
||||
alignment = Alignment.Start
|
||||
)
|
||||
) {
|
||||
Column {
|
||||
ProfileAvatar(
|
||||
publicKey = publicKey,
|
||||
profile = this@Profile
|
||||
)
|
||||
}
|
||||
|
||||
Column(
|
||||
modifier = Modifier.weight(1f)
|
||||
) {
|
||||
Text(
|
||||
text = humanReadableNameOrPubkey(),
|
||||
style = MaterialTheme.typography.bodyMedium
|
||||
)
|
||||
|
||||
Text(
|
||||
text = nip05 ?: "",
|
||||
style = MaterialTheme.typography.labelMedium
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun ProfileRenderAsListItemPreview() {
|
||||
val profile = Profile(
|
||||
publicKey = "pubKey",
|
||||
displayName = "John Doe",
|
||||
nip05 = "john@doe.com",
|
||||
about = "I am the stone that the builder refused.",
|
||||
nostrEventId = "nostrEventId"
|
||||
)
|
||||
AuxTheme {
|
||||
Surface(
|
||||
modifier = Modifier.padding(20.dp)
|
||||
) {
|
||||
profile.RenderAsListItem(
|
||||
onNavigateToEvent = {}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import ac.cord.auxiliary.compose.database.model.Profile
|
||||
import ac.cord.auxiliary.compose.database.model.intermdiate.LocalNostrEvent
|
||||
import ac.cord.auxiliary.compose.repository.NostrRepository
|
||||
import ac.cord.auxiliary.compose.ui.composable.navigation.routes.Route
|
||||
import ac.cord.auxiliary.compose.ui.composable.widgets.profile.ProfileAvatar
|
||||
import ac.cord.auxiliary.compose.ui.theme.AuxTheme
|
||||
import ac.cord.auxiliary.compose.ui.view.model.FeedListViewModel
|
||||
import ac.cord.auxiliary.compose.ui.view.model.FollowersListViewModel
|
||||
@@ -25,6 +26,7 @@ import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.pager.HorizontalPager
|
||||
import androidx.compose.foundation.pager.rememberPagerState
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.ArrowBackIosNew
|
||||
import androidx.compose.material.icons.filled.Bolt
|
||||
@@ -48,6 +50,7 @@ import androidx.compose.runtime.key
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
@@ -145,11 +148,10 @@ fun MetadataEventDetail(
|
||||
horizontalArrangement = Arrangement.spacedBy(10.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
|
||||
Icon(
|
||||
Icons.Default.Person,
|
||||
modifier = Modifier.size(50.dp),
|
||||
contentDescription = profile?.displayName ?: profile?.userName ?: "Profile picture"
|
||||
ProfileAvatar(
|
||||
modifier = Modifier.size(75.dp).clip(shape = CircleShape),
|
||||
profile = profile,
|
||||
publicKey = localNostrEvent.nostrEvent.pubKey
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -25,7 +25,11 @@ import coil3.compose.AsyncImage
|
||||
import kotlin.math.abs
|
||||
|
||||
@Composable
|
||||
fun ProfileAvatar(publicKey: String, profile: Profile?) {
|
||||
fun ProfileAvatar(
|
||||
modifier: Modifier = Modifier.size(55.dp).clip(shape = CircleShape),
|
||||
publicKey: String,
|
||||
profile: Profile?
|
||||
) {
|
||||
val tintColor = Color.hsl(
|
||||
hue = abs(
|
||||
publicKey.hashCode()
|
||||
@@ -33,11 +37,10 @@ fun ProfileAvatar(publicKey: String, profile: Profile?) {
|
||||
saturation = 0.55f,
|
||||
lightness = 0.45f
|
||||
)
|
||||
val imageModifier = Modifier.size(55.dp).clip(shape = CircleShape)
|
||||
|
||||
if (profile?.picture == null) {
|
||||
Icon(
|
||||
modifier = imageModifier,
|
||||
modifier = modifier,
|
||||
imageVector = Icons.Default.AccountCircle,
|
||||
tint = tintColor,
|
||||
contentDescription = "Profile picture",
|
||||
@@ -60,7 +63,7 @@ fun ProfileAvatar(publicKey: String, profile: Profile?) {
|
||||
|
||||
AsyncImage(
|
||||
model = profile.picture,
|
||||
modifier = imageModifier,
|
||||
modifier = modifier,
|
||||
contentDescription = "Profile picture for ${profile.displayName ?: profile.publicKey}",
|
||||
placeholder = placeHolderGraphic,
|
||||
fallback = fallbackGraphic,
|
||||
|
||||
@@ -144,25 +144,9 @@ class FollowersListViewModel(
|
||||
items = followersListUIState.followers,
|
||||
key = { profile -> profile.publicKey }
|
||||
) { follower ->
|
||||
Column(
|
||||
modifier = Modifier.clickable {
|
||||
onNavigateToEvent.invoke(
|
||||
NostrEventDetailRoute(
|
||||
follower.nostrEventId
|
||||
)
|
||||
)
|
||||
}
|
||||
) {
|
||||
Text(
|
||||
text = follower.displayName ?: follower.userName ?: follower.userName ?: follower.publicKey
|
||||
)
|
||||
|
||||
follower.nip05?.let {
|
||||
Text(
|
||||
text = follower.nip05
|
||||
)
|
||||
}
|
||||
}
|
||||
follower.RenderAsListItem(
|
||||
onNavigateToEvent = onNavigateToEvent
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,25 +143,9 @@ class FollowingListViewModel(
|
||||
items = feedListUIState.following,
|
||||
key = { profile -> profile.publicKey }
|
||||
) { profile ->
|
||||
Column(
|
||||
modifier = Modifier.clickable {
|
||||
onNavigateToEvent.invoke(
|
||||
NostrEventDetailRoute(
|
||||
profile.nostrEventId
|
||||
)
|
||||
)
|
||||
}
|
||||
) {
|
||||
Text(
|
||||
text = profile.displayName ?: profile.userName ?: profile.userName ?: profile.publicKey
|
||||
)
|
||||
|
||||
profile.nip05?.let {
|
||||
Text(
|
||||
text = profile.nip05
|
||||
)
|
||||
}
|
||||
}
|
||||
profile.RenderAsListItem(
|
||||
onNavigateToEvent = onNavigateToEvent
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user