add few more OSes and add sub categories

This commit is contained in:
2026-03-12 15:20:11 +05:00
parent 0d5a73251c
commit cd807ff304
15 changed files with 206 additions and 13 deletions

View File

@@ -50,6 +50,7 @@ import org.json.JSONArray
data class OsDownload(
val name: String,
val category: String,
val subcategory: String?,
val description: String,
val icon: String?,
val url: String
@@ -67,6 +68,7 @@ private fun loadOsDownloads(context: Context): List<OsDownload> {
OsDownload(
name = obj.getString("name"),
category = obj.getString("category"),
subcategory = if (obj.isNull("subcategory")) null else obj.optString("subcategory", null),
description = obj.optString("description", ""),
icon = if (obj.isNull("icon")) null else obj.optString("icon", null),
url = obj.getString("url")
@@ -88,11 +90,9 @@ fun DownloadsScreen(
val context = LocalContext.current
val downloads = remember { loadOsDownloads(context) }
// Group by category and maintain order: Linux, BSD, Windows, Recovery
val categoryOrder = listOf("Linux", "BSD", "Windows", "Recovery")
// Group by category alphabetically
val groupedDownloads = remember(downloads) {
downloads.groupBy { it.category }
.toSortedMap(compareBy { categoryOrder.indexOf(it).takeIf { i -> i >= 0 } ?: Int.MAX_VALUE })
downloads.groupBy { it.category }.toSortedMap()
}
fun openUrl(url: String) {
@@ -166,22 +166,86 @@ private fun DownloadCategory(
)
) {
Column {
downloads.forEachIndexed { index, os ->
DownloadItem(
os = os,
onClick = { onItemClick(os) }
)
if (index < downloads.lastIndex) {
HorizontalDivider(
modifier = Modifier.padding(horizontal = 16.dp),
color = MaterialTheme.colorScheme.outline.copy(alpha = 0.3f)
// Check if any items have subcategories
val hasSubcategories = downloads.any { it.subcategory != null }
if (hasSubcategories) {
// Group by subcategory alphabetically
val groupedBySubcategory = downloads
.groupBy { it.subcategory ?: "" }
.toSortedMap()
var isFirstGroup = true
groupedBySubcategory.forEach { (subcategory, osList) ->
if (subcategory.isNotEmpty()) {
// Subcategory header
if (!isFirstGroup) {
HorizontalDivider(
modifier = Modifier.padding(horizontal = 16.dp),
color = MaterialTheme.colorScheme.outline.copy(alpha = 0.3f)
)
}
SubcategoryHeader(subcategory)
}
isFirstGroup = false
osList.sortedBy { it.name.lowercase() }.forEachIndexed { index, os ->
DownloadItem(
os = os,
onClick = { onItemClick(os) }
)
if (index < osList.lastIndex) {
HorizontalDivider(
modifier = Modifier.padding(horizontal = 16.dp),
color = MaterialTheme.colorScheme.outline.copy(alpha = 0.15f)
)
}
}
}
} else {
// No subcategories, show flat list
downloads.forEachIndexed { index, os ->
DownloadItem(
os = os,
onClick = { onItemClick(os) }
)
if (index < downloads.lastIndex) {
HorizontalDivider(
modifier = Modifier.padding(horizontal = 16.dp),
color = MaterialTheme.colorScheme.outline.copy(alpha = 0.3f)
)
}
}
}
}
}
}
@Composable
private fun SubcategoryHeader(title: String) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 12.dp),
verticalAlignment = Alignment.CenterVertically
) {
HorizontalDivider(
modifier = Modifier.weight(1f),
color = MaterialTheme.colorScheme.outline.copy(alpha = 0.5f)
)
Text(
text = title,
style = MaterialTheme.typography.labelMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant,
modifier = Modifier.padding(horizontal = 12.dp)
)
HorizontalDivider(
modifier = Modifier.weight(1f),
color = MaterialTheme.colorScheme.outline.copy(alpha = 0.5f)
)
}
}
@Composable
private fun DownloadItem(
os: OsDownload,