Render drawer Navigate/You/Feeds sections from NavBarCatalog
Previously the drawer hand-coded label + icon + route for every item, duplicating what NavBarCatalog already stored. Adding a new screen meant updating both files (and forgetting the catalog silently broke the bottom-bar settings, as happened with Polls). - Add POLLS to the catalog (was missing). - Add three ordered id lists in NavBarItem.kt: DrawerNavigateItems, DrawerYouItems, DrawerFeedsItems. Each drawer section iterates its list and looks each id up in NavBarCatalog. - Add CatalogSection + CatalogNavigationRow helpers in DrawerContent that render a NavBarItemDef using the existing NavigationRow overloads (Drawable vs Vector icon). - Profile keeps its primary-color tint via a special case inside CatalogSection (the only item with a non-default tint). - Create (Share HLS Video / Chess) and System (IconRowRelays + Settings) stay hand-coded: they contain non-catalog items or custom composables. Net: DrawerContent.kt shrinks by ~160 lines; adding a new drawer screen is now a single catalog entry plus one list membership.
This commit is contained in:
+48
@@ -73,6 +73,7 @@ enum class NavBarItem {
|
||||
FOLLOW_PACKS,
|
||||
LIVE_STREAMS,
|
||||
LONGS,
|
||||
POLLS,
|
||||
BADGES,
|
||||
PRODUCTS,
|
||||
EMOJI_SETS,
|
||||
@@ -246,6 +247,13 @@ val NavBarCatalog: Map<NavBarItem, NavBarItemDef> =
|
||||
icon = NavBarIcon.Vector(Icons.Outlined.SmartDisplay),
|
||||
resolveRoute = { Route.Longs },
|
||||
),
|
||||
NavBarItem.POLLS to
|
||||
NavBarItemDef(
|
||||
id = NavBarItem.POLLS,
|
||||
labelRes = R.string.polls,
|
||||
icon = NavBarIcon.Drawable(R.drawable.ic_poll, reference = 1),
|
||||
resolveRoute = { Route.Polls },
|
||||
),
|
||||
NavBarItem.BADGES to
|
||||
NavBarItemDef(
|
||||
id = NavBarItem.BADGES,
|
||||
@@ -284,3 +292,43 @@ val DefaultBottomBarItems: List<NavBarItem> =
|
||||
NavBarItem.DISCOVER,
|
||||
NavBarItem.NOTIFICATIONS,
|
||||
)
|
||||
|
||||
// Ordered membership lists for each drawer section. The drawer renders these by looking up
|
||||
// each id in NavBarCatalog, so adding a new screen only requires editing the catalog + the
|
||||
// matching section list below — not two separate files.
|
||||
val DrawerNavigateItems: List<NavBarItem> =
|
||||
listOf(
|
||||
NavBarItem.HOME,
|
||||
NavBarItem.MESSAGES,
|
||||
NavBarItem.VIDEO,
|
||||
NavBarItem.DISCOVER,
|
||||
NavBarItem.NOTIFICATIONS,
|
||||
)
|
||||
|
||||
val DrawerYouItems: List<NavBarItem> =
|
||||
listOf(
|
||||
NavBarItem.PROFILE,
|
||||
NavBarItem.MY_LISTS,
|
||||
NavBarItem.BOOKMARKS,
|
||||
NavBarItem.WEB_BOOKMARKS,
|
||||
NavBarItem.DRAFTS,
|
||||
NavBarItem.INTEREST_SETS,
|
||||
NavBarItem.EMOJI_PACKS,
|
||||
NavBarItem.WALLET,
|
||||
)
|
||||
|
||||
val DrawerFeedsItems: List<NavBarItem> =
|
||||
listOf(
|
||||
NavBarItem.COMMUNITIES,
|
||||
NavBarItem.ARTICLES,
|
||||
NavBarItem.PICTURES,
|
||||
NavBarItem.SHORTS,
|
||||
NavBarItem.PUBLIC_CHATS,
|
||||
NavBarItem.FOLLOW_PACKS,
|
||||
NavBarItem.LIVE_STREAMS,
|
||||
NavBarItem.LONGS,
|
||||
NavBarItem.POLLS,
|
||||
NavBarItem.BADGES,
|
||||
NavBarItem.PRODUCTS,
|
||||
NavBarItem.EMOJI_SETS,
|
||||
)
|
||||
|
||||
+68
-233
@@ -50,30 +50,17 @@ import androidx.compose.foundation.text.KeyboardActions
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.filled.FormatListBulleted
|
||||
import androidx.compose.material.icons.automirrored.filled.Send
|
||||
import androidx.compose.material.icons.automirrored.outlined.Article
|
||||
import androidx.compose.material.icons.automirrored.outlined.Chat
|
||||
import androidx.compose.material.icons.filled.AccountCircle
|
||||
import androidx.compose.material.icons.filled.Delete
|
||||
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
|
||||
import androidx.compose.material.icons.outlined.MilitaryTech
|
||||
import androidx.compose.material.icons.outlined.Photo
|
||||
import androidx.compose.material.icons.outlined.PlayCircle
|
||||
import androidx.compose.material.icons.outlined.Sensors
|
||||
import androidx.compose.material.icons.outlined.Settings
|
||||
import androidx.compose.material.icons.outlined.SettingsInputAntenna
|
||||
import androidx.compose.material.icons.outlined.SmartDisplay
|
||||
import androidx.compose.material.icons.outlined.Storefront
|
||||
import androidx.compose.material.icons.outlined.Tag
|
||||
import androidx.compose.material3.HorizontalDivider
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
@@ -122,6 +109,13 @@ 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.bottombars.DrawerFeedsItems
|
||||
import com.vitorpamplona.amethyst.ui.navigation.bottombars.DrawerNavigateItems
|
||||
import com.vitorpamplona.amethyst.ui.navigation.bottombars.DrawerYouItems
|
||||
import com.vitorpamplona.amethyst.ui.navigation.bottombars.NavBarCatalog
|
||||
import com.vitorpamplona.amethyst.ui.navigation.bottombars.NavBarIcon
|
||||
import com.vitorpamplona.amethyst.ui.navigation.bottombars.NavBarItem
|
||||
import com.vitorpamplona.amethyst.ui.navigation.bottombars.NavBarItemDef
|
||||
import com.vitorpamplona.amethyst.ui.navigation.navs.EmptyNav
|
||||
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
||||
import com.vitorpamplona.amethyst.ui.navigation.routes.Route
|
||||
@@ -549,219 +543,9 @@ fun ListContent(
|
||||
nav: INav,
|
||||
) {
|
||||
Column(modifier) {
|
||||
CollapsibleSection(title = R.string.drawer_section_navigate) {
|
||||
NavigationRow(
|
||||
title = R.string.route_home,
|
||||
icon = R.drawable.ic_home,
|
||||
iconReference = 0,
|
||||
tint = MaterialTheme.colorScheme.onBackground,
|
||||
nav = nav,
|
||||
route = Route.Home,
|
||||
)
|
||||
|
||||
NavigationRow(
|
||||
title = R.string.route_messages,
|
||||
icon = R.drawable.ic_dm,
|
||||
iconReference = 0,
|
||||
tint = MaterialTheme.colorScheme.onBackground,
|
||||
nav = nav,
|
||||
route = Route.Message,
|
||||
)
|
||||
|
||||
NavigationRow(
|
||||
title = R.string.route_video,
|
||||
icon = R.drawable.ic_video,
|
||||
iconReference = 0,
|
||||
tint = MaterialTheme.colorScheme.onBackground,
|
||||
nav = nav,
|
||||
route = Route.Video,
|
||||
)
|
||||
|
||||
NavigationRow(
|
||||
title = R.string.route_discover,
|
||||
icon = R.drawable.ic_sensors,
|
||||
iconReference = 0,
|
||||
tint = MaterialTheme.colorScheme.onBackground,
|
||||
nav = nav,
|
||||
route = Route.Discover,
|
||||
)
|
||||
|
||||
NavigationRow(
|
||||
title = R.string.route_notifications,
|
||||
icon = R.drawable.ic_notifications,
|
||||
iconReference = 0,
|
||||
tint = MaterialTheme.colorScheme.onBackground,
|
||||
nav = nav,
|
||||
computeRoute = { Route.Notification() },
|
||||
)
|
||||
}
|
||||
|
||||
CollapsibleSection(title = R.string.drawer_section_you) {
|
||||
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.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,
|
||||
)
|
||||
}
|
||||
|
||||
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.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.public_chats,
|
||||
icon = Icons.AutoMirrored.Outlined.Chat,
|
||||
tint = MaterialTheme.colorScheme.onBackground,
|
||||
nav = nav,
|
||||
route = Route.PublicChats,
|
||||
)
|
||||
|
||||
NavigationRow(
|
||||
title = R.string.follow_packs,
|
||||
icon = Icons.Outlined.CollectionsBookmark,
|
||||
tint = MaterialTheme.colorScheme.onBackground,
|
||||
nav = nav,
|
||||
route = Route.FollowPacks,
|
||||
)
|
||||
|
||||
NavigationRow(
|
||||
title = R.string.live_streams,
|
||||
icon = Icons.Outlined.Sensors,
|
||||
tint = MaterialTheme.colorScheme.onBackground,
|
||||
nav = nav,
|
||||
route = Route.LiveStreams,
|
||||
)
|
||||
|
||||
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,
|
||||
)
|
||||
}
|
||||
CatalogSection(R.string.drawer_section_navigate, DrawerNavigateItems, accountViewModel, nav)
|
||||
CatalogSection(R.string.drawer_section_you, DrawerYouItems, accountViewModel, nav)
|
||||
CatalogSection(R.string.drawer_section_feeds, DrawerFeedsItems, accountViewModel, nav)
|
||||
|
||||
CollapsibleSection(title = R.string.drawer_section_create) {
|
||||
NavigationRow(
|
||||
@@ -793,13 +577,9 @@ fun ListContent(
|
||||
},
|
||||
)
|
||||
|
||||
NavigationRow(
|
||||
title = R.string.settings,
|
||||
icon = Icons.Outlined.Settings,
|
||||
tint = MaterialTheme.colorScheme.onBackground,
|
||||
nav = nav,
|
||||
route = Route.AllSettings,
|
||||
)
|
||||
NavBarCatalog[NavBarItem.SETTINGS]?.let {
|
||||
CatalogNavigationRow(it, MaterialTheme.colorScheme.onBackground, accountViewModel, nav)
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
@@ -813,6 +593,61 @@ fun ListContent(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a drawer section by iterating [ids] and looking each one up in [NavBarCatalog].
|
||||
* Profile gets the primary-colored tint; every other item uses onBackground.
|
||||
*/
|
||||
@Composable
|
||||
fun CatalogSection(
|
||||
titleRes: Int,
|
||||
ids: List<NavBarItem>,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
val primary = MaterialTheme.colorScheme.primary
|
||||
val onBackground = MaterialTheme.colorScheme.onBackground
|
||||
|
||||
CollapsibleSection(title = titleRes) {
|
||||
ids.forEach { id ->
|
||||
NavBarCatalog[id]?.let { def ->
|
||||
val tint = if (def.id == NavBarItem.PROFILE) primary else onBackground
|
||||
CatalogNavigationRow(def, tint, accountViewModel, nav)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun CatalogNavigationRow(
|
||||
def: NavBarItemDef,
|
||||
tint: Color,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
when (val icon = def.icon) {
|
||||
is NavBarIcon.Drawable -> {
|
||||
NavigationRow(
|
||||
title = def.labelRes,
|
||||
icon = icon.resId,
|
||||
iconReference = icon.reference,
|
||||
tint = tint,
|
||||
nav = nav,
|
||||
computeRoute = { def.resolveRoute(accountViewModel) },
|
||||
)
|
||||
}
|
||||
|
||||
is NavBarIcon.Vector -> {
|
||||
NavigationRow(
|
||||
title = def.labelRes,
|
||||
icon = icon.vector,
|
||||
tint = tint,
|
||||
nav = nav,
|
||||
computeRoute = { def.resolveRoute(accountViewModel) },
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun CollapsibleSection(
|
||||
title: Int,
|
||||
|
||||
Reference in New Issue
Block a user