add signer dialog to communities and public chats

This commit is contained in:
greenart7c3
2023-08-14 16:34:40 -03:00
parent e6f6f64512
commit 66b1e4b15d
3 changed files with 158 additions and 26 deletions

View File

@@ -503,7 +503,7 @@ class Account(
returningContactList = if (keyPair.privKey == null) {
ContactListEvent.followAddressableEvent(returningContactList, it, keyPair.pubKey.toHexKey())
} else {
ContactListEvent.followAddressableEvent(returningContactList, it, keyPair.privKey)
ContactListEvent.followAddressableEvent(returningContactList, it, keyPair.pubKey.toHexKey(), keyPair.privKey)
}
}
}
@@ -515,7 +515,7 @@ class Account(
returningContactList = if (keyPair.privKey == null) {
ContactListEvent.followEvent(returningContactList, it, keyPair.pubKey.toHexKey())
} else {
ContactListEvent.followEvent(returningContactList, it, keyPair.privKey)
ContactListEvent.followEvent(returningContactList, it, keyPair.pubKey.toHexKey(), keyPair.privKey)
}
}
followingChannels = emptySet()
@@ -557,13 +557,13 @@ class Account(
return null
}
fun follow(channel: Channel) {
if (!isWriteable()) return
fun follow(channel: Channel, signEvent: Boolean): ContactListEvent? {
if (!isWriteable() && signEvent) return null
val contactList = migrateCommunitiesAndChannelsIfNeeded(userProfile().latestContactList)
val event = if (contactList != null) {
ContactListEvent.followEvent(contactList, channel.idHex, keyPair.privKey!!)
ContactListEvent.followEvent(contactList, channel.idHex, keyPair.pubKey.toHexKey(), keyPair.privKey)
} else {
ContactListEvent.createFromScratch(
followUsers = emptyList(),
@@ -572,21 +572,27 @@ class Account(
followCommunities = emptyList(),
followEvents = DefaultChannels.toList().plus(channel.idHex),
relayUse = Constants.defaultRelays.associate { it.url to ContactListEvent.ReadWrite(it.read, it.write) },
privateKey = keyPair.privKey!!
publicKey = if (!signEvent) keyPair.pubKey else null,
privateKey = keyPair.privKey
)
}
if (!signEvent) {
return event
}
Client.send(event)
LocalCache.consume(event)
return null
}
fun follow(community: AddressableNote) {
if (!isWriteable()) return
fun follow(community: AddressableNote, signEvent: Boolean): ContactListEvent? {
if (!isWriteable() && signEvent) return null
val contactList = migrateCommunitiesAndChannelsIfNeeded(userProfile().latestContactList)
val event = if (contactList != null) {
ContactListEvent.followAddressableEvent(contactList, community.address, keyPair.privKey!!)
ContactListEvent.followAddressableEvent(contactList, community.address, keyPair.pubKey.toHexKey(), keyPair.privKey)
} else {
val relays = Constants.defaultRelays.associate { it.url to ContactListEvent.ReadWrite(it.read, it.write) }
ContactListEvent.createFromScratch(
@@ -596,12 +602,18 @@ class Account(
followCommunities = listOf(community.address),
followEvents = DefaultChannels.toList(),
relayUse = relays,
privateKey = keyPair.privKey!!
publicKey = if (!signEvent) keyPair.pubKey else null,
privateKey = keyPair.privKey
)
}
if (!signEvent) {
return event
}
Client.send(event)
LocalCache.consume(event)
return null
}
fun followHashtag(tag: String, signEvent: Boolean = true): ContactListEvent? {
@@ -745,8 +757,8 @@ class Account(
}
}
fun unfollow(channel: Channel) {
if (!isWriteable()) return
fun unfollow(channel: Channel, signEvent: Boolean): ContactListEvent? {
if (!isWriteable() && signEvent) return null
val contactList = migrateCommunitiesAndChannelsIfNeeded(userProfile().latestContactList)
@@ -754,16 +766,22 @@ class Account(
val event = ContactListEvent.unfollowEvent(
contactList,
channel.idHex,
keyPair.privKey!!
keyPair.pubKey.toHexKey(),
keyPair.privKey
)
if (!signEvent) {
return event
}
Client.send(event)
LocalCache.consume(event)
}
return null
}
fun unfollow(community: AddressableNote) {
if (!isWriteable()) return
fun unfollow(community: AddressableNote, signEvent: Boolean): ContactListEvent? {
if (!isWriteable() && signEvent) return null
val contactList = migrateCommunitiesAndChannelsIfNeeded(userProfile().latestContactList)
@@ -771,12 +789,18 @@ class Account(
val event = ContactListEvent.unfollowAddressableEvent(
contactList,
community.address,
keyPair.privKey!!
keyPair.pubKey.toHexKey(),
keyPair.privKey
)
if (!signEvent) {
return event
}
Client.send(event)
LocalCache.consume(event)
}
return null
}
fun createNip95(byteArray: ByteArray, headerInfo: FileHeader): Pair<FileStorageEvent, FileStorageHeaderEvent>? {
@@ -1131,7 +1155,7 @@ class Account(
LocalCache.consume(event)
LocalCache.getChannelIfExists(event.id)?.let {
follow(it)
follow(it, true)
}
}
@@ -1597,7 +1621,7 @@ class Account(
Client.send(event)
LocalCache.consume(event)
follow(channel)
follow(channel, true)
}
fun unwrap(event: GiftWrapEvent): Event? {

View File

@@ -253,9 +253,18 @@ class ContactListEvent(
)
}
fun followEvent(earlierVersion: ContactListEvent, idHex: String, privateKey: ByteArray, createdAt: Long = TimeUtils.now()): ContactListEvent {
fun followEvent(earlierVersion: ContactListEvent, idHex: String, pubKey: HexKey, privateKey: ByteArray?, createdAt: Long = TimeUtils.now()): ContactListEvent {
if (earlierVersion.isTaggedEvent(idHex)) return earlierVersion
if (privateKey == null) {
return create(
content = earlierVersion.content,
tags = earlierVersion.tags.plus(element = listOf("e", idHex)),
pubKey = pubKey,
createdAt = createdAt
)
}
return create(
content = earlierVersion.content,
tags = earlierVersion.tags.plus(element = listOf("e", idHex)),
@@ -275,9 +284,18 @@ class ContactListEvent(
)
}
fun unfollowEvent(earlierVersion: ContactListEvent, idHex: String, privateKey: ByteArray, createdAt: Long = TimeUtils.now()): ContactListEvent {
fun unfollowEvent(earlierVersion: ContactListEvent, idHex: String, publicKey: HexKey, privateKey: ByteArray?, createdAt: Long = TimeUtils.now()): ContactListEvent {
if (!earlierVersion.isTaggedEvent(idHex)) return earlierVersion
if (privateKey == null) {
return create(
content = earlierVersion.content,
tags = earlierVersion.tags.filter { it.size > 1 && it[1] != idHex },
pubKey = publicKey,
createdAt = createdAt
)
}
return create(
content = earlierVersion.content,
tags = earlierVersion.tags.filter { it.size > 1 && it[1] != idHex },
@@ -286,9 +304,18 @@ class ContactListEvent(
)
}
fun followAddressableEvent(earlierVersion: ContactListEvent, aTag: ATag, privateKey: ByteArray, createdAt: Long = TimeUtils.now()): ContactListEvent {
fun followAddressableEvent(earlierVersion: ContactListEvent, aTag: ATag, pubKey: HexKey, privateKey: ByteArray?, createdAt: Long = TimeUtils.now()): ContactListEvent {
if (earlierVersion.isTaggedAddressableNote(aTag.toTag())) return earlierVersion
if (privateKey == null) {
return create(
content = earlierVersion.content,
tags = earlierVersion.tags.plus(element = listOfNotNull("a", aTag.toTag(), aTag.relay)),
pubKey = pubKey,
createdAt = createdAt
)
}
return create(
content = earlierVersion.content,
tags = earlierVersion.tags.plus(element = listOfNotNull("a", aTag.toTag(), aTag.relay)),
@@ -308,9 +335,18 @@ class ContactListEvent(
)
}
fun unfollowAddressableEvent(earlierVersion: ContactListEvent, aTag: ATag, privateKey: ByteArray, createdAt: Long = TimeUtils.now()): ContactListEvent {
fun unfollowAddressableEvent(earlierVersion: ContactListEvent, aTag: ATag, pubKey: HexKey, privateKey: ByteArray?, createdAt: Long = TimeUtils.now()): ContactListEvent {
if (!earlierVersion.isTaggedAddressableNote(aTag.toTag())) return earlierVersion
if (privateKey == null) {
return create(
content = earlierVersion.content,
tags = earlierVersion.tags.filter { it.size > 1 && it[1] != aTag.toTag() },
pubKey = pubKey,
createdAt = createdAt
)
}
return create(
content = earlierVersion.content,
tags = earlierVersion.tags.filter { it.size > 1 && it[1] != aTag.toTag() },

View File

@@ -87,13 +87,17 @@ import com.vitorpamplona.amethyst.model.PublicChatChannel
import com.vitorpamplona.amethyst.model.ServersAvailable
import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.amethyst.service.NostrChannelDataSource
import com.vitorpamplona.amethyst.service.PackageUtils
import com.vitorpamplona.amethyst.service.model.Event
import com.vitorpamplona.amethyst.service.model.LiveActivitiesEvent.Companion.STATUS_LIVE
import com.vitorpamplona.amethyst.service.model.Participant
import com.vitorpamplona.amethyst.service.relays.Client
import com.vitorpamplona.amethyst.ui.actions.ImmutableListOfLists
import com.vitorpamplona.amethyst.ui.actions.NewChannelView
import com.vitorpamplona.amethyst.ui.actions.NewMessageTagger
import com.vitorpamplona.amethyst.ui.actions.NewPostViewModel
import com.vitorpamplona.amethyst.ui.actions.PostButton
import com.vitorpamplona.amethyst.ui.actions.SignerDialog
import com.vitorpamplona.amethyst.ui.actions.UploadFromGallery
import com.vitorpamplona.amethyst.ui.actions.toImmutableListOfLists
import com.vitorpamplona.amethyst.ui.components.LoadNote
@@ -1090,12 +1094,29 @@ private fun EditButton(accountViewModel: AccountViewModel, channel: PublicChatCh
@Composable
fun JoinChatButton(accountViewModel: AccountViewModel, channel: Channel, nav: (String) -> Unit) {
val scope = rememberCoroutineScope()
val context = LocalContext.current
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!!
)
}
Button(
modifier = Modifier.padding(horizontal = 3.dp),
onClick = {
scope.launch(Dispatchers.IO) {
accountViewModel.account.follow(channel)
event = accountViewModel.account.follow(channel, !PackageUtils.isAmberInstalled(context))
}
},
shape = ButtonBorder,
@@ -1112,12 +1133,29 @@ fun JoinChatButton(accountViewModel: AccountViewModel, channel: Channel, nav: (S
@Composable
fun LeaveChatButton(accountViewModel: AccountViewModel, channel: Channel, nav: (String) -> Unit) {
val scope = rememberCoroutineScope()
val context = LocalContext.current
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!!
)
}
Button(
modifier = Modifier.padding(horizontal = 3.dp),
onClick = {
scope.launch(Dispatchers.IO) {
accountViewModel.account.unfollow(channel)
event = accountViewModel.account.unfollow(channel, !PackageUtils.isAmberInstalled(context))
}
},
shape = ButtonBorder,
@@ -1134,12 +1172,29 @@ fun LeaveChatButton(accountViewModel: AccountViewModel, channel: Channel, nav: (
@Composable
fun JoinCommunityButton(accountViewModel: AccountViewModel, note: AddressableNote, nav: (String) -> Unit) {
val scope = rememberCoroutineScope()
val context = LocalContext.current
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!!
)
}
Button(
modifier = Modifier.padding(horizontal = 3.dp),
onClick = {
scope.launch(Dispatchers.IO) {
accountViewModel.account.follow(note)
event = accountViewModel.account.follow(note, !PackageUtils.isAmberInstalled(context))
}
},
shape = ButtonBorder,
@@ -1156,12 +1211,29 @@ fun JoinCommunityButton(accountViewModel: AccountViewModel, note: AddressableNot
@Composable
fun LeaveCommunityButton(accountViewModel: AccountViewModel, note: AddressableNote, nav: (String) -> Unit) {
val scope = rememberCoroutineScope()
val context = LocalContext.current
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!!
)
}
Button(
modifier = Modifier.padding(horizontal = 3.dp),
onClick = {
scope.launch(Dispatchers.IO) {
accountViewModel.account.unfollow(note)
event = accountViewModel.account.unfollow(note, !PackageUtils.isAmberInstalled(context))
}
},
shape = ButtonBorder,