added SignerDialog in the like reaction
This commit is contained in:
@@ -212,12 +212,12 @@ class Account(
|
||||
return note.hasReacted(userProfile(), reaction)
|
||||
}
|
||||
|
||||
fun reactTo(note: Note, reaction: String) {
|
||||
if (!isWriteable()) return
|
||||
fun reactTo(note: Note, reaction: String, signEvent: Boolean = true): ReactionEvent? {
|
||||
if (!isWriteable() && signEvent) return null
|
||||
|
||||
if (hasReacted(note, reaction)) {
|
||||
// has already liked this note
|
||||
return
|
||||
return null
|
||||
}
|
||||
|
||||
if (note.event is ChatMessageEvent) {
|
||||
@@ -272,6 +272,7 @@ class Account(
|
||||
LocalCache.consume(event)
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
fun createZapRequestFor(note: Note, pollOption: Int?, message: String = "", zapType: LnZapEvent.ZapType): LnZapRequestEvent? {
|
||||
@@ -407,16 +408,21 @@ class Account(
|
||||
delete(listOf(note))
|
||||
}
|
||||
|
||||
fun delete(notes: List<Note>) {
|
||||
if (!isWriteable()) return
|
||||
fun delete(notes: List<Note>, signEvent: Boolean = true): DeletionEvent? {
|
||||
if (!isWriteable() && signEvent) return null
|
||||
|
||||
val myNotes = notes.filter { it.author == userProfile() }.map { it.idHex }
|
||||
|
||||
if (myNotes.isNotEmpty()) {
|
||||
if (!signEvent) {
|
||||
return DeletionEvent.create(myNotes, keyPair.pubKey.toHexKey())
|
||||
}
|
||||
|
||||
val event = DeletionEvent.create(myNotes, keyPair.privKey!!)
|
||||
Client.send(event)
|
||||
LocalCache.consume(event)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
fun createHTTPAuthorization(url: String, method: String, body: String? = null): HTTPAuthorizationEvent? {
|
||||
|
||||
@@ -20,6 +20,13 @@ class DeletionEvent(
|
||||
companion object {
|
||||
const val kind = 5
|
||||
|
||||
fun create(deleteEvents: List<String>, pubKey: HexKey, createdAt: Long = TimeUtils.now()): DeletionEvent {
|
||||
val content = ""
|
||||
val tags = deleteEvents.map { listOf("e", it) }
|
||||
val id = generateId(pubKey, createdAt, kind, tags, content)
|
||||
return DeletionEvent(id.toHexKey(), pubKey, createdAt, tags, content, "")
|
||||
}
|
||||
|
||||
fun create(deleteEvents: List<String>, privateKey: ByteArray, createdAt: Long = TimeUtils.now()): DeletionEvent {
|
||||
val content = ""
|
||||
val pubKey = CryptoUtils.pubkeyCreate(privateKey).toHexKey()
|
||||
|
||||
@@ -43,6 +43,33 @@ class ReactionEvent(
|
||||
return ReactionEvent(id.toHexKey(), pubKey, createdAt, tags, content, sig.toHexKey())
|
||||
}
|
||||
|
||||
fun create(content: String, originalNote: EventInterface, pubKey: HexKey, createdAt: Long = TimeUtils.now()): ReactionEvent {
|
||||
var tags = listOf(listOf("e", originalNote.id()), listOf("p", originalNote.pubKey()))
|
||||
if (originalNote is AddressableEvent) {
|
||||
tags = tags + listOf(listOf("a", originalNote.address().toTag()))
|
||||
}
|
||||
|
||||
val id = generateId(pubKey, createdAt, kind, tags, content)
|
||||
return ReactionEvent(id.toHexKey(), pubKey, createdAt, tags, content, "")
|
||||
}
|
||||
|
||||
fun create(emojiUrl: EmojiUrl, originalNote: EventInterface, pubKey: HexKey, createdAt: Long = TimeUtils.now()): ReactionEvent {
|
||||
val content = ":${emojiUrl.code}:"
|
||||
|
||||
var tags = listOf(
|
||||
listOf("e", originalNote.id()),
|
||||
listOf("p", originalNote.pubKey()),
|
||||
listOf("emoji", emojiUrl.code, emojiUrl.url)
|
||||
)
|
||||
|
||||
if (originalNote is AddressableEvent) {
|
||||
tags = tags + listOf(listOf("a", originalNote.address().toTag()))
|
||||
}
|
||||
|
||||
val id = generateId(pubKey, createdAt, kind, tags, content)
|
||||
return ReactionEvent(id.toHexKey(), pubKey, createdAt, tags, content, "")
|
||||
}
|
||||
|
||||
fun create(emojiUrl: EmojiUrl, originalNote: EventInterface, privateKey: ByteArray, createdAt: Long = TimeUtils.now()): ReactionEvent {
|
||||
val content = ":${emojiUrl.code}:"
|
||||
val pubKey = CryptoUtils.pubkeyCreate(privateKey).toHexKey()
|
||||
|
||||
@@ -75,8 +75,13 @@ import coil.compose.AsyncImage
|
||||
import coil.request.CachePolicy
|
||||
import coil.request.ImageRequest
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.model.LocalCache
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.amethyst.service.PackageUtils
|
||||
import com.vitorpamplona.amethyst.service.model.Event
|
||||
import com.vitorpamplona.amethyst.service.relays.Client
|
||||
import com.vitorpamplona.amethyst.ui.actions.NewPostView
|
||||
import com.vitorpamplona.amethyst.ui.actions.SignerDialog
|
||||
import com.vitorpamplona.amethyst.ui.components.ImageUrlType
|
||||
import com.vitorpamplona.amethyst.ui.components.InLineIconRenderer
|
||||
import com.vitorpamplona.amethyst.ui.components.TextType
|
||||
@@ -758,6 +763,23 @@ fun LikeReaction(
|
||||
|
||||
var wantsToChangeReactionSymbol by remember { mutableStateOf(false) }
|
||||
var wantsToReact by remember { mutableStateOf(false) }
|
||||
var event by remember { mutableStateOf<Event?>(null) }
|
||||
|
||||
if (event != null) {
|
||||
SignerDialog(
|
||||
onClose = {
|
||||
event = null
|
||||
},
|
||||
onPost = {
|
||||
scope.launch(Dispatchers.IO) {
|
||||
Client.send(it)
|
||||
LocalCache.verifyAndConsume(it, null)
|
||||
event = null
|
||||
}
|
||||
},
|
||||
event = event!!
|
||||
)
|
||||
}
|
||||
|
||||
Box(
|
||||
contentAlignment = Center,
|
||||
@@ -773,6 +795,18 @@ fun LikeReaction(
|
||||
context,
|
||||
onMultipleChoices = {
|
||||
wantsToReact = true
|
||||
},
|
||||
onWantsToSignReaction = {
|
||||
if (accountViewModel.account.reactionChoices.size == 1) {
|
||||
val reaction = accountViewModel.account.reactionChoices.first()
|
||||
if (accountViewModel.hasReactedTo(baseNote, reaction)) {
|
||||
event = accountViewModel.deleteReactionTo(baseNote, reaction, false)
|
||||
} else {
|
||||
event = accountViewModel.reactTo(baseNote, reaction, false)
|
||||
}
|
||||
} else if (accountViewModel.account.reactionChoices.size > 1) {
|
||||
wantsToReact = true
|
||||
}
|
||||
}
|
||||
)
|
||||
},
|
||||
@@ -917,7 +951,8 @@ private fun likeClick(
|
||||
accountViewModel: AccountViewModel,
|
||||
scope: CoroutineScope,
|
||||
context: Context,
|
||||
onMultipleChoices: () -> Unit
|
||||
onMultipleChoices: () -> Unit,
|
||||
onWantsToSignReaction: () -> Unit
|
||||
) {
|
||||
if (accountViewModel.account.reactionChoices.isEmpty()) {
|
||||
scope.launch {
|
||||
@@ -930,14 +965,18 @@ private fun likeClick(
|
||||
.show()
|
||||
}
|
||||
} else if (!accountViewModel.isWriteable()) {
|
||||
scope.launch {
|
||||
Toast
|
||||
.makeText(
|
||||
context,
|
||||
context.getString(R.string.login_with_a_private_key_to_like_posts),
|
||||
Toast.LENGTH_SHORT
|
||||
)
|
||||
.show()
|
||||
if (PackageUtils.isAmberInstalled(context)) {
|
||||
onWantsToSignReaction()
|
||||
} else {
|
||||
scope.launch {
|
||||
Toast
|
||||
.makeText(
|
||||
context,
|
||||
context.getString(R.string.login_with_a_private_key_to_like_posts),
|
||||
Toast.LENGTH_SHORT
|
||||
)
|
||||
.show()
|
||||
}
|
||||
}
|
||||
} else if (accountViewModel.account.reactionChoices.size == 1) {
|
||||
scope.launch(Dispatchers.IO) {
|
||||
@@ -1313,16 +1352,39 @@ private fun ActionableReactionButton(
|
||||
toRemove: Set<String>
|
||||
) {
|
||||
val scope = rememberCoroutineScope()
|
||||
val context = LocalContext.current
|
||||
var event by remember { mutableStateOf<Event?>(null) }
|
||||
if (event != null) {
|
||||
SignerDialog(
|
||||
onClose = {
|
||||
event = null
|
||||
onDismiss()
|
||||
},
|
||||
onPost = {
|
||||
scope.launch(Dispatchers.IO) {
|
||||
Client.send(it)
|
||||
LocalCache.verifyAndConsume(it, null)
|
||||
event = null
|
||||
onDismiss()
|
||||
}
|
||||
},
|
||||
event = event!!
|
||||
)
|
||||
}
|
||||
|
||||
Button(
|
||||
modifier = Modifier.padding(horizontal = 3.dp),
|
||||
onClick = {
|
||||
val isAmberInstalled = PackageUtils.isAmberInstalled(context)
|
||||
scope.launch(Dispatchers.IO) {
|
||||
accountViewModel.reactToOrDelete(
|
||||
event = accountViewModel.reactToOrDelete(
|
||||
baseNote,
|
||||
reactionType
|
||||
reactionType,
|
||||
!isAmberInstalled
|
||||
)
|
||||
onDismiss()
|
||||
if (!isAmberInstalled) {
|
||||
onDismiss()
|
||||
}
|
||||
}
|
||||
},
|
||||
shape = ButtonBorder,
|
||||
@@ -1334,12 +1396,16 @@ private fun ActionableReactionButton(
|
||||
val thisModifier = remember(reactionType) {
|
||||
Modifier.combinedClickable(
|
||||
onClick = {
|
||||
val isAmberInstalled = PackageUtils.isAmberInstalled(context)
|
||||
scope.launch(Dispatchers.IO) {
|
||||
accountViewModel.reactToOrDelete(
|
||||
event = accountViewModel.reactToOrDelete(
|
||||
baseNote,
|
||||
reactionType
|
||||
reactionType,
|
||||
!isAmberInstalled
|
||||
)
|
||||
onDismiss()
|
||||
if (!isAmberInstalled) {
|
||||
onDismiss()
|
||||
}
|
||||
}
|
||||
},
|
||||
onLongClick = {
|
||||
|
||||
@@ -21,10 +21,12 @@ import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.amethyst.model.User
|
||||
import com.vitorpamplona.amethyst.model.UserState
|
||||
import com.vitorpamplona.amethyst.service.lnurl.LightningAddressResolver
|
||||
import com.vitorpamplona.amethyst.service.model.DeletionEvent
|
||||
import com.vitorpamplona.amethyst.service.model.Event
|
||||
import com.vitorpamplona.amethyst.service.model.GiftWrapEvent
|
||||
import com.vitorpamplona.amethyst.service.model.LnZapEvent
|
||||
import com.vitorpamplona.amethyst.service.model.PayInvoiceErrorResponse
|
||||
import com.vitorpamplona.amethyst.service.model.ReactionEvent
|
||||
import com.vitorpamplona.amethyst.service.model.ReportEvent
|
||||
import com.vitorpamplona.amethyst.service.model.SealedGossipEvent
|
||||
import kotlinx.collections.immutable.ImmutableSet
|
||||
@@ -87,16 +89,16 @@ class AccountViewModel(val account: Account) : ViewModel() {
|
||||
return account.userProfile()
|
||||
}
|
||||
|
||||
fun reactTo(note: Note, reaction: String) {
|
||||
account.reactTo(note, reaction)
|
||||
fun reactTo(note: Note, reaction: String, signEvent: Boolean = true): ReactionEvent? {
|
||||
return account.reactTo(note, reaction, signEvent)
|
||||
}
|
||||
|
||||
fun reactToOrDelete(note: Note, reaction: String) {
|
||||
fun reactToOrDelete(note: Note, reaction: String, signEvent: Boolean = true): Event? {
|
||||
val currentReactions = account.reactionTo(note, reaction)
|
||||
if (currentReactions.isNotEmpty()) {
|
||||
account.delete(currentReactions)
|
||||
return account.delete(currentReactions, signEvent)
|
||||
} else {
|
||||
account.reactTo(note, reaction)
|
||||
return account.reactTo(note, reaction, signEvent)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,8 +111,8 @@ class AccountViewModel(val account: Account) : ViewModel() {
|
||||
return account.hasReacted(baseNote, reaction)
|
||||
}
|
||||
|
||||
fun deleteReactionTo(note: Note, reaction: String) {
|
||||
account.delete(account.reactionTo(note, reaction))
|
||||
fun deleteReactionTo(note: Note, reaction: String, signEvent: Boolean = true): DeletionEvent? {
|
||||
return account.delete(account.reactionTo(note, reaction), signEvent)
|
||||
}
|
||||
|
||||
fun hasBoosted(baseNote: Note): Boolean {
|
||||
|
||||
Reference in New Issue
Block a user