UI: allow drawer's gesture control only on Home and Settings screens; enable alert dialog on back navigation inside conversation and benchmark

This commit is contained in:
Han Yin 2025-04-11 21:23:26 -07:00
parent 648b97818e
commit 65c09b2b32
5 changed files with 20 additions and 36 deletions

View File

@ -3,12 +3,10 @@ package com.example.llama.revamp
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.OnBackPressedCallback
import androidx.activity.OnBackPressedDispatcher
import androidx.activity.compose.BackHandler
import androidx.activity.compose.LocalOnBackPressedDispatcherOwner
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.DrawerState
import androidx.compose.material3.DrawerValue
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
@ -39,8 +37,8 @@ import com.example.llama.revamp.ui.components.AppNavigationDrawer
import com.example.llama.revamp.ui.components.UnloadModelConfirmationDialog
import com.example.llama.revamp.ui.screens.BenchmarkScreen
import com.example.llama.revamp.ui.screens.ConversationScreen
import com.example.llama.revamp.ui.screens.ModelSelectionScreen
import com.example.llama.revamp.ui.screens.ModeSelectionScreen
import com.example.llama.revamp.ui.screens.ModelSelectionScreen
import com.example.llama.revamp.ui.screens.SettingsScreen
import com.example.llama.revamp.ui.screens.SettingsTab
import com.example.llama.revamp.ui.theme.LlamaTheme
@ -80,11 +78,7 @@ fun AppContent() {
val viewModel: MainViewModel = viewModel(factory = factory)
val engineState by viewModel.engineState.collectAsState()
// Track if model is loaded for gesture handling
val isModelLoaded = remember(engineState) {
viewModel.isModelLoaded()
}
val isModelLoaded = remember(engineState) { viewModel.isModelLoaded() }
val navigationActions = remember(navController) {
NavigationActions(navController)
@ -97,7 +91,21 @@ fun AppContent() {
// Get current route
val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentRoute by remember {
derivedStateOf { navBackStackEntry?.destination?.route }
derivedStateOf { navBackStackEntry?.destination?.route ?: "" }
}
// Determine if drawer gestures should be enabled based on route
val drawerGesturesEnabled by remember(currentRoute, drawerState.currentValue) {
derivedStateOf {
// Always allow gesture dismissal when drawer is open
if (drawerState.currentValue == DrawerValue.Open) {
true
} else {
// Only enable drawer opening by gesture on these screens
currentRoute == AppDestinations.MODEL_SELECTION_ROUTE ||
currentRoute.startsWith(AppDestinations.SETTINGS_ROUTE)
}
}
}
// Determine if current route requires model unloading
@ -172,7 +180,7 @@ fun AppContent() {
AppNavigationDrawer(
drawerState = drawerState,
navigationActions = navigationActions,
modelLoaded = isModelLoaded
gesturesEnabled = drawerGesturesEnabled
) {
NavHost(
navController = navController,

View File

@ -1,22 +1,17 @@
package com.example.llama.revamp.ui.components
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.DrawerState
import androidx.compose.material3.DrawerValue
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Surface
import androidx.compose.material3.rememberDrawerState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.lifecycle.viewmodel.compose.viewModel
import com.example.llama.revamp.data.preferences.UserPreferences

View File

@ -12,7 +12,6 @@ import androidx.compose.foundation.layout.width
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Home
import androidx.compose.material.icons.filled.Settings
import androidx.compose.material3.Divider
import androidx.compose.material3.DrawerState
import androidx.compose.material3.DrawerValue
import androidx.compose.material3.HorizontalDivider
@ -23,10 +22,6 @@ import androidx.compose.material3.ModalNavigationDrawer
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
@ -38,14 +33,13 @@ import kotlinx.coroutines.launch
/**
* App navigation drawer that provides access to different sections of the app.
* Gesture opening is disabled when a model is loaded to prevent accidental navigation,
* but gesture dismissal is always enabled.
* Gesture opening can be controlled based on current screen.
*/
@Composable
fun AppNavigationDrawer(
drawerState: DrawerState,
navigationActions: NavigationActions,
modelLoaded: Boolean = false,
gesturesEnabled: Boolean,
content: @Composable () -> Unit
) {
val coroutineScope = rememberCoroutineScope()
@ -54,15 +48,6 @@ fun AppNavigationDrawer(
// Calculate drawer width (60% of screen width)
val drawerWidth = (configuration.screenWidthDp * 0.6).dp
// Determine if gestures should be enabled
// Always enable when drawer is open (to allow dismissal)
// Only enable when model is not loaded (to prevent accidental opening)
val gesturesEnabled by remember(drawerState.currentValue, modelLoaded) {
derivedStateOf {
drawerState.currentValue == DrawerValue.Open || !modelLoaded
}
}
// Handle back button to close drawer if open
BackHandler(enabled = drawerState.currentValue == DrawerValue.Open) {
coroutineScope.launch {

View File

@ -14,20 +14,17 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.PlayArrow
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.Divider
import androidx.compose.material3.DrawerState
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import com.example.llama.revamp.data.model.ModelInfo
import com.example.llama.revamp.navigation.NavigationActions

View File

@ -5,7 +5,6 @@ import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import com.example.llama.revamp.data.model.ModelInfo
import com.example.llama.revamp.engine.InferenceEngine
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow