diff --git a/examples/llama.android/app/src/main/java/com/example/llama/MainActivity.kt b/examples/llama.android/app/src/main/java/com/example/llama/MainActivity.kt index b4242884e8..020a74665e 100644 --- a/examples/llama.android/app/src/main/java/com/example/llama/MainActivity.kt +++ b/examples/llama.android/app/src/main/java/com/example/llama/MainActivity.kt @@ -220,7 +220,9 @@ fun AppContent( modelsViewModel.resetPreselection() openDrawer() }, - onToggleMode = modelsViewModel::toggleMode, + onToggleManaging = if (hasModelsInstalled) { + { modelsViewModel.toggleMode(ModelScreenUiMode.MANAGING) } + } else null, ) ModelScreenUiMode.SEARCHING -> TopBarConfig.None() @@ -321,6 +323,7 @@ fun AppContent( toggleMenu = modelsViewModel::toggleFilterMenu ), importing = BottomBarConfig.Models.Managing.ImportConfig( + showTooltip = true, isMenuVisible = showImportModelMenu, toggleMenu = { show -> modelsManagementViewModel.toggleImportMenu(show) }, importFromLocal = { diff --git a/examples/llama.android/app/src/main/java/com/example/llama/ui/scaffold/AppScaffold.kt b/examples/llama.android/app/src/main/java/com/example/llama/ui/scaffold/AppScaffold.kt index 0c26e90c6e..3f24e2ad12 100644 --- a/examples/llama.android/app/src/main/java/com/example/llama/ui/scaffold/AppScaffold.kt +++ b/examples/llama.android/app/src/main/java/com/example/llama/ui/scaffold/AppScaffold.kt @@ -71,7 +71,7 @@ fun AppScaffold( is TopBarConfig.ModelsBrowsing -> ModelsBrowsingTopBar( title = topBarconfig.title, - onToggleMode = topBarconfig.onToggleMode, + onToggleManaging = topBarconfig.onToggleManaging, onNavigateBack = topBarconfig.navigationIcon.backAction, onMenuOpen = topBarconfig.navigationIcon.menuAction ) diff --git a/examples/llama.android/app/src/main/java/com/example/llama/ui/scaffold/bottombar/BottomBarConfig.kt b/examples/llama.android/app/src/main/java/com/example/llama/ui/scaffold/bottombar/BottomBarConfig.kt index b176799038..a1eb050805 100644 --- a/examples/llama.android/app/src/main/java/com/example/llama/ui/scaffold/bottombar/BottomBarConfig.kt +++ b/examples/llama.android/app/src/main/java/com/example/llama/ui/scaffold/bottombar/BottomBarConfig.kt @@ -72,6 +72,7 @@ sealed class BottomBarConfig { ) data class ImportConfig( + val showTooltip: Boolean, val isMenuVisible: Boolean, val toggleMenu: (Boolean) -> Unit, val importFromLocal: () -> Unit, diff --git a/examples/llama.android/app/src/main/java/com/example/llama/ui/scaffold/bottombar/ModelsManagementBottomBar.kt b/examples/llama.android/app/src/main/java/com/example/llama/ui/scaffold/bottombar/ModelsManagementBottomBar.kt index 44c4da521c..2e1003381f 100644 --- a/examples/llama.android/app/src/main/java/com/example/llama/ui/scaffold/bottombar/ModelsManagementBottomBar.kt +++ b/examples/llama.android/app/src/main/java/com/example/llama/ui/scaffold/bottombar/ModelsManagementBottomBar.kt @@ -15,14 +15,21 @@ import androidx.compose.material3.BottomAppBar import androidx.compose.material3.Checkbox import androidx.compose.material3.DropdownMenu import androidx.compose.material3.DropdownMenuItem +import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.FloatingActionButton import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.IconButtonDefaults import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.PlainTooltip import androidx.compose.material3.Text +import androidx.compose.material3.TooltipAnchorPosition +import androidx.compose.material3.TooltipBox +import androidx.compose.material3.TooltipDefaults +import androidx.compose.material3.rememberTooltipState import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.painterResource @@ -30,6 +37,7 @@ import androidx.compose.ui.unit.dp import com.example.llama.R import com.example.llama.data.model.ModelSortOrder +@OptIn(ExperimentalMaterial3Api::class) @Composable fun ModelsManagementBottomBar( isDeletionEnabled: Boolean, @@ -38,6 +46,14 @@ fun ModelsManagementBottomBar( filteringConfig: BottomBarConfig.Models.Managing.FilteringConfig, importingConfig: BottomBarConfig.Models.Managing.ImportConfig, ) { + val tooltipState = rememberTooltipState() + + LaunchedEffect(importingConfig) { + if (importingConfig.showTooltip && !importingConfig.isMenuVisible) { + tooltipState.show() + } + } + BottomAppBar( actions = { // Batch-deletion action @@ -162,13 +178,24 @@ fun ModelsManagementBottomBar( } }, floatingActionButton = { - FloatingActionButton( - onClick = { importingConfig.toggleMenu(true) }, + TooltipBox( + positionProvider = TooltipDefaults.rememberTooltipPositionProvider( + TooltipAnchorPosition.Above), + tooltip = { + PlainTooltip { + Text("Tap this button to install your first model!") + } + }, + state = tooltipState ) { - Icon( - imageVector = Icons.Default.Add, - contentDescription = "Add model" - ) + FloatingActionButton( + onClick = { importingConfig.toggleMenu(true) }, + ) { + Icon( + imageVector = Icons.Default.Add, + contentDescription = "Add model" + ) + } } // Add model dropdown menu @@ -177,7 +204,7 @@ fun ModelsManagementBottomBar( onDismissRequest = { importingConfig.toggleMenu(false) } ) { DropdownMenuItem( - text = { Text("Import local model") }, + text = { Text("Import a local model") }, leadingIcon = { Icon( imageVector = Icons.Default.FolderOpen, diff --git a/examples/llama.android/app/src/main/java/com/example/llama/ui/scaffold/topbar/ModelsBrowsingTopBar.kt b/examples/llama.android/app/src/main/java/com/example/llama/ui/scaffold/topbar/ModelsBrowsingTopBar.kt index 5409595026..8d97eec061 100644 --- a/examples/llama.android/app/src/main/java/com/example/llama/ui/scaffold/topbar/ModelsBrowsingTopBar.kt +++ b/examples/llama.android/app/src/main/java/com/example/llama/ui/scaffold/topbar/ModelsBrowsingTopBar.kt @@ -18,13 +18,12 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp -import com.example.llama.viewmodel.ModelScreenUiMode @OptIn(ExperimentalMaterial3Api::class) @Composable fun ModelsBrowsingTopBar( title: String, - onToggleMode: (ModelScreenUiMode) -> Unit, + onToggleManaging: (() -> Unit)? = null, onNavigateBack: (() -> Unit)? = null, onMenuOpen: (() -> Unit)? = null, ) { @@ -52,9 +51,9 @@ fun ModelsBrowsingTopBar( } }, actions = { - ModelManageActionToggle(onToggleManageMode = { - onToggleMode(ModelScreenUiMode.MANAGING) - }) + onToggleManaging?.let { + ModelManageActionToggle(it) + } }, colors = TopAppBarDefaults.topAppBarColors( containerColor = MaterialTheme.colorScheme.surface, @@ -65,11 +64,11 @@ fun ModelsBrowsingTopBar( @Composable private fun ModelManageActionToggle( - onToggleManageMode: () -> Unit, + onToggleManaging: () -> Unit, ) { FilledTonalButton( modifier = Modifier.padding(end = 12.dp), - onClick = onToggleManageMode + onClick = onToggleManaging ) { Row(verticalAlignment = Alignment.CenterVertically) { Icon( diff --git a/examples/llama.android/app/src/main/java/com/example/llama/ui/scaffold/topbar/TopBarConfig.kt b/examples/llama.android/app/src/main/java/com/example/llama/ui/scaffold/topbar/TopBarConfig.kt index d9076460fd..2f07fc5773 100644 --- a/examples/llama.android/app/src/main/java/com/example/llama/ui/scaffold/topbar/TopBarConfig.kt +++ b/examples/llama.android/app/src/main/java/com/example/llama/ui/scaffold/topbar/TopBarConfig.kt @@ -3,7 +3,6 @@ package com.example.llama.ui.scaffold.topbar import com.example.llama.monitoring.MemoryMetrics import com.example.llama.monitoring.StorageMetrics import com.example.llama.monitoring.TemperatureMetrics -import com.example.llama.ui.scaffold.ScaffoldEvent import com.example.llama.viewmodel.ModelScreenUiMode /** @@ -29,7 +28,7 @@ sealed class TopBarConfig { data class ModelsBrowsing( override val title: String, override val navigationIcon: NavigationIcon, - val onToggleMode: (ModelScreenUiMode) -> Unit, + val onToggleManaging: (() -> Unit)?, ) : TopBarConfig() // Model batch-deletion top bar with a toggle to turn on/off manage mode diff --git a/examples/llama.android/app/src/main/java/com/example/llama/ui/screens/ModelsManagementAndDeletingScreen.kt b/examples/llama.android/app/src/main/java/com/example/llama/ui/screens/ModelsManagementAndDeletingScreen.kt index 61897a6abd..5f2a411206 100644 --- a/examples/llama.android/app/src/main/java/com/example/llama/ui/screens/ModelsManagementAndDeletingScreen.kt +++ b/examples/llama.android/app/src/main/java/com/example/llama/ui/screens/ModelsManagementAndDeletingScreen.kt @@ -25,7 +25,7 @@ import androidx.compose.material.icons.filled.Attribution import androidx.compose.material.icons.filled.Download import androidx.compose.material.icons.filled.Error import androidx.compose.material.icons.filled.Favorite -import androidx.compose.material.icons.filled.FolderOpen +import androidx.compose.material.icons.filled.Info import androidx.compose.material.icons.filled.Today import androidx.compose.material3.AlertDialog import androidx.compose.material3.Card @@ -108,17 +108,22 @@ fun ModelsManagementAndDeletingScreen( if (filteredModels == null) { ModelsLoadingInProgressView() } else if (filteredModels.isEmpty()) { - // Import model prompt + // Prompt the user to import a model val title = when (activeFiltersCount) { - 0 -> "Tap the \"+\" button\n to install a model" + 0 -> "Import or download,\n have it your way" 1 -> "No models match\n the selected filter" else -> "No models match\n the selected filters" } + + val message = "If you already have GGUF models on your computer, " + + "please transfer it onto your device, and then select \"Import a local model\".\n\n" + + "Otherwise, select \"Download from HuggingFace\" and pick one you like." + InfoView( modifier = Modifier.fillMaxSize(0.9f).align(Alignment.Center), title = title, - icon = Icons.Default.FolderOpen, - message = "Import a local GGUF model file, or download directly from HuggingFace!", + icon = Icons.Default.Info, + message = message, action = InfoAction( label = "Learn More", icon = Icons.AutoMirrored.Default.Help,