mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2025-07-04 18:10:38 +02:00
add/remove private bookmarks
This commit is contained in:
@ -8,6 +8,7 @@ import androidx.core.os.ConfigurationCompat
|
|||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.distinctUntilChanged
|
import androidx.lifecycle.distinctUntilChanged
|
||||||
import com.vitorpamplona.amethyst.OptOutFromFilters
|
import com.vitorpamplona.amethyst.OptOutFromFilters
|
||||||
|
import com.vitorpamplona.amethyst.service.AmberUtils
|
||||||
import com.vitorpamplona.amethyst.service.FileHeader
|
import com.vitorpamplona.amethyst.service.FileHeader
|
||||||
import com.vitorpamplona.amethyst.service.NostrLnZapPaymentResponseDataSource
|
import com.vitorpamplona.amethyst.service.NostrLnZapPaymentResponseDataSource
|
||||||
import com.vitorpamplona.amethyst.service.relays.Client
|
import com.vitorpamplona.amethyst.service.relays.Client
|
||||||
@ -1237,6 +1238,96 @@ class Account(
|
|||||||
LocalCache.consume(event)
|
LocalCache.consume(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun addPrivateBookmark(note: Note, decryptedContent: String): BookmarkListEvent? {
|
||||||
|
val bookmarks = userProfile().latestBookmarkList
|
||||||
|
val privTags = mutableListOf<List<String>>()
|
||||||
|
|
||||||
|
val privEvents = if (note is AddressableNote) {
|
||||||
|
bookmarks?.privateTaggedEvents(decryptedContent) ?: emptyList()
|
||||||
|
} else {
|
||||||
|
bookmarks?.privateTaggedEvents(decryptedContent)?.plus(note.idHex) ?: listOf(note.idHex)
|
||||||
|
}
|
||||||
|
val privUsers = bookmarks?.privateTaggedUsers(decryptedContent) ?: emptyList()
|
||||||
|
val privAddresses = if (note is AddressableNote) {
|
||||||
|
bookmarks?.privateTaggedAddresses(decryptedContent)?.plus(note.address) ?: listOf(note.address)
|
||||||
|
} else {
|
||||||
|
bookmarks?.privateTaggedAddresses(decryptedContent) ?: emptyList()
|
||||||
|
}
|
||||||
|
|
||||||
|
privEvents.forEach {
|
||||||
|
privTags.add(listOf("e", it))
|
||||||
|
}
|
||||||
|
privUsers.forEach {
|
||||||
|
privTags.add(listOf("p", it))
|
||||||
|
}
|
||||||
|
privAddresses.forEach {
|
||||||
|
privTags.add(listOf("a", it.toTag()))
|
||||||
|
}
|
||||||
|
val msg = Event.mapper.writeValueAsString(privTags)
|
||||||
|
|
||||||
|
AmberUtils.encryptBookmark(msg, keyPair.pubKey.toHexKey())
|
||||||
|
|
||||||
|
if (AmberUtils.content.isBlank()) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return BookmarkListEvent.create(
|
||||||
|
"bookmark",
|
||||||
|
bookmarks?.taggedEvents() ?: emptyList(),
|
||||||
|
bookmarks?.taggedUsers() ?: emptyList(),
|
||||||
|
bookmarks?.taggedAddresses() ?: emptyList(),
|
||||||
|
|
||||||
|
AmberUtils.content,
|
||||||
|
|
||||||
|
keyPair.pubKey.toHexKey()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun removePrivateBookmark(note: Note, decryptedContent: String): BookmarkListEvent? {
|
||||||
|
val bookmarks = userProfile().latestBookmarkList
|
||||||
|
val privTags = mutableListOf<List<String>>()
|
||||||
|
|
||||||
|
val privEvents = if (note is AddressableNote) {
|
||||||
|
bookmarks?.privateTaggedEvents(decryptedContent) ?: emptyList()
|
||||||
|
} else {
|
||||||
|
bookmarks?.privateTaggedEvents(decryptedContent)?.minus(note.idHex) ?: listOf(note.idHex)
|
||||||
|
}
|
||||||
|
val privUsers = bookmarks?.privateTaggedUsers(decryptedContent) ?: emptyList()
|
||||||
|
val privAddresses = if (note is AddressableNote) {
|
||||||
|
bookmarks?.privateTaggedAddresses(decryptedContent)?.minus(note.address) ?: listOf(note.address)
|
||||||
|
} else {
|
||||||
|
bookmarks?.privateTaggedAddresses(decryptedContent) ?: emptyList()
|
||||||
|
}
|
||||||
|
|
||||||
|
privEvents.forEach {
|
||||||
|
privTags.add(listOf("e", it))
|
||||||
|
}
|
||||||
|
privUsers.forEach {
|
||||||
|
privTags.add(listOf("p", it))
|
||||||
|
}
|
||||||
|
privAddresses.forEach {
|
||||||
|
privTags.add(listOf("a", it.toTag()))
|
||||||
|
}
|
||||||
|
val msg = Event.mapper.writeValueAsString(privTags)
|
||||||
|
|
||||||
|
AmberUtils.encryptBookmark(msg, keyPair.pubKey.toHexKey())
|
||||||
|
|
||||||
|
if (AmberUtils.content.isBlank()) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return BookmarkListEvent.create(
|
||||||
|
"bookmark",
|
||||||
|
bookmarks?.taggedEvents() ?: emptyList(),
|
||||||
|
bookmarks?.taggedUsers() ?: emptyList(),
|
||||||
|
bookmarks?.taggedAddresses() ?: emptyList(),
|
||||||
|
|
||||||
|
AmberUtils.content,
|
||||||
|
|
||||||
|
keyPair.pubKey.toHexKey()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fun addPrivateBookmark(note: Note) {
|
fun addPrivateBookmark(note: Note) {
|
||||||
if (!isWriteable()) return
|
if (!isWriteable()) return
|
||||||
|
|
||||||
@ -1392,14 +1483,24 @@ class Account(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun isInPrivateBookmarks(note: Note): Boolean {
|
fun isInPrivateBookmarks(note: Note): Boolean {
|
||||||
if (!isWriteable()) return false
|
if (!isWriteable() && !loginWithAmber) return false
|
||||||
|
|
||||||
if (note is AddressableNote) {
|
if (loginWithAmber) {
|
||||||
return userProfile().latestBookmarkList?.privateTaggedAddresses(keyPair.privKey!!)
|
return if (note is AddressableNote) {
|
||||||
?.contains(note.address) == true
|
userProfile().latestBookmarkList?.privateTaggedAddresses(userProfile().latestBookmarkList?.decryptedContent ?: "")
|
||||||
|
?.contains(note.address) == true
|
||||||
|
} else {
|
||||||
|
userProfile().latestBookmarkList?.privateTaggedEvents(userProfile().latestBookmarkList?.decryptedContent ?: "")
|
||||||
|
?.contains(note.idHex) == true
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return userProfile().latestBookmarkList?.privateTaggedEvents(keyPair.privKey!!)
|
return if (note is AddressableNote) {
|
||||||
?.contains(note.idHex) == true
|
userProfile().latestBookmarkList?.privateTaggedAddresses(keyPair.privKey!!)
|
||||||
|
?.contains(note.address) == true
|
||||||
|
} else {
|
||||||
|
userProfile().latestBookmarkList?.privateTaggedEvents(keyPair.privKey!!)
|
||||||
|
?.contains(note.idHex) == true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,10 +4,10 @@ import android.util.Log
|
|||||||
import androidx.compose.runtime.Stable
|
import androidx.compose.runtime.Stable
|
||||||
import com.vitorpamplona.amethyst.Amethyst
|
import com.vitorpamplona.amethyst.Amethyst
|
||||||
import com.vitorpamplona.amethyst.LocalPreferences
|
import com.vitorpamplona.amethyst.LocalPreferences
|
||||||
|
import com.vitorpamplona.amethyst.service.AmberUtils
|
||||||
import com.vitorpamplona.amethyst.service.checkNotInMainThread
|
import com.vitorpamplona.amethyst.service.checkNotInMainThread
|
||||||
import com.vitorpamplona.amethyst.service.relays.Relay
|
import com.vitorpamplona.amethyst.service.relays.Relay
|
||||||
import com.vitorpamplona.amethyst.ui.components.BundledInsert
|
import com.vitorpamplona.amethyst.ui.components.BundledInsert
|
||||||
import com.vitorpamplona.amethyst.ui.dal.BookmarkPrivateFeedFilter
|
|
||||||
import com.vitorpamplona.quartz.encoders.ATag
|
import com.vitorpamplona.quartz.encoders.ATag
|
||||||
import com.vitorpamplona.quartz.encoders.Hex
|
import com.vitorpamplona.quartz.encoders.Hex
|
||||||
import com.vitorpamplona.quartz.encoders.HexKey
|
import com.vitorpamplona.quartz.encoders.HexKey
|
||||||
@ -207,7 +207,7 @@ object LocalCache {
|
|||||||
if (hexKey != null) {
|
if (hexKey != null) {
|
||||||
val pubKey = Hex.encode(hexKey)
|
val pubKey = Hex.encode(hexKey)
|
||||||
if (pubKey == event.pubKey) {
|
if (pubKey == event.pubKey) {
|
||||||
BookmarkPrivateFeedFilter.content = ""
|
AmberUtils.content = ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
user.updateBookmark(event)
|
user.updateBookmark(event)
|
||||||
|
@ -0,0 +1,40 @@
|
|||||||
|
package com.vitorpamplona.amethyst.service
|
||||||
|
|
||||||
|
import com.vitorpamplona.amethyst.ui.actions.SignerType
|
||||||
|
import com.vitorpamplona.amethyst.ui.actions.openAmber
|
||||||
|
import com.vitorpamplona.quartz.encoders.HexKey
|
||||||
|
|
||||||
|
object AmberUtils {
|
||||||
|
var content: String = ""
|
||||||
|
var isActivityRunning: Boolean = false
|
||||||
|
|
||||||
|
fun decryptBookmark(encryptedContent: String, pubKey: HexKey) {
|
||||||
|
if (content.isBlank()) {
|
||||||
|
isActivityRunning = true
|
||||||
|
openAmber(
|
||||||
|
encryptedContent,
|
||||||
|
SignerType.NIP04_DECRYPT,
|
||||||
|
IntentUtils.decryptActivityResultLauncher,
|
||||||
|
pubKey
|
||||||
|
)
|
||||||
|
while (isActivityRunning) {
|
||||||
|
Thread.sleep(250)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun encryptBookmark(decryptedContent: String, pubKey: HexKey) {
|
||||||
|
if (content.isBlank()) {
|
||||||
|
isActivityRunning = true
|
||||||
|
openAmber(
|
||||||
|
decryptedContent,
|
||||||
|
SignerType.NIP04_ENCRYPT,
|
||||||
|
IntentUtils.decryptActivityResultLauncher,
|
||||||
|
pubKey
|
||||||
|
)
|
||||||
|
while (isActivityRunning) {
|
||||||
|
Thread.sleep(250)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -25,6 +25,7 @@ import androidx.lifecycle.viewmodel.compose.viewModel
|
|||||||
import com.vitorpamplona.amethyst.Amethyst
|
import com.vitorpamplona.amethyst.Amethyst
|
||||||
import com.vitorpamplona.amethyst.LocalPreferences
|
import com.vitorpamplona.amethyst.LocalPreferences
|
||||||
import com.vitorpamplona.amethyst.ServiceManager
|
import com.vitorpamplona.amethyst.ServiceManager
|
||||||
|
import com.vitorpamplona.amethyst.service.AmberUtils
|
||||||
import com.vitorpamplona.amethyst.service.IntentUtils
|
import com.vitorpamplona.amethyst.service.IntentUtils
|
||||||
import com.vitorpamplona.amethyst.service.connectivitystatus.ConnectivityStatus
|
import com.vitorpamplona.amethyst.service.connectivitystatus.ConnectivityStatus
|
||||||
import com.vitorpamplona.amethyst.service.notifications.PushNotificationUtils
|
import com.vitorpamplona.amethyst.service.notifications.PushNotificationUtils
|
||||||
@ -32,7 +33,6 @@ import com.vitorpamplona.amethyst.service.notifications.RegisterAccounts
|
|||||||
import com.vitorpamplona.amethyst.service.relays.Client
|
import com.vitorpamplona.amethyst.service.relays.Client
|
||||||
import com.vitorpamplona.amethyst.ui.components.DefaultMutedSetting
|
import com.vitorpamplona.amethyst.ui.components.DefaultMutedSetting
|
||||||
import com.vitorpamplona.amethyst.ui.components.keepPlayingMutex
|
import com.vitorpamplona.amethyst.ui.components.keepPlayingMutex
|
||||||
import com.vitorpamplona.amethyst.ui.dal.BookmarkPrivateFeedFilter
|
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.Route
|
import com.vitorpamplona.amethyst.ui.navigation.Route
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.debugState
|
import com.vitorpamplona.amethyst.ui.navigation.debugState
|
||||||
import com.vitorpamplona.amethyst.ui.note.Nip47
|
import com.vitorpamplona.amethyst.ui.note.Nip47
|
||||||
@ -122,13 +122,13 @@ class MainActivity : AppCompatActivity() {
|
|||||||
Toast.LENGTH_SHORT
|
Toast.LENGTH_SHORT
|
||||||
).show()
|
).show()
|
||||||
}
|
}
|
||||||
BookmarkPrivateFeedFilter.isActivityRunning = false
|
AmberUtils.isActivityRunning = false
|
||||||
return@registerForActivityResult
|
return@registerForActivityResult
|
||||||
}
|
}
|
||||||
|
|
||||||
val event = it.data?.getStringExtra("signature") ?: ""
|
val event = it.data?.getStringExtra("signature") ?: ""
|
||||||
BookmarkPrivateFeedFilter.content = event
|
AmberUtils.content = event
|
||||||
BookmarkPrivateFeedFilter.isActivityRunning = false
|
AmberUtils.isActivityRunning = false
|
||||||
}
|
}
|
||||||
|
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
@ -3,15 +3,11 @@ package com.vitorpamplona.amethyst.ui.dal
|
|||||||
import com.vitorpamplona.amethyst.model.Account
|
import com.vitorpamplona.amethyst.model.Account
|
||||||
import com.vitorpamplona.amethyst.model.LocalCache
|
import com.vitorpamplona.amethyst.model.LocalCache
|
||||||
import com.vitorpamplona.amethyst.model.Note
|
import com.vitorpamplona.amethyst.model.Note
|
||||||
import com.vitorpamplona.amethyst.service.IntentUtils
|
import com.vitorpamplona.amethyst.service.AmberUtils
|
||||||
import com.vitorpamplona.amethyst.ui.actions.SignerType
|
|
||||||
import com.vitorpamplona.amethyst.ui.actions.openAmber
|
|
||||||
import com.vitorpamplona.quartz.encoders.toHexKey
|
import com.vitorpamplona.quartz.encoders.toHexKey
|
||||||
|
|
||||||
object BookmarkPrivateFeedFilter : FeedFilter<Note>() {
|
object BookmarkPrivateFeedFilter : FeedFilter<Note>() {
|
||||||
lateinit var account: Account
|
lateinit var account: Account
|
||||||
var content: String = ""
|
|
||||||
var isActivityRunning: Boolean = false
|
|
||||||
|
|
||||||
override fun feedKey(): String {
|
override fun feedKey(): String {
|
||||||
return account.userProfile().latestBookmarkList?.id ?: ""
|
return account.userProfile().latestBookmarkList?.id ?: ""
|
||||||
@ -21,22 +17,14 @@ object BookmarkPrivateFeedFilter : FeedFilter<Note>() {
|
|||||||
val bookmarks = account.userProfile().latestBookmarkList
|
val bookmarks = account.userProfile().latestBookmarkList
|
||||||
|
|
||||||
if (account.loginWithAmber) {
|
if (account.loginWithAmber) {
|
||||||
if (content.isBlank()) {
|
if (AmberUtils.content.isBlank()) {
|
||||||
isActivityRunning = true
|
AmberUtils.decryptBookmark(bookmarks?.content ?: "", account.keyPair.pubKey.toHexKey())
|
||||||
openAmber(
|
bookmarks?.decryptedContent = AmberUtils.content
|
||||||
bookmarks?.content ?: "",
|
|
||||||
SignerType.NIP04_DECRYPT,
|
|
||||||
IntentUtils.decryptActivityResultLauncher,
|
|
||||||
account.keyPair.pubKey.toHexKey()
|
|
||||||
)
|
|
||||||
while (isActivityRunning) {
|
|
||||||
Thread.sleep(250)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val notes = bookmarks?.privateTaggedEvents(content)
|
val notes = bookmarks?.privateTaggedEvents(bookmarks.decryptedContent)
|
||||||
?.mapNotNull { LocalCache.checkGetOrCreateNote(it) } ?: emptyList()
|
?.mapNotNull { LocalCache.checkGetOrCreateNote(it) } ?: emptyList()
|
||||||
val addresses = bookmarks?.privateTaggedAddresses(content)
|
val addresses = bookmarks?.privateTaggedAddresses(bookmarks.decryptedContent)
|
||||||
?.map { LocalCache.getOrCreateAddressableNote(it) } ?: emptyList()
|
?.map { LocalCache.getOrCreateAddressableNote(it) } ?: emptyList()
|
||||||
|
|
||||||
return notes.plus(addresses).toSet()
|
return notes.plus(addresses).toSet()
|
||||||
|
@ -41,13 +41,19 @@ import androidx.core.content.ContextCompat
|
|||||||
import androidx.lifecycle.distinctUntilChanged
|
import androidx.lifecycle.distinctUntilChanged
|
||||||
import androidx.lifecycle.map
|
import androidx.lifecycle.map
|
||||||
import com.vitorpamplona.amethyst.R
|
import com.vitorpamplona.amethyst.R
|
||||||
|
import com.vitorpamplona.amethyst.model.LocalCache
|
||||||
import com.vitorpamplona.amethyst.model.Note
|
import com.vitorpamplona.amethyst.model.Note
|
||||||
import com.vitorpamplona.amethyst.model.User
|
import com.vitorpamplona.amethyst.model.User
|
||||||
|
import com.vitorpamplona.amethyst.service.AmberUtils
|
||||||
|
import com.vitorpamplona.amethyst.service.relays.Client
|
||||||
|
import com.vitorpamplona.amethyst.ui.actions.SignerDialog
|
||||||
import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImage
|
import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImage
|
||||||
import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImageProxy
|
import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImageProxy
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.ReportNoteDialog
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.ReportNoteDialog
|
||||||
import com.vitorpamplona.quartz.encoders.HexKey
|
import com.vitorpamplona.quartz.encoders.HexKey
|
||||||
|
import com.vitorpamplona.quartz.encoders.toHexKey
|
||||||
|
import com.vitorpamplona.quartz.events.Event
|
||||||
import kotlinx.collections.immutable.ImmutableSet
|
import kotlinx.collections.immutable.ImmutableSet
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@ -390,6 +396,25 @@ fun NoteDropDownMenu(note: Note, popupExpanded: MutableState<Boolean>, accountVi
|
|||||||
|
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
|
|
||||||
|
var event by remember { mutableStateOf<Event?>(null) }
|
||||||
|
if (event != null) {
|
||||||
|
SignerDialog(
|
||||||
|
onClose = {
|
||||||
|
event = null
|
||||||
|
},
|
||||||
|
onPost = {
|
||||||
|
scope.launch(Dispatchers.IO) {
|
||||||
|
val signedEvent = Event.fromJson(it)
|
||||||
|
Client.send(signedEvent)
|
||||||
|
LocalCache.verifyAndConsume(signedEvent, null)
|
||||||
|
event = null
|
||||||
|
onDismiss()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data = event!!.toJson()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
if (!state.isFollowingAuthor) {
|
if (!state.isFollowingAuthor) {
|
||||||
DropdownMenuItem(onClick = {
|
DropdownMenuItem(onClick = {
|
||||||
accountViewModel.follow(
|
accountViewModel.follow(
|
||||||
@ -447,11 +472,47 @@ fun NoteDropDownMenu(note: Note, popupExpanded: MutableState<Boolean>, accountVi
|
|||||||
}
|
}
|
||||||
Divider()
|
Divider()
|
||||||
if (state.isPrivateBookmarkNote) {
|
if (state.isPrivateBookmarkNote) {
|
||||||
DropdownMenuItem(onClick = { scope.launch(Dispatchers.IO) { accountViewModel.removePrivateBookmark(note); onDismiss() } }) {
|
DropdownMenuItem(
|
||||||
|
onClick = {
|
||||||
|
scope.launch(Dispatchers.IO) {
|
||||||
|
if (accountViewModel.loggedInWithAmber()) {
|
||||||
|
val bookmarks = accountViewModel.userProfile().latestBookmarkList
|
||||||
|
AmberUtils.decryptBookmark(
|
||||||
|
bookmarks?.content ?: "",
|
||||||
|
accountViewModel.account.keyPair.pubKey.toHexKey()
|
||||||
|
)
|
||||||
|
bookmarks?.decryptedContent = AmberUtils.content
|
||||||
|
AmberUtils.content = ""
|
||||||
|
event = accountViewModel.removePrivateBookmark(note, bookmarks?.decryptedContent ?: "")
|
||||||
|
} else {
|
||||||
|
accountViewModel.removePrivateBookmark(note)
|
||||||
|
onDismiss()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
) {
|
||||||
Text(stringResource(R.string.remove_from_private_bookmarks))
|
Text(stringResource(R.string.remove_from_private_bookmarks))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
DropdownMenuItem(onClick = { scope.launch(Dispatchers.IO) { accountViewModel.addPrivateBookmark(note); onDismiss() } }) {
|
DropdownMenuItem(
|
||||||
|
onClick = {
|
||||||
|
scope.launch(Dispatchers.IO) {
|
||||||
|
if (accountViewModel.loggedInWithAmber()) {
|
||||||
|
val bookmarks = accountViewModel.userProfile().latestBookmarkList
|
||||||
|
AmberUtils.decryptBookmark(
|
||||||
|
bookmarks?.content ?: "",
|
||||||
|
accountViewModel.account.keyPair.pubKey.toHexKey()
|
||||||
|
)
|
||||||
|
bookmarks?.decryptedContent = AmberUtils.content
|
||||||
|
AmberUtils.content = ""
|
||||||
|
event = accountViewModel.addPrivateBookmark(note, bookmarks?.decryptedContent ?: "")
|
||||||
|
} else {
|
||||||
|
accountViewModel.addPrivateBookmark(note)
|
||||||
|
onDismiss()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
) {
|
||||||
Text(stringResource(R.string.add_to_private_bookmarks))
|
Text(stringResource(R.string.add_to_private_bookmarks))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ import com.vitorpamplona.amethyst.model.User
|
|||||||
import com.vitorpamplona.amethyst.model.UserState
|
import com.vitorpamplona.amethyst.model.UserState
|
||||||
import com.vitorpamplona.amethyst.service.lnurl.LightningAddressResolver
|
import com.vitorpamplona.amethyst.service.lnurl.LightningAddressResolver
|
||||||
import com.vitorpamplona.quartz.encoders.HexKey
|
import com.vitorpamplona.quartz.encoders.HexKey
|
||||||
|
import com.vitorpamplona.quartz.events.BookmarkListEvent
|
||||||
import com.vitorpamplona.quartz.events.DeletionEvent
|
import com.vitorpamplona.quartz.events.DeletionEvent
|
||||||
import com.vitorpamplona.quartz.events.Event
|
import com.vitorpamplona.quartz.events.Event
|
||||||
import com.vitorpamplona.quartz.events.GiftWrapEvent
|
import com.vitorpamplona.quartz.events.GiftWrapEvent
|
||||||
@ -231,10 +232,18 @@ class AccountViewModel(val account: Account) : ViewModel() {
|
|||||||
account.addPrivateBookmark(note)
|
account.addPrivateBookmark(note)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun addPrivateBookmark(note: Note, decryptedContent: String): BookmarkListEvent? {
|
||||||
|
return account.addPrivateBookmark(note, decryptedContent)
|
||||||
|
}
|
||||||
|
|
||||||
fun addPublicBookmark(note: Note) {
|
fun addPublicBookmark(note: Note) {
|
||||||
account.addPublicBookmark(note)
|
account.addPublicBookmark(note)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun removePrivateBookmark(note: Note, decryptedContent: String): BookmarkListEvent? {
|
||||||
|
return account.removePrivateBookmark(note, decryptedContent)
|
||||||
|
}
|
||||||
|
|
||||||
fun removePrivateBookmark(note: Note) {
|
fun removePrivateBookmark(note: Note) {
|
||||||
account.removePrivateBookmark(note)
|
account.removePrivateBookmark(note)
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ import androidx.compose.ui.res.stringResource
|
|||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
import com.vitorpamplona.amethyst.R
|
import com.vitorpamplona.amethyst.R
|
||||||
|
import com.vitorpamplona.amethyst.service.AmberUtils
|
||||||
import com.vitorpamplona.amethyst.ui.dal.BookmarkPrivateFeedFilter
|
import com.vitorpamplona.amethyst.ui.dal.BookmarkPrivateFeedFilter
|
||||||
import com.vitorpamplona.amethyst.ui.dal.BookmarkPublicFeedFilter
|
import com.vitorpamplona.amethyst.ui.dal.BookmarkPublicFeedFilter
|
||||||
import com.vitorpamplona.amethyst.ui.screen.NostrBookmarkPrivateFeedViewModel
|
import com.vitorpamplona.amethyst.ui.screen.NostrBookmarkPrivateFeedViewModel
|
||||||
@ -95,7 +96,7 @@ fun BookmarkListScreen(accountViewModel: AccountViewModel, nav: (String) -> Unit
|
|||||||
|
|
||||||
DisposableEffect(Unit) {
|
DisposableEffect(Unit) {
|
||||||
onDispose {
|
onDispose {
|
||||||
BookmarkPrivateFeedFilter.content = ""
|
AmberUtils.content = ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,9 +16,37 @@ class BookmarkListEvent(
|
|||||||
content: String,
|
content: String,
|
||||||
sig: HexKey
|
sig: HexKey
|
||||||
) : GeneralListEvent(id, pubKey, createdAt, kind, tags, content, sig) {
|
) : GeneralListEvent(id, pubKey, createdAt, kind, tags, content, sig) {
|
||||||
|
var decryptedContent = ""
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val kind = 30001
|
const val kind = 30001
|
||||||
|
|
||||||
|
fun create(
|
||||||
|
name: String = "",
|
||||||
|
events: List<String>? = null,
|
||||||
|
users: List<String>? = null,
|
||||||
|
addresses: List<ATag>? = null,
|
||||||
|
content: String,
|
||||||
|
pubKey: HexKey,
|
||||||
|
createdAt: Long = TimeUtils.now()
|
||||||
|
): BookmarkListEvent {
|
||||||
|
val tags = mutableListOf<List<String>>()
|
||||||
|
tags.add(listOf("d", name))
|
||||||
|
|
||||||
|
events?.forEach {
|
||||||
|
tags.add(listOf("e", it))
|
||||||
|
}
|
||||||
|
users?.forEach {
|
||||||
|
tags.add(listOf("p", it))
|
||||||
|
}
|
||||||
|
addresses?.forEach {
|
||||||
|
tags.add(listOf("a", it.toTag()))
|
||||||
|
}
|
||||||
|
|
||||||
|
val id = generateId(pubKey, createdAt, kind, tags, content)
|
||||||
|
return BookmarkListEvent(id.toHexKey(), pubKey, createdAt, tags, content, "")
|
||||||
|
}
|
||||||
|
|
||||||
fun create(
|
fun create(
|
||||||
name: String = "",
|
name: String = "",
|
||||||
|
|
||||||
|
@ -71,9 +71,11 @@ abstract class GeneralListEvent(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun privateTaggedUsers(privKey: ByteArray) = privateTags(privKey)?.filter { it.size > 1 && it[0] == "p" }?.map { it[1] }
|
fun privateTaggedUsers(privKey: ByteArray) = privateTags(privKey)?.filter { it.size > 1 && it[0] == "p" }?.map { it[1] }
|
||||||
|
fun privateTaggedUsers(content: String) = privateTags(content)?.filter { it.size > 1 && it[0] == "p" }?.map { it[1] }
|
||||||
fun privateHashtags(privKey: ByteArray) = privateTags(privKey)?.filter { it.size > 1 && it[0] == "t" }?.map { it[1] }
|
fun privateHashtags(privKey: ByteArray) = privateTags(privKey)?.filter { it.size > 1 && it[0] == "t" }?.map { it[1] }
|
||||||
|
fun privateHashtags(content: String) = privateTags(content)?.filter { it.size > 1 && it[0] == "t" }?.map { it[1] }
|
||||||
fun privateGeohashes(privKey: ByteArray) = privateTags(privKey)?.filter { it.size > 1 && it[0] == "g" }?.map { it[1] }
|
fun privateGeohashes(privKey: ByteArray) = privateTags(privKey)?.filter { it.size > 1 && it[0] == "g" }?.map { it[1] }
|
||||||
|
fun privateGeohashes(content: String) = privateTags(content)?.filter { it.size > 1 && it[0] == "g" }?.map { it[1] }
|
||||||
fun privateTaggedEvents(privKey: ByteArray) = privateTags(privKey)?.filter { it.size > 1 && it[0] == "e" }?.map { it[1] }
|
fun privateTaggedEvents(privKey: ByteArray) = privateTags(privKey)?.filter { it.size > 1 && it[0] == "e" }?.map { it[1] }
|
||||||
fun privateTaggedEvents(content: String) = privateTags(content)?.filter { it.size > 1 && it[0] == "e" }?.map { it[1] }
|
fun privateTaggedEvents(content: String) = privateTags(content)?.filter { it.size > 1 && it[0] == "e" }?.map { it[1] }
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user