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:
+115
-25
@@ -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() {
|
||||||
|
|||||||
@@ -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>
|
||||||
Reference in New Issue
Block a user