add signerDialog in the profile screen follow button

This commit is contained in:
greenart7c3
2023-08-07 17:16:05 -03:00
parent 41fd2e087c
commit 3a08db2dfb
6 changed files with 140 additions and 24 deletions
@@ -460,7 +460,11 @@ class Account(
if (followingCommunities.isNotEmpty()) {
followingCommunities.forEach {
ATag.parse(it, null)?.let {
returningContactList = ContactListEvent.followAddressableEvent(returningContactList, it, keyPair.privKey!!)
returningContactList = if (keyPair.privKey == null) {
ContactListEvent.followAddressableEvent(returningContactList, it, keyPair.pubKey.toHexKey())
} else {
ContactListEvent.followAddressableEvent(returningContactList, it, keyPair.privKey)
}
}
}
followingCommunities = emptySet()
@@ -468,7 +472,11 @@ class Account(
if (followingChannels.isNotEmpty()) {
followingChannels.forEach {
returningContactList = ContactListEvent.followEvent(returningContactList, it, keyPair.privKey!!)
returningContactList = if (keyPair.privKey == null) {
ContactListEvent.followEvent(returningContactList, it, keyPair.pubKey.toHexKey())
} else {
ContactListEvent.followEvent(returningContactList, it, keyPair.privKey)
}
}
followingChannels = emptySet()
}
@@ -476,13 +484,17 @@ class Account(
return returningContactList
}
fun follow(user: User) {
if (!isWriteable()) return
fun follow(user: User, signEvent: Boolean = true): ContactListEvent? {
if (!isWriteable() && signEvent) return null
val contactList = migrateCommunitiesAndChannelsIfNeeded(userProfile().latestContactList)
val event = if (contactList != null) {
ContactListEvent.followUser(contactList, user.pubkeyHex, keyPair.privKey!!)
if (signEvent) {
ContactListEvent.followUser(contactList, user.pubkeyHex, keyPair.privKey!!)
} else {
ContactListEvent.followUser(contactList, user.pubkeyHex, keyPair.pubKey.toHexKey())
}
} else {
ContactListEvent.createFromScratch(
followUsers = listOf(Contact(user.pubkeyHex, null)),
@@ -491,12 +503,18 @@ class Account(
followCommunities = emptyList(),
followEvents = DefaultChannels.toList(),
relayUse = Constants.defaultRelays.associate { it.url to ContactListEvent.ReadWrite(it.read, it.write) },
privateKey = keyPair.privKey!!
privateKey = keyPair.privKey!!,
publicKey = keyPair.pubKey
)
}
if (!signEvent) {
return event
}
Client.send(event)
LocalCache.consume(event)
return null
}
fun follow(channel: Channel) {
@@ -0,0 +1,9 @@
package com.vitorpamplona.amethyst.service
import android.content.Context
object PackageUtils {
fun isPackageInstalled(context: Context, target: String): Boolean {
return context.packageManager.getInstalledApplications(0).find { info -> info.packageName == target } != null
}
}
@@ -98,7 +98,8 @@ class ContactListEvent(
followEvents: List<String>,
relayUse: Map<String, ReadWrite>?,
privateKey: ByteArray,
createdAt: Long = TimeUtils.now()
createdAt: Long = TimeUtils.now(),
publicKey: ByteArray? = null
): ContactListEvent {
val content = if (relayUse != null) {
gson.toJson(relayUse)
@@ -126,10 +127,29 @@ class ContactListEvent(
listOf("g", it)
}
if (publicKey == null) {
return create(
content = content,
tags = tags,
privateKey = privateKey,
createdAt = createdAt
)
}
return create(
content = content,
tags = tags,
privateKey = privateKey,
pubKey = publicKey.toHexKey(),
createdAt = createdAt
)
}
fun followUser(earlierVersion: ContactListEvent, pubKeyHex: String, pubKey: HexKey, createdAt: Long = TimeUtils.now()): ContactListEvent {
if (earlierVersion.isTaggedUser(pubKeyHex)) return earlierVersion
return create(
content = earlierVersion.content,
tags = earlierVersion.tags.plus(element = listOf("p", pubKeyHex)),
pubKey = pubKey,
createdAt = createdAt
)
}
@@ -211,6 +231,17 @@ class ContactListEvent(
)
}
fun followEvent(earlierVersion: ContactListEvent, idHex: String, pubKey: HexKey, createdAt: Long = TimeUtils.now()): ContactListEvent {
if (earlierVersion.isTaggedEvent(idHex)) return earlierVersion
return create(
content = earlierVersion.content,
tags = earlierVersion.tags.plus(element = listOf("e", idHex)),
pubKey = pubKey,
createdAt = createdAt
)
}
fun unfollowEvent(earlierVersion: ContactListEvent, idHex: String, privateKey: ByteArray, createdAt: Long = TimeUtils.now()): ContactListEvent {
if (!earlierVersion.isTaggedEvent(idHex)) return earlierVersion
@@ -233,6 +264,17 @@ class ContactListEvent(
)
}
fun followAddressableEvent(earlierVersion: ContactListEvent, aTag: ATag, pubKey: HexKey, createdAt: Long = TimeUtils.now()): ContactListEvent {
if (earlierVersion.isTaggedAddressableNote(aTag.toTag())) return earlierVersion
return create(
content = earlierVersion.content,
tags = earlierVersion.tags.plus(element = listOfNotNull("a", aTag.toTag(), aTag.relay)),
pubKey = pubKey,
createdAt = createdAt
)
}
fun unfollowAddressableEvent(earlierVersion: ContactListEvent, aTag: ATag, privateKey: ByteArray, createdAt: Long = TimeUtils.now()): ContactListEvent {
if (!earlierVersion.isTaggedAddressableNote(aTag.toTag())) return earlierVersion
@@ -259,6 +301,11 @@ class ContactListEvent(
)
}
fun create(content: String, tags: List<List<String>>, pubKey: HexKey, createdAt: Long = TimeUtils.now()): ContactListEvent {
val id = generateId(pubKey, createdAt, kind, tags, content)
return ContactListEvent(id.toHexKey(), pubKey, createdAt, tags, content, "")
}
fun create(content: String, tags: List<List<String>>, privateKey: ByteArray, createdAt: Long = TimeUtils.now()): ContactListEvent {
val pubKey = CryptoUtils.pubkeyCreate(privateKey).toHexKey()
val id = generateId(pubKey, createdAt, kind, tags, content)
@@ -59,7 +59,7 @@ fun openAmber(
@Composable
fun SignerDialog(
onClose: () -> Unit,
onPost: () -> Unit,
onPost: (signedEvent: Event) -> Unit,
event: Event
) {
var signature by remember { mutableStateOf("") }
@@ -120,7 +120,26 @@ fun SignerDialog(
PostButton(
onPost = {
onPost()
val signedEvent = Event(
event.id,
event.pubKey,
event.createdAt,
event.kind,
event.tags,
event.content,
signature
)
if (!signedEvent.hasValidSignature()) {
scope.launch {
Toast.makeText(
context,
"Invalid signature",
Toast.LENGTH_SHORT
).show()
}
return@PostButton
}
onPost(signedEvent)
},
isActive = true
)
@@ -59,16 +59,21 @@ import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.amethyst.service.NostrUserProfileDataSource
import com.vitorpamplona.amethyst.service.PackageUtils
import com.vitorpamplona.amethyst.service.model.ATag
import com.vitorpamplona.amethyst.service.model.AppDefinitionEvent
import com.vitorpamplona.amethyst.service.model.BadgeDefinitionEvent
import com.vitorpamplona.amethyst.service.model.BadgeProfilesEvent
import com.vitorpamplona.amethyst.service.model.ContactListEvent
import com.vitorpamplona.amethyst.service.model.Event
import com.vitorpamplona.amethyst.service.model.IdentityClaim
import com.vitorpamplona.amethyst.service.model.PayInvoiceErrorResponse
import com.vitorpamplona.amethyst.service.model.PayInvoiceSuccessResponse
import com.vitorpamplona.amethyst.service.model.ReportEvent
import com.vitorpamplona.amethyst.service.relays.Client
import com.vitorpamplona.amethyst.ui.actions.ImmutableListOfLists
import com.vitorpamplona.amethyst.ui.actions.NewUserMetadataView
import com.vitorpamplona.amethyst.ui.actions.SignerDialog
import com.vitorpamplona.amethyst.ui.actions.toImmutableListOfLists
import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji
import com.vitorpamplona.amethyst.ui.components.DisplayNip05ProfileStatus
@@ -742,6 +747,24 @@ private fun DisplayFollowUnfollowButton(
it.user.isFollowing(accountViewModel.account.userProfile())
}.distinctUntilChanged().observeAsState(initial = baseUser.isFollowing(accountViewModel.account.userProfile()))
var event by remember { mutableStateOf<ContactListEvent?>(null) }
if (event != null) {
SignerDialog(
onClose = {
event = null
},
onPost = {
scope.launch(Dispatchers.IO) {
Client.send(it)
LocalCache.verifyAndConsume(it, null)
event = null
}
},
event = event!!
)
}
if (isLoggedInFollowingUser) {
UnfollowButton {
if (!accountViewModel.isWriteable()) {
@@ -782,14 +805,18 @@ private fun DisplayFollowUnfollowButton(
} else {
FollowButton(R.string.follow) {
if (!accountViewModel.isWriteable()) {
scope.launch {
Toast
.makeText(
context,
context.getString(R.string.login_with_a_private_key_to_be_able_to_follow),
Toast.LENGTH_SHORT
)
.show()
if (PackageUtils.isPackageInstalled(context, "com.greenart7c3.nostrsigner")) {
event = accountViewModel.account.follow(baseUser, false)
} else {
scope.launch {
Toast
.makeText(
context,
context.getString(R.string.login_with_a_private_key_to_be_able_to_follow),
Toast.LENGTH_SHORT
)
.show()
}
}
} else {
scope.launch(Dispatchers.IO) {
@@ -1,6 +1,5 @@
package com.vitorpamplona.amethyst.ui.screen.loggedOff
import android.content.Context
import android.util.Log
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.*
@@ -37,6 +36,7 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.unit.dp
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.service.PackageUtils
import com.vitorpamplona.amethyst.ui.qrcode.SimpleQrCodeScanner
import com.vitorpamplona.amethyst.ui.screen.AccountStateViewModel
import com.vitorpamplona.amethyst.ui.screen.loggedIn.ConnectOrbotDialog
@@ -229,7 +229,7 @@ fun LoginPage(
}
}
if (isPackageInstalled(context, "org.torproject.android")) {
if (PackageUtils.isPackageInstalled(context, "org.torproject.android")) {
Row(verticalAlignment = Alignment.CenterVertically) {
Checkbox(
checked = useProxy.value,
@@ -315,7 +315,3 @@ fun LoginPage(
)
}
}
fun isPackageInstalled(context: Context, target: String): Boolean {
return context.packageManager.getInstalledApplications(0).find { info -> info.packageName == target } != null
}