From d130a43358d347c6cca0e4f4b774c374caf397b8 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Fri, 13 Jan 2023 21:35:28 -0500 Subject: [PATCH] Sending confirmation events back to the Repository. --- .../vitorpamplona/amethyst/model/Account.kt | 6 +++++ .../amethyst/service/NostrDataSource.kt | 4 ++++ .../amethyst/service/relays/Client.kt | 9 +++++++ .../amethyst/service/relays/Relay.kt | 5 ++-- .../amethyst/service/relays/RelayPool.kt | 15 +++++++++--- .../amethyst/ui/components/RichTextViewer.kt | 24 +++++++++++++------ .../vitorpamplona/amethyst/ui/note/Note.kt | 2 +- .../amethyst/ui/screen/ThreadFeedView.kt | 2 +- .../ui/screen/loggedIn/AccountViewModel.kt | 4 +--- 9 files changed, 54 insertions(+), 17 deletions(-) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt b/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt index d1dd273e8..abcfae6b8 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt @@ -44,6 +44,12 @@ class Account(val loggedIn: Persona) { } } + fun broadcast(note: Note) { + note.event?.let { + Client.send(it) + } + } + fun sendPost(message: String, replyingTo: Note?) { if (!isWriteable()) return diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrDataSource.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrDataSource.kt index 090e29dca..1805fd09f 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrDataSource.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrDataSource.kt @@ -57,6 +57,10 @@ abstract class NostrDataSource(val debugName: String) { resetFilters() }*/ } + + override fun onSendResponse(eventId: String, success: Boolean, message: String, relay: Relay) { + + } } init { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/relays/Client.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/relays/Client.kt index 5396db171..acfda2ef1 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/relays/Client.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/relays/Client.kt @@ -85,6 +85,10 @@ object Client: RelayPool.Listener { listeners.forEach { it.onRelayStateChange(type, relay) } } + override fun onSendResponse(eventId: String, success: Boolean, message: String, relay: Relay) { + listeners.forEach { it.onSendResponse(eventId, success, message, relay) } + } + fun subscribe(listener: Listener) { listeners.add(listener) } @@ -109,5 +113,10 @@ object Client: RelayPool.Listener { * Connected to or disconnected from a relay */ open fun onRelayStateChange(type: Relay.Type, relay: Relay) = Unit + + /** + * When an relay saves or rejects a new event. + */ + open fun onSendResponse(eventId: String, success: Boolean, message: String, relay: Relay) = Unit } } \ No newline at end of file diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/relays/Relay.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/relays/Relay.kt index b5770cbe7..16668028d 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/relays/Relay.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/relays/Relay.kt @@ -59,10 +59,10 @@ class Relay( it.onError(this@Relay, channel, Error("Relay sent notice: $channel")) } "OK" -> listeners.forEach { - // "channel" being the second string in the string array ... - // Event was saved correctly? + it.onSendResponse(this@Relay, msg[1].asString, msg[2].asBoolean, msg[3].asString) } else -> listeners.forEach { + println("else: " + text) it.onError( this@Relay, channel, @@ -155,6 +155,7 @@ class Relay( fun onError(relay: Relay, subscriptionId: String, error: Error) + fun onSendResponse(relay: Relay, eventId: String, success: Boolean, message: String) /** * Connected to or disconnected from a relay * diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/relays/RelayPool.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/relays/RelayPool.kt index 7172ab76b..6b1e89a57 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/relays/RelayPool.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/relays/RelayPool.kt @@ -12,9 +12,12 @@ object RelayPool: Relay.Listener { private val relays = Collections.synchronizedList(ArrayList()) private val listeners = Collections.synchronizedSet(HashSet()) - fun report(): String { - val connected = relays.filter { it.isConnected() } - return "${connected.size}/${relays.size}" + fun availableRelays(): Int { + return relays.size + } + + fun connectedRelays(): Int { + return relays.filter { it.isConnected() }.size } fun loadRelays(relayList: List? = null){ @@ -79,6 +82,8 @@ object RelayPool: Relay.Listener { fun onError(error: Error, subscriptionId: String, relay: Relay) fun onRelayStateChange(type: Relay.Type, relay: Relay) + + fun onSendResponse(eventId: String, success: Boolean, message: String, relay: Relay) } @Synchronized @@ -96,6 +101,10 @@ object RelayPool: Relay.Listener { refreshObservers() } + override fun onSendResponse(relay: Relay, eventId: String, success: Boolean, message: String) { + listeners.forEach { it.onSendResponse(eventId, success, message, relay) } + } + // Observers line up here. val live: RelayPoolLiveData = RelayPoolLiveData(this) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/components/RichTextViewer.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/components/RichTextViewer.kt index d775b4fd6..8a147c755 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/components/RichTextViewer.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/components/RichTextViewer.kt @@ -1,18 +1,26 @@ package com.vitorpamplona.amethyst.ui.components import android.util.Patterns +import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.text.ClickableText +import androidx.compose.material.LocalTextStyle +import androidx.compose.material.MaterialTheme import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.livedata.observeAsState import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.Modifier +import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.unit.dp +import androidx.navigation.NavController import com.google.accompanist.flowlayout.FlowRow import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note +import com.vitorpamplona.amethyst.model.toNote +import com.vitorpamplona.amethyst.ui.note.toDisplayHex import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import java.net.MalformedURLException import java.net.URISyntaxException @@ -22,7 +30,7 @@ import java.util.regex.Pattern val imageExtension = Pattern.compile("(.*/)*.+\\.(png|jpg|gif|bmp|jpeg|webp)$") val videoExtension = Pattern.compile("(.*/)*.+\\.(mp4|avi|wmv|mpg|amv|webm)$") val noProtocolUrlValidator = Pattern.compile("^[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}\\b(?:[-a-zA-Z0-9()@:%_\\+.~#?&//=]*)$") -val tagIndex = Pattern.compile("\\#\\[([0-9]*)\\]") +val tagIndex = Pattern.compile(".*\\#\\[([0-9]+)\\].*") val mentionsPattern: Pattern = Pattern.compile("@([A-Za-z0-9_-]+)") val hashTagsPattern: Pattern = Pattern.compile("#([A-Za-z0-9_-]+)") @@ -41,7 +49,7 @@ fun isValidURL(url: String?): Boolean { @OptIn(ExperimentalComposeUiApi::class) @Composable -fun RichTextViewer(content: String, tags: List>?, note: Note, accountViewModel: AccountViewModel) { +fun RichTextViewer(content: String, tags: List>?, note: Note, accountViewModel: AccountViewModel, navController: NavController) { Column(modifier = Modifier.padding(top = 5.dp)) { // FlowRow doesn't work well with paragraphs. So we need to split them content.split('\n').forEach { paragraph -> @@ -64,7 +72,7 @@ fun RichTextViewer(content: String, tags: List>?, note: Note, accou } else if (noProtocolUrlValidator.matcher(word).matches()) { UrlPreview("https://$word", word) } else if (tagIndex.matcher(word).matches() && tags != null) { - TagLink(word, tags) + TagLink(word, tags, navController) } else { Text(text = "$word ") } @@ -76,7 +84,7 @@ fun RichTextViewer(content: String, tags: List>?, note: Note, accou } @Composable -fun TagLink(word: String, tags: List>) { +fun TagLink(word: String, tags: List>, navController: NavController) { val matcher = tagIndex.matcher(word) val index = try { @@ -97,15 +105,17 @@ fun TagLink(word: String, tags: List>) { if (user != null) { val innerUserState by user.live.observeAsState() Text( - "${innerUserState?.user?.toBestDisplayName()}" + "@${innerUserState?.user?.toBestDisplayName()} " ) } } else if (tags[index][0] == "e") { val note = LocalCache.notes[tags[index][1]] if (note != null) { val innerNoteState by note.live.observeAsState() - Text( - "${innerNoteState?.note?.idDisplayHex}" + ClickableText( + text = AnnotatedString("@${innerNoteState?.note?.id?.toNote()?.toDisplayHex()} "), + onClick = { navController.navigate("Note/${note.idHex}") }, + style = LocalTextStyle.current.copy(color = MaterialTheme.colors.primary) ) } } else diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/Note.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/Note.kt index e6c241e8e..e3febe5dc 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/Note.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/Note.kt @@ -145,7 +145,7 @@ fun NoteCompose(baseNote: Note, modifier: Modifier = Modifier, isInnerNote: Bool } else { val eventContent = note.event?.content if (eventContent != null) - RichTextViewer(eventContent, note.event?.tags, note, accountViewModel) + RichTextViewer(eventContent, note.event?.tags, note, accountViewModel, navController) ReactionsRowState(note, accountViewModel) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/ThreadFeedView.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/ThreadFeedView.kt index f5c103149..a0db16733 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/ThreadFeedView.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/ThreadFeedView.kt @@ -213,7 +213,7 @@ fun NoteMaster(baseNote: Note, accountViewModel: AccountViewModel, navController Column() { val eventContent = note.event?.content if (eventContent != null) - RichTextViewer(eventContent, note.event?.tags, note, accountViewModel) + RichTextViewer(eventContent, note.event?.tags, note, accountViewModel, navController) ReactionsRowState(note, accountViewModel) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt index 9cac8e538..af7dc28ab 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt @@ -22,8 +22,6 @@ class AccountViewModel(private val account: Account): ViewModel() { } fun broadcast(note: Note) { - note.event?.let { - Client.send(it) - } + account.broadcast(note) } } \ No newline at end of file