diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/nip51Lists/labeledBookmarkLists/LabeledBookmarkList.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/nip51Lists/labeledBookmarkLists/LabeledBookmarkList.kt index b60e77fef..ac33fb0dd 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/nip51Lists/labeledBookmarkLists/LabeledBookmarkList.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/nip51Lists/labeledBookmarkLists/LabeledBookmarkList.kt @@ -21,7 +21,9 @@ package com.vitorpamplona.amethyst.model.nip51Lists.labeledBookmarkLists import androidx.compose.runtime.Stable +import com.vitorpamplona.quartz.nip51Lists.bookmarkList.tags.AddressBookmark import com.vitorpamplona.quartz.nip51Lists.bookmarkList.tags.BookmarkIdTag +import com.vitorpamplona.quartz.nip51Lists.bookmarkList.tags.EventBookmark @Stable data class LabeledBookmarkList( @@ -30,4 +32,12 @@ data class LabeledBookmarkList( val description: String?, val privateBookmarks: Set = emptySet(), val publicBookmarks: Set = emptySet(), -) +) { + // TODO: Add methods for LInk and Hashtag, after their implementation. + + val privatePostBookmarks = privateBookmarks.filter { it is EventBookmark }.map { bookmarkIdTag -> bookmarkIdTag as EventBookmark } + val publicPostBookmarks = publicBookmarks.filter { it is EventBookmark }.map { bookmarkIdTag -> bookmarkIdTag as EventBookmark } + + val privateArticleBookmarks = privateBookmarks.filter { it is AddressBookmark }.map { bookmarkIdTag -> bookmarkIdTag as AddressBookmark } + val publicArticleBookmarks = publicBookmarks.filter { it is AddressBookmark }.map { bookmarkIdTag -> bookmarkIdTag as AddressBookmark } +} diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/nip51Lists/labeledBookmarkLists/LabeledBookmarkListsState.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/nip51Lists/labeledBookmarkLists/LabeledBookmarkListsState.kt index bac6be565..6d980d63a 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/nip51Lists/labeledBookmarkLists/LabeledBookmarkListsState.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/nip51Lists/labeledBookmarkLists/LabeledBookmarkListsState.kt @@ -98,6 +98,11 @@ class LabeledBookmarkListsState( .flowOn(Dispatchers.IO) .stateIn(scope, SharingStarted.Eagerly, emptyList()) + fun List.getList(bookmarkListId: String) = + this.firstOrNull { + it.identifier == bookmarkListId + } + fun DeletionEvent.hasAnyDeletedBookmarkLists() = deleteAddressesWithKind(LabeledBookmarkListEvent.KIND) || deletesAnyEventIn(labeledBookmarkListEventIds.value) fun hasItemInNoteList(notes: Set): Boolean = @@ -130,11 +135,11 @@ class LabeledBookmarkListsState( fun getLabeledBookmarkListEvent(bookmarkIdentifier: String): LabeledBookmarkListEvent = getLabeledBookmarkListNote(bookmarkIdentifier)?.event as LabeledBookmarkListEvent fun getLabeledBookmarkListFlow(bookmarkIdentifier: String) = - labeledBookmarkListNotes - .map { getLabeledBookmarkListEvent(bookmarkIdentifier).toLabeledBookmarkList() } + listFeedFlow + .map { it.getList(bookmarkIdentifier) } .onStart { emit( - getLabeledBookmarkListEvent(bookmarkIdentifier).toLabeledBookmarkList(), + listFeedFlow.value.getList(bookmarkIdentifier), ) }.flowOn(Dispatchers.IO) @@ -204,21 +209,22 @@ class LabeledBookmarkListsState( } suspend fun deleteBookmarkList( - bookmarkList: LabeledBookmarkList, + bookmarkListIdentifier: String, account: Account, ) { - val listEvent = getLabeledBookmarkListEvent(bookmarkList.identifier) - val deletionEvent = account.signer.sign(DeletionEvent.build(listOf(listEvent))) + val listEvent = getLabeledBookmarkListEvent(bookmarkListIdentifier) + val deletionEventTemplate = DeletionEvent.build(listOf(listEvent)) + val deletionEvent = account.signer.sign(deletionEventTemplate) account.sendMyPublicAndPrivateOutbox(deletionEvent) } suspend fun addBookmarkToList( bookmark: BookmarkIdTag, - bookmarkList: LabeledBookmarkList, + bookmarkListIdentifier: String, isBookmarkPrivate: Boolean, account: Account, ) { - val currentBookmarkList = getLabeledBookmarkListEvent(bookmarkList.identifier) + val currentBookmarkList = getLabeledBookmarkListEvent(bookmarkListIdentifier) val updatedList = LabeledBookmarkListEvent.addBookmark( earlierVersion = currentBookmarkList, @@ -231,11 +237,11 @@ class LabeledBookmarkListsState( suspend fun removeBookmarkFromList( bookmark: BookmarkIdTag, - bookmarkList: LabeledBookmarkList, + bookmarkListIdentifier: String, isBookmarkPrivate: Boolean, account: Account, ) { - val currentBookmarkList = getLabeledBookmarkListEvent(bookmarkList.identifier) + val currentBookmarkList = getLabeledBookmarkListEvent(bookmarkListIdentifier) val updatedList = LabeledBookmarkListEvent.removeBookmark( earlierVersion = currentBookmarkList, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/display/BookmarkGroupViewModel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/display/BookmarkGroupViewModel.kt index e057dff93..a0cd966be 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/display/BookmarkGroupViewModel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/display/BookmarkGroupViewModel.kt @@ -25,6 +25,7 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.viewModelScope import com.vitorpamplona.amethyst.model.Account +import com.vitorpamplona.quartz.nip01Core.core.Address import com.vitorpamplona.quartz.nip51Lists.bookmarkList.tags.AddressBookmark import com.vitorpamplona.quartz.nip51Lists.bookmarkList.tags.BookmarkIdTag import com.vitorpamplona.quartz.nip51Lists.bookmarkList.tags.EventBookmark @@ -32,11 +33,12 @@ import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.filterNotNull import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn +import kotlin.collections.emptyList @Stable class BookmarkGroupViewModel( val account: Account, - bookmarkGroupIdentifier: String, + val bookmarkGroupIdentifier: String, ) : ViewModel() { val selectedBookmarkGroupFlow = account.labeledBookmarkLists @@ -46,75 +48,83 @@ class BookmarkGroupViewModel( fun publicPosts() = selectedBookmarkGroupFlow .filterNotNull() - .map { group -> - group.publicBookmarks - .filter { it is EventBookmark } - .map { account.cache.getOrCreateNote((it as EventBookmark).eventId) } - }.stateIn(viewModelScope, SharingStarted.Lazily, emptyList()) + .map { group -> group.publicPostBookmarks.map { account.cache.getOrCreateNote(it.eventId) } } + .stateIn(viewModelScope, SharingStarted.Eagerly, emptyList()) fun privatePosts() = selectedBookmarkGroupFlow .filterNotNull() - .map { group -> - group.privateBookmarks - .filter { it is EventBookmark } - .map { account.cache.getOrCreateNote((it as EventBookmark).eventId) } - }.stateIn(viewModelScope, SharingStarted.Lazily, emptyList()) + .map { group -> group.privatePostBookmarks.map { account.cache.getOrCreateNote(it.eventId) } } + .stateIn(viewModelScope, SharingStarted.Eagerly, emptyList()) fun publicArticles() = selectedBookmarkGroupFlow .filterNotNull() - .map { group -> - group.publicBookmarks - .filter { it is AddressBookmark } - .map { account.cache.getOrCreateAddressableNote((it as AddressBookmark).address) } - }.stateIn(viewModelScope, SharingStarted.Lazily, emptyList()) + .map { group -> group.publicArticleBookmarks.map { account.cache.getOrCreateAddressableNote(it.address) } } + .stateIn(viewModelScope, SharingStarted.Eagerly, emptyList()) fun privateArticles() = selectedBookmarkGroupFlow .filterNotNull() - .map { group -> - group.privateBookmarks - .filter { it is AddressBookmark } - .map { account.cache.getOrCreateAddressableNote((it as AddressBookmark).address) } - }.stateIn(viewModelScope, SharingStarted.Lazily, emptyList()) + .map { group -> group.privateArticleBookmarks.map { account.cache.getOrCreateAddressableNote(it.address) } } + .stateIn(viewModelScope, SharingStarted.Eagerly, emptyList()) // TODO: Add implementations for Hashtag and Link bookmarks - suspend fun deleteBookmarkGroup() { - selectedBookmarkGroupFlow.value?.let { - account.labeledBookmarkLists.deleteBookmarkList(it, account) - } + suspend fun deleteBookmarkGroup(groupIdentifier: String) { + account.labeledBookmarkLists.deleteBookmarkList(groupIdentifier, account) } suspend fun addBookmarkToGroup( + groupIdentifier: String = bookmarkGroupIdentifier, bookmark: BookmarkIdTag, isPrivate: Boolean, - account: Account, ) { - selectedBookmarkGroupFlow.value?.let { - account.labeledBookmarkLists.addBookmarkToList( - bookmark, - it, - isPrivate, - account, - ) - } + account.labeledBookmarkLists.addBookmarkToList( + bookmark, + groupIdentifier, + isPrivate, + account, + ) + } + + suspend fun removePostBookmark( + groupIdentifier: String = bookmarkGroupIdentifier, + bookmarkPostId: String, + isPrivate: Boolean, + ) { + val eventBookmark = EventBookmark(bookmarkPostId) + removeBookmarkFromGroup( + groupIdentifier, + eventBookmark, + isPrivate, + ) + } + + suspend fun removeArticleBookmark( + groupIdentifier: String = bookmarkGroupIdentifier, + bookmarkArticleAddress: Address, + isPrivate: Boolean, + ) { + val eventBookmark = AddressBookmark(bookmarkArticleAddress) + removeBookmarkFromGroup( + groupIdentifier, + eventBookmark, + isPrivate, + ) } suspend fun removeBookmarkFromGroup( + groupIdentifier: String = bookmarkGroupIdentifier, bookmark: BookmarkIdTag, isPrivate: Boolean, - account: Account, ) { - selectedBookmarkGroupFlow.value?.let { - account.labeledBookmarkLists.removeBookmarkFromList( - bookmark, - it, - isPrivate, - account, - ) - } + account.labeledBookmarkLists.removeBookmarkFromList( + bookmark, + groupIdentifier, + isPrivate, + account, + ) } class Initializer(