Support moving articles/posts from private to public and vice versa.

This commit is contained in:
KotlinGeekDev
2025-11-28 04:31:08 +01:00
parent 74193a006d
commit 194f57acc3
5 changed files with 90 additions and 7 deletions
@@ -43,6 +43,7 @@ fun RenderArticleList(
bookmarkGroupViewModel: BookmarkGroupViewModel, bookmarkGroupViewModel: BookmarkGroupViewModel,
pagerState: PagerState, pagerState: PagerState,
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
moveArticleBookmark: (articleAddress: Address, fromPrivate: Boolean) -> Unit,
deleteArticleBookmark: (articleAddress: Address, isPrivate: Boolean) -> Unit, deleteArticleBookmark: (articleAddress: Address, isPrivate: Boolean) -> Unit,
nav: INav, nav: INav,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
@@ -56,6 +57,10 @@ fun RenderArticleList(
ArticleList( ArticleList(
modifier = Modifier.fillMaxSize(), modifier = Modifier.fillMaxSize(),
articles = publicArticles, articles = publicArticles,
isArticleBookmarkPrivate = false,
onMoveBookmarkToPrivate = { articleAddress ->
moveArticleBookmark(articleAddress, false)
},
onDeleteArticleBookmark = { articleAddress -> onDeleteArticleBookmark = { articleAddress ->
deleteArticleBookmark(articleAddress, false) deleteArticleBookmark(articleAddress, false)
}, },
@@ -66,6 +71,10 @@ fun RenderArticleList(
ArticleList( ArticleList(
modifier = Modifier.fillMaxSize(), modifier = Modifier.fillMaxSize(),
articles = privateArticles, articles = privateArticles,
isArticleBookmarkPrivate = true,
onMoveBookmarkToPublic = { articleAddress ->
moveArticleBookmark(articleAddress, true)
},
onDeleteArticleBookmark = { articleAddress -> onDeleteArticleBookmark = { articleAddress ->
deleteArticleBookmark(articleAddress, true) deleteArticleBookmark(articleAddress, true)
}, },
@@ -80,6 +89,9 @@ fun RenderArticleList(
fun ArticleList( fun ArticleList(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
articles: List<AddressableNote>, articles: List<AddressableNote>,
isArticleBookmarkPrivate: Boolean,
onMoveBookmarkToPublic: (articleAddress: Address) -> Unit = {},
onMoveBookmarkToPrivate: (articleAddress: Address) -> Unit = {},
onDeleteArticleBookmark: (Address) -> Unit, onDeleteArticleBookmark: (Address) -> Unit,
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
nav: INav, nav: INav,
@@ -101,6 +113,9 @@ fun ArticleList(
moreOptions = { moreOptions = {
BookmarkGroupItemOptions( BookmarkGroupItemOptions(
baseNote = item, baseNote = item,
isBookmarkItemPrivate = isArticleBookmarkPrivate,
onMoveBookmarkToPublic = { onMoveBookmarkToPublic(item.address) },
onMoveBookmarkToPrivate = { onMoveBookmarkToPrivate(item.address) },
onDeleteBookmarkItem = { onDeleteBookmarkItem = {
onDeleteArticleBookmark(item.address) onDeleteArticleBookmark(item.address)
}, },
@@ -60,6 +60,9 @@ import kotlinx.coroutines.launch
@Composable @Composable
fun BookmarkGroupItemOptions( fun BookmarkGroupItemOptions(
baseNote: Note, baseNote: Note,
isBookmarkItemPrivate: Boolean,
onMoveBookmarkToPublic: () -> Unit,
onMoveBookmarkToPrivate: () -> Unit,
onDeleteBookmarkItem: () -> Unit, onDeleteBookmarkItem: () -> Unit,
editState: State<GenericLoadable<EditState>>? = null, editState: State<GenericLoadable<EditState>>? = null,
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
@@ -76,7 +79,10 @@ fun BookmarkGroupItemOptions(
if (popupExpanded.value) { if (popupExpanded.value) {
BookmarkGroupItemOptionsMenu( BookmarkGroupItemOptionsMenu(
note = baseNote, note = baseNote,
isBookmarkItemPrivate = isBookmarkItemPrivate,
onDismiss = { popupExpanded.value = false }, onDismiss = { popupExpanded.value = false },
onMoveBookmarkToPublic = onMoveBookmarkToPublic,
onMoveBookmarkToPrivate = onMoveBookmarkToPrivate,
onDeleteBookmarkItem = onDeleteBookmarkItem, onDeleteBookmarkItem = onDeleteBookmarkItem,
editState = editState, editState = editState,
accountViewModel = accountViewModel, accountViewModel = accountViewModel,
@@ -89,7 +95,10 @@ fun BookmarkGroupItemOptions(
@Composable @Composable
fun BookmarkGroupItemOptionsMenu( fun BookmarkGroupItemOptionsMenu(
note: Note, note: Note,
isBookmarkItemPrivate: Boolean,
onDismiss: () -> Unit, onDismiss: () -> Unit,
onMoveBookmarkToPublic: () -> Unit,
onMoveBookmarkToPrivate: () -> Unit,
onDeleteBookmarkItem: () -> Unit, onDeleteBookmarkItem: () -> Unit,
editState: State<GenericLoadable<EditState>>? = null, editState: State<GenericLoadable<EditState>>? = null,
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
@@ -149,6 +158,10 @@ fun BookmarkGroupItemOptionsMenu(
} }
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
DropdownMenuItem(
text = { Text(if (isBookmarkItemPrivate) "Move to Public" else "Move to Private") },
onClick = if (isBookmarkItemPrivate) onMoveBookmarkToPublic else onMoveBookmarkToPrivate,
)
DropdownMenuItem( DropdownMenuItem(
text = { Text(stringRes(R.string.bookmark_remove_action_label)) }, text = { Text(stringRes(R.string.bookmark_remove_action_label)) },
onClick = { onClick = {
@@ -156,11 +169,6 @@ fun BookmarkGroupItemOptionsMenu(
onDismiss() onDismiss()
}, },
) )
// TODO: Work on moving feature below
// DropdownMenuItem(
// text = { Text("Move to Public") },
// onClick =
// )
HorizontalDivider(thickness = DividerThickness) HorizontalDivider(thickness = DividerThickness)
if (!state.isFollowingAuthor) { if (!state.isFollowingAuthor) {
@@ -162,6 +162,15 @@ fun BookmarkGroupScreenView(
bookmarkGroupViewModel, bookmarkGroupViewModel,
pagerState, pagerState,
accountViewModel, accountViewModel,
movePostBookmark = { postId, isPrivate ->
accountViewModel.launchSigner {
bookmarkGroupViewModel.movePostBookmark(
groupIdentifier = bookmarkGroupViewModel.bookmarkGroupIdentifier,
postId = postId,
isCurrentlyPrivate = isPrivate,
)
}
},
deletePostBookmark = { postId, isPrivate -> deletePostBookmark = { postId, isPrivate ->
accountViewModel.launchSigner { accountViewModel.launchSigner {
bookmarkGroupViewModel.removePostBookmark( bookmarkGroupViewModel.removePostBookmark(
@@ -178,6 +187,15 @@ fun BookmarkGroupScreenView(
bookmarkGroupViewModel, bookmarkGroupViewModel,
pagerState, pagerState,
accountViewModel, accountViewModel,
moveArticleBookmark = { articleAddress, isPrivate ->
accountViewModel.launchSigner {
bookmarkGroupViewModel.moveArticleBookmark(
groupIdentifier = bookmarkGroupViewModel.bookmarkGroupIdentifier,
articleAddress = articleAddress,
isCurrentlyPrivate = isPrivate,
)
}
},
deleteArticleBookmark = { articleAddress, isPrivate -> deleteArticleBookmark = { articleAddress, isPrivate ->
accountViewModel.launchSigner { accountViewModel.launchSigner {
bookmarkGroupViewModel.removeArticleBookmark( bookmarkGroupViewModel.removeArticleBookmark(
@@ -29,6 +29,7 @@ import com.vitorpamplona.quartz.nip01Core.core.Address
import com.vitorpamplona.quartz.nip51Lists.bookmarkList.tags.AddressBookmark import com.vitorpamplona.quartz.nip51Lists.bookmarkList.tags.AddressBookmark
import com.vitorpamplona.quartz.nip51Lists.bookmarkList.tags.BookmarkIdTag import com.vitorpamplona.quartz.nip51Lists.bookmarkList.tags.BookmarkIdTag
import com.vitorpamplona.quartz.nip51Lists.bookmarkList.tags.EventBookmark import com.vitorpamplona.quartz.nip51Lists.bookmarkList.tags.EventBookmark
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.filterNotNull import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
@@ -69,8 +70,6 @@ class BookmarkGroupViewModel(
.map { group -> group.privateArticleBookmarks.map { account.cache.getOrCreateAddressableNote(it.address) } } .map { group -> group.privateArticleBookmarks.map { account.cache.getOrCreateAddressableNote(it.address) } }
.stateIn(viewModelScope, SharingStarted.Eagerly, emptyList()) .stateIn(viewModelScope, SharingStarted.Eagerly, emptyList())
// TODO: Add implementations for Hashtag and Link bookmarks
suspend fun deleteBookmarkGroup(groupIdentifier: String) { suspend fun deleteBookmarkGroup(groupIdentifier: String) {
account.labeledBookmarkLists.deleteBookmarkList(groupIdentifier, account) account.labeledBookmarkLists.deleteBookmarkList(groupIdentifier, account)
} }
@@ -88,6 +87,34 @@ class BookmarkGroupViewModel(
) )
} }
suspend fun movePostBookmark(
groupIdentifier: String = bookmarkGroupIdentifier,
postId: String,
isCurrentlyPrivate: Boolean,
) {
val eventBookmark = EventBookmark(postId)
moveBookmark(groupIdentifier, eventBookmark, isCurrentlyPrivate)
}
suspend fun moveArticleBookmark(
groupIdentifier: String = bookmarkGroupIdentifier,
articleAddress: Address,
isCurrentlyPrivate: Boolean,
) {
val eventBookmark = AddressBookmark(articleAddress)
moveBookmark(groupIdentifier, eventBookmark, isCurrentlyPrivate)
}
suspend fun moveBookmark(
groupIdentifier: String = bookmarkGroupIdentifier,
bookmark: BookmarkIdTag,
isCurrentlyPrivate: Boolean,
) {
removeBookmarkFromGroup(groupIdentifier, bookmark, isCurrentlyPrivate)
delay(1000L)
addBookmarkToGroup(groupIdentifier, bookmark, !isCurrentlyPrivate)
}
suspend fun removePostBookmark( suspend fun removePostBookmark(
groupIdentifier: String = bookmarkGroupIdentifier, groupIdentifier: String = bookmarkGroupIdentifier,
bookmarkPostId: String, bookmarkPostId: String,
@@ -42,6 +42,7 @@ fun RenderPostList(
bookmarkGroupViewModel: BookmarkGroupViewModel, bookmarkGroupViewModel: BookmarkGroupViewModel,
pagerState: PagerState, pagerState: PagerState,
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
movePostBookmark: (postId: String, fromPrivate: Boolean) -> Unit,
deletePostBookmark: (postId: String, isPrivate: Boolean) -> Unit, deletePostBookmark: (postId: String, isPrivate: Boolean) -> Unit,
nav: INav, nav: INav,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
@@ -55,6 +56,10 @@ fun RenderPostList(
PostList( PostList(
modifier = Modifier.fillMaxSize(), modifier = Modifier.fillMaxSize(),
posts = publicPosts, posts = publicPosts,
isPostBookmarkPrivate = false,
onMoveBookmarkToPrivate = { postId ->
movePostBookmark(postId, false)
},
onDeletePostBookmark = { postId -> onDeletePostBookmark = { postId ->
deletePostBookmark(postId, false) deletePostBookmark(postId, false)
}, },
@@ -65,6 +70,10 @@ fun RenderPostList(
PostList( PostList(
modifier = Modifier.fillMaxSize(), modifier = Modifier.fillMaxSize(),
posts = privatePosts, posts = privatePosts,
isPostBookmarkPrivate = true,
onMoveBookmarkToPublic = { postId ->
movePostBookmark(postId, true)
},
onDeletePostBookmark = { postId -> onDeletePostBookmark = { postId ->
deletePostBookmark(postId, true) deletePostBookmark(postId, true)
}, },
@@ -79,6 +88,9 @@ fun RenderPostList(
private fun PostList( private fun PostList(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
posts: List<Note>, posts: List<Note>,
isPostBookmarkPrivate: Boolean,
onMoveBookmarkToPublic: (postId: String) -> Unit = {},
onMoveBookmarkToPrivate: (postId: String) -> Unit = {},
onDeletePostBookmark: (postId: String) -> Unit, onDeletePostBookmark: (postId: String) -> Unit,
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
nav: INav, nav: INav,
@@ -100,6 +112,9 @@ private fun PostList(
moreOptions = { moreOptions = {
BookmarkGroupItemOptions( BookmarkGroupItemOptions(
baseNote = item, baseNote = item,
isBookmarkItemPrivate = isPostBookmarkPrivate,
onMoveBookmarkToPublic = { onMoveBookmarkToPublic(item.idHex) },
onMoveBookmarkToPrivate = { onMoveBookmarkToPrivate(item.idHex) },
onDeleteBookmarkItem = { onDeletePostBookmark(item.idHex) }, onDeleteBookmarkItem = { onDeletePostBookmark(item.idHex) },
accountViewModel = accountViewModel, accountViewModel = accountViewModel,
nav = nav, nav = nav,