Show a snackbar when import succeeded.

Also handle duplicated import better.
This commit is contained in:
Jing Jin 2025-04-19 19:57:58 -07:00
parent 604972fe23
commit d197f8e0fb
2 changed files with 32 additions and 6 deletions

View file

@ -54,6 +54,8 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.Scaffold
import androidx.compose.material3.SmallFloatingActionButton
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.rememberModalBottomSheetState
@ -71,6 +73,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.scale
import androidx.compose.ui.focus.focusModifier
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.layout.layout
@ -127,6 +130,8 @@ fun HomeScreen(
val selectedLocalModelFileUri = remember { mutableStateOf<Uri?>(null) }
val selectedImportedModelInfo = remember { mutableStateOf<ImportedModelInfo?>(null) }
val coroutineScope = rememberCoroutineScope()
val snackbarHostState = remember { SnackbarHostState() }
val scope = rememberCoroutineScope()
val tasks = uiState.tasks
val loadingHfModels = uiState.loadingHfModels
@ -173,12 +178,16 @@ fun HomeScreen(
}
}
) { innerPadding ->
TaskList(
tasks = tasks,
navigateToTaskScreen = navigateToTaskScreen,
modifier = Modifier.fillMaxSize(),
contentPadding = innerPadding,
)
Box(contentAlignment = Alignment.BottomCenter, modifier = Modifier.fillMaxSize()) {
TaskList(
tasks = tasks,
navigateToTaskScreen = navigateToTaskScreen,
modifier = Modifier.fillMaxSize(),
contentPadding = innerPadding,
)
SnackbarHost(hostState = snackbarHostState, modifier = Modifier.padding(bottom = 16.dp))
}
}
// Settings dialog.
@ -270,6 +279,11 @@ fun HomeScreen(
info = it,
)
showImportingDialog = false
// Show a snack bar for successful import.
scope.launch {
snackbarHostState.showSnackbar("✅ Model imported successfully")
}
})
}
}

View file

@ -424,6 +424,13 @@ open class ModelManagerViewModel(
fun addImportedLlmModel(task: Task, info: ImportedModelInfo) {
Log.d(TAG, "adding imported llm model: $info")
// Remove duplicated imported model if existed.
val modelIndex = task.models.indexOfFirst { info.fileName == it.name && it.imported }
if (modelIndex >= 0) {
Log.d(TAG, "duplicated imported model found in task. Removing it first")
task.models.removeAt(modelIndex)
}
// Create model.
val model = createModelFromImportedModelInfo(info = info, task = task)
task.models.add(model)
@ -451,6 +458,11 @@ open class ModelManagerViewModel(
// Add to preference storage.
val importedModels = dataStoreRepository.readImportedModels().toMutableList()
val importedModelIndex = importedModels.indexOfFirst { info.fileName == it.fileName }
if (importedModelIndex >= 0) {
Log.d(TAG, "duplicated imported model found in preference storage. Removing it first")
importedModels.removeAt(importedModelIndex)
}
importedModels.add(info)
dataStoreRepository.saveImportedModels(importedModels = importedModels)
}