UI: add "Learn More" hyperlinks to Error dialog upon model import failures

This commit is contained in:
Han Yin 2025-08-04 09:04:49 -07:00
parent 381994234c
commit 2c9b1d37e0
2 changed files with 24 additions and 2 deletions

View File

@ -1,5 +1,6 @@
package com.example.llama.ui.screens package com.example.llama.ui.screens
import android.content.Intent
import androidx.activity.compose.BackHandler import androidx.activity.compose.BackHandler
import androidx.compose.foundation.basicMarquee import androidx.compose.foundation.basicMarquee
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
@ -17,6 +18,7 @@ import androidx.compose.foundation.layout.width
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.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.outlined.ContactSupport
import androidx.compose.material.icons.filled.Attribution import androidx.compose.material.icons.filled.Attribution
import androidx.compose.material.icons.filled.Download import androidx.compose.material.icons.filled.Download
import androidx.compose.material.icons.filled.Error import androidx.compose.material.icons.filled.Error
@ -45,14 +47,17 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.DialogProperties import androidx.compose.ui.window.DialogProperties
import androidx.core.net.toUri
import com.example.llama.data.model.ModelInfo import com.example.llama.data.model.ModelInfo
import com.example.llama.data.source.remote.HuggingFaceModel import com.example.llama.data.source.remote.HuggingFaceModel
import com.example.llama.ui.components.InfoAction
import com.example.llama.ui.components.InfoView import com.example.llama.ui.components.InfoView
import com.example.llama.ui.components.ModelCardFullExpandable import com.example.llama.ui.components.ModelCardFullExpandable
import com.example.llama.ui.scaffold.ScaffoldEvent import com.example.llama.ui.scaffold.ScaffoldEvent
@ -185,6 +190,7 @@ fun ModelsManagementScreen(
ErrorDialog( ErrorDialog(
title = "Import Failed", title = "Import Failed",
message = state.message, message = state.message,
learnMoreUrl = state.learnMoreUrl,
onDismiss = { viewModel.resetManagementState() } onDismiss = { viewModel.resetManagementState() }
) )
} }
@ -662,8 +668,22 @@ private fun BatchDeleteConfirmationDialog(
private fun ErrorDialog( private fun ErrorDialog(
title: String, title: String,
message: String, message: String,
learnMoreUrl: String? = null,
onDismiss: () -> Unit onDismiss: () -> Unit
) { ) {
val context = LocalContext.current
val action = learnMoreUrl?.let { url ->
InfoAction(
label = "Learn More",
icon = Icons.AutoMirrored.Outlined.ContactSupport,
onAction = {
val intent = Intent(Intent.ACTION_VIEW, url.toUri())
context.startActivity(intent)
}
)
}
AlertDialog( AlertDialog(
onDismissRequest = onDismiss, onDismissRequest = onDismiss,
text = { text = {
@ -672,6 +692,7 @@ private fun ErrorDialog(
title = title, title = title,
icon = Icons.Default.Error, icon = Icons.Default.Error,
message = message, message = message,
action = action
) )
}, },
confirmButton = { confirmButton = {

View File

@ -212,10 +212,12 @@ class ModelsManagementViewModel @Inject constructor(
} catch (_: InvalidFileFormatException) { } catch (_: InvalidFileFormatException) {
_managementState.value = Importation.Error( _managementState.value = Importation.Error(
message = "Not a valid GGUF model!", message = "Not a valid GGUF model!",
learnMoreUrl = "https://huggingface.co/docs/hub/en/gguf",
) )
} catch (e: InsufficientStorageException) { } catch (e: InsufficientStorageException) {
_managementState.value = Importation.Error( _managementState.value = Importation.Error(
message = e.message ?: "Insufficient storage space to import $fileName", message = e.message ?: "Insufficient storage space to import $fileName",
learnMoreUrl = "https://support.google.com/android/answer/7431795?hl=en",
) )
} catch (e: Exception) { } catch (e: Exception) {
Log.e(TAG, "Unknown exception importing $fileName", e) Log.e(TAG, "Unknown exception importing $fileName", e)
@ -382,8 +384,7 @@ sealed class ModelManagementState {
data class Confirming(val uri: Uri, val fileName: String, val fileSize: Long) : Importation() data class Confirming(val uri: Uri, val fileName: String, val fileSize: Long) : Importation()
data class Importing(val progress: Float = 0f, val fileName: String, val fileSize: Long, val isCancelling: Boolean = false) : Importation() data class Importing(val progress: Float = 0f, val fileName: String, val fileSize: Long, val isCancelling: Boolean = false) : Importation()
data class Success(val model: ModelInfo) : Importation() data class Success(val model: ModelInfo) : Importation()
// TODO-han.yin: Add an optional explanation URL for more info! data class Error(val message: String, val learnMoreUrl: String? = null) : Importation()
data class Error(val message: String) : Importation()
} }
sealed class Download: ModelManagementState() { sealed class Download: ModelManagementState() {