diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppNavigation.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppNavigation.kt index 9948892b0..7447524e5 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppNavigation.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppNavigation.kt @@ -71,6 +71,7 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.bookmarkgroups.list.metadat import com.vitorpamplona.amethyst.ui.screen.loggedIn.bookmarkgroups.membershipManagement.ArticleBookmarkListManagementScreen import com.vitorpamplona.amethyst.ui.screen.loggedIn.bookmarkgroups.membershipManagement.PostBookmarkListManagementScreen import com.vitorpamplona.amethyst.ui.screen.loggedIn.bookmarkgroups.old.OldBookmarkListScreen +import com.vitorpamplona.amethyst.ui.screen.loggedIn.pinnednotes.PinnedNotesScreen import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.marmotGroup.AddMemberScreen import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.marmotGroup.CreateGroupScreen import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.marmotGroup.EditGroupInfoScreen @@ -258,6 +259,7 @@ fun BuildNavigation( composableFromEnd { OtsSettingsScreen(nav) } composableFromEnd { BookmarkListScreen(accountViewModel, nav) } composableFromEnd { OldBookmarkListScreen(accountViewModel, nav) } + composableFromEnd { PinnedNotesScreen(accountViewModel, nav) } composableFromEnd { WebBookmarksScreen(accountViewModel, nav) } composableFromEnd { DraftListScreen(accountViewModel, nav) } composableFromEnd { SettingsScreen(accountViewModel, nav) } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/routes/Routes.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/routes/Routes.kt index 149a41907..8c6f7c359 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/routes/Routes.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/routes/Routes.kt @@ -82,6 +82,8 @@ sealed class Route { @Serializable object OldBookmarks : Route() + @Serializable object PinnedNotes : Route() + @Serializable object BookmarkGroups : Route() @Serializable object ImportFollowsSelectUser : Route() diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/default/BookmarkListScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/default/BookmarkListScreen.kt index 7c0e3be39..7ee7752c3 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/default/BookmarkListScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/default/BookmarkListScreen.kt @@ -27,7 +27,7 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.pager.HorizontalPager import androidx.compose.foundation.pager.rememberPagerState import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.SecondaryScrollableTabRow +import androidx.compose.material3.SecondaryTabRow import androidx.compose.material3.Tab import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -38,7 +38,6 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.viewmodel.compose.viewModel import com.vitorpamplona.amethyst.R @@ -50,7 +49,6 @@ import com.vitorpamplona.amethyst.ui.screen.RefresheableFeedView import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.bookmarkgroups.default.dal.BookmarkPrivateFeedViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.bookmarkgroups.default.dal.BookmarkPublicFeedViewModel -import com.vitorpamplona.amethyst.ui.screen.loggedIn.bookmarkgroups.default.dal.PinnedNotesFeedViewModel import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.amethyst.ui.theme.TabRowHeight import kotlinx.coroutines.launch @@ -72,31 +70,18 @@ fun BookmarkListScreen( factory = BookmarkPrivateFeedViewModel.Factory(accountViewModel.account), ) - val pinnedNotesFeedViewModel: PinnedNotesFeedViewModel = - viewModel( - key = "NostrPinnedNotesFeedViewModel", - factory = PinnedNotesFeedViewModel.Factory(accountViewModel.account), - ) - val bookmarkState by accountViewModel.account.bookmarkState.bookmarks .collectAsStateWithLifecycle(null) - val pinState by accountViewModel.account.pinState.pinnedNotesList - .collectAsStateWithLifecycle(null) - LaunchedEffect(bookmarkState) { publicFeedViewModel.invalidateData() privateFeedViewModel.invalidateData() } - LaunchedEffect(pinState) { - pinnedNotesFeedViewModel.invalidateData() - } + // Preload all bookmarked events so they don't load one-by-one when scrolling + PreloadBookmarkEvents(bookmarkState, accountViewModel) - // Preload all bookmarked and pinned events so they don't load one-by-one when scrolling - PreloadBookmarkEvents(bookmarkState, pinState, accountViewModel) - - RenderBookmarkScreen(publicFeedViewModel, privateFeedViewModel, pinnedNotesFeedViewModel, accountViewModel, nav) + RenderBookmarkScreen(publicFeedViewModel, privateFeedViewModel, accountViewModel, nav) } @Composable @@ -104,11 +89,10 @@ fun BookmarkListScreen( private fun RenderBookmarkScreen( publicFeedViewModel: BookmarkPublicFeedViewModel, privateFeedViewModel: BookmarkPrivateFeedViewModel, - pinnedNotesFeedViewModel: PinnedNotesFeedViewModel, accountViewModel: AccountViewModel, nav: INav, ) { - val pagerState = rememberPagerState { 3 } + val pagerState = rememberPagerState { 2 } val coroutineScope = rememberCoroutineScope() DisappearingScaffold( @@ -116,11 +100,10 @@ private fun RenderBookmarkScreen( topBar = { Column { TopBarWithBackButton(stringRes(id = R.string.bookmarks_title), nav::popBack) - SecondaryScrollableTabRow( + SecondaryTabRow( containerColor = Color.Transparent, contentColor = MaterialTheme.colorScheme.onBackground, selectedTabIndex = pagerState.currentPage, - edgePadding = 8.dp, modifier = TabRowHeight, ) { Tab( @@ -133,11 +116,6 @@ private fun RenderBookmarkScreen( onClick = { coroutineScope.launch { pagerState.animateScrollToPage(1) } }, text = { Text(text = stringRes(R.string.public_bookmarks)) }, ) - Tab( - selected = pagerState.currentPage == 2, - onClick = { coroutineScope.launch { pagerState.animateScrollToPage(2) } }, - text = { Text(text = stringRes(R.string.pinned_notes)) }, - ) } } }, @@ -163,15 +141,6 @@ private fun RenderBookmarkScreen( nav = nav, ) } - - 2 -> { - RefresheableFeedView( - pinnedNotesFeedViewModel, - null, - accountViewModel = accountViewModel, - nav = nav, - ) - } } } } @@ -181,15 +150,14 @@ private fun RenderBookmarkScreen( @Composable private fun PreloadBookmarkEvents( bookmarkState: com.vitorpamplona.amethyst.commons.model.nip51Lists.BookmarkListState.BookmarkList?, - pinState: List?, accountViewModel: AccountViewModel, ) { val eventFinder = accountViewModel.dataSources().eventFinder val account = accountViewModel.account val queries = - remember(bookmarkState, pinState) { - val allNotes = (bookmarkState?.public.orEmpty() + bookmarkState?.private.orEmpty() + pinState.orEmpty()) + remember(bookmarkState) { + val allNotes = bookmarkState?.public.orEmpty() + bookmarkState?.private.orEmpty() allNotes .filter { it.event == null } .map { EventFinderQueryState(it, account) } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/list/ListOfBookmarkGroupsFeedView.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/list/ListOfBookmarkGroupsFeedView.kt index 2db79c105..bad0e79dc 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/list/ListOfBookmarkGroupsFeedView.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/list/ListOfBookmarkGroupsFeedView.kt @@ -31,6 +31,7 @@ import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.BookmarkBorder +import androidx.compose.material.icons.outlined.PushPin import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.ListItem @@ -44,6 +45,7 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.model.nip51Lists.BookmarkListState import com.vitorpamplona.amethyst.model.nip51Lists.OldBookmarkListState +import com.vitorpamplona.amethyst.model.nip51Lists.PinListState import com.vitorpamplona.amethyst.model.nip51Lists.labeledBookmarkLists.LabeledBookmarkList import com.vitorpamplona.amethyst.ui.screen.loggedIn.bookmarkgroups.BookmarkType import com.vitorpamplona.amethyst.ui.stringRes @@ -57,9 +59,11 @@ import kotlinx.coroutines.flow.StateFlow fun ListOfBookmarkGroupsFeedView( defaultBookmarks: BookmarkListState, oldBookmarks: OldBookmarkListState, + pinnedNotes: PinListState, groupListFeedSource: StateFlow>, openDefaultBookmarks: () -> Unit, openOldBookmarks: () -> Unit, + openPinnedNotes: () -> Unit, onOpenItem: (String, BookmarkType) -> Unit, onRenameItem: (targetBookmarkGroup: LabeledBookmarkList) -> Unit, onItemDescriptionChange: (bookmarkGroup: LabeledBookmarkList) -> Unit, @@ -82,6 +86,11 @@ fun ListOfBookmarkGroupsFeedView( HorizontalDivider(thickness = DividerThickness) } + item { + PinnedNotesList(pinnedNotes, openPinnedNotes) + HorizontalDivider(thickness = DividerThickness) + } + itemsIndexed( bookmarkGroupFeedState, key = { _: Int, item: LabeledBookmarkList -> item.identifier }, @@ -144,6 +153,50 @@ fun DefaultBookmarkList( ) } +@Composable +fun PinnedNotesList( + pinnedNotes: PinListState, + openPinnedNotes: () -> Unit, +) { + val pinState by pinnedNotes.pinnedNotesList.collectAsStateWithLifecycle() + + ListItem( + modifier = Modifier.clickable(onClick = openPinnedNotes), + headlineContent = { + Text(stringRes(R.string.pinned_notes), maxLines = 1, overflow = TextOverflow.Ellipsis) + }, + supportingContent = { + Column( + modifier = Modifier.fillMaxWidth(), + ) { + Text( + stringRes(R.string.pinned_notes_explainer), + overflow = TextOverflow.Ellipsis, + maxLines = 2, + ) + } + }, + leadingContent = { + Column( + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally, + ) { + Icon( + imageVector = Icons.Outlined.PushPin, + contentDescription = stringRes(R.string.bookmark_list_icon_label), + modifier = Size40Modifier, + ) + Spacer(StdVertSpacer) + BookmarkMembershipStatusAndNumberDisplay( + modifier = Modifier.align(Alignment.CenterHorizontally), + postBookmarksSize = pinState.size, + articleBookmarksSize = 0, + ) + } + }, + ) +} + @Composable fun OldBookmarkList( oldBookmarks: OldBookmarkListState, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/list/ListOfBookmarkGroupsScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/list/ListOfBookmarkGroupsScreen.kt index d4d4a67fa..e3486cb3b 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/list/ListOfBookmarkGroupsScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/list/ListOfBookmarkGroupsScreen.kt @@ -36,6 +36,7 @@ import androidx.compose.ui.Modifier import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.model.nip51Lists.BookmarkListState import com.vitorpamplona.amethyst.model.nip51Lists.OldBookmarkListState +import com.vitorpamplona.amethyst.model.nip51Lists.PinListState import com.vitorpamplona.amethyst.model.nip51Lists.labeledBookmarkLists.LabeledBookmarkList import com.vitorpamplona.amethyst.ui.navigation.navs.INav import com.vitorpamplona.amethyst.ui.navigation.routes.Route @@ -53,9 +54,11 @@ fun ListOfBookmarkGroupsScreen( ListOfBookmarkGroupsFeed( defaultBookmarks = accountViewModel.account.bookmarkState, oldBookmarks = accountViewModel.account.oldBookmarkState, + pinnedNotes = accountViewModel.account.pinState, listSource = accountViewModel.account.labeledBookmarkLists.listFeedFlow, openDefaultBookmarks = { nav.nav(Route.Bookmarks) }, openOldBookmarks = { nav.nav(Route.OldBookmarks) }, + openPinnedNotes = { nav.nav(Route.PinnedNotes) }, addBookmarkGroup = { nav.nav(Route.BookmarkGroupMetadataEdit()) }, openBookmarkGroup = { identifier, bookmarkType -> nav.nav(Route.BookmarkGroupView(identifier, bookmarkType)) @@ -92,9 +95,11 @@ fun ListOfBookmarkGroupsScreen( fun ListOfBookmarkGroupsFeed( defaultBookmarks: BookmarkListState, oldBookmarks: OldBookmarkListState, + pinnedNotes: PinListState, listSource: StateFlow>, openDefaultBookmarks: () -> Unit, openOldBookmarks: () -> Unit, + openPinnedNotes: () -> Unit, addBookmarkGroup: () -> Unit, openBookmarkGroup: (identifier: String, bookmarkType: BookmarkType) -> Unit, renameBookmarkGroup: (bookmarkGroup: LabeledBookmarkList) -> Unit, @@ -121,9 +126,11 @@ fun ListOfBookmarkGroupsFeed( ListOfBookmarkGroupsFeedView( defaultBookmarks = defaultBookmarks, oldBookmarks = oldBookmarks, + pinnedNotes = pinnedNotes, groupListFeedSource = listSource, openDefaultBookmarks = openDefaultBookmarks, openOldBookmarks = openOldBookmarks, + openPinnedNotes = openPinnedNotes, onOpenItem = openBookmarkGroup, onRenameItem = renameBookmarkGroup, onItemDescriptionChange = changeBookmarkGroupDescription, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/pinnednotes/PinnedNotesScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/pinnednotes/PinnedNotesScreen.kt new file mode 100644 index 000000000..97b1880d1 --- /dev/null +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/pinnednotes/PinnedNotesScreen.kt @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2025 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.amethyst.ui.screen.loggedIn.pinnednotes + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.runtime.DisposableEffect +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import androidx.lifecycle.viewmodel.compose.viewModel +import com.vitorpamplona.amethyst.R +import com.vitorpamplona.amethyst.model.Note +import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.EventFinderQueryState +import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold +import com.vitorpamplona.amethyst.ui.navigation.navs.INav +import com.vitorpamplona.amethyst.ui.navigation.topbars.TopBarWithBackButton +import com.vitorpamplona.amethyst.ui.screen.RefresheableFeedView +import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel +import com.vitorpamplona.amethyst.ui.screen.loggedIn.pinnednotes.dal.PinnedNotesFeedViewModel +import com.vitorpamplona.amethyst.ui.stringRes + +@Composable +fun PinnedNotesScreen( + accountViewModel: AccountViewModel, + nav: INav, +) { + val pinnedNotesFeedViewModel: PinnedNotesFeedViewModel = + viewModel( + key = "NostrPinnedNotesFeedViewModel", + factory = PinnedNotesFeedViewModel.Factory(accountViewModel.account), + ) + + val pinState by accountViewModel.account.pinState.pinnedNotesList + .collectAsStateWithLifecycle(null) + + LaunchedEffect(pinState) { + pinnedNotesFeedViewModel.invalidateData() + } + + // Preload all pinned events so they don't load one-by-one when scrolling + PreloadPinnedEvents(pinState, accountViewModel) + + RenderPinnedNotesScreen(pinnedNotesFeedViewModel, accountViewModel, nav) +} + +@Composable +private fun RenderPinnedNotesScreen( + pinnedNotesFeedViewModel: PinnedNotesFeedViewModel, + accountViewModel: AccountViewModel, + nav: INav, +) { + DisappearingScaffold( + isInvertedLayout = false, + topBar = { + TopBarWithBackButton(stringRes(id = R.string.pinned_notes), nav::popBack) + }, + accountViewModel = accountViewModel, + ) { + Column(Modifier.padding(it).fillMaxHeight()) { + RefresheableFeedView( + pinnedNotesFeedViewModel, + null, + accountViewModel = accountViewModel, + nav = nav, + ) + } + } +} + +@Composable +private fun PreloadPinnedEvents( + pinState: List?, + accountViewModel: AccountViewModel, +) { + val eventFinder = accountViewModel.dataSources().eventFinder + val account = accountViewModel.account + + val queries = + remember(pinState) { + pinState + .orEmpty() + .filter { it.event == null } + .map { EventFinderQueryState(it, account) } + } + + DisposableEffect(queries) { + eventFinder.subscribe(queries) + onDispose { + eventFinder.unsubscribe(queries) + } + } +} diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/default/dal/PinnedNotesFeedFilter.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/pinnednotes/dal/PinnedNotesFeedFilter.kt similarity index 95% rename from amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/default/dal/PinnedNotesFeedFilter.kt rename to amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/pinnednotes/dal/PinnedNotesFeedFilter.kt index b20c5492f..360a0f10c 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/default/dal/PinnedNotesFeedFilter.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/pinnednotes/dal/PinnedNotesFeedFilter.kt @@ -18,7 +18,7 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.amethyst.ui.screen.loggedIn.bookmarkgroups.default.dal +package com.vitorpamplona.amethyst.ui.screen.loggedIn.pinnednotes.dal import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.Note diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/default/dal/PinnedNotesFeedViewModel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/pinnednotes/dal/PinnedNotesFeedViewModel.kt similarity index 95% rename from amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/default/dal/PinnedNotesFeedViewModel.kt rename to amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/pinnednotes/dal/PinnedNotesFeedViewModel.kt index ec3a43466..ec26d217c 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/default/dal/PinnedNotesFeedViewModel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/pinnednotes/dal/PinnedNotesFeedViewModel.kt @@ -18,7 +18,7 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.amethyst.ui.screen.loggedIn.bookmarkgroups.default.dal +package com.vitorpamplona.amethyst.ui.screen.loggedIn.pinnednotes.dal import androidx.compose.runtime.Stable import androidx.lifecycle.ViewModel diff --git a/amethyst/src/main/res/values/strings.xml b/amethyst/src/main/res/values/strings.xml index 4fffe2ae2..7495f4203 100644 --- a/amethyst/src/main/res/values/strings.xml +++ b/amethyst/src/main/res/values/strings.xml @@ -429,6 +429,7 @@ Remove from Public Bookmarks Pinned Notes + Your pinned notes Pin to Profile Unpin from Profile