UI: combine TopBarConfig and BottomBarConfig into each route's ScaffoldConfig

This commit is contained in:
Han Yin 2025-04-17 18:38:44 -07:00
parent 225c5435c5
commit e269da655f
3 changed files with 86 additions and 76 deletions

View File

@ -40,6 +40,8 @@ import com.example.llama.revamp.ui.components.AnimatedNavHost
import com.example.llama.revamp.ui.components.AppNavigationDrawer
import com.example.llama.revamp.ui.components.AppScaffold
import com.example.llama.revamp.ui.components.BottomBarConfig
import com.example.llama.revamp.ui.components.NavigationIcon
import com.example.llama.revamp.ui.components.ScaffoldConfig
import com.example.llama.revamp.ui.components.ScaffoldEvent
import com.example.llama.revamp.ui.components.TopBarConfig
import com.example.llama.revamp.ui.components.UnloadModelConfirmationDialog
@ -147,66 +149,52 @@ fun AppContent(
val openDrawer: () -> Unit = { coroutineScope.launch { drawerState.open() } }
// Create scaffold's top & bottom bar configs based on current route
val topBarConfig = when (currentRoute) {
// (Home) Model selection screen
AppDestinations.MODEL_SELECTION_ROUTE -> {
TopBarConfig.Default(
val scaffoldConfig = when (currentRoute) {
// Model selection screen
AppDestinations.MODEL_SELECTION_ROUTE ->
ScaffoldConfig(
topBarConfig = TopBarConfig.Default(
title = "Models",
navigationIcon = TopBarConfig.NavigationIcon.Menu(openDrawer)
navigationIcon = NavigationIcon.Menu(openDrawer)
)
}
// Settings screen
AppDestinations.SETTINGS_GENERAL_ROUTE -> {
TopBarConfig.Default(
title = "Settings",
navigationIcon = TopBarConfig.NavigationIcon.Back { navigationActions.navigateUp() }
)
}
// Storage management screen
AppDestinations.MODELS_MANAGEMENT_ROUTE -> {
TopBarConfig.Storage(
title = "Models Management",
navigationIcon = TopBarConfig.NavigationIcon.Back { navigationActions.navigateUp() },
storageMetrics = storageMetrics
)
}
// Model loading screen
AppDestinations.MODEL_LOADING_ROUTE -> {
TopBarConfig.Performance(
AppDestinations.MODEL_LOADING_ROUTE ->
ScaffoldConfig(
topBarConfig = TopBarConfig.Performance(
title = "Load Model",
navigationIcon = TopBarConfig.NavigationIcon.Back(handleBackWithModelCheck),
navigationIcon = NavigationIcon.Back(handleBackWithModelCheck),
memoryMetrics = memoryUsage,
temperatureInfo = null
)
}
)
// Benchmark and Conversation screens
AppDestinations.BENCHMARK_ROUTE, AppDestinations.CONVERSATION_ROUTE -> {
TopBarConfig.Performance(
AppDestinations.BENCHMARK_ROUTE, AppDestinations.CONVERSATION_ROUTE ->
ScaffoldConfig(
topBarConfig = TopBarConfig.Performance(
title = when(currentRoute) {
AppDestinations.CONVERSATION_ROUTE -> "Chat"
AppDestinations.BENCHMARK_ROUTE -> "Benchmark"
else -> "LlamaAndroid"
},
navigationIcon = TopBarConfig.NavigationIcon.Back(handleBackWithModelCheck),
navigationIcon = NavigationIcon.Back(handleBackWithModelCheck),
memoryMetrics = memoryUsage,
temperatureInfo = Pair(temperatureInfo, useFahrenheit)
)
}
// Fallback for unknown routes
else -> {
TopBarConfig.Default(
title = "LlamaAndroid",
navigationIcon = TopBarConfig.NavigationIcon.None
)
}
}
val bottomBarConfig = when (currentRoute) {
// Settings screen
AppDestinations.SETTINGS_GENERAL_ROUTE ->
ScaffoldConfig(
topBarConfig = TopBarConfig.Default(
title = "Settings",
navigationIcon = NavigationIcon.Back { navigationActions.navigateUp() }
)
)
// Storage management screen
AppDestinations.MODELS_MANAGEMENT_ROUTE -> {
// Collect the needed states
val sortOrder by modelsManagementViewModel.sortOrder.collectAsState()
@ -220,11 +208,11 @@ fun AppContent(
contract = ActivityResultContracts.OpenDocument()
) { uri -> uri?.let { modelsManagementViewModel.localModelFileSelected(it) } }
BottomBarConfig.ModelsManagement(
val bottomBarConfig = BottomBarConfig.ModelsManagement(
sorting = BottomBarConfig.ModelsManagement.SortingConfig(
currentOrder = sortOrder,
isMenuVisible = showSortMenu,
toggleMenu = { show -> modelsManagementViewModel.toggleSortMenu(show) },
toggleMenu = { modelsManagementViewModel.toggleSortMenu(it) },
selectOrder = {
modelsManagementViewModel.setSortOrder(it)
modelsManagementViewModel.toggleSortMenu(false)
@ -235,9 +223,9 @@ fun AppContent(
),
selection = BottomBarConfig.ModelsManagement.SelectionConfig(
isActive = isMultiSelectionMode,
toggleMode = { enabled -> modelsManagementViewModel.toggleSelectionMode(enabled) },
toggleMode = { modelsManagementViewModel.toggleSelectionMode(it) },
selectedModels = selectedModels,
toggleAllSelection = { selectAll -> modelsManagementViewModel.toggleAllSelection(selectAll) },
toggleAllSelection = { modelsManagementViewModel.toggleAllSelection(it) },
deleteSelected = {
if (selectedModels.isNotEmpty()) {
modelsManagementViewModel.batchDeletionClicked(selectedModels)
@ -255,10 +243,23 @@ fun AppContent(
modelsManagementViewModel.importFromHuggingFace()
modelsManagementViewModel.toggleImportMenu(false)
}
)
)
ScaffoldConfig(
topBarConfig = TopBarConfig.Storage(
title = "Models Management",
navigationIcon = NavigationIcon.Back { navigationActions.navigateUp() },
storageMetrics = storageMetrics
),
bottomBarConfig = bottomBarConfig
)
}
else -> BottomBarConfig.None
// Fallback for empty screen or unknown routes
else -> ScaffoldConfig(
topBarConfig = TopBarConfig.Default(title = "", navigationIcon = NavigationIcon.None)
)
}
// Handle child screens' scaffold events
@ -309,8 +310,8 @@ fun AppContent(
) {
// The AppScaffold now uses the config we created
AppScaffold(
topBarconfig = topBarConfig,
bottomBarConfig = bottomBarConfig,
topBarconfig = scaffoldConfig.topBarConfig,
bottomBarConfig = scaffoldConfig.bottomBarConfig,
snackbarHostState = snackbarHostState,
) { paddingValues ->
// AnimatedNavHost inside the scaffold content

View File

@ -8,6 +8,13 @@ import androidx.compose.material3.SnackbarHostState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
/**
* Configuration of both [TopBarConfig] and [BottomBarConfig]
*/
data class ScaffoldConfig(
val topBarConfig: TopBarConfig,
val bottomBarConfig: BottomBarConfig = BottomBarConfig.None
)
/**
* Events called back from child screens
@ -38,8 +45,8 @@ fun AppScaffold(
title = topBarconfig.title,
memoryMetrics = topBarconfig.memoryMetrics,
temperatureDisplay = topBarconfig.temperatureInfo,
onNavigateBack = (topBarconfig.navigationIcon as? TopBarConfig.NavigationIcon.Back)?.onNavigateBack,
onMenuOpen = (topBarconfig.navigationIcon as? TopBarConfig.NavigationIcon.Menu)?.onMenuOpen
onNavigateBack = (topBarconfig.navigationIcon as? NavigationIcon.Back)?.onNavigateBack,
onMenuOpen = (topBarconfig.navigationIcon as? NavigationIcon.Menu)?.onMenuOpen
)
}
@ -47,15 +54,15 @@ fun AppScaffold(
StorageTopBar(
title = topBarconfig.title,
storageMetrics = topBarconfig.storageMetrics,
onNavigateBack = (topBarconfig.navigationIcon as? TopBarConfig.NavigationIcon.Back)?.onNavigateBack
onNavigateBack = (topBarconfig.navigationIcon as? NavigationIcon.Back)?.onNavigateBack
)
}
is TopBarConfig.Default -> {
DefaultTopBar(
title = topBarconfig.title,
onNavigateBack = (topBarconfig.navigationIcon as? TopBarConfig.NavigationIcon.Back)?.onNavigateBack,
onMenuOpen = (topBarconfig.navigationIcon as? TopBarConfig.NavigationIcon.Menu)?.onMenuOpen
onNavigateBack = (topBarconfig.navigationIcon as? NavigationIcon.Back)?.onNavigateBack,
onMenuOpen = (topBarconfig.navigationIcon as? NavigationIcon.Menu)?.onMenuOpen
)
}
}

View File

@ -35,7 +35,13 @@ sealed class TopBarConfig {
abstract val title: String
abstract val navigationIcon: NavigationIcon
// Data class for performance monitoring scaffolds
// Default/simple top bar with only a navigation icon
data class Default(
override val title: String,
override val navigationIcon: NavigationIcon
) : TopBarConfig()
// Performance monitoring top bar with RAM and optional temperature
data class Performance(
override val title: String,
override val navigationIcon: NavigationIcon,
@ -43,25 +49,21 @@ sealed class TopBarConfig {
val temperatureInfo: Pair<TemperatureMetrics, Boolean>?,
) : TopBarConfig()
// Data class for storage management scaffolds
// Storage management top bar with used & total storage
data class Storage(
override val title: String,
override val navigationIcon: NavigationIcon,
val storageMetrics: StorageMetrics?
) : TopBarConfig()
}
// Data class for default/simple scaffolds
data class Default(
override val title: String,
override val navigationIcon: NavigationIcon
) : TopBarConfig()
// Helper class for navigation icon configuration
sealed class NavigationIcon {
data class Menu(val onMenuOpen: () -> Unit) : NavigationIcon()
/**
* Helper class for navigation icon configuration
*/
sealed class NavigationIcon {
data class Back(val onNavigateBack: () -> Unit) : NavigationIcon()
data class Menu(val onMenuOpen: () -> Unit) : NavigationIcon()
object None : NavigationIcon()
}
}
@OptIn(ExperimentalMaterial3Api::class)