mirror of
https://github.com/google-ai-edge/gallery.git
synced 2025-07-06 14:40:36 -04:00
- Fix a bug where deleting a local model when there are >1 local models shows the wrong download status.
- Don't go back to model selection screen automatically when there is an error during model initialization, so that users have a chance to change model parameters (e.g. accelerator) to retry the initialization. - Show error dialog properly in prompt lab screen.
This commit is contained in:
parent
e53acf6065
commit
7d567c3499
6 changed files with 92 additions and 43 deletions
|
@ -30,7 +30,7 @@ android {
|
||||||
minSdk = 26
|
minSdk = 26
|
||||||
targetSdk = 35
|
targetSdk = 35
|
||||||
versionCode = 1
|
versionCode = 1
|
||||||
versionName = "0.9.3"
|
versionName = "0.9.4"
|
||||||
|
|
||||||
// Needed for HuggingFace auth workflows.
|
// Needed for HuggingFace auth workflows.
|
||||||
manifestPlaceholders["appAuthRedirectScheme"] = "com.google.aiedge.gallery.oauth"
|
manifestPlaceholders["appAuthRedirectScheme"] = "com.google.aiedge.gallery.oauth"
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2025 Google LLC
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.google.aiedge.gallery.ui.common
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.material3.Button
|
||||||
|
import androidx.compose.material3.Card
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.window.Dialog
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ErrorDialog(error: String, onDismiss: () -> Unit) {
|
||||||
|
Dialog(
|
||||||
|
onDismissRequest = onDismiss
|
||||||
|
) {
|
||||||
|
Card(modifier = Modifier.fillMaxWidth(), shape = RoundedCornerShape(16.dp)) {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier.padding(20.dp), verticalArrangement = Arrangement.spacedBy(16.dp)
|
||||||
|
) {
|
||||||
|
// Title
|
||||||
|
Text(
|
||||||
|
"Error",
|
||||||
|
style = MaterialTheme.typography.titleLarge,
|
||||||
|
modifier = Modifier.padding(bottom = 8.dp)
|
||||||
|
)
|
||||||
|
|
||||||
|
// Error
|
||||||
|
Text(
|
||||||
|
error,
|
||||||
|
style = MaterialTheme.typography.bodySmall,
|
||||||
|
color = MaterialTheme.colorScheme.error,
|
||||||
|
)
|
||||||
|
|
||||||
|
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.End) {
|
||||||
|
Button(
|
||||||
|
onClick = onDismiss
|
||||||
|
) {
|
||||||
|
Text("Close")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -43,14 +43,11 @@ import androidx.compose.foundation.layout.wrapContentWidth
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.items
|
import androidx.compose.foundation.lazy.items
|
||||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.outlined.Timer
|
import androidx.compose.material.icons.outlined.Timer
|
||||||
import androidx.compose.material.icons.rounded.Close
|
import androidx.compose.material.icons.rounded.Close
|
||||||
import androidx.compose.material.icons.rounded.ContentCopy
|
import androidx.compose.material.icons.rounded.ContentCopy
|
||||||
import androidx.compose.material.icons.rounded.Refresh
|
import androidx.compose.material.icons.rounded.Refresh
|
||||||
import androidx.compose.material3.Button
|
|
||||||
import androidx.compose.material3.Card
|
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
import androidx.compose.material3.IconButton
|
||||||
|
@ -97,11 +94,11 @@ import androidx.compose.ui.text.AnnotatedString
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.IntSize
|
import androidx.compose.ui.unit.IntSize
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.window.Dialog
|
|
||||||
import com.google.aiedge.gallery.R
|
import com.google.aiedge.gallery.R
|
||||||
import com.google.aiedge.gallery.data.Model
|
import com.google.aiedge.gallery.data.Model
|
||||||
import com.google.aiedge.gallery.data.Task
|
import com.google.aiedge.gallery.data.Task
|
||||||
import com.google.aiedge.gallery.data.TaskType
|
import com.google.aiedge.gallery.data.TaskType
|
||||||
|
import com.google.aiedge.gallery.ui.common.ErrorDialog
|
||||||
import com.google.aiedge.gallery.ui.modelmanager.ModelInitializationStatusType
|
import com.google.aiedge.gallery.ui.modelmanager.ModelInitializationStatusType
|
||||||
import com.google.aiedge.gallery.ui.modelmanager.ModelManagerViewModel
|
import com.google.aiedge.gallery.ui.modelmanager.ModelManagerViewModel
|
||||||
import com.google.aiedge.gallery.ui.preview.PreviewChatModel
|
import com.google.aiedge.gallery.ui.preview.PreviewChatModel
|
||||||
|
@ -581,41 +578,9 @@ fun ChatPanel(
|
||||||
|
|
||||||
// Error dialog.
|
// Error dialog.
|
||||||
if (showErrorDialog) {
|
if (showErrorDialog) {
|
||||||
Dialog(
|
ErrorDialog(error = modelInitializationStatus?.error ?: "", onDismiss = {
|
||||||
onDismissRequest = {
|
|
||||||
showErrorDialog = false
|
showErrorDialog = false
|
||||||
navigateUp()
|
})
|
||||||
},
|
|
||||||
) {
|
|
||||||
Card(modifier = Modifier.fillMaxWidth(), shape = RoundedCornerShape(16.dp)) {
|
|
||||||
Column(
|
|
||||||
modifier = Modifier.padding(20.dp), verticalArrangement = Arrangement.spacedBy(16.dp)
|
|
||||||
) {
|
|
||||||
// Title
|
|
||||||
Text(
|
|
||||||
"Error",
|
|
||||||
style = MaterialTheme.typography.titleLarge,
|
|
||||||
modifier = Modifier.padding(bottom = 8.dp)
|
|
||||||
)
|
|
||||||
|
|
||||||
// Error
|
|
||||||
Text(
|
|
||||||
modelInitializationStatus?.error ?: "",
|
|
||||||
style = MaterialTheme.typography.bodySmall,
|
|
||||||
color = MaterialTheme.colorScheme.error,
|
|
||||||
)
|
|
||||||
|
|
||||||
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.End) {
|
|
||||||
Button(onClick = {
|
|
||||||
showErrorDialog = false
|
|
||||||
navigateUp()
|
|
||||||
}) {
|
|
||||||
Text("Close")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Benchmark config dialog.
|
// Benchmark config dialog.
|
||||||
|
|
|
@ -43,8 +43,10 @@ import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
import com.google.aiedge.gallery.data.ModelDownloadStatusType
|
import com.google.aiedge.gallery.data.ModelDownloadStatusType
|
||||||
import com.google.aiedge.gallery.ui.ViewModelProvider
|
import com.google.aiedge.gallery.ui.ViewModelProvider
|
||||||
|
import com.google.aiedge.gallery.ui.common.ErrorDialog
|
||||||
import com.google.aiedge.gallery.ui.common.ModelPageAppBar
|
import com.google.aiedge.gallery.ui.common.ModelPageAppBar
|
||||||
import com.google.aiedge.gallery.ui.common.chat.ModelDownloadStatusInfoPanel
|
import com.google.aiedge.gallery.ui.common.chat.ModelDownloadStatusInfoPanel
|
||||||
|
import com.google.aiedge.gallery.ui.modelmanager.ModelInitializationStatusType
|
||||||
import com.google.aiedge.gallery.ui.modelmanager.ModelManagerViewModel
|
import com.google.aiedge.gallery.ui.modelmanager.ModelManagerViewModel
|
||||||
import com.google.aiedge.gallery.ui.preview.PreviewLlmSingleTurnViewModel
|
import com.google.aiedge.gallery.ui.preview.PreviewLlmSingleTurnViewModel
|
||||||
import com.google.aiedge.gallery.ui.preview.PreviewModelManagerViewModel
|
import com.google.aiedge.gallery.ui.preview.PreviewModelManagerViewModel
|
||||||
|
@ -78,6 +80,7 @@ fun LlmSingleTurnScreen(
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
var navigatingUp by remember { mutableStateOf(false) }
|
var navigatingUp by remember { mutableStateOf(false) }
|
||||||
|
var showErrorDialog by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
val handleNavigateUp = {
|
val handleNavigateUp = {
|
||||||
navigatingUp = true
|
navigatingUp = true
|
||||||
|
@ -110,6 +113,11 @@ fun LlmSingleTurnScreen(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val modelInitializationStatus = modelManagerUiState.modelInitializationStatus[selectedModel.name]
|
||||||
|
LaunchedEffect(modelInitializationStatus) {
|
||||||
|
showErrorDialog = modelInitializationStatus?.status == ModelInitializationStatusType.ERROR
|
||||||
|
}
|
||||||
|
|
||||||
Scaffold(modifier = modifier, topBar = {
|
Scaffold(modifier = modifier, topBar = {
|
||||||
ModelPageAppBar(
|
ModelPageAppBar(
|
||||||
task = task,
|
task = task,
|
||||||
|
@ -186,6 +194,12 @@ fun LlmSingleTurnScreen(
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (showErrorDialog) {
|
||||||
|
ErrorDialog(error = modelInitializationStatus?.error ?: "", onDismiss = {
|
||||||
|
showErrorDialog = false
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -160,7 +160,7 @@ fun ModelList(
|
||||||
}
|
}
|
||||||
|
|
||||||
// List of imported models within a task.
|
// List of imported models within a task.
|
||||||
items(items = importedModels) { model ->
|
items(items = importedModels, key = { it.name }) { model ->
|
||||||
Box {
|
Box {
|
||||||
ModelItem(
|
ModelItem(
|
||||||
model = model,
|
model = model,
|
||||||
|
|
|
@ -683,6 +683,9 @@ open class ModelManagerViewModel(
|
||||||
Log.d(TAG, "Allowlist: $modelAllowlist")
|
Log.d(TAG, "Allowlist: $modelAllowlist")
|
||||||
|
|
||||||
// Convert models in the allowlist.
|
// Convert models in the allowlist.
|
||||||
|
TASK_LLM_CHAT.models.clear()
|
||||||
|
TASK_LLM_PROMPT_LAB.models.clear()
|
||||||
|
TASK_LLM_ASK_IMAGE.models.clear()
|
||||||
for (allowedModel in modelAllowlist.models) {
|
for (allowedModel in modelAllowlist.models) {
|
||||||
if (allowedModel.disabled == true) {
|
if (allowedModel.disabled == true) {
|
||||||
continue
|
continue
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue