Quote a nostrEvent

This commit is contained in:
Kgothatso Ngako committed 2026-04-27 02:37:06 +02:00
1 parent ec5aebe627
commit 7bb46d2b74
7 files changed
+97 -21

No files matched your search

@@ -277,6 +277,16 @@ data class NostrEvent(
} }
} }
fun toTextNoteEvent(): TextNoteEvent {
return TextNoteEvent(
id = id,
content = content,
sig = sig,
tags = tags,
createdAt = createdAt.epochSeconds,
pubKey = pubKey
)
}
companion object { companion object {
fun fromEvent(event: Event, synchronizeNostrEventRequest: SynchronizeNostrEventRequest? = null): NostrEvent? = try { fun fromEvent(event: Event, synchronizeNostrEventRequest: SynchronizeNostrEventRequest? = null): NostrEvent? = try {
@@ -46,6 +46,7 @@ import com.vitorpamplona.quartz.nip10Notes.tags.prepareETagsAsReplyTo
import com.vitorpamplona.quartz.nip17Dm.settings.ChatMessageRelayListEvent import com.vitorpamplona.quartz.nip17Dm.settings.ChatMessageRelayListEvent
import com.vitorpamplona.quartz.nip18Reposts.RepostEvent import com.vitorpamplona.quartz.nip18Reposts.RepostEvent
import com.vitorpamplona.quartz.nip18Reposts.quotes.quotes import com.vitorpamplona.quartz.nip18Reposts.quotes.quotes
import com.vitorpamplona.quartz.nip21UriScheme.toNostrUri
import com.vitorpamplona.quartz.nip25Reactions.ReactionEvent import com.vitorpamplona.quartz.nip25Reactions.ReactionEvent
import com.vitorpamplona.quartz.nip28PublicChat.list.ChannelListEvent import com.vitorpamplona.quartz.nip28PublicChat.list.ChannelListEvent
import com.vitorpamplona.quartz.nip31Alts.AltTag import com.vitorpamplona.quartz.nip31Alts.AltTag
@@ -232,25 +233,28 @@ class DatabaseNostrRepository(
override suspend fun createNewTextNote( override suspend fun createNewTextNote(
publicKey: HexKey, publicKey: HexKey,
text: String, textInput: String,
inReplyToNostrEvent: LocalNostrEvent?, inReplyToNostrEvent: LocalNostrEvent?,
quotedNostrEvent: LocalNostrEvent?, quotedNostrEvent: LocalNostrEvent?,
onError: () -> Unit, onError: () -> Unit,
onSuccess: () -> Unit onSuccess: () -> Unit
) { ) {
// TODO: Handle event and profile tags... val quotedNostrURI = quotedNostrEvent?.let {
// TODO: Convert qoutedNostrEvent to nostrURI
val quotedTextNoteEvent = it.nostrEvent.toTextNoteEvent()
val relayHint = null // TODO: get relyhint from where ever the nostrEvent was synced from...
"\n\n${quotedTextNoteEvent.toNostrUri(relayHint)}"
} ?: ""
val text: String = textInput + quotedNostrURI
// TODO: Handle mentioned profile tags...
val textNote = TextNoteEvent.build( val textNote = TextNoteEvent.build(
note = text, note = text,
) { ) {
inReplyToNostrEvent?.let { inReplyToNostrEvent?.let {
val replyToTextNoteEvent = TextNoteEvent( val replyToTextNoteEvent = it.nostrEvent.toTextNoteEvent()
id = it.nostrEvent.id,
content = it.nostrEvent.content,
sig = it.nostrEvent.sig,
tags = it.nostrEvent.tags,
createdAt = it.nostrEvent.createdAt.epochSeconds,
pubKey = it.nostrEvent.pubKey
)
val replyingTo = EventHintBundle( val replyingTo = EventHintBundle(
replyToTextNoteEvent replyToTextNoteEvent
@@ -277,6 +281,22 @@ class DatabaseNostrRepository(
} }
} }
quotedNostrEvent?.let {
it.profile?.let { profile ->
val ptags = arrayOf(
profile,
// Other profiles tagged in the event...
).map { notifyProfile ->
PTag(
notifyProfile.publicKey,
// TODO: Add relayHints...
)
}
notify(ptags)
}
}
hashtags(findHashtags(text)) hashtags(findHashtags(text))
references(findURLs(text)) references(findURLs(text))
quotes(findNostrUris(text)) quotes(findNostrUris(text))
@@ -40,7 +40,8 @@ fun NostrEventDetailScreen(
onNavigateBack: () -> Unit, onNavigateBack: () -> Unit,
onNavigateToEvent: (Route) -> Unit, onNavigateToEvent: (Route) -> Unit,
onNavigateToEditProfile: () -> Unit, onNavigateToEditProfile: () -> Unit,
onNavigateToWriteAReply: (String) -> Unit onNavigateToWriteAReply: (String) -> Unit,
onNavigateToQuoteNostrEvent: (String) -> Unit,
) { ) {
val nostrEventDetailViewModel: NostrEventDetailViewModel = viewModel( val nostrEventDetailViewModel: NostrEventDetailViewModel = viewModel(
factory = NostrEventDetailViewModel.factory( factory = NostrEventDetailViewModel.factory(
@@ -76,7 +77,8 @@ fun NostrEventDetailScreen(
TextNoteEventDetail( TextNoteEventDetail(
feedListUIState.localNostrEvent, feedListUIState.localNostrEvent,
onNavigateBack = onNavigateBack, onNavigateBack = onNavigateBack,
onNavigateToWriteAReply = onNavigateToWriteAReply onNavigateToWriteAReply = onNavigateToWriteAReply,
onNavigateToQuoteNostrEvent = onNavigateToQuoteNostrEvent
) )
} }
RepostEvent.KIND -> { RepostEvent.KIND -> {
@@ -163,7 +165,8 @@ It has survived not only five centuries, but also the leap into electronic types
onNavigateBack = {}, onNavigateBack = {},
onNavigateToEvent = {}, onNavigateToEvent = {},
onNavigateToWriteAReply = {}, onNavigateToWriteAReply = {},
onNavigateToEditProfile = {} onNavigateToEditProfile = {},
onNavigateToQuoteNostrEvent = {}
) )
} }
} }
@@ -125,6 +125,7 @@ fun WriteNewNoteScreen(
color = MaterialTheme.colorScheme.onSurfaceVariant color = MaterialTheme.colorScheme.onSurfaceVariant
) )
} }
TextField( TextField(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
value = writeNewNoteViewModel.writeNewNoteFormState.textField.text.value, value = writeNewNoteViewModel.writeNewNoteFormState.textField.text.value,
@@ -147,7 +148,13 @@ fun WriteNewNoteScreen(
), ),
label = { label = {
Text( Text(
text = "What vibrations do you want to send out?", text = if (writeNewNoteUIState.inReplyToNostrEvent != null) {
"What's your reply to the above"
} else if (writeNewNoteUIState.quotedNostrEvent != null) {
"What's your comment on the below"
} else {
"What vibrations do you want to send out?"
},
maxLines = 1, maxLines = 1,
) )
}, },
@@ -164,6 +171,17 @@ fun WriteNewNoteScreen(
) )
} }
) )
if (writeNewNoteUIState.quotedNostrEvent?.nostrEvent?.kind == TextNoteEvent.KIND) {
Card(
modifier = Modifier.padding(
start = 50.dp,
top = 10.dp
)
) {
writeNewNoteUIState.quotedNostrEvent.RenderNotePreview()
}
}
} }
@@ -260,6 +278,13 @@ fun WriteNewNoteScreen(
textAlign = TextAlign.Center textAlign = TextAlign.Center
) )
if (writeNewNoteUIState.quotedNostrEvent?.nostrEvent?.kind == TextNoteEvent.KIND) {
Card {
writeNewNoteUIState.quotedNostrEvent.RenderNotePreview()
}
}
Text( Text(
text = Clock.System.now().toFormattedTimeAndDateString(), text = Clock.System.now().toFormattedTimeAndDateString(),
style = MaterialTheme.typography.labelSmall style = MaterialTheme.typography.labelSmall
@@ -335,9 +360,9 @@ private fun WriteNewNoteScreenPreview() {
replyToNostrEventId = null, replyToNostrEventId = null,
quotedNostrEventId = null, quotedNostrEventId = null,
initialWriteNewNoteUIState = initialWriteNewNoteUIState =
WriteNewNoteUIState.ConfirmNote( WriteNewNoteUIState.InputPrompt(
text = "Yes, I did it. So WHAT?!", // text = "Yes, I did it. So WHAT?!",
inReplyToNostrEvent = LocalNostrEvent( quotedNostrEvent = LocalNostrEvent(
nostrEvent = NostrEvent( nostrEvent = NostrEvent(
id = "eventId", id = "eventId",
pubKey = "publicKey", pubKey = "publicKey",
@@ -392,6 +392,13 @@ fun AuxNavHost(
navController.navigate( navController.navigate(
route = ImplementationPendingRoute("Edit Profile") route = ImplementationPendingRoute("Edit Profile")
) )
},
onNavigateToQuoteNostrEvent = { nostrEventId ->
navController.navigate(
route = WriteNewNoteRoute(
quotedEventId = nostrEventId
)
)
} }
) )
} }
@@ -49,7 +49,8 @@ import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent
fun TextNoteEventDetail( fun TextNoteEventDetail(
localNostrEvent: LocalNostrEvent, localNostrEvent: LocalNostrEvent,
onNavigateBack: () -> Unit, onNavigateBack: () -> Unit,
onNavigateToWriteAReply: (String) -> Unit onNavigateToWriteAReply: (String) -> Unit,
onNavigateToQuoteNostrEvent: (String) -> Unit,
) { ) {
Scaffold( Scaffold(
modifier = Modifier.fillMaxSize(), modifier = Modifier.fillMaxSize(),
@@ -184,7 +185,9 @@ fun TextNoteEventDetail(
IconButton( IconButton(
onClick = { onClick = {
// TODO: Repost... onNavigateToQuoteNostrEvent.invoke(
localNostrEvent.nostrEvent.id
)
} }
) { ) {
Icon( Icon(
@@ -253,7 +256,8 @@ It has survived not only five centuries, but also the leap into electronic types
) )
), ),
onNavigateBack = {}, onNavigateBack = {},
onNavigateToWriteAReply = {} onNavigateToWriteAReply = {},
onNavigateToQuoteNostrEvent = {}
) )
} }
} }
@@ -71,6 +71,12 @@ class WriteNewNoteViewModel(
).firstOrNull() ).firstOrNull()
} }
val nostrEventBeingQuoted = quotedNostrEventId?.let {
nostrRepository.observeLocalNostrEventById(
it
).firstOrNull()
}
val activePublicKey = SeedManager.activePublicKey().toHexKey() val activePublicKey = SeedManager.activePublicKey().toHexKey()
// TODO: Get note being replied too... // TODO: Get note being replied too...
@@ -82,7 +88,8 @@ class WriteNewNoteViewModel(
writeNewNoteUIState = if (profileWithFollowing != null) { writeNewNoteUIState = if (profileWithFollowing != null) {
WriteNewNoteUIState.InputPrompt( WriteNewNoteUIState.InputPrompt(
localProfile = profileWithFollowing, localProfile = profileWithFollowing,
inReplyToNostrEvent = nostrEventBeingRepliedTo inReplyToNostrEvent = nostrEventBeingRepliedTo,
quotedNostrEvent = nostrEventBeingQuoted
) )
} else { } else {
WriteNewNoteUIState.Error WriteNewNoteUIState.Error