feat: configurable bottom navigation bar (Issue #23)

## What
Adds a new Navigation Bar section to Settings where users can customize which items appear in the bottom navigation bar.

## Features
- Pick from any of the 19 drawer screens (max 5 items)
- Remove items with a close/delete button
- Items persist via SharedPreferences (CSV format)
- Invalid names are silently dropped
- Existing screens and auth-aware filtering respected

Closes #23
This commit is contained in:
M57 authored and GitHub committed 2026-06-18 21:16:21 +03:00
1 parent 837678c590
commit 34df198c4d
6 files changed
+179 -18

No files matched your search

@@ -17,9 +17,11 @@ import androidx.navigation3.runtime.NavKey
object NavigationController {
var backStack: NavBackStack<NavKey>? = null
// Bottom-nav primary screens — tapping one clears the stack to root.
private val primaryScreens: Set<NavKey> =
setOf(
// Bottom-nav primary screens — dynamic, updated by Navigation.kt via
// updatePrimaryScreens() when the user customises the bottom nav bar.
// Default matches the default 5 bottom-nav items.
private val primaryScreens: MutableSet<NavKey> =
mutableSetOf(
ChatScreen,
SkillsScreen,
CronJobsScreen,
@@ -27,11 +29,21 @@ object NavigationController {
SettingsScreen,
)
/** Returns whether the given key is a primary (bottom-nav) screen. */
fun isPrimaryScreen(key: NavKey): Boolean = key in primaryScreens
/** Replace the primary screen set. Called by Navigation.kt when the
* bottom-nav item config changes. */
fun updatePrimaryScreens(keys: Set<NavKey>) {
primaryScreens.clear()
primaryScreens.addAll(keys)
}
fun navigateTo(key: NavKey) {
val stack = backStack ?: return
if (stack.lastOrNull() == key) return
if (key in primaryScreens) {
if (isPrimaryScreen(key)) {
stack.clear()
}
stack.add(key)