From 7a46376bc10a5b6f956e0909cc935a28d00d50e7 Mon Sep 17 00:00:00 2001 From: greenart7c3 Date: Wed, 9 Aug 2023 10:42:00 -0300 Subject: [PATCH] added SignerDialog in the hashtagscreen --- .../vitorpamplona/amethyst/model/Account.kt | 50 +++++++++++---- .../service/model/ContactListEvent.kt | 26 +++++++- .../ui/screen/loggedIn/HashtagScreen.kt | 64 ++++++++++++++----- 3 files changed, 110 insertions(+), 30 deletions(-) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt b/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt index c7816a100..6b225dd2f 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt @@ -503,8 +503,8 @@ class Account( followCommunities = emptyList(), followEvents = DefaultChannels.toList(), relayUse = Constants.defaultRelays.associate { it.url to ContactListEvent.ReadWrite(it.read, it.write) }, - privateKey = keyPair.privKey!!, - publicKey = keyPair.pubKey + privateKey = keyPair.privKey, + publicKey = if (signEvent) null else keyPair.pubKey ) } @@ -564,17 +564,25 @@ class Account( LocalCache.consume(event) } - fun followHashtag(tag: String) { - if (!isWriteable()) return + fun followHashtag(tag: String, signEvent: Boolean = true): ContactListEvent? { + if (!isWriteable() && signEvent) return null val contactList = migrateCommunitiesAndChannelsIfNeeded(userProfile().latestContactList) val event = if (contactList != null) { - ContactListEvent.followHashtag( - contactList, - tag, - keyPair.privKey!! - ) + if (signEvent) { + ContactListEvent.followHashtag( + contactList, + tag, + keyPair.privKey!! + ) + } else { + ContactListEvent.followHashtag( + contactList, + tag, + keyPair.pubKey.toHexKey() + ) + } } else { ContactListEvent.createFromScratch( followUsers = emptyList(), @@ -583,12 +591,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 = if (signEvent) null else keyPair.pubKey ) } + if (!signEvent) { + return event + } + Client.send(event) LocalCache.consume(event) + return null } fun followGeohash(geohash: String) { @@ -645,12 +659,20 @@ class Account( return null } - fun unfollowHashtag(tag: String) { - if (!isWriteable()) return + fun unfollowHashtag(tag: String, signEvent: Boolean = true): ContactListEvent? { + if (!isWriteable() && signEvent) return null val contactList = migrateCommunitiesAndChannelsIfNeeded(userProfile().latestContactList) if (contactList != null && contactList.tags.isNotEmpty()) { + if (!signEvent) { + return ContactListEvent.unfollowHashtag( + contactList, + tag, + keyPair.pubKey.toHexKey() + ) + } + val event = ContactListEvent.unfollowHashtag( contactList, tag, @@ -659,7 +681,11 @@ class Account( Client.send(event) LocalCache.consume(event) + + return null } + + return null } fun unfollowGeohash(geohash: String) { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/ContactListEvent.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/model/ContactListEvent.kt index c5d3eee1c..e6a1e6ff2 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/ContactListEvent.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/model/ContactListEvent.kt @@ -97,7 +97,7 @@ class ContactListEvent( followCommunities: List, followEvents: List, relayUse: Map?, - privateKey: ByteArray, + privateKey: ByteArray?, createdAt: Long = TimeUtils.now(), publicKey: ByteArray? = null ): ContactListEvent { @@ -131,7 +131,7 @@ class ContactListEvent( return create( content = content, tags = tags, - privateKey = privateKey, + privateKey = privateKey!!, createdAt = createdAt ) } @@ -198,6 +198,17 @@ class ContactListEvent( ) } + fun followHashtag(earlierVersion: ContactListEvent, hashtag: String, pubKey: HexKey, createdAt: Long = TimeUtils.now()): ContactListEvent { + if (earlierVersion.isTaggedHash(hashtag)) return earlierVersion + + return create( + content = earlierVersion.content, + tags = earlierVersion.tags.plus(element = listOf("t", hashtag)), + pubKey = pubKey, + createdAt = createdAt + ) + } + fun unfollowHashtag(earlierVersion: ContactListEvent, hashtag: String, privateKey: ByteArray, createdAt: Long = TimeUtils.now()): ContactListEvent { if (!earlierVersion.isTaggedHash(hashtag)) return earlierVersion @@ -209,6 +220,17 @@ class ContactListEvent( ) } + fun unfollowHashtag(earlierVersion: ContactListEvent, hashtag: String, pubKey: HexKey, createdAt: Long = TimeUtils.now()): ContactListEvent { + if (!earlierVersion.isTaggedHash(hashtag)) return earlierVersion + + return create( + content = earlierVersion.content, + tags = earlierVersion.tags.filter { it.size > 1 && it[1] != hashtag }, + pubKey = pubKey, + createdAt = createdAt + ) + } + fun followGeohash(earlierVersion: ContactListEvent, hashtag: String, privateKey: ByteArray, createdAt: Long = TimeUtils.now()): ContactListEvent { if (earlierVersion.isTaggedGeoHash(hashtag)) return earlierVersion diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/HashtagScreen.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/HashtagScreen.kt index 834a5a30b..c17146046 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/HashtagScreen.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/HashtagScreen.kt @@ -16,8 +16,10 @@ import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.livedata.observeAsState +import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext @@ -28,7 +30,12 @@ import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleEventObserver import androidx.lifecycle.viewmodel.compose.viewModel import com.vitorpamplona.amethyst.R +import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.service.NostrHashtagDataSource +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.SignerDialog import com.vitorpamplona.amethyst.ui.screen.NostrHashtagFeedViewModel import com.vitorpamplona.amethyst.ui.screen.RefresheableFeedView import com.vitorpamplona.amethyst.ui.theme.StdPadding @@ -143,18 +150,39 @@ private fun HashtagActionOptions( userState?.user?.isFollowingHashtagCached(tag) ?: false } } + var event by remember { mutableStateOf(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 (isFollowingTag) { UnfollowButton { if (!accountViewModel.isWriteable()) { - scope.launch { - Toast - .makeText( - context, - context.getString(R.string.login_with_a_private_key_to_be_able_to_unfollow), - Toast.LENGTH_SHORT - ) - .show() + if (PackageUtils.isAmberInstalled(context)) { + event = accountViewModel.account.unfollowHashtag(tag, false) + } else { + scope.launch { + Toast + .makeText( + context, + context.getString(R.string.login_with_a_private_key_to_be_able_to_unfollow), + Toast.LENGTH_SHORT + ) + .show() + } } } else { scope.launch(Dispatchers.IO) { @@ -165,14 +193,18 @@ private fun HashtagActionOptions( } else { FollowButton { 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.isAmberInstalled(context)) { + event = accountViewModel.account.followHashtag(tag, 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) {