added SignerDialog in the like reaction

This commit is contained in:
greenart7c3
2023-08-09 11:45:54 -03:00
parent 7a46376bc1
commit 10b15226a1
5 changed files with 135 additions and 27 deletions
@@ -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 {