This commit is contained in:
Believethehype
2023-04-12 19:08:46 +02:00
11 changed files with 56 additions and 22 deletions
@@ -137,7 +137,7 @@ class Account(
} }
} }
fun createZapRequestFor(note: Note, pollOption: Int?, message: String = ""): LnZapRequestEvent? { fun createZapRequestFor(note: Note, pollOption: Int?, message: String = "", zapType: LnZapEvent.ZapType): LnZapRequestEvent? {
if (!isWriteable()) return null if (!isWriteable()) return null
note.event?.let { event -> note.event?.let { event ->
@@ -147,7 +147,8 @@ class Account(
?: localRelays.map { it.url }.toSet(), ?: localRelays.map { it.url }.toSet(),
loggedIn.privKey!!, loggedIn.privKey!!,
pollOption, pollOption,
message message,
zapType
) )
} }
return null return null
@@ -171,14 +172,15 @@ class Account(
return createZapRequestFor(user) return createZapRequestFor(user)
} }
fun createZapRequestFor(userPubKeyHex: String, message: String = ""): LnZapRequestEvent? { fun createZapRequestFor(userPubKeyHex: String, message: String = "", zapType: LnZapEvent.ZapType): LnZapRequestEvent? {
if (!isWriteable()) return null if (!isWriteable()) return null
return LnZapRequestEvent.create( return LnZapRequestEvent.create(
userPubKeyHex, userPubKeyHex,
userProfile().latestContactList?.relays()?.keys?.ifEmpty { null } ?: localRelays.map { it.url }.toSet(), userProfile().latestContactList?.relays()?.keys?.ifEmpty { null } ?: localRelays.map { it.url }.toSet(),
loggedIn.privKey!!, loggedIn.privKey!!,
message message,
zapType
) )
} }
@@ -72,8 +72,8 @@ class LnZapEvent(
enum class ZapType() { enum class ZapType() {
PUBLIC, PUBLIC,
PRIVATE, // not implemented PRIVATE, // not yet implemented
ANONYMOUS, // not implemented ANONYMOUS,
NONZAP NONZAP
} }
} }
@@ -25,10 +25,12 @@ class LnZapRequestEvent(
privateKey: ByteArray, privateKey: ByteArray,
pollOption: Int?, pollOption: Int?,
message: String, message: String,
zapType: LnZapEvent.ZapType,
createdAt: Long = Date().time / 1000 createdAt: Long = Date().time / 1000
): LnZapRequestEvent { ): LnZapRequestEvent {
val content = message val content = message
val pubKey = Utils.pubkeyCreate(privateKey).toHexKey() var privkey = privateKey
var pubKey = Utils.pubkeyCreate(privateKey).toHexKey()
var tags = listOf( var tags = listOf(
listOf("e", originalNote.id()), listOf("e", originalNote.id()),
listOf("p", originalNote.pubKey()), listOf("p", originalNote.pubKey()),
@@ -40,9 +42,13 @@ class LnZapRequestEvent(
if (pollOption != null && pollOption >= 0) { if (pollOption != null && pollOption >= 0) {
tags = tags + listOf(listOf(POLL_OPTION, pollOption.toString())) tags = tags + listOf(listOf(POLL_OPTION, pollOption.toString()))
} }
if (zapType == LnZapEvent.ZapType.ANONYMOUS) {
tags = tags + listOf(listOf("anon", ""))
privkey = Utils.privkeyCreate()
pubKey = Utils.pubkeyCreate(privkey).toHexKey()
}
val id = generateId(pubKey, createdAt, kind, tags, content) val id = generateId(pubKey, createdAt, kind, tags, content)
val sig = Utils.sign(id, privateKey) val sig = Utils.sign(id, privkey)
return LnZapRequestEvent(id.toHexKey(), pubKey, createdAt, tags, content, sig.toHexKey()) return LnZapRequestEvent(id.toHexKey(), pubKey, createdAt, tags, content, sig.toHexKey())
} }
@@ -51,17 +57,24 @@ class LnZapRequestEvent(
relays: Set<String>, relays: Set<String>,
privateKey: ByteArray, privateKey: ByteArray,
message: String, message: String,
zapType: LnZapEvent.ZapType,
createdAt: Long = Date().time / 1000 createdAt: Long = Date().time / 1000
): LnZapRequestEvent { ): LnZapRequestEvent {
val content = message val content = message
val pubKey = Utils.pubkeyCreate(privateKey).toHexKey() var privkey = privateKey
val tags = listOf( var pubKey = Utils.pubkeyCreate(privateKey).toHexKey()
var tags = listOf(
listOf("p", userHex), listOf("p", userHex),
listOf("relays") + relays listOf("relays") + relays
) )
if (zapType == LnZapEvent.ZapType.ANONYMOUS) {
tags = tags + listOf(listOf("anon", ""))
privkey = Utils.privkeyCreate()
pubKey = Utils.pubkeyCreate(privkey).toHexKey()
}
val id = generateId(pubKey, createdAt, kind, tags, content) val id = generateId(pubKey, createdAt, kind, tags, content)
val sig = Utils.sign(id, privateKey) val sig = Utils.sign(id, privkey)
return LnZapRequestEvent(id.toHexKey(), pubKey, createdAt, tags, content, sig.toHexKey()) return LnZapRequestEvent(id.toHexKey(), pubKey, createdAt, tags, content, sig.toHexKey())
} }
} }
@@ -271,8 +271,10 @@ fun NewPostView(onClose: () -> Unit, baseReplyTo: Note? = null, quote: Note? = n
} }
if (postViewModel.canUsePoll) { if (postViewModel.canUsePoll) {
val hashtag = stringResource(R.string.poll_hashtag)
AddPollButton(postViewModel.wantsPoll) { AddPollButton(postViewModel.wantsPoll) {
postViewModel.wantsPoll = !postViewModel.wantsPoll postViewModel.wantsPoll = !postViewModel.wantsPoll
postViewModel.includePollHashtagInMessage(postViewModel.wantsPoll, hashtag)
} }
} }
@@ -195,4 +195,17 @@ open class NewPostViewModel : ViewModel() {
return message.text.isNotBlank() && !isUploadingImage && !wantsInvoice && return message.text.isNotBlank() && !isUploadingImage && !wantsInvoice &&
(!wantsPoll || pollOptions.values.all { it.isNotEmpty() }) (!wantsPoll || pollOptions.values.all { it.isNotEmpty() })
} }
fun includePollHashtagInMessage(include: Boolean, hashtag: String) {
if (include) {
updateMessage(TextFieldValue(message.text + " $hashtag"))
} else {
updateMessage(
TextFieldValue(
message.text.replace(" $hashtag", "")
.replace(hashtag, "")
)
)
}
}
} }
@@ -37,6 +37,7 @@ import androidx.compose.ui.unit.sp
import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.Account
import com.vitorpamplona.amethyst.service.lnurl.LightningAddressResolver import com.vitorpamplona.amethyst.service.lnurl.LightningAddressResolver
import com.vitorpamplona.amethyst.service.model.LnZapEvent
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@Composable @Composable
@@ -135,7 +136,7 @@ fun InvoiceRequest(
Button( Button(
modifier = Modifier.fillMaxWidth().padding(vertical = 10.dp), modifier = Modifier.fillMaxWidth().padding(vertical = 10.dp),
onClick = { onClick = {
val zapRequest = account.createZapRequestFor(toUserPubKeyHex, message) val zapRequest = account.createZapRequestFor(toUserPubKeyHex, message, LnZapEvent.ZapType.PUBLIC)
LightningAddressResolver().lnAddressInvoice( LightningAddressResolver().lnAddressInvoice(
lud16, lud16,
@@ -253,7 +253,7 @@ fun ZapVote(
zappingProgress = it zappingProgress = it
} }
}, },
type = LnZapEvent.ZapType.PUBLIC zapType = LnZapEvent.ZapType.PUBLIC
) )
} }
} else { } else {
@@ -365,7 +365,7 @@ fun ZapReaction(
zappingProgress = it zappingProgress = it
} }
}, },
type = LnZapEvent.ZapType.PUBLIC zapType = LnZapEvent.ZapType.PUBLIC
) )
} }
} else if (account.zapAmountChoices.size > 1) { } else if (account.zapAmountChoices.size > 1) {
@@ -59,7 +59,6 @@ fun ZapCustomDialog(onClose: () -> Unit, account: Account, accountViewModel: Acc
val context = LocalContext.current val context = LocalContext.current
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
val postViewModel: ZapOptionstViewModel = viewModel() val postViewModel: ZapOptionstViewModel = viewModel()
postViewModel.load(account)
LaunchedEffect(account) { LaunchedEffect(account) {
postViewModel.load(account) postViewModel.load(account)
} }
@@ -68,6 +67,7 @@ fun ZapCustomDialog(onClose: () -> Unit, account: Account, accountViewModel: Acc
val zapTypes = listOf( val zapTypes = listOf(
Pair(LnZapEvent.ZapType.PUBLIC, "Public"), Pair(LnZapEvent.ZapType.PUBLIC, "Public"),
Pair(LnZapEvent.ZapType.ANONYMOUS, "Anonymous"),
Pair(LnZapEvent.ZapType.NONZAP, "Non-Zap") Pair(LnZapEvent.ZapType.NONZAP, "Non-Zap")
) )
@@ -115,7 +115,7 @@ fun ZapCustomDialog(onClose: () -> Unit, account: Account, accountViewModel: Acc
zappingProgress = it zappingProgress = it
} }
}, },
type = selectedZapType.first zapType = selectedZapType.first
) )
} }
onClose() onClose()
@@ -53,7 +53,7 @@ class AccountViewModel(private val account: Account) : ViewModel() {
account.delete(account.boostsTo(note)) account.delete(account.boostsTo(note))
} }
fun zap(note: Note, amount: Long, pollOption: Int?, message: String, context: Context, onError: (String) -> Unit, onProgress: (percent: Float) -> Unit, type: LnZapEvent.ZapType) { fun zap(note: Note, amount: Long, pollOption: Int?, message: String, context: Context, onError: (String) -> Unit, onProgress: (percent: Float) -> Unit, zapType: LnZapEvent.ZapType) {
val lud16 = note.author?.info?.lud16?.trim() ?: note.author?.info?.lud06?.trim() val lud16 = note.author?.info?.lud16?.trim() ?: note.author?.info?.lud06?.trim()
if (lud16.isNullOrBlank()) { if (lud16.isNullOrBlank()) {
@@ -61,11 +61,13 @@ class AccountViewModel(private val account: Account) : ViewModel() {
return return
} }
var zapRequest = account.createZapRequestFor(note, pollOption, message) var zapRequestJson = ""
var zapRequestJson = zapRequest?.toJson()
if (type == LnZapEvent.ZapType.NONZAP) { if (zapType != LnZapEvent.ZapType.NONZAP) {
zapRequestJson = "" val zapRequest = account.createZapRequestFor(note, pollOption, message, zapType)
if (zapRequest != null) {
zapRequestJson = zapRequest.toJson()
}
} }
onProgress(0.10f) onProgress(0.10f)
+1
View File
@@ -291,4 +291,5 @@
<string name="lightning_create_and_add_invoice">Create and Add</string> <string name="lightning_create_and_add_invoice">Create and Add</string>
<string name="poll_author_no_vote">Poll authors can\'t vote in their own polls.</string> <string name="poll_author_no_vote">Poll authors can\'t vote in their own polls.</string>
<string name="poll_hashtag" translatable="false">#zappoll</string>
</resources> </resources>