mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2025-10-09 21:12:31 +02:00
add option to send notes to selected relays
This commit is contained in:
@@ -671,7 +671,8 @@ class Account(
|
|||||||
zapRaiserAmount: Long? = null,
|
zapRaiserAmount: Long? = null,
|
||||||
replyingTo: String?,
|
replyingTo: String?,
|
||||||
root: String?,
|
root: String?,
|
||||||
directMentions: Set<HexKey>
|
directMentions: Set<HexKey>,
|
||||||
|
relayList: List<Relay>? = null
|
||||||
) {
|
) {
|
||||||
if (!isWriteable()) return
|
if (!isWriteable()) return
|
||||||
|
|
||||||
@@ -694,7 +695,7 @@ class Account(
|
|||||||
privateKey = loggedIn.privKey!!
|
privateKey = loggedIn.privKey!!
|
||||||
)
|
)
|
||||||
|
|
||||||
Client.send(signedEvent)
|
Client.send(signedEvent, relayList = relayList)
|
||||||
LocalCache.consume(signedEvent)
|
LocalCache.consume(signedEvent)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -709,7 +710,8 @@ class Account(
|
|||||||
closedAt: Int?,
|
closedAt: Int?,
|
||||||
zapReceiver: String? = null,
|
zapReceiver: String? = null,
|
||||||
wantsToMarkAsSensitive: Boolean,
|
wantsToMarkAsSensitive: Boolean,
|
||||||
zapRaiserAmount: Long? = null
|
zapRaiserAmount: Long? = null,
|
||||||
|
relayList: List<Relay>? = null
|
||||||
) {
|
) {
|
||||||
if (!isWriteable()) return
|
if (!isWriteable()) return
|
||||||
|
|
||||||
@@ -733,7 +735,7 @@ class Account(
|
|||||||
zapRaiserAmount = zapRaiserAmount
|
zapRaiserAmount = zapRaiserAmount
|
||||||
)
|
)
|
||||||
// println("Sending new PollNoteEvent: %s".format(signedEvent.toJson()))
|
// println("Sending new PollNoteEvent: %s".format(signedEvent.toJson()))
|
||||||
Client.send(signedEvent)
|
Client.send(signedEvent, relayList = relayList)
|
||||||
LocalCache.consume(signedEvent)
|
LocalCache.consume(signedEvent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
package com.vitorpamplona.amethyst.service.relays
|
package com.vitorpamplona.amethyst.service.relays
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
import com.vitorpamplona.amethyst.service.HttpClient
|
import com.vitorpamplona.amethyst.service.HttpClient
|
||||||
import com.vitorpamplona.amethyst.service.checkNotInMainThread
|
import com.vitorpamplona.amethyst.service.checkNotInMainThread
|
||||||
import com.vitorpamplona.amethyst.service.model.Event
|
import com.vitorpamplona.amethyst.service.model.Event
|
||||||
@@ -73,10 +74,18 @@ object Client : RelayPool.Listener {
|
|||||||
RelayPool.sendFilterOnlyIfDisconnected()
|
RelayPool.sendFilterOnlyIfDisconnected()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun send(signedEvent: EventInterface, relay: String? = null, feedTypes: Set<FeedType>? = null, onDone: (() -> Unit)? = null) {
|
fun send(
|
||||||
|
signedEvent: EventInterface,
|
||||||
|
relay: String? = null,
|
||||||
|
feedTypes: Set<FeedType>? = null,
|
||||||
|
relayList: List<Relay>? = null,
|
||||||
|
onDone: (() -> Unit)? = null
|
||||||
|
) {
|
||||||
checkNotInMainThread()
|
checkNotInMainThread()
|
||||||
|
|
||||||
if (relay == null) {
|
if (relayList != null) {
|
||||||
|
RelayPool.sendToSelectedRelays(relayList, signedEvent)
|
||||||
|
} else if (relay == null) {
|
||||||
RelayPool.send(signedEvent)
|
RelayPool.send(signedEvent)
|
||||||
} else {
|
} else {
|
||||||
val useConnectedRelayIfPresent = RelayPool.getRelays(relay)
|
val useConnectedRelayIfPresent = RelayPool.getRelays(relay)
|
||||||
|
@@ -62,6 +62,12 @@ object RelayPool : Relay.Listener {
|
|||||||
relays.forEach { it.sendFilterOnlyIfDisconnected() }
|
relays.forEach { it.sendFilterOnlyIfDisconnected() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun sendToSelectedRelays(list: List<Relay>, signedEvent: EventInterface) {
|
||||||
|
list.forEach { relay ->
|
||||||
|
relays.filter { it.url == relay.url }.forEach { it.send(signedEvent) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun send(signedEvent: EventInterface) {
|
fun send(signedEvent: EventInterface) {
|
||||||
relays.forEach { it.send(signedEvent) }
|
relays.forEach { it.send(signedEvent) }
|
||||||
}
|
}
|
||||||
|
@@ -9,6 +9,7 @@ import android.widget.Toast
|
|||||||
import androidx.compose.foundation.BorderStroke
|
import androidx.compose.foundation.BorderStroke
|
||||||
import androidx.compose.foundation.Image
|
import androidx.compose.foundation.Image
|
||||||
import androidx.compose.foundation.border
|
import androidx.compose.foundation.border
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.itemsIndexed
|
import androidx.compose.foundation.lazy.itemsIndexed
|
||||||
@@ -72,6 +73,7 @@ import com.vitorpamplona.amethyst.model.Note
|
|||||||
import com.vitorpamplona.amethyst.model.User
|
import com.vitorpamplona.amethyst.model.User
|
||||||
import com.vitorpamplona.amethyst.service.NostrSearchEventOrUserDataSource
|
import com.vitorpamplona.amethyst.service.NostrSearchEventOrUserDataSource
|
||||||
import com.vitorpamplona.amethyst.service.noProtocolUrlValidator
|
import com.vitorpamplona.amethyst.service.noProtocolUrlValidator
|
||||||
|
import com.vitorpamplona.amethyst.service.relays.Relay
|
||||||
import com.vitorpamplona.amethyst.ui.components.*
|
import com.vitorpamplona.amethyst.ui.components.*
|
||||||
import com.vitorpamplona.amethyst.ui.note.NoteCompose
|
import com.vitorpamplona.amethyst.ui.note.NoteCompose
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
@@ -92,6 +94,11 @@ import kotlinx.coroutines.delay
|
|||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
|
data class RelayList(
|
||||||
|
val relay: Relay,
|
||||||
|
val isSelected: Boolean
|
||||||
|
)
|
||||||
|
|
||||||
@OptIn(ExperimentalComposeUiApi::class)
|
@OptIn(ExperimentalComposeUiApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun NewPostView(onClose: () -> Unit, baseReplyTo: Note? = null, quote: Note? = null, accountViewModel: AccountViewModel, nav: (String) -> Unit) {
|
fun NewPostView(onClose: () -> Unit, baseReplyTo: Note? = null, quote: Note? = null, accountViewModel: AccountViewModel, nav: (String) -> Unit) {
|
||||||
@@ -107,6 +114,27 @@ fun NewPostView(onClose: () -> Unit, baseReplyTo: Note? = null, quote: Note? = n
|
|||||||
|
|
||||||
val scrollState = rememberScrollState()
|
val scrollState = rememberScrollState()
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
|
var showRelaysDialog by remember {
|
||||||
|
mutableStateOf(false)
|
||||||
|
}
|
||||||
|
val relayList = account.activeRelays()?.filter {
|
||||||
|
it.write
|
||||||
|
}?.map {
|
||||||
|
it
|
||||||
|
} ?: account.convertLocalRelays().filter {
|
||||||
|
it.write
|
||||||
|
}
|
||||||
|
|
||||||
|
var relays by remember {
|
||||||
|
mutableStateOf(
|
||||||
|
relayList.map {
|
||||||
|
RelayList(
|
||||||
|
it,
|
||||||
|
true
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
LaunchedEffect(Unit) {
|
LaunchedEffect(Unit) {
|
||||||
postViewModel.load(account, baseReplyTo, quote)
|
postViewModel.load(account, baseReplyTo, quote)
|
||||||
@@ -141,6 +169,90 @@ fun NewPostView(onClose: () -> Unit, baseReplyTo: Note? = null, quote: Note? = n
|
|||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.fillMaxHeight()
|
.fillMaxHeight()
|
||||||
) {
|
) {
|
||||||
|
if (showRelaysDialog) {
|
||||||
|
Dialog(
|
||||||
|
onDismissRequest = { showRelaysDialog = false },
|
||||||
|
properties = DialogProperties(
|
||||||
|
usePlatformDefaultWidth = false,
|
||||||
|
dismissOnClickOutside = false,
|
||||||
|
decorFitsSystemWindows = false
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Surface(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.fillMaxHeight()
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.fillMaxHeight()
|
||||||
|
.padding(start = 10.dp, end = 10.dp, top = 10.dp)
|
||||||
|
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
CloseButton(
|
||||||
|
onCancel = {
|
||||||
|
showRelaysDialog = false
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
PostButton(
|
||||||
|
onPost = {
|
||||||
|
scope.launch(Dispatchers.IO) {
|
||||||
|
showRelaysDialog = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
isActive = true
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
LazyColumn(
|
||||||
|
contentPadding = PaddingValues(
|
||||||
|
top = 10.dp,
|
||||||
|
bottom = 10.dp
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
itemsIndexed(
|
||||||
|
relays,
|
||||||
|
key = { _, item -> item.relay.url }
|
||||||
|
) { index, item ->
|
||||||
|
Row(
|
||||||
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.clickable {
|
||||||
|
relays = relays.mapIndexed { j, item ->
|
||||||
|
if (index == j) {
|
||||||
|
item.copy(isSelected = !item.isSelected)
|
||||||
|
} else { item }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
Text(text = item.relay.url)
|
||||||
|
Switch(
|
||||||
|
checked = item.isSelected,
|
||||||
|
onCheckedChange = {
|
||||||
|
relays = relays.mapIndexed { j, item ->
|
||||||
|
if (index == j) {
|
||||||
|
item.copy(isSelected = !item.isSelected)
|
||||||
|
} else { item }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
@@ -162,10 +274,27 @@ fun NewPostView(onClose: () -> Unit, baseReplyTo: Note? = null, quote: Note? = n
|
|||||||
onClose()
|
onClose()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Box {
|
||||||
|
IconButton(
|
||||||
|
modifier = Modifier.align(Alignment.Center),
|
||||||
|
onClick = {
|
||||||
|
showRelaysDialog = true
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
painter = painterResource(R.drawable.relays),
|
||||||
|
contentDescription = null,
|
||||||
|
modifier = Modifier.height(25.dp),
|
||||||
|
tint = MaterialTheme.colors.onBackground
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
PostButton(
|
PostButton(
|
||||||
onPost = {
|
onPost = {
|
||||||
|
val list = relays.filter { it.isSelected }.map { it.relay }
|
||||||
|
|
||||||
scope.launch(Dispatchers.IO) {
|
scope.launch(Dispatchers.IO) {
|
||||||
postViewModel.sendPost()
|
postViewModel.sendPost(relayList = list)
|
||||||
onClose()
|
onClose()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@@ -22,6 +22,7 @@ import com.vitorpamplona.amethyst.service.model.CommunityDefinitionEvent
|
|||||||
import com.vitorpamplona.amethyst.service.model.PrivateDmEvent
|
import com.vitorpamplona.amethyst.service.model.PrivateDmEvent
|
||||||
import com.vitorpamplona.amethyst.service.model.TextNoteEvent
|
import com.vitorpamplona.amethyst.service.model.TextNoteEvent
|
||||||
import com.vitorpamplona.amethyst.service.noProtocolUrlValidator
|
import com.vitorpamplona.amethyst.service.noProtocolUrlValidator
|
||||||
|
import com.vitorpamplona.amethyst.service.relays.Relay
|
||||||
import com.vitorpamplona.amethyst.ui.components.MediaCompressor
|
import com.vitorpamplona.amethyst.ui.components.MediaCompressor
|
||||||
import com.vitorpamplona.amethyst.ui.components.isValidURL
|
import com.vitorpamplona.amethyst.ui.components.isValidURL
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@@ -128,7 +129,7 @@ open class NewPostViewModel() : ViewModel() {
|
|||||||
this.account = account
|
this.account = account
|
||||||
}
|
}
|
||||||
|
|
||||||
fun sendPost() {
|
fun sendPost(relayList: List<Relay>? = null) {
|
||||||
val tagger = NewMessageTagger(originalNote?.channelHex(), mentions, replyTos, message.text)
|
val tagger = NewMessageTagger(originalNote?.channelHex(), mentions, replyTos, message.text)
|
||||||
tagger.run()
|
tagger.run()
|
||||||
|
|
||||||
@@ -145,7 +146,20 @@ open class NewPostViewModel() : ViewModel() {
|
|||||||
val localZapRaiserAmount = if (wantsZapraiser) zapRaiserAmount else null
|
val localZapRaiserAmount = if (wantsZapraiser) zapRaiserAmount else null
|
||||||
|
|
||||||
if (wantsPoll) {
|
if (wantsPoll) {
|
||||||
account?.sendPoll(tagger.message, tagger.replyTos, tagger.mentions, pollOptions, valueMaximum, valueMinimum, consensusThreshold, closedAt, zapReceiver, wantsToMarkAsSensitive, localZapRaiserAmount)
|
account?.sendPoll(
|
||||||
|
tagger.message,
|
||||||
|
tagger.replyTos,
|
||||||
|
tagger.mentions,
|
||||||
|
pollOptions,
|
||||||
|
valueMaximum,
|
||||||
|
valueMinimum,
|
||||||
|
consensusThreshold,
|
||||||
|
closedAt,
|
||||||
|
zapReceiver,
|
||||||
|
wantsToMarkAsSensitive,
|
||||||
|
localZapRaiserAmount,
|
||||||
|
relayList
|
||||||
|
)
|
||||||
} else if (originalNote?.channelHex() != null) {
|
} else if (originalNote?.channelHex() != null) {
|
||||||
if (originalNote is AddressableEvent && originalNote?.address() != null) {
|
if (originalNote is AddressableEvent && originalNote?.address() != null) {
|
||||||
account?.sendLiveMessage(tagger.message, originalNote?.address()!!, tagger.replyTos, tagger.mentions, zapReceiver, wantsToMarkAsSensitive, localZapRaiserAmount)
|
account?.sendLiveMessage(tagger.message, originalNote?.address()!!, tagger.replyTos, tagger.mentions, zapReceiver, wantsToMarkAsSensitive, localZapRaiserAmount)
|
||||||
@@ -172,7 +186,8 @@ open class NewPostViewModel() : ViewModel() {
|
|||||||
zapRaiserAmount = localZapRaiserAmount,
|
zapRaiserAmount = localZapRaiserAmount,
|
||||||
replyingTo = replyId,
|
replyingTo = replyId,
|
||||||
root = rootId,
|
root = rootId,
|
||||||
directMentions = tagger.directMentions
|
directMentions = tagger.directMentions,
|
||||||
|
relayList = relayList
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user