From e7e935aeb2067a98bb1f09e7d83b7eeb78b587d4 Mon Sep 17 00:00:00 2001 From: rifsxd Date: Sun, 1 Jun 2025 15:37:13 +0600 Subject: [PATCH] manager: added module size label --- .../com/rifsxd/ksunext/ui/screen/Module.kt | 126 +++++++++++------- .../java/com/rifsxd/ksunext/ui/util/KsuCli.kt | 7 + .../ksunext/ui/viewmodel/ModuleViewModel.kt | 11 +- 3 files changed, 92 insertions(+), 52 deletions(-) diff --git a/manager/app/src/main/java/com/rifsxd/ksunext/ui/screen/Module.kt b/manager/app/src/main/java/com/rifsxd/ksunext/ui/screen/Module.kt index f3222757..764c3cfc 100644 --- a/manager/app/src/main/java/com/rifsxd/ksunext/ui/screen/Module.kt +++ b/manager/app/src/main/java/com/rifsxd/ksunext/ui/screen/Module.kt @@ -896,6 +896,13 @@ fun ModuleItem( verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(6.dp) ) { + LabelItem( + text = formatSize(module.size), + style = com.dergoogler.mmrl.ui.component.LabelItemDefaults.style.copy( + containerColor = MaterialTheme.colorScheme.secondaryContainer, + contentColor = MaterialTheme.colorScheme.onSecondaryContainer + ) + ) LabelItem( text = if (module.enabled) stringResource(R.string.enabled) else stringResource(R.string.disabled), style = if (module.enabled) @@ -935,23 +942,25 @@ fun ModuleItem( ) } } - if (module.hasWebUi) { - LabelItem( - text = stringResource(R.string.webui), - style = com.dergoogler.mmrl.ui.component.LabelItemDefaults.style.copy( - containerColor = MaterialTheme.colorScheme.primaryContainer, - contentColor = MaterialTheme.colorScheme.onPrimaryContainer + if (!module.remove) { + if (module.hasWebUi) { + LabelItem( + text = stringResource(R.string.webui), + style = com.dergoogler.mmrl.ui.component.LabelItemDefaults.style.copy( + containerColor = MaterialTheme.colorScheme.primaryContainer, + contentColor = MaterialTheme.colorScheme.onPrimaryContainer + ) ) - ) - } - if (module.hasActionScript) { - LabelItem( - text = stringResource(R.string.action), - style = com.dergoogler.mmrl.ui.component.LabelItemDefaults.style.copy( - containerColor = MaterialTheme.colorScheme.secondaryContainer, - contentColor = MaterialTheme.colorScheme.onSecondaryContainer + } + if (module.hasActionScript) { + LabelItem( + text = stringResource(R.string.action), + style = com.dergoogler.mmrl.ui.component.LabelItemDefaults.style.copy( + containerColor = MaterialTheme.colorScheme.secondaryContainer, + contentColor = MaterialTheme.colorScheme.onSecondaryContainer + ) ) - ) + } } } @@ -1036,42 +1045,46 @@ fun ModuleItem( HorizontalDivider() } - if (module.hasWebUi) { - DropdownMenuItem( - text = { Text(stringResource(R.string.webui)) }, - onClick = { - expanded = false - onClick(module) - } - ) - } - if (module.hasActionScript) { - DropdownMenuItem( - text = { Text(stringResource(R.string.action)) }, - onClick = { - expanded = false - navigator.navigate(ExecuteModuleActionScreenDestination(module.dirId)) - viewModel.markNeedRefresh() - } - ) - } - - if (module.hasWebUi || module.hasActionScript ) { - HorizontalDivider() - } - - DropdownMenuItem( - text = { - Text( - if (module.enabled) stringResource(R.string.disable) - else stringResource(R.string.enable) + if (!module.remove) { + if (module.hasWebUi) { + DropdownMenuItem( + text = { Text(stringResource(R.string.webui)) }, + onClick = { + expanded = false + onClick(module) + } ) - }, - onClick = { - expanded = false - onCheckChanged(!module.enabled) } - ) + if (module.hasActionScript) { + DropdownMenuItem( + text = { Text(stringResource(R.string.action)) }, + onClick = { + expanded = false + navigator.navigate(ExecuteModuleActionScreenDestination(module.dirId)) + viewModel.markNeedRefresh() + } + ) + } + + if (module.hasWebUi || module.hasActionScript ) { + HorizontalDivider() + } + } + + if (!module.remove) { + DropdownMenuItem( + text = { + Text( + if (module.enabled) stringResource(R.string.disable) + else stringResource(R.string.enable) + ) + }, + onClick = { + expanded = false + onCheckChanged(!module.enabled) + } + ) + } if (module.remove) { DropdownMenuItem( text = { Text(stringResource(R.string.restore)) }, @@ -1112,6 +1125,18 @@ fun ModuleItem( } } +fun formatSize(size: Long): String { + val kb = 1024 + val mb = kb * 1024 + val gb = mb * 1024 + return when { + size >= gb -> String.format("%.2f GB", size.toDouble() / gb) + size >= mb -> String.format("%.2f MB", size.toDouble() / mb) + size >= kb -> String.format("%.2f KB", size.toDouble() / kb) + else -> "$size B" + } +} + @Preview @Composable fun ModuleItemPreview() { @@ -1128,7 +1153,8 @@ fun ModuleItemPreview() { updateJson = "", hasWebUi = false, hasActionScript = false, - dirId = "dirId" + dirId = "dirId", + size = 12345678L ) ModuleItem(EmptyDestinationsNavigator, module, "", {}, {}, {}, {}, {}) } diff --git a/manager/app/src/main/java/com/rifsxd/ksunext/ui/util/KsuCli.kt b/manager/app/src/main/java/com/rifsxd/ksunext/ui/util/KsuCli.kt index 3771eb33..a75f0bdd 100644 --- a/manager/app/src/main/java/com/rifsxd/ksunext/ui/util/KsuCli.kt +++ b/manager/app/src/main/java/com/rifsxd/ksunext/ui/util/KsuCli.kt @@ -621,6 +621,13 @@ fun currentMountSystem(): String { return result.substringAfter(":").substringAfter(" ").trim() } +fun getModuleSize(dir: File): Long { + val shell = getRootShell() + val cmd = "du -sb '${dir.absolutePath}' | awk '{print \$1}'" + val result = ShellUtils.fastCmd(shell, cmd).trim() + return result.toLongOrNull() ?: 0L +} + fun setAppProfileTemplate(id: String, template: String): Boolean { val shell = getRootShell() val escapedTemplate = template.replace("\"", "\\\"") diff --git a/manager/app/src/main/java/com/rifsxd/ksunext/ui/viewmodel/ModuleViewModel.kt b/manager/app/src/main/java/com/rifsxd/ksunext/ui/viewmodel/ModuleViewModel.kt index aff1f413..c48cf89b 100644 --- a/manager/app/src/main/java/com/rifsxd/ksunext/ui/viewmodel/ModuleViewModel.kt +++ b/manager/app/src/main/java/com/rifsxd/ksunext/ui/viewmodel/ModuleViewModel.kt @@ -15,11 +15,13 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import kotlinx.coroutines.withTimeoutOrNull +import java.io.File import java.text.Collator import java.util.Locale import com.rifsxd.ksunext.ksuApp import com.rifsxd.ksunext.ui.util.HanziToPinyin import com.rifsxd.ksunext.ui.util.listModules +import com.rifsxd.ksunext.ui.util.getModuleSize import org.json.JSONArray import org.json.JSONObject @@ -43,7 +45,8 @@ class ModuleViewModel : ViewModel() { val updateJson: String, val hasWebUi: Boolean, val hasActionScript: Boolean, - val dirId: String + val dirId: String, + val size: Long ) data class ModuleUpdateInfo( @@ -117,6 +120,9 @@ class ModuleViewModel : ViewModel() { .map { array.getJSONObject(it) } .map { obj -> val id = obj.getString("id") + val dirId = obj.getString("dir_id") + val moduleDir = File("/data/adb/modules/$dirId") + val size = getModuleSize(moduleDir) ModuleInfo( id, @@ -131,7 +137,8 @@ class ModuleViewModel : ViewModel() { obj.optString("updateJson"), obj.optBoolean("web"), obj.optBoolean("action"), - obj.getString("dir_id") + dirId, + size ) }.toList() isNeedRefresh = false