UI: polish UI for ModelsManagementScreen; inject ModelsManagementVieModel

This commit is contained in:
Han Yin 2025-04-14 12:55:26 -07:00
parent 6e82bb37d3
commit eebc05b559
4 changed files with 336 additions and 122 deletions

View File

@ -73,6 +73,7 @@ fun StorageAppScaffold(
storageTotal: Float,
onNavigateBack: (() -> Unit)? = null,
snackbarHostState: SnackbarHostState = remember { SnackbarHostState() },
bottomBar: @Composable () -> Unit = {},
content: @Composable (PaddingValues) -> Unit
) {
Scaffold(
@ -87,6 +88,7 @@ fun StorageAppScaffold(
snackbarHost = {
SnackbarHost(hostState = snackbarHostState)
},
bottomBar = bottomBar,
content = content
)
}

View File

@ -1,5 +1,6 @@
package com.example.llama.revamp.ui.screens
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
@ -7,35 +8,52 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.Sort
import androidx.compose.material.icons.filled.Add
import androidx.compose.material.icons.filled.ClearAll
import androidx.compose.material.icons.filled.Close
import androidx.compose.material.icons.filled.Delete
import androidx.compose.material.icons.filled.DeleteSweep
import androidx.compose.material.icons.filled.FilterAlt
import androidx.compose.material.icons.filled.FolderOpen
import androidx.compose.material.icons.filled.Info
import androidx.compose.material.icons.filled.SelectAll
import androidx.compose.material3.BottomAppBar
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Checkbox
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.FloatingActionButton
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.LinearProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateMapOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import com.example.llama.revamp.data.model.ModelInfo
import com.example.llama.revamp.ui.components.StorageAppScaffold
import com.example.llama.revamp.viewmodel.ModelSortOrder
import com.example.llama.revamp.viewmodel.ModelsManagementViewModel
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import com.example.llama.R
/**
* Screen for managing LLM models (view, download, delete)
@ -43,132 +61,317 @@ import java.util.Locale
@Composable
fun ModelsManagementScreen(
onBackPressed: () -> Unit,
viewModel: ModelsManagementViewModel = hiltViewModel()
) {
// For demo purposes, we'll use sample models
val installedModels = remember { ModelInfo.getSampleModels() }
val models by viewModel.availableModels.collectAsState()
val storageMetrics by viewModel.storageMetrics.collectAsState()
// Edit mode for models' batch deletion
var isEditMode by remember { mutableStateOf(false) }
// UI states
var isMultiSelectionMode by remember { mutableStateOf(false) }
val selectedModels = remember { mutableStateMapOf<String, ModelInfo>() }
var showSortMenu by remember { mutableStateOf(false) }
var showAddModelMenu by remember { mutableStateOf(false) }
// Calculate storage info
val storageUsed = 14.6f // This would be calculated from actual models
val storageTotal = 32.0f // This would be from device storage info
val exitSelectionMode = {
isMultiSelectionMode = false
selectedModels.clear()
}
StorageAppScaffold(
title = "Models Management",
storageUsed = storageUsed,
storageTotal = storageTotal,
storageUsed = storageMetrics.usedGB,
storageTotal = storageMetrics.totalGB,
onNavigateBack = onBackPressed,
) { paddingValues ->
Column(
modifier = Modifier
.fillMaxSize()
.padding(paddingValues)
.padding(16.dp)
) {
// Summary card
Card(
modifier = Modifier
.fillMaxWidth()
.padding(bottom = 16.dp)
) {
Column(
modifier = Modifier.padding(16.dp)
) {
Text(
text = "Models Storage",
style = MaterialTheme.typography.titleMedium
)
Spacer(modifier = Modifier.height(8.dp))
Row(
verticalAlignment = Alignment.CenterVertically
) {
Column(
modifier = Modifier.weight(1f)
) {
Text(
text = "Storage Used: 14.6GB / 32GB",
style = MaterialTheme.typography.bodyMedium
)
Spacer(modifier = Modifier.height(4.dp))
LinearProgressIndicator(
progress = { 0.45f },
modifier = Modifier.fillMaxWidth()
bottomBar = {
BottomAppBar(
actions = {
if (isMultiSelectionMode) {
// Multi-selection mode actions
IconButton(onClick = {
// Select all
selectedModels.putAll(models.map { it.id to it })
}) {
Icon(
imageVector = Icons.Default.SelectAll,
contentDescription = "Select all"
)
}
OutlinedButton(
onClick = { /* Download new model */ },
modifier = Modifier.padding(start = 16.dp)
IconButton(onClick = {
// Deselect all
selectedModels.clear()
}) {
Icon(
imageVector = Icons.Default.ClearAll,
contentDescription = "Deselect all"
)
}
IconButton(
onClick = {
// Delete selected
if (selectedModels.isNotEmpty()) {
viewModel.deleteModels(selectedModels)
exitSelectionMode()
}
},
enabled = selectedModels.isNotEmpty()
) {
Text("Add Model")
Icon(
imageVector = Icons.Default.Delete,
contentDescription = "Delete selected",
tint = if (selectedModels.isNotEmpty())
MaterialTheme.colorScheme.error
else
MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.38f)
)
}
} else {
// Default mode actions
IconButton(onClick = { showSortMenu = true }) {
Icon(
imageVector = Icons.AutoMirrored.Filled.Sort,
contentDescription = "Sort models"
)
}
// Sort dropdown menu
DropdownMenu(
expanded = showSortMenu,
onDismissRequest = { showSortMenu = false }
) {
DropdownMenuItem(
text = { Text("Name (A-Z)") },
onClick = {
viewModel.setSortOrder(ModelSortOrder.NAME_ASC)
showSortMenu = false
}
)
DropdownMenuItem(
text = { Text("Name (Z-A)") },
onClick = {
viewModel.setSortOrder(ModelSortOrder.NAME_DESC)
showSortMenu = false
}
)
DropdownMenuItem(
text = { Text("Size (Largest first)") },
onClick = {
viewModel.setSortOrder(ModelSortOrder.SIZE_DESC)
showSortMenu = false
}
)
DropdownMenuItem(
text = { Text("Size (Smallest first)") },
onClick = {
viewModel.setSortOrder(ModelSortOrder.SIZE_ASC)
showSortMenu = false
}
)
DropdownMenuItem(
text = { Text("Last used") },
onClick = {
viewModel.setSortOrder(ModelSortOrder.LAST_USED)
showSortMenu = false
}
)
}
IconButton(onClick = { /* Filter action - stub for now */ }) {
Icon(
imageVector = Icons.Default.FilterAlt,
contentDescription = "Filter models"
)
}
IconButton(onClick = {
isMultiSelectionMode = true
}) {
Icon(
imageVector = Icons.Default.DeleteSweep,
contentDescription = "Delete models"
)
}
}
}
}
},
floatingActionButton = {
FloatingActionButton(
onClick = {
if (isMultiSelectionMode) {
exitSelectionMode()
} else {
showAddModelMenu = true
}
},
containerColor = MaterialTheme.colorScheme.primaryContainer
) {
Icon(
imageVector = if (isMultiSelectionMode) Icons.Default.Close else Icons.Default.Add,
contentDescription = if (isMultiSelectionMode) "Exit selection mode" else "Add model"
)
}
// Installed models list
Text(
text = "Installed Models",
style = MaterialTheme.typography.titleMedium,
modifier = Modifier.padding(vertical = 8.dp)
// Add model dropdown menu
DropdownMenu(
expanded = showAddModelMenu,
onDismissRequest = { showAddModelMenu = false }
) {
DropdownMenuItem(
text = { Text("Import local model") },
leadingIcon = {
Icon(
imageVector = Icons.Default.FolderOpen,
contentDescription = "Import a local model on the device"
)
},
onClick = {
viewModel.importLocalModel()
showAddModelMenu = false
}
)
DropdownMenuItem(
text = { Text("Download from HuggingFace") },
leadingIcon = {
Icon(
painter = painterResource(id = R.drawable.logo_huggingface),
contentDescription = "Browse and download a model from HuggingFace",
modifier = Modifier.size(24.dp),
tint = Color.Unspecified,
)
},
onClick = {
viewModel.importFromHuggingFace()
showAddModelMenu = false
}
)
}
}
)
LazyColumn {
items(installedModels) { model ->
ModelManagementItem(
model = model,
onInfoClick = { /* Show model details */ },
onDeleteClick = { /* Delete model */ }
)
Spacer(modifier = Modifier.height(8.dp))
},
) { paddingValues ->
// Main content
ModelList(
models = models,
isMultiSelectionMode = isMultiSelectionMode,
selectedModels = selectedModels,
onModelClick = { modelId ->
if (isMultiSelectionMode) {
// Toggle selection
if (selectedModels.contains(modelId)) {
selectedModels.remove(modelId)
} else {
selectedModels.put(modelId, models.first { it.id == modelId } )
}
} else {
// View model details
viewModel.viewModelDetails(modelId)
}
}
},
onModelInfoClick = { modelId ->
viewModel.viewModelDetails(modelId)
},
onModelDeleteClick = { modelId ->
viewModel.deleteModel(modelId)
},
modifier = Modifier.padding(paddingValues)
)
}
}
@Composable
private fun ModelList(
models: List<ModelInfo>,
isMultiSelectionMode: Boolean,
selectedModels: Map<String, ModelInfo>,
onModelClick: (String) -> Unit,
onModelInfoClick: (String) -> Unit,
onModelDeleteClick: (String) -> Unit,
modifier: Modifier = Modifier
) {
LazyColumn(
modifier = modifier
.fillMaxSize()
.padding(16.dp)
) {
items(
items = models,
key = { it.id }
) { model ->
ModelItem(
model = model,
isMultiSelectionMode = isMultiSelectionMode,
isSelected = selectedModels.contains(model.id),
onClick = { onModelClick(model.id) },
onInfoClick = { onModelInfoClick(model.id) },
onDeleteClick = { onModelDeleteClick(model.id) }
)
Spacer(modifier = Modifier.height(8.dp))
}
}
}
@Composable
fun ModelManagementItem(
private fun ModelItem(
model: ModelInfo,
isMultiSelectionMode: Boolean,
isSelected: Boolean,
onClick: () -> Unit,
onInfoClick: () -> Unit,
onDeleteClick: () -> Unit
) {
// Model item implementation with selection support
Card(
modifier = Modifier.fillMaxWidth(),
elevation = CardDefaults.cardElevation(defaultElevation = 2.dp)
modifier = Modifier
.fillMaxWidth()
.clickable(onClick = onClick),
colors = if (isSelected && isMultiSelectionMode)
CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.primaryContainer)
else
CardDefaults.cardColors()
) {
Column(
modifier = Modifier.padding(16.dp)
Row(
modifier = Modifier.padding(16.dp),
verticalAlignment = Alignment.CenterVertically
) {
Row(
verticalAlignment = Alignment.CenterVertically
) {
Column(
modifier = Modifier.weight(1f)
) {
Text(
text = model.name,
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.Bold
)
// Show checkbox in selection mode
if (isMultiSelectionMode) {
Checkbox(
checked = isSelected,
onCheckedChange = { onClick() },
modifier = Modifier.padding(end = 8.dp)
)
}
// Model info
Column(modifier = Modifier.weight(1f)) {
Text(
text = model.name,
style = MaterialTheme.typography.titleMedium
)
Text(
text = "${model.parameters}${model.quantization}${model.formattedSize}",
style = MaterialTheme.typography.bodySmall
)
model.lastUsed?.let { lastUsed ->
val dateFormat = SimpleDateFormat("MMM d, yyyy", Locale.getDefault())
Text(
text = "${model.parameters}${model.quantization}${model.formattedSize}",
style = MaterialTheme.typography.bodyMedium,
text = "Last used: ${dateFormat.format(Date(lastUsed))}",
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
}
}
// Only show action buttons in non-selection mode
if (!isMultiSelectionMode) {
IconButton(onClick = onInfoClick) {
Icon(
imageVector = Icons.Default.Info,
contentDescription = "Model details",
tint = MaterialTheme.colorScheme.primary
contentDescription = "Model details"
)
}
@ -180,35 +383,6 @@ fun ModelManagementItem(
)
}
}
HorizontalDivider(
modifier = Modifier.padding(vertical = 8.dp)
)
Row(
verticalAlignment = Alignment.CenterVertically
) {
Column(
modifier = Modifier.weight(1f)
) {
Text(
text = "Location: ${model.path}",
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.onSurfaceVariant,
maxLines = 1,
overflow = TextOverflow.Ellipsis
)
model.lastUsed?.let { lastUsed ->
val dateFormat = SimpleDateFormat("MMM d, yyyy", Locale.getDefault())
Text(
text = "Last used: ${dateFormat.format(Date(lastUsed))}",
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
}
}
}
}
}
}

View File

@ -97,6 +97,10 @@ class ModelsManagementViewModel @Inject constructor(
// TODO-han.yin: Stub for now. Would open file picker and import model
}
fun importFromHuggingFace() {
// TODO-han.yin: Stub for now. Would need to investigate HuggingFace APIs
}
private fun updateStorageMetrics() {
// Recalculate storage metrics after model changes
// TODO-han.yin: Stub for now. Would query actual storage

View File

@ -0,0 +1,34 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="95dp"
android:height="88dp"
android:viewportWidth="95"
android:viewportHeight="88">
<path
android:pathData="M47.21,76.5a34.75,34.75 0,1 0,0 -69.5,34.75 34.75,0 0,0 0,69.5Z"
android:fillColor="#FFD21E"/>
<path
android:pathData="M81.96,41.75a34.75,34.75 0,1 0,-69.5 0,34.75 34.75,0 0,0 69.5,0ZM8.46,41.75a38.75,38.75 0,1 1,77.5 0,38.75 38.75,0 0,1 -77.5,0Z"
android:fillColor="#FF9D0B"/>
<path
android:pathData="M58.5,32.3c1.28,0.44 1.78,3.06 3.07,2.38a5,5 0,1 0,-6.76 -2.07c0.61,1.15 2.55,-0.72 3.7,-0.32ZM34.95,32.3c-1.28,0.44 -1.79,3.06 -3.07,2.38a5,5 0,1 1,6.76 -2.07c-0.61,1.15 -2.56,-0.72 -3.7,-0.32Z"
android:fillColor="#3A3B45"/>
<path
android:pathData="M46.96,56.29c9.83,0 13,-8.76 13,-13.26 0,-2.34 -1.57,-1.6 -4.09,-0.36 -2.33,1.15 -5.46,2.74 -8.9,2.74 -7.19,0 -13,-6.88 -13,-2.38s3.16,13.26 13,13.26Z"
android:fillColor="#FF323D"/>
<path
android:pathData="M39.43,54a8.7,8.7 0,0 1,5.3 -4.49c0.4,-0.12 0.81,0.57 1.24,1.28 0.4,0.68 0.82,1.37 1.24,1.37 0.45,0 0.9,-0.68 1.33,-1.35 0.45,-0.7 0.89,-1.38 1.32,-1.25a8.61,8.61 0,0 1,5 4.17c3.73,-2.94 5.1,-7.74 5.1,-10.7 0,-2.34 -1.57,-1.6 -4.09,-0.36l-0.14,0.07c-2.31,1.15 -5.39,2.67 -8.77,2.67s-6.45,-1.52 -8.77,-2.67c-2.6,-1.29 -4.23,-2.1 -4.23,0.29 0,3.05 1.46,8.06 5.47,10.97Z"
android:fillColor="#3A3B45"
android:fillType="evenOdd"/>
<path
android:pathData="M70.71,37a3.25,3.25 0,1 0,0 -6.5,3.25 3.25,0 0,0 0,6.5ZM24.21,37a3.25,3.25 0,1 0,0 -6.5,3.25 3.25,0 0,0 0,6.5ZM17.52,48c-1.62,0 -3.06,0.66 -4.07,1.87a5.97,5.97 0,0 0,-1.33 3.76,7.1 7.1,0 0,0 -1.94,-0.3c-1.55,0 -2.95,0.59 -3.94,1.66a5.8,5.8 0,0 0,-0.8 7,5.3 5.3,0 0,0 -1.79,2.82c-0.24,0.9 -0.48,2.8 0.8,4.74a5.22,5.22 0,0 0,-0.37 5.02c1.02,2.32 3.57,4.14 8.52,6.1 3.07,1.22 5.89,2 5.91,2.01a44.33,44.33 0,0 0,10.93 1.6c5.86,0 10.05,-1.8 12.46,-5.34 3.88,-5.69 3.33,-10.9 -1.7,-15.92 -2.77,-2.78 -4.62,-6.87 -5,-7.77 -0.78,-2.66 -2.84,-5.62 -6.25,-5.62a5.7,5.7 0,0 0,-4.6 2.46c-1,-1.26 -1.98,-2.25 -2.86,-2.82A7.4,7.4 0,0 0,17.52 48ZM17.52,52c0.51,0 1.14,0.22 1.82,0.65 2.14,1.36 6.25,8.43 7.76,11.18 0.5,0.92 1.37,1.31 2.14,1.31 1.55,0 2.75,-1.53 0.15,-3.48 -3.92,-2.93 -2.55,-7.72 -0.68,-8.01 0.08,-0.02 0.17,-0.02 0.24,-0.02 1.7,0 2.45,2.93 2.45,2.93s2.2,5.52 5.98,9.3c3.77,3.77 3.97,6.8 1.22,10.83 -1.88,2.75 -5.47,3.58 -9.16,3.58 -3.81,0 -7.73,-0.9 -9.92,-1.46 -0.11,-0.03 -13.45,-3.8 -11.76,-7 0.28,-0.54 0.75,-0.76 1.34,-0.76 2.38,0 6.7,3.54 8.57,3.54 0.41,0 0.7,-0.17 0.83,-0.6 0.79,-2.85 -12.06,-4.05 -10.98,-8.17 0.2,-0.73 0.71,-1.02 1.44,-1.02 3.14,0 10.2,5.53 11.68,5.53 0.11,0 0.2,-0.03 0.24,-0.1 0.74,-1.2 0.33,-2.04 -4.9,-5.2 -5.21,-3.16 -8.88,-5.06 -6.8,-7.33 0.24,-0.26 0.58,-0.38 1,-0.38 3.17,0 10.66,6.82 10.66,6.82s2.02,2.1 3.25,2.1c0.28,0 0.52,-0.1 0.68,-0.38 0.86,-1.46 -8.06,-8.22 -8.56,-11.01 -0.34,-1.9 0.24,-2.85 1.31,-2.85Z"
android:fillColor="#FF9D0B"/>
<path
android:pathData="M38.6,76.69c2.75,-4.04 2.55,-7.07 -1.22,-10.84 -3.78,-3.77 -5.98,-9.3 -5.98,-9.3s-0.82,-3.2 -2.69,-2.9c-1.87,0.3 -3.24,5.08 0.68,8.01 3.91,2.93 -0.78,4.92 -2.29,2.17 -1.5,-2.75 -5.62,-9.82 -7.76,-11.18 -2.13,-1.35 -3.63,-0.6 -3.13,2.2 0.5,2.79 9.43,9.55 8.56,11 -0.87,1.47 -3.93,-1.71 -3.93,-1.71s-9.57,-8.71 -11.66,-6.44c-2.08,2.27 1.59,4.17 6.8,7.33 5.23,3.16 5.64,4 4.9,5.2 -0.75,1.2 -12.28,-8.53 -13.36,-4.4 -1.08,4.11 11.77,5.3 10.98,8.15 -0.8,2.85 -9.06,-5.38 -10.74,-2.18 -1.7,3.21 11.65,6.98 11.76,7.01 4.3,1.12 15.25,3.49 19.08,-2.12Z"
android:fillColor="#FFD21E"/>
<path
android:pathData="M77.4,48c1.62,0 3.07,0.66 4.07,1.87a5.97,5.97 0,0 1,1.33 3.76,7.1 7.1,0 0,1 1.95,-0.3c1.55,0 2.95,0.59 3.94,1.66a5.8,5.8 0,0 1,0.8 7,5.3 5.3,0 0,1 1.78,2.82c0.24,0.9 0.48,2.8 -0.8,4.74a5.22,5.22 0,0 1,0.37 5.02c-1.02,2.32 -3.57,4.14 -8.51,6.1 -3.08,1.22 -5.9,2 -5.92,2.01a44.33,44.33 0,0 1,-10.93 1.6c-5.86,0 -10.05,-1.8 -12.46,-5.34 -3.88,-5.69 -3.33,-10.9 1.7,-15.92 2.78,-2.78 4.63,-6.87 5.01,-7.77 0.78,-2.66 2.83,-5.62 6.24,-5.62a5.7,5.7 0,0 1,4.6 2.46c1,-1.26 1.98,-2.25 2.87,-2.82A7.4,7.4 0,0 1,77.4 48ZM77.4,52c-0.51,0 -1.13,0.22 -1.82,0.65 -2.13,1.36 -6.25,8.43 -7.76,11.18a2.43,2.43 0,0 1,-2.14 1.31c-1.54,0 -2.75,-1.53 -0.14,-3.48 3.91,-2.93 2.54,-7.72 0.67,-8.01a1.54,1.54 0,0 0,-0.24 -0.02c-1.7,0 -2.45,2.93 -2.45,2.93s-2.2,5.52 -5.97,9.3c-3.78,3.77 -3.98,6.8 -1.22,10.83 1.87,2.75 5.47,3.58 9.15,3.58 3.82,0 7.73,-0.9 9.93,-1.46 0.1,-0.03 13.45,-3.8 11.76,-7 -0.29,-0.54 -0.75,-0.76 -1.34,-0.76 -2.38,0 -6.71,3.54 -8.57,3.54 -0.42,0 -0.71,-0.17 -0.83,-0.6 -0.8,-2.85 12.05,-4.05 10.97,-8.17 -0.19,-0.73 -0.7,-1.02 -1.44,-1.02 -3.14,0 -10.2,5.53 -11.68,5.53 -0.1,0 -0.19,-0.03 -0.23,-0.1 -0.74,-1.2 -0.34,-2.04 4.88,-5.2 5.23,-3.16 8.9,-5.06 6.8,-7.33 -0.23,-0.26 -0.57,-0.38 -0.98,-0.38 -3.18,0 -10.67,6.82 -10.67,6.82s-2.02,2.1 -3.24,2.1a0.74,0.74 0,0 1,-0.68 -0.38c-0.87,-1.46 8.05,-8.22 8.55,-11.01 0.34,-1.9 -0.24,-2.85 -1.31,-2.85Z"
android:fillColor="#FF9D0B"/>
<path
android:pathData="M56.33,76.69c-2.75,-4.04 -2.56,-7.07 1.22,-10.84 3.77,-3.77 5.97,-9.3 5.97,-9.3s0.82,-3.2 2.7,-2.9c1.86,0.3 3.23,5.08 -0.68,8.01 -3.92,2.93 0.78,4.92 2.28,2.17 1.51,-2.75 5.63,-9.82 7.76,-11.18 2.13,-1.35 3.64,-0.6 3.13,2.2 -0.5,2.79 -9.42,9.55 -8.55,11 0.86,1.47 3.92,-1.71 3.92,-1.71s9.58,-8.71 11.66,-6.44c2.08,2.27 -1.58,4.17 -6.8,7.33 -5.23,3.16 -5.63,4 -4.9,5.2 0.75,1.2 12.28,-8.53 13.36,-4.4 1.08,4.11 -11.76,5.3 -10.97,8.15 0.8,2.85 9.05,-5.38 10.74,-2.18 1.69,3.21 -11.65,6.98 -11.76,7.01 -4.31,1.12 -15.26,3.49 -19.08,-2.12Z"
android:fillColor="#FFD21E"/>
</vector>