diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/drawer/DrawerContent.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/drawer/DrawerContent.kt index c422a679a..cebcfd271 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/drawer/DrawerContent.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/drawer/DrawerContent.kt @@ -20,6 +20,7 @@ */ package com.vitorpamplona.amethyst.ui.navigation.drawer +import androidx.compose.animation.animateContentSize import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.background import androidx.compose.foundation.border @@ -58,6 +59,8 @@ import androidx.compose.material.icons.outlined.AccountBalanceWallet import androidx.compose.material.icons.outlined.CollectionsBookmark import androidx.compose.material.icons.outlined.Drafts import androidx.compose.material.icons.outlined.EmojiEmotions +import androidx.compose.material.icons.outlined.ExpandLess +import androidx.compose.material.icons.outlined.ExpandMore import androidx.compose.material.icons.outlined.GroupAdd import androidx.compose.material.icons.outlined.Groups import androidx.compose.material.icons.outlined.Language @@ -100,6 +103,7 @@ import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.input.KeyboardCapitalization import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.withLink +import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.lifecycle.compose.collectAsStateWithLifecycle @@ -116,14 +120,18 @@ import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUse import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserStatuses import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji import com.vitorpamplona.amethyst.ui.components.RobohashFallbackAsyncImage +import com.vitorpamplona.amethyst.ui.navigation.navs.EmptyNav import com.vitorpamplona.amethyst.ui.navigation.navs.INav import com.vitorpamplona.amethyst.ui.navigation.routes.Route import com.vitorpamplona.amethyst.ui.navigation.routes.routeFor import com.vitorpamplona.amethyst.ui.painterRes import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel +import com.vitorpamplona.amethyst.ui.screen.loggedIn.mockAccountViewModel import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.amethyst.ui.theme.DividerThickness import com.vitorpamplona.amethyst.ui.theme.DoubleHorzSpacer +import com.vitorpamplona.amethyst.ui.theme.DrawerSectionHeaderModifier +import com.vitorpamplona.amethyst.ui.theme.Font14SP import com.vitorpamplona.amethyst.ui.theme.Font18SP import com.vitorpamplona.amethyst.ui.theme.IconRowTextModifier import com.vitorpamplona.amethyst.ui.theme.Size20Modifier @@ -133,6 +141,7 @@ import com.vitorpamplona.amethyst.ui.theme.Size24Modifier import com.vitorpamplona.amethyst.ui.theme.Size26Modifier import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer import com.vitorpamplona.amethyst.ui.theme.TextStyleBottomNavBar +import com.vitorpamplona.amethyst.ui.theme.ThemeComparisonColumn import com.vitorpamplona.amethyst.ui.theme.Width16Space import com.vitorpamplona.amethyst.ui.theme.bannerModifier import com.vitorpamplona.amethyst.ui.theme.drawerSpacing @@ -538,179 +547,187 @@ fun ListContent( nav: INav, ) { Column(modifier) { - NavigationRow( - title = R.string.profile, - icon = Icons.Default.AccountCircle, - tint = MaterialTheme.colorScheme.primary, - nav = nav, - computeRoute = { - Route.Profile(accountViewModel.userProfile().pubkeyHex) - }, - ) - - NavigationRow( - title = R.string.my_lists, - icon = Icons.AutoMirrored.Filled.FormatListBulleted, - tint = MaterialTheme.colorScheme.onBackground, - nav = nav, - route = Route.Lists, - ) - - NavigationRow( - title = R.string.bookmarks, - icon = Icons.Outlined.CollectionsBookmark, - tint = MaterialTheme.colorScheme.onBackground, - nav = nav, - route = Route.BookmarkGroups, - ) - - NavigationRow( - title = R.string.manage_emoji_packs, - icon = Icons.Outlined.EmojiEmotions, - tint = MaterialTheme.colorScheme.onBackground, - nav = nav, - route = Route.EmojiPacks, - ) - - NavigationRow( - title = R.string.interest_sets_title, - icon = Icons.Outlined.Tag, - tint = MaterialTheme.colorScheme.onBackground, - nav = nav, - route = Route.InterestSets, - ) - - NavigationRow( - title = R.string.web_bookmarks, - icon = Icons.Outlined.Language, - tint = MaterialTheme.colorScheme.onBackground, - nav = nav, - route = Route.WebBookmarks, - ) - - NavigationRow( - title = R.string.drafts, - icon = Icons.Outlined.Drafts, - tint = MaterialTheme.colorScheme.onBackground, - nav = nav, - route = Route.Drafts, - ) - - NavigationRow( - title = R.string.badges, - icon = Icons.Outlined.MilitaryTech, - tint = MaterialTheme.colorScheme.onBackground, - nav = nav, - route = Route.Badges, - ) - - NavigationRow( - title = R.string.communities, - icon = Icons.Outlined.Groups, - tint = MaterialTheme.colorScheme.onBackground, - nav = nav, - route = Route.Communities, - ) - - NavigationRow( - title = R.string.discover_marketplace, - icon = Icons.Outlined.Storefront, - tint = MaterialTheme.colorScheme.onBackground, - nav = nav, - route = Route.Products, - ) - - NavigationRow( - title = R.string.pictures, - icon = Icons.Outlined.Photo, - tint = MaterialTheme.colorScheme.onBackground, - nav = nav, - route = Route.Pictures, - ) - - NavigationRow( - title = R.string.polls, - icon = R.drawable.ic_poll, - iconReference = 1, - tint = MaterialTheme.colorScheme.onBackground, - nav = nav, - route = Route.Polls, - ) - - NavigationRow( - title = R.string.discover_reads, - icon = Icons.AutoMirrored.Outlined.Article, - tint = MaterialTheme.colorScheme.onBackground, - nav = nav, - route = Route.Articles, - ) - - NavigationRow( - title = R.string.shorts, - icon = Icons.Outlined.PlayCircle, - tint = MaterialTheme.colorScheme.onBackground, - nav = nav, - route = Route.Shorts, - ) - - NavigationRow( - title = R.string.longs, - icon = Icons.Outlined.SmartDisplay, - tint = MaterialTheme.colorScheme.onBackground, - nav = nav, - route = Route.Longs, - ) - - NavigationRow( - title = R.string.wallet, - icon = Icons.Outlined.AccountBalanceWallet, - tint = MaterialTheme.colorScheme.onBackground, - nav = nav, - route = Route.Wallet, - ) - - NavigationRow( - title = R.string.emoji_sets, - icon = Icons.Outlined.EmojiEmotions, - tint = MaterialTheme.colorScheme.onBackground, - nav = nav, - route = Route.BrowseEmojiSets, - ) - - NavigationRow( - title = R.string.share_hls_video, - icon = Icons.Outlined.SettingsInputAntenna, - tint = MaterialTheme.colorScheme.onBackground, - nav = nav, - route = Route.NewHlsVideo, - ) - - if (isDebug) { + CollapsibleSection(title = R.string.drawer_section_you) { NavigationRow( - title = R.string.route_chess, - icon = R.drawable.ic_chess, - iconReference = 1, + title = R.string.profile, + icon = Icons.Default.AccountCircle, + tint = MaterialTheme.colorScheme.primary, + nav = nav, + computeRoute = { + Route.Profile(accountViewModel.userProfile().pubkeyHex) + }, + ) + + NavigationRow( + title = R.string.my_lists, + icon = Icons.AutoMirrored.Filled.FormatListBulleted, tint = MaterialTheme.colorScheme.onBackground, nav = nav, - route = Route.Chess, + route = Route.Lists, + ) + + NavigationRow( + title = R.string.bookmarks, + icon = Icons.Outlined.CollectionsBookmark, + tint = MaterialTheme.colorScheme.onBackground, + nav = nav, + route = Route.BookmarkGroups, + ) + + NavigationRow( + title = R.string.web_bookmarks, + icon = Icons.Outlined.Language, + tint = MaterialTheme.colorScheme.onBackground, + nav = nav, + route = Route.WebBookmarks, + ) + + NavigationRow( + title = R.string.drafts, + icon = Icons.Outlined.Drafts, + tint = MaterialTheme.colorScheme.onBackground, + nav = nav, + route = Route.Drafts, + ) + + NavigationRow( + title = R.string.interest_sets_title, + icon = Icons.Outlined.Tag, + tint = MaterialTheme.colorScheme.onBackground, + nav = nav, + route = Route.InterestSets, + ) + + NavigationRow( + title = R.string.manage_emoji_packs, + icon = Icons.Outlined.EmojiEmotions, + tint = MaterialTheme.colorScheme.onBackground, + nav = nav, + route = Route.EmojiPacks, + ) + + NavigationRow( + title = R.string.wallet, + icon = Icons.Outlined.AccountBalanceWallet, + tint = MaterialTheme.colorScheme.onBackground, + nav = nav, + route = Route.Wallet, ) } - IconRowRelays( - accountViewModel = accountViewModel, - onClick = { - nav.closeDrawer() - nav.nav(Route.EditRelays) - }, - ) + CollapsibleSection(title = R.string.drawer_section_feeds) { + NavigationRow( + title = R.string.communities, + icon = Icons.Outlined.Groups, + tint = MaterialTheme.colorScheme.onBackground, + nav = nav, + route = Route.Communities, + ) - NavigationRow( - title = R.string.settings, - icon = Icons.Outlined.Settings, - tint = MaterialTheme.colorScheme.onBackground, - nav = nav, - route = Route.AllSettings, - ) + NavigationRow( + title = R.string.discover_reads, + icon = Icons.AutoMirrored.Outlined.Article, + tint = MaterialTheme.colorScheme.onBackground, + nav = nav, + route = Route.Articles, + ) + + NavigationRow( + title = R.string.pictures, + icon = Icons.Outlined.Photo, + tint = MaterialTheme.colorScheme.onBackground, + nav = nav, + route = Route.Pictures, + ) + + NavigationRow( + title = R.string.shorts, + icon = Icons.Outlined.PlayCircle, + tint = MaterialTheme.colorScheme.onBackground, + nav = nav, + route = Route.Shorts, + ) + + NavigationRow( + title = R.string.longs, + icon = Icons.Outlined.SmartDisplay, + tint = MaterialTheme.colorScheme.onBackground, + nav = nav, + route = Route.Longs, + ) + + NavigationRow( + title = R.string.polls, + icon = R.drawable.ic_poll, + iconReference = 1, + tint = MaterialTheme.colorScheme.onBackground, + nav = nav, + route = Route.Polls, + ) + + NavigationRow( + title = R.string.badges, + icon = Icons.Outlined.MilitaryTech, + tint = MaterialTheme.colorScheme.onBackground, + nav = nav, + route = Route.Badges, + ) + + NavigationRow( + title = R.string.discover_marketplace, + icon = Icons.Outlined.Storefront, + tint = MaterialTheme.colorScheme.onBackground, + nav = nav, + route = Route.Products, + ) + + NavigationRow( + title = R.string.emoji_sets, + icon = Icons.Outlined.EmojiEmotions, + tint = MaterialTheme.colorScheme.onBackground, + nav = nav, + route = Route.BrowseEmojiSets, + ) + } + + CollapsibleSection(title = R.string.drawer_section_create) { + NavigationRow( + title = R.string.share_hls_video, + icon = Icons.Outlined.SettingsInputAntenna, + tint = MaterialTheme.colorScheme.onBackground, + nav = nav, + route = Route.NewHlsVideo, + ) + + if (isDebug) { + NavigationRow( + title = R.string.route_chess, + icon = R.drawable.ic_chess, + iconReference = 1, + tint = MaterialTheme.colorScheme.onBackground, + nav = nav, + route = Route.Chess, + ) + } + } + + CollapsibleSection(title = R.string.drawer_section_system) { + IconRowRelays( + accountViewModel = accountViewModel, + onClick = { + nav.closeDrawer() + nav.nav(Route.EditRelays) + }, + ) + + NavigationRow( + title = R.string.settings, + icon = Icons.Outlined.Settings, + tint = MaterialTheme.colorScheme.onBackground, + nav = nav, + route = Route.AllSettings, + ) + } Spacer(modifier = Modifier.weight(1f)) @@ -723,6 +740,40 @@ fun ListContent( } } +@Composable +fun CollapsibleSection( + title: Int, + content: @Composable () -> Unit, +) { + var expanded by remember { mutableStateOf(true) } + val sectionTitle = stringRes(title) + + Column(modifier = Modifier.animateContentSize()) { + Row( + modifier = DrawerSectionHeaderModifier.clickable { expanded = !expanded }, + verticalAlignment = Alignment.CenterVertically, + ) { + Text( + modifier = Modifier.weight(1f), + text = sectionTitle, + fontSize = Font14SP, + fontWeight = FontWeight.SemiBold, + color = MaterialTheme.colorScheme.onSurfaceVariant, + ) + Icon( + imageVector = if (expanded) Icons.Outlined.ExpandLess else Icons.Outlined.ExpandMore, + contentDescription = sectionTitle, + modifier = Size22Modifier, + tint = MaterialTheme.colorScheme.onSurfaceVariant, + ) + } + + if (expanded) { + content() + } + } +} + @Composable fun NavigationRow( title: Int, @@ -970,3 +1021,59 @@ fun BottomContent( } } } + +@Preview +@Composable +private fun CollapsibleSectionPreview() { + ThemeComparisonColumn { + Column { + CollapsibleSection(title = R.string.drawer_section_you) { + IconRow( + title = R.string.profile, + icon = Icons.Default.AccountCircle, + tint = MaterialTheme.colorScheme.primary, + onClick = {}, + ) + IconRow( + title = R.string.bookmarks, + icon = Icons.Outlined.CollectionsBookmark, + tint = MaterialTheme.colorScheme.onBackground, + onClick = {}, + ) + IconRow( + title = R.string.drafts, + icon = Icons.Outlined.Drafts, + tint = MaterialTheme.colorScheme.onBackground, + onClick = {}, + ) + } + CollapsibleSection(title = R.string.drawer_section_feeds) { + IconRow( + title = R.string.pictures, + icon = Icons.Outlined.Photo, + tint = MaterialTheme.colorScheme.onBackground, + onClick = {}, + ) + IconRow( + title = R.string.longs, + icon = Icons.Outlined.SmartDisplay, + tint = MaterialTheme.colorScheme.onBackground, + onClick = {}, + ) + } + } + } +} + +@Preview(widthDp = 320, heightDp = 1400) +@Composable +private fun ListContentPreview() { + ThemeComparisonColumn { + ListContent( + modifier = Modifier.fillMaxWidth(), + openSheet = {}, + accountViewModel = mockAccountViewModel(), + nav = EmptyNav(), + ) + } +} diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/theme/Shape.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/theme/Shape.kt index 3096570b8..940990b44 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/theme/Shape.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/theme/Shape.kt @@ -263,6 +263,7 @@ val drawerSpacing = Modifier.padding(top = Size10dp, start = Size25dp, end = Siz val IconRowTextModifier = Modifier.padding(start = 16.dp) val IconRowModifier = Modifier.fillMaxWidth().padding(vertical = 15.dp, horizontal = 25.dp) +val DrawerSectionHeaderModifier = Modifier.fillMaxWidth().padding(top = 12.dp, bottom = 4.dp, start = 25.dp, end = 15.dp) val Width16Space = Modifier.width(Size16dp) diff --git a/amethyst/src/main/res/values/strings.xml b/amethyst/src/main/res/values/strings.xml index 020f7908a..963970ed1 100644 --- a/amethyst/src/main/res/values/strings.xml +++ b/amethyst/src/main/res/values/strings.xml @@ -369,6 +369,10 @@ "<Unable to decrypt private message>\n\nYou were cited in a private/encrypted conversation between %1$s and %2$s." Add New Account Accounts + You + Feeds + Create + System Select Account Add New Account Active account