Quote a nostrEvent

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

View File

@@ -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 {
fun fromEvent(event: Event, synchronizeNostrEventRequest: SynchronizeNostrEventRequest? = null): NostrEvent? = try {

View File

@@ -46,6 +46,7 @@ import com.vitorpamplona.quartz.nip10Notes.tags.prepareETagsAsReplyTo
import com.vitorpamplona.quartz.nip17Dm.settings.ChatMessageRelayListEvent
import com.vitorpamplona.quartz.nip18Reposts.RepostEvent
import com.vitorpamplona.quartz.nip18Reposts.quotes.quotes
import com.vitorpamplona.quartz.nip21UriScheme.toNostrUri
import com.vitorpamplona.quartz.nip25Reactions.ReactionEvent
import com.vitorpamplona.quartz.nip28PublicChat.list.ChannelListEvent
import com.vitorpamplona.quartz.nip31Alts.AltTag
@@ -232,25 +233,28 @@ class DatabaseNostrRepository(
override suspend fun createNewTextNote(
publicKey: HexKey,
text: String,
textInput: String,
inReplyToNostrEvent: LocalNostrEvent?,
quotedNostrEvent: LocalNostrEvent?,
onError: () -> 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(
note = text,
) {
inReplyToNostrEvent?.let {
val replyToTextNoteEvent = TextNoteEvent(
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 replyToTextNoteEvent = it.nostrEvent.toTextNoteEvent()
val replyingTo = EventHintBundle(
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))
references(findURLs(text))
quotes(findNostrUris(text))

View File

@@ -40,7 +40,8 @@ fun NostrEventDetailScreen(
onNavigateBack: () -> Unit,
onNavigateToEvent: (Route) -> Unit,
onNavigateToEditProfile: () -> Unit,
onNavigateToWriteAReply: (String) -> Unit
onNavigateToWriteAReply: (String) -> Unit,
onNavigateToQuoteNostrEvent: (String) -> Unit,
) {
val nostrEventDetailViewModel: NostrEventDetailViewModel = viewModel(
factory = NostrEventDetailViewModel.factory(
@@ -76,7 +77,8 @@ fun NostrEventDetailScreen(
TextNoteEventDetail(
feedListUIState.localNostrEvent,
onNavigateBack = onNavigateBack,
onNavigateToWriteAReply = onNavigateToWriteAReply
onNavigateToWriteAReply = onNavigateToWriteAReply,
onNavigateToQuoteNostrEvent = onNavigateToQuoteNostrEvent
)
}
RepostEvent.KIND -> {
@@ -163,7 +165,8 @@ It has survived not only five centuries, but also the leap into electronic types
onNavigateBack = {},
onNavigateToEvent = {},
onNavigateToWriteAReply = {},
onNavigateToEditProfile = {}
onNavigateToEditProfile = {},
onNavigateToQuoteNostrEvent = {}
)
}
}

View File

@@ -125,6 +125,7 @@ fun WriteNewNoteScreen(
color = MaterialTheme.colorScheme.onSurfaceVariant
)
}
TextField(
modifier = Modifier.fillMaxWidth(),
value = writeNewNoteViewModel.writeNewNoteFormState.textField.text.value,
@@ -147,7 +148,13 @@ fun WriteNewNoteScreen(
),
label = {
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,
)
},
@@ -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
)
if (writeNewNoteUIState.quotedNostrEvent?.nostrEvent?.kind == TextNoteEvent.KIND) {
Card {
writeNewNoteUIState.quotedNostrEvent.RenderNotePreview()
}
}
Text(
text = Clock.System.now().toFormattedTimeAndDateString(),
style = MaterialTheme.typography.labelSmall
@@ -335,9 +360,9 @@ private fun WriteNewNoteScreenPreview() {
replyToNostrEventId = null,
quotedNostrEventId = null,
initialWriteNewNoteUIState =
WriteNewNoteUIState.ConfirmNote(
text = "Yes, I did it. So WHAT?!",
inReplyToNostrEvent = LocalNostrEvent(
WriteNewNoteUIState.InputPrompt(
// text = "Yes, I did it. So WHAT?!",
quotedNostrEvent = LocalNostrEvent(
nostrEvent = NostrEvent(
id = "eventId",
pubKey = "publicKey",

View File

@@ -392,6 +392,13 @@ fun AuxNavHost(
navController.navigate(
route = ImplementationPendingRoute("Edit Profile")
)
},
onNavigateToQuoteNostrEvent = { nostrEventId ->
navController.navigate(
route = WriteNewNoteRoute(
quotedEventId = nostrEventId
)
)
}
)
}

View File

@@ -49,7 +49,8 @@ import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent
fun TextNoteEventDetail(
localNostrEvent: LocalNostrEvent,
onNavigateBack: () -> Unit,
onNavigateToWriteAReply: (String) -> Unit
onNavigateToWriteAReply: (String) -> Unit,
onNavigateToQuoteNostrEvent: (String) -> Unit,
) {
Scaffold(
modifier = Modifier.fillMaxSize(),
@@ -184,7 +185,9 @@ fun TextNoteEventDetail(
IconButton(
onClick = {
// TODO: Repost...
onNavigateToQuoteNostrEvent.invoke(
localNostrEvent.nostrEvent.id
)
}
) {
Icon(
@@ -253,7 +256,8 @@ It has survived not only five centuries, but also the leap into electronic types
)
),
onNavigateBack = {},
onNavigateToWriteAReply = {}
onNavigateToWriteAReply = {},
onNavigateToQuoteNostrEvent = {}
)
}
}

View File

@@ -71,6 +71,12 @@ class WriteNewNoteViewModel(
).firstOrNull()
}
val nostrEventBeingQuoted = quotedNostrEventId?.let {
nostrRepository.observeLocalNostrEventById(
it
).firstOrNull()
}
val activePublicKey = SeedManager.activePublicKey().toHexKey()
// TODO: Get note being replied too...
@@ -82,7 +88,8 @@ class WriteNewNoteViewModel(
writeNewNoteUIState = if (profileWithFollowing != null) {
WriteNewNoteUIState.InputPrompt(
localProfile = profileWithFollowing,
inReplyToNostrEvent = nostrEventBeingRepliedTo
inReplyToNostrEvent = nostrEventBeingRepliedTo,
quotedNostrEvent = nostrEventBeingQuoted
)
} else {
WriteNewNoteUIState.Error