Add stub for GeneralBookmarks tab. Use a different icon for representing private lists. Add dropdown menu for follow set component(for actions such as delete, rename, etc).

This commit is contained in:
KotlinGeekDev
2025-04-25 13:42:39 +01:00
parent 3a5e6dbe90
commit b52943a826
2 changed files with 116 additions and 25 deletions
@@ -38,6 +38,8 @@ import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.People import androidx.compose.material.icons.filled.People
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.FilterChip import androidx.compose.material3.FilterChip
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
@@ -49,7 +51,10 @@ import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
@@ -65,12 +70,14 @@ import androidx.lifecycle.compose.LocalLifecycleOwner
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
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.ui.components.ClickableBox
import com.vitorpamplona.amethyst.ui.feeds.FeedEmpty import com.vitorpamplona.amethyst.ui.feeds.FeedEmpty
import com.vitorpamplona.amethyst.ui.feeds.FeedError import com.vitorpamplona.amethyst.ui.feeds.FeedError
import com.vitorpamplona.amethyst.ui.feeds.LoadingFeed import com.vitorpamplona.amethyst.ui.feeds.LoadingFeed
import com.vitorpamplona.amethyst.ui.feeds.RefresheableBox import com.vitorpamplona.amethyst.ui.feeds.RefresheableBox
import com.vitorpamplona.amethyst.ui.navigation.INav import com.vitorpamplona.amethyst.ui.navigation.INav
import com.vitorpamplona.amethyst.ui.navigation.TopBarWithBackButton import com.vitorpamplona.amethyst.ui.navigation.TopBarWithBackButton
import com.vitorpamplona.amethyst.ui.note.VerticalDotsIcon
import com.vitorpamplona.amethyst.ui.screen.NostrUserListFeedViewModel import com.vitorpamplona.amethyst.ui.screen.NostrUserListFeedViewModel
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.screen.loggedIn.DisappearingScaffold import com.vitorpamplona.amethyst.ui.screen.loggedIn.DisappearingScaffold
@@ -148,7 +155,7 @@ fun CustomListsScreen(
nav: INav, nav: INav,
) { ) {
// val setsState by followSetsViewModel.feedContent.collectAsStateWithLifecycle() // val setsState by followSetsViewModel.feedContent.collectAsStateWithLifecycle()
val pagerState = rememberPagerState { 2 } val pagerState = rememberPagerState { 3 }
val coroutineScope = rememberCoroutineScope() val coroutineScope = rememberCoroutineScope()
DisappearingScaffold( DisappearingScaffold(
@@ -166,16 +173,24 @@ fun CustomListsScreen(
Tab( Tab(
selected = pagerState.currentPage == 0, selected = pagerState.currentPage == 0,
onClick = { coroutineScope.launch { pagerState.animateScrollToPage(0) } }, onClick = { coroutineScope.launch { pagerState.animateScrollToPage(0) } },
text = { Text(text = "Follow Sets") }, text = { Text(text = "Follow Sets", overflow = TextOverflow.Ellipsis, maxLines = 1) },
) )
Tab( Tab(
selected = pagerState.currentPage == 1, selected = pagerState.currentPage == 1,
onClick = { coroutineScope.launch { pagerState.animateScrollToPage(1) } }, onClick = { coroutineScope.launch { pagerState.animateScrollToPage(1) } },
text = { Text(text = "Labeled Bookmarks") }, text = { Text(text = "Labeled Bookmarks", overflow = TextOverflow.Ellipsis, maxLines = 1) },
)
Tab(
selected = pagerState.currentPage == 2,
onClick = { coroutineScope.launch { pagerState.animateScrollToPage(2) } },
text = { Text(text = "General Bookmarks", overflow = TextOverflow.Ellipsis, maxLines = 1) },
) )
} }
} }
}, },
floatingButton = {
// TODO: Add buttons for list creation and/or removal.
},
) { ) {
Column( Column(
Modifier Modifier
@@ -192,6 +207,7 @@ fun CustomListsScreen(
) )
1 -> LabeledBookmarksFeedView() 1 -> LabeledBookmarksFeedView()
2 -> GeneralBookmarksFeedView()
} }
} }
} }
@@ -244,6 +260,18 @@ fun LabeledBookmarksFeedView() {
} }
} }
@Composable
fun GeneralBookmarksFeedView() {
Column(
Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center,
) {
Text(text = "Not implemented yet.")
Spacer(modifier = StdVertSpacer)
}
}
@Composable @Composable
fun FollowListLoaded( fun FollowListLoaded(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
@@ -288,7 +316,7 @@ fun CustomListItem(
color = Color.Gray, color = Color.Gray,
shape = RoundedCornerShape(percent = 20), shape = RoundedCornerShape(percent = 20),
).padding(all = 12.dp), ).padding(all = 12.dp),
verticalAlignment = Alignment.CenterVertically, // verticalAlignment = Alignment.CenterVertically,
) { ) {
Column( Column(
modifier = modifier.weight(1f), modifier = modifier.weight(1f),
@@ -323,36 +351,98 @@ fun CustomListItem(
) )
} }
followSet.visibility.let { Row(
val text by derivedStateOf { verticalAlignment = Alignment.Top,
when (it) { horizontalArrangement = Arrangement.End,
ListVisibility.Public -> "Public" ) {
ListVisibility.Private -> "Private" followSet.visibility.let {
ListVisibility.Mixed -> "Mixed" val text by derivedStateOf {
when (it) {
ListVisibility.Public -> "Public"
ListVisibility.Private -> "Private"
ListVisibility.Mixed -> "Mixed"
}
}
Column(
modifier = modifier.padding(top = 15.dp),
verticalArrangement = Arrangement.Bottom,
horizontalAlignment = Alignment.CenterHorizontally,
) {
Icon(
painter =
painterResource(
when (it) {
ListVisibility.Public -> R.drawable.ic_public
ListVisibility.Private -> R.drawable.lock
ListVisibility.Mixed -> R.drawable.format_list_bulleted_type
},
),
contentDescription = "Icon for $text List",
)
Text(text, color = Color.Gray, fontWeight = FontWeight.Light)
} }
} }
Column( Column(
// modifier = modifier.weight(1f), verticalArrangement = Arrangement.Top,
verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.End,
horizontalAlignment = Alignment.CenterHorizontally,
) { ) {
Icon( ListOptionsButton(followSetName = followSet.title)
painter =
painterResource(
when (it) {
ListVisibility.Public -> R.drawable.ic_public
ListVisibility.Private -> R.drawable.incognito
ListVisibility.Mixed -> R.drawable.format_list_bulleted_type
},
),
contentDescription = "Icon for $text List",
)
Text(text, color = Color.Gray, fontWeight = FontWeight.Light)
} }
} }
} }
} }
@Composable
fun ListOptionsButton(
modifier: Modifier = Modifier,
followSetName: String,
) {
val isMenuOpen = remember { mutableStateOf(false) }
ClickableBox(
onClick = { isMenuOpen.value = true },
) {
VerticalDotsIcon()
ListOptionsMenu(
listName = followSetName,
isExpanded = isMenuOpen.value,
onDismiss = { isMenuOpen.value = false },
)
}
}
@Composable
fun ListOptionsMenu(
modifier: Modifier = Modifier,
isExpanded: Boolean,
listName: String,
onDismiss: () -> Unit,
) {
DropdownMenu(
expanded = isExpanded,
onDismissRequest = onDismiss,
) {
DropdownMenuItem(
text = {
Text(text = "Delete")
},
onClick = {
println("The list named $listName has been selected for deletion.")
},
)
DropdownMenuItem(
text = {
Text(text = "Rename list")
},
onClick = {
println("The list $listName should be renamed...")
},
)
}
}
@Preview(showSystemUi = true) @Preview(showSystemUi = true)
@Composable @Composable
private fun ListItemPreview() { private fun ListItemPreview() {
+1
View File
@@ -0,0 +1 @@
<!-- drawable/lock.xml --><vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:width="24dp" android:viewportWidth="24" android:viewportHeight="24"><path android:fillColor="#000000" android:pathData="M12,17A2,2 0 0,0 14,15C14,13.89 13.1,13 12,13A2,2 0 0,0 10,15A2,2 0 0,0 12,17M18,8A2,2 0 0,1 20,10V20A2,2 0 0,1 18,22H6A2,2 0 0,1 4,20V10C4,8.89 4.9,8 6,8H7V6A5,5 0 0,1 12,1A5,5 0 0,1 17,6V8H18M12,3A3,3 0 0,0 9,6V8H15V6A3,3 0 0,0 12,3Z" /></vector>