Improve RichContent for reposted notes
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
package ac.cord.auxiliary.compose.database.model.intermdiate
|
||||
|
||||
import ac.cord.auxiliary.compose.database.model.InReplyToRelation
|
||||
import ac.cord.auxiliary.compose.database.model.NostrEvent
|
||||
import ac.cord.auxiliary.compose.database.model.Profile
|
||||
import ac.cord.auxiliary.compose.database.model.QuotedRelation
|
||||
import ac.cord.auxiliary.compose.extensions.toFormattedTimeAndDateString
|
||||
import ac.cord.auxiliary.compose.ui.composable.widgets.profile.ProfileAvatar
|
||||
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.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.text.style.TextAlign
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.room.Embedded
|
||||
import androidx.room.Relation
|
||||
|
||||
data class LocalInReplyToNostrEvent(
|
||||
@Embedded val inReplyToRelation: InReplyToRelation,
|
||||
|
||||
@Relation(
|
||||
parentColumn = "inReplyToNostrEventId",
|
||||
entityColumn = "id"
|
||||
)
|
||||
val nostrEvent: NostrEvent,
|
||||
|
||||
@Relation(
|
||||
parentColumn = "inReplyToProfilePublicKey",
|
||||
entityColumn = "publicKey"
|
||||
)
|
||||
val profile: Profile?,
|
||||
|
||||
// TODO: Figure out if we want to add the root of the reply...
|
||||
// @Relation(
|
||||
// entity = Mention::class,
|
||||
// parentColumn = "id",
|
||||
// entityColumn = "nostrEventId",
|
||||
// )
|
||||
// val mentionedProfiles: List<LocalMention?> = emptyList(),
|
||||
) {
|
||||
@Composable
|
||||
fun RenderNotePreview() {
|
||||
Column {
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth().padding(12.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(4.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
val profile = profile
|
||||
|
||||
ProfileAvatar(
|
||||
profile = profile,
|
||||
publicKey = nostrEvent.pubKey
|
||||
)
|
||||
|
||||
Column(
|
||||
modifier = Modifier.weight(1f)
|
||||
) {
|
||||
Text(
|
||||
text = profile?.displayName ?: profile?.userName ?: nostrEvent.pubKey,
|
||||
style = MaterialTheme.typography.labelLarge
|
||||
)
|
||||
|
||||
profile?.nip05?.let {
|
||||
Text(
|
||||
text = profile.nip05 ?: "",
|
||||
style = MaterialTheme.typography.labelMedium
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Use RichContent...
|
||||
Text(
|
||||
modifier = Modifier.fillMaxWidth().padding(
|
||||
horizontal = 20.dp
|
||||
),
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
textAlign = TextAlign.Start,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
text = nostrEvent.content
|
||||
)
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth().padding(20.dp),
|
||||
horizontalArrangement = Arrangement.Start
|
||||
) {
|
||||
Text(
|
||||
text = nostrEvent.createdAt.toFormattedTimeAndDateString(),
|
||||
style = MaterialTheme.typography.labelSmall
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -36,10 +36,11 @@ data class LocalNostrEvent(
|
||||
val profile: Profile?,
|
||||
|
||||
@Relation(
|
||||
entity = RepostedRelation::class,
|
||||
parentColumn = "id",
|
||||
entityColumn = "repostingNostrEventId"
|
||||
)
|
||||
val repostedRelation: RepostedRelation? = null,
|
||||
val localRepostedNostrEvent: LocalRepostedNostrEvent? = null,
|
||||
|
||||
@Relation(
|
||||
entity = QuotedRelation::class,
|
||||
@@ -48,33 +49,12 @@ data class LocalNostrEvent(
|
||||
)
|
||||
val localQuotedNostrEvent: LocalQuotedNostrEvent? = null,
|
||||
|
||||
// @Relation(
|
||||
// parentColumn = "id",
|
||||
// entityColumn = "id",
|
||||
// associateBy = Junction(
|
||||
// value = QuotedRelation::class,
|
||||
// parentColumn = "quotingNostrEventId",
|
||||
// entityColumn = "quotedNostrEventId"
|
||||
// )
|
||||
// )
|
||||
// val quotedNostrEvent: NostrEvent? = null,
|
||||
|
||||
@Relation(
|
||||
parentColumn = "id",
|
||||
entityColumn = "publicKey",
|
||||
associateBy = Junction(
|
||||
value = QuotedRelation::class,
|
||||
parentColumn = "quotingNostrEventId",
|
||||
entityColumn = "quotedProfilePublicKey"
|
||||
)
|
||||
)
|
||||
val quotedAuthorProfile: Profile? = null,
|
||||
|
||||
@Relation(
|
||||
entity = InReplyToRelation::class,
|
||||
parentColumn = "id",
|
||||
entityColumn = "replyingNostrEventId"
|
||||
)
|
||||
val inReplyToNostrEvent: InReplyToRelation? = null,
|
||||
val localInReplyToNostrEvent: LocalInReplyToNostrEvent? = null,
|
||||
|
||||
@Relation(
|
||||
entity = Mention::class,
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
package ac.cord.auxiliary.compose.database.model.intermdiate
|
||||
|
||||
import ac.cord.auxiliary.compose.database.model.NostrEvent
|
||||
import ac.cord.auxiliary.compose.database.model.Profile
|
||||
import ac.cord.auxiliary.compose.database.model.QuotedRelation
|
||||
import ac.cord.auxiliary.compose.database.model.RepostedRelation
|
||||
import ac.cord.auxiliary.compose.extensions.toFormattedTimeAndDateString
|
||||
import ac.cord.auxiliary.compose.ui.composable.widgets.profile.ProfileAvatar
|
||||
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.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.text.style.TextAlign
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.room.Embedded
|
||||
import androidx.room.Relation
|
||||
|
||||
data class LocalRepostedNostrEvent(
|
||||
@Embedded val repostedRelation: RepostedRelation,
|
||||
|
||||
@Relation(
|
||||
parentColumn = "repostedNostrEventId",
|
||||
entityColumn = "id"
|
||||
)
|
||||
val nostrEvent: NostrEvent,
|
||||
|
||||
@Relation(
|
||||
parentColumn = "repostedProfilePublicKey",
|
||||
entityColumn = "publicKey"
|
||||
)
|
||||
val profile: Profile?,
|
||||
|
||||
// @Relation(
|
||||
// entity = Mention::class,
|
||||
// parentColumn = "id",
|
||||
// entityColumn = "nostrEventId",
|
||||
// )
|
||||
// val mentionedProfiles: List<LocalMention?> = emptyList(),
|
||||
) {
|
||||
@Composable
|
||||
fun RenderNotePreview() {
|
||||
Column {
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth().padding(12.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(4.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
val profile = profile
|
||||
|
||||
ProfileAvatar(
|
||||
profile = profile,
|
||||
publicKey = nostrEvent.pubKey
|
||||
)
|
||||
|
||||
Column(
|
||||
modifier = Modifier.weight(1f)
|
||||
) {
|
||||
Text(
|
||||
text = profile?.displayName ?: profile?.userName ?: nostrEvent.pubKey,
|
||||
style = MaterialTheme.typography.labelLarge
|
||||
)
|
||||
|
||||
profile?.nip05?.let {
|
||||
Text(
|
||||
text = profile.nip05 ?: "",
|
||||
style = MaterialTheme.typography.labelMedium
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Use RichContent...
|
||||
Text(
|
||||
modifier = Modifier.fillMaxWidth().padding(
|
||||
horizontal = 20.dp
|
||||
),
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
textAlign = TextAlign.Start,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
text = nostrEvent.content
|
||||
)
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth().padding(20.dp),
|
||||
horizontalArrangement = Arrangement.Start
|
||||
) {
|
||||
Text(
|
||||
text = nostrEvent.createdAt.toFormattedTimeAndDateString(),
|
||||
style = MaterialTheme.typography.labelSmall
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,9 @@
|
||||
package ac.cord.auxiliary.compose.ui.composable.widgets.content
|
||||
|
||||
import ac.cord.auxiliary.compose.database.model.NostrEvent
|
||||
import ac.cord.auxiliary.compose.database.model.intermdiate.LocalMention
|
||||
import ac.cord.auxiliary.compose.database.model.intermdiate.LocalNostrEvent
|
||||
import ac.cord.auxiliary.compose.database.model.intermdiate.LocalQuotedNostrEvent
|
||||
import ac.cord.auxiliary.compose.ui.composable.widgets.content.Constants.INLINE_CONTENT_TAG
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
@@ -30,7 +33,9 @@ import coil3.compose.AsyncImage
|
||||
|
||||
@Composable
|
||||
fun RichContent(
|
||||
localNostrEvent: LocalNostrEvent,
|
||||
nostrEvent: NostrEvent,
|
||||
localQuotedNostrEvent: LocalQuotedNostrEvent?,
|
||||
mentionedProfiles: List<LocalMention?>,
|
||||
style: TextStyle = MaterialTheme.typography.bodyLarge,
|
||||
color: Color = MaterialTheme.colorScheme.onSurface,
|
||||
linkColor: Color = Color.Unspecified,
|
||||
@@ -44,7 +49,7 @@ fun RichContent(
|
||||
noteActions: NoteActions? = null,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
val content = localNostrEvent.nostrEvent.content
|
||||
val content = nostrEvent.content
|
||||
|
||||
val segments = remember(content, emojiMap, imetaMap, plainLinks) { ContentParser.parse(content.trimEnd('\n', '\r'), emojiMap, imetaMap, trimBlankLines = !plainLinks) }
|
||||
// val profileVer = eventRepo?.profileVersion?.collectAsState()?.value ?: 0
|
||||
@@ -105,10 +110,10 @@ fun RichContent(
|
||||
val profileNames = remember(profilePubkeys) {
|
||||
val names = mutableMapOf<String, String>()
|
||||
|
||||
if (localNostrEvent.mentionedProfiles.isNotEmpty()) {
|
||||
Logger.withTag("RichContent").d("mentionedProfiles: ${localNostrEvent.mentionedProfiles}")
|
||||
if (mentionedProfiles.isNotEmpty()) {
|
||||
Logger.withTag("RichContent").d("mentionedProfiles: ${mentionedProfiles}")
|
||||
for (pubkey in profilePubkeys) {
|
||||
val mentionedProfile = localNostrEvent.mentionedProfiles.find { mentionedProfile -> mentionedProfile?.profile?.publicKey == pubkey }
|
||||
val mentionedProfile = mentionedProfiles.find { mentionedProfile -> mentionedProfile?.profile?.publicKey == pubkey }
|
||||
names[pubkey] = mentionedProfile?.profile?.humanReadableNameOrPubkey()
|
||||
?: "${pubkey.take(8)}...${pubkey.takeLast(4)}"
|
||||
}
|
||||
@@ -275,9 +280,9 @@ fun RichContent(
|
||||
LinkPreview(url = segment.url)
|
||||
}
|
||||
is ContentSegment.NostrNoteSegment -> {
|
||||
if (localNostrEvent.localQuotedNostrEvent != null) {
|
||||
if (localQuotedNostrEvent != null) {
|
||||
QuotedNote(
|
||||
localQuotedNostrEvent = localNostrEvent.localQuotedNostrEvent,
|
||||
localQuotedNostrEvent = localQuotedNostrEvent,
|
||||
relayHints = segment.relayHints,
|
||||
onNoteClick = onNoteClick,
|
||||
noteActions = noteActions
|
||||
|
||||
@@ -141,7 +141,9 @@ fun TextNoteEventDetail(
|
||||
modifier = Modifier.fillMaxWidth().padding(
|
||||
horizontal = 20.dp
|
||||
),
|
||||
localNostrEvent = localNostrEvent,
|
||||
nostrEvent = localNostrEvent.nostrEvent,
|
||||
localQuotedNostrEvent = localNostrEvent.localQuotedNostrEvent,
|
||||
mentionedProfiles = localNostrEvent.mentionedProfiles
|
||||
)
|
||||
|
||||
Row(
|
||||
|
||||
@@ -62,9 +62,13 @@ fun LocalNostrEvent.ListView(
|
||||
style = MaterialTheme.typography.labelSmall)
|
||||
}
|
||||
|
||||
if (repostedRelation != null) {
|
||||
if (localRepostedNostrEvent != null) {
|
||||
TextNoteFeedItem(
|
||||
localNostrEvent = this@ListView,
|
||||
nostrEvent = localRepostedNostrEvent.nostrEvent,
|
||||
profile = localRepostedNostrEvent.profile,
|
||||
localQuotedNostrEvent = null,
|
||||
localInReplyToNostrEvent = null,
|
||||
mentionedProfiles = emptyList(), // TODO: Add localReposted.mentionedProfiles...
|
||||
onNavigateToEvent = onNavigateToEvent
|
||||
)
|
||||
} else {
|
||||
@@ -96,155 +100,17 @@ fun LocalNostrEvent.ListView(
|
||||
// TODO: Support other kinds...
|
||||
else -> {
|
||||
TextNoteFeedItem(
|
||||
localNostrEvent = this,
|
||||
nostrEvent = nostrEvent,
|
||||
profile = profile,
|
||||
localQuotedNostrEvent = localQuotedNostrEvent,
|
||||
localInReplyToNostrEvent = localInReplyToNostrEvent,
|
||||
mentionedProfiles = mentionedProfiles,
|
||||
onNavigateToEvent = onNavigateToEvent
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
|
||||
@Composable
|
||||
private fun TextNoteFeedItem(
|
||||
localNostrEvent: LocalNostrEvent,
|
||||
onNavigateToEvent: (HexKey) -> Unit
|
||||
) {
|
||||
val nostrEvent = localNostrEvent.nostrEvent
|
||||
if (localNostrEvent.repostedRelation != null) {
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth().padding(
|
||||
horizontal = 20.dp
|
||||
),
|
||||
horizontalArrangement = Arrangement.End,
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
// TODO: Get a nested repost... localNostrEvent...
|
||||
Text(
|
||||
"In reply to ",
|
||||
style = MaterialTheme.typography.labelSmall
|
||||
)
|
||||
|
||||
Text(
|
||||
modifier = Modifier.clickable(
|
||||
onClick = {
|
||||
onNavigateToEvent.invoke(localNostrEvent.repostedRelation.repostedNostrEventId)
|
||||
}
|
||||
),
|
||||
style = MaterialTheme.typography.labelLargeEmphasized,
|
||||
text = localNostrEvent.repostedRelation.repostedProfilePublicKey ?: "loading information..."
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
ElevatedCard(
|
||||
modifier = Modifier.padding(
|
||||
horizontal = 10.dp
|
||||
),
|
||||
onClick = {
|
||||
onNavigateToEvent.invoke(nostrEvent.id)
|
||||
}
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.padding(10.dp).fillMaxWidth(),
|
||||
verticalArrangement = Arrangement.spacedBy(10.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
val profile = localNostrEvent.profile
|
||||
if (profile != null) {
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth().clickable(
|
||||
onClick = {
|
||||
onNavigateToEvent.invoke(profile.nostrEventId)
|
||||
}
|
||||
),
|
||||
horizontalArrangement = Arrangement.spacedBy(10.dp, Alignment.Start),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
ProfileAvatar(
|
||||
publicKey = nostrEvent.pubKey,
|
||||
profile = profile
|
||||
)
|
||||
|
||||
Text(
|
||||
modifier = Modifier.weight(1f),
|
||||
text = profile.displayName ?: profile.userName ?: nostrEvent.pubKey,
|
||||
style = MaterialTheme.typography.bodyMedium
|
||||
)
|
||||
}
|
||||
} else {
|
||||
Text(
|
||||
text = "Loading author information"
|
||||
)
|
||||
}
|
||||
|
||||
RichContent(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
localNostrEvent = localNostrEvent,
|
||||
)
|
||||
|
||||
LazyRow(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.spacedBy(
|
||||
10.dp,
|
||||
alignment = Alignment.Start
|
||||
)
|
||||
) {
|
||||
item {
|
||||
AssistChip(
|
||||
label = {
|
||||
Text(
|
||||
text = nostrEvent.kind.toString() // TODO: Kind by name...
|
||||
)
|
||||
},
|
||||
onClick = {
|
||||
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
// item {
|
||||
// SuggestionChip(
|
||||
// label = {
|
||||
// Text(
|
||||
// text = if (localNostrEvent.mentionedProfiles.isNotEmpty()) {
|
||||
// localNostrEvent.mentionedProfiles.joinToString(",") { it?.profile?.humanReadableNameOrPubkey() ?: "Find user information" }
|
||||
// } else {
|
||||
// ":-("
|
||||
// }
|
||||
// )
|
||||
// },
|
||||
// onClick = {
|
||||
//
|
||||
// }
|
||||
// )
|
||||
// }
|
||||
|
||||
items(
|
||||
items = nostrEvent.tags,
|
||||
) { tag ->
|
||||
SuggestionChip(
|
||||
label = {
|
||||
Text(
|
||||
text = tag.joinToString(":"),
|
||||
maxLines = 1
|
||||
)
|
||||
},
|
||||
onClick = {
|
||||
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Text(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
style = MaterialTheme.typography.labelLarge,
|
||||
textAlign = TextAlign.End,
|
||||
text = nostrEvent.createdAt.toFormattedTimeAndDateString()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
|
||||
@@ -0,0 +1,176 @@
|
||||
package ac.cord.auxiliary.compose.ui.composable.widgets.feed
|
||||
|
||||
import ac.cord.auxiliary.compose.database.model.NostrEvent
|
||||
import ac.cord.auxiliary.compose.database.model.Profile
|
||||
import ac.cord.auxiliary.compose.database.model.intermdiate.LocalInReplyToNostrEvent
|
||||
import ac.cord.auxiliary.compose.database.model.intermdiate.LocalMention
|
||||
import ac.cord.auxiliary.compose.database.model.intermdiate.LocalQuotedNostrEvent
|
||||
import ac.cord.auxiliary.compose.extensions.toFormattedTimeAndDateString
|
||||
import ac.cord.auxiliary.compose.ui.composable.widgets.content.RichContent
|
||||
import ac.cord.auxiliary.compose.ui.composable.widgets.profile.ProfileAvatar
|
||||
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.foundation.lazy.LazyRow
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.material3.AssistChip
|
||||
import androidx.compose.material3.ElevatedCard
|
||||
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.SuggestionChip
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
|
||||
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
|
||||
@Composable
|
||||
internal fun TextNoteFeedItem(
|
||||
nostrEvent: NostrEvent,
|
||||
profile: Profile?,
|
||||
localInReplyToNostrEvent: LocalInReplyToNostrEvent?,
|
||||
localQuotedNostrEvent: LocalQuotedNostrEvent?,
|
||||
mentionedProfiles: List<LocalMention?>,
|
||||
onNavigateToEvent: (HexKey) -> Unit
|
||||
) {
|
||||
if (localInReplyToNostrEvent != null) {
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth().padding(
|
||||
horizontal = 20.dp
|
||||
),
|
||||
horizontalArrangement = Arrangement.End,
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Text(
|
||||
"In reply to ",
|
||||
style = MaterialTheme.typography.labelSmall
|
||||
)
|
||||
|
||||
Text(
|
||||
modifier = Modifier.clickable(
|
||||
onClick = {
|
||||
onNavigateToEvent.invoke(localInReplyToNostrEvent.inReplyToRelation.inReplyToNostrEventId)
|
||||
}
|
||||
),
|
||||
style = MaterialTheme.typography.labelLargeEmphasized,
|
||||
text = localInReplyToNostrEvent.profile?.humanReadableNameOrPubkey() ?: "loading information..."
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
ElevatedCard(
|
||||
modifier = Modifier.padding(
|
||||
horizontal = 10.dp
|
||||
),
|
||||
onClick = {
|
||||
onNavigateToEvent.invoke(nostrEvent.id)
|
||||
}
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.padding(10.dp).fillMaxWidth(),
|
||||
verticalArrangement = Arrangement.spacedBy(10.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
if (profile != null) {
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth().clickable(
|
||||
onClick = {
|
||||
onNavigateToEvent.invoke(profile.nostrEventId)
|
||||
}
|
||||
),
|
||||
horizontalArrangement = Arrangement.spacedBy(10.dp, Alignment.Start),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
ProfileAvatar(
|
||||
publicKey = nostrEvent.pubKey,
|
||||
profile = profile
|
||||
)
|
||||
|
||||
Text(
|
||||
modifier = Modifier.weight(1f),
|
||||
text = profile.displayName ?: profile.userName ?: nostrEvent.pubKey,
|
||||
style = MaterialTheme.typography.bodyMedium
|
||||
)
|
||||
}
|
||||
} else {
|
||||
Text(
|
||||
text = "Loading author information"
|
||||
)
|
||||
}
|
||||
|
||||
RichContent(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
nostrEvent = nostrEvent,
|
||||
localQuotedNostrEvent = localQuotedNostrEvent,
|
||||
mentionedProfiles = mentionedProfiles
|
||||
)
|
||||
|
||||
LazyRow(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.spacedBy(
|
||||
10.dp,
|
||||
alignment = Alignment.Start
|
||||
)
|
||||
) {
|
||||
item {
|
||||
AssistChip(
|
||||
label = {
|
||||
Text(
|
||||
text = nostrEvent.kind.toString() // TODO: Kind by name...
|
||||
)
|
||||
},
|
||||
onClick = {
|
||||
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
// item {
|
||||
// SuggestionChip(
|
||||
// label = {
|
||||
// Text(
|
||||
// text = if (localNostrEvent.mentionedProfiles.isNotEmpty()) {
|
||||
// localNostrEvent.mentionedProfiles.joinToString(",") { it?.profile?.humanReadableNameOrPubkey() ?: "Find user information" }
|
||||
// } else {
|
||||
// ":-("
|
||||
// }
|
||||
// )
|
||||
// },
|
||||
// onClick = {
|
||||
//
|
||||
// }
|
||||
// )
|
||||
// }
|
||||
|
||||
items(
|
||||
items = nostrEvent.tags,
|
||||
) { tag ->
|
||||
SuggestionChip(
|
||||
label = {
|
||||
Text(
|
||||
text = tag.joinToString(":"),
|
||||
maxLines = 1
|
||||
)
|
||||
},
|
||||
onClick = {
|
||||
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Text(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
style = MaterialTheme.typography.labelLarge,
|
||||
textAlign = TextAlign.End,
|
||||
text = nostrEvent.createdAt.toFormattedTimeAndDateString()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user