manager: add folder size labels for module items to optimize the display of module information

This commit is contained in:
ShirkNeko
2025-06-15 19:27:26 +08:00
parent 9285945e8b
commit 776ae8744c
2 changed files with 110 additions and 0 deletions

View File

@@ -897,6 +897,9 @@ fun ModuleItem(
val interactionSource = remember { MutableInteractionSource() } val interactionSource = remember { MutableInteractionSource() }
val indication = LocalIndication.current val indication = LocalIndication.current
val viewModel = viewModel<ModuleViewModel>() val viewModel = viewModel<ModuleViewModel>()
val moduleSize by remember(module.dirId) {
mutableStateOf(viewModel.getModuleSize(module.dirId))
}
Column( Column(
modifier = Modifier modifier = Modifier
@@ -981,6 +984,46 @@ fun ModuleItem(
textDecoration = textDecoration, textDecoration = textDecoration,
) )
Spacer(modifier = Modifier.height(12.dp))
// 标签行
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp),
modifier = Modifier.fillMaxWidth()
) {
// 文件夹名称标签
Surface(
shape = RoundedCornerShape(4.dp),
color = MaterialTheme.colorScheme.primary,
modifier = Modifier
) {
Text(
text = module.dirId,
style = MaterialTheme.typography.labelSmall,
modifier = Modifier.padding(horizontal = 4.dp, vertical = 1.dp),
color = MaterialTheme.colorScheme.onPrimary,
maxLines = 1,
overflow = TextOverflow.Ellipsis
)
}
// 大小标签
Surface(
shape = RoundedCornerShape(4.dp),
color = MaterialTheme.colorScheme.secondaryContainer,
modifier = Modifier
) {
Text(
text = moduleSize,
style = MaterialTheme.typography.labelSmall,
modifier = Modifier.padding(horizontal = 4.dp, vertical = 1.dp),
color = MaterialTheme.colorScheme.onSecondaryContainer,
maxLines = 1
)
}
}
Spacer(modifier = Modifier.height(16.dp)) Spacer(modifier = Modifier.height(16.dp))
HorizontalDivider(thickness = Dp.Hairline) HorizontalDivider(thickness = Dp.Hairline)

View File

@@ -17,9 +17,15 @@ import com.sukisu.ultra.ui.util.listModules
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import org.json.JSONArray import org.json.JSONArray
import org.json.JSONObject import org.json.JSONObject
import java.io.BufferedReader
import java.io.File
import java.io.InputStreamReader
import java.text.Collator import java.text.Collator
import java.text.DecimalFormat
import java.util.Locale import java.util.Locale
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import kotlin.math.log10
import kotlin.math.pow
/** /**
* @author ShirkNeko * @author ShirkNeko
@@ -33,6 +39,11 @@ class ModuleViewModel : ViewModel() {
private const val CUSTOM_USER_AGENT = "SukiSU-Ultra/2.0" private const val CUSTOM_USER_AGENT = "SukiSU-Ultra/2.0"
} }
fun getModuleSize(dirId: String): String {
val size = getModuleFolderSize(dirId)
return formatFileSize(size)
}
class ModuleInfo( class ModuleInfo(
val id: String, val id: String,
val name: String, val name: String,
@@ -220,4 +231,60 @@ class ModuleViewModel : ViewModel() {
return Triple(zipUrl, version, changelog) return Triple(zipUrl, version, changelog)
} }
}
/**
* 格式化文件大小的工具函数
*/
fun formatFileSize(bytes: Long): String {
if (bytes <= 0) return "0 KB"
val units = arrayOf("B", "KB", "MB", "GB", "TB")
val digitGroups = (log10(bytes.toDouble()) / log10(1024.0)).toInt()
return DecimalFormat("#,##0.#").format(
bytes / 1024.0.pow(digitGroups.toDouble())
) + " " + units[digitGroups]
}
/**
* 使用 su 权限调用 du 命令获取模块文件夹大小
*/
fun getModuleFolderSize(dirId: String): Long {
return try {
val process = Runtime.getRuntime().exec(arrayOf("su", "-c", "du -sb /data/adb/modules/$dirId"))
val reader = BufferedReader(InputStreamReader(process.inputStream))
val output = reader.readLine()
process.waitFor()
reader.close()
if (output != null) {
val sizeStr = output.split("\t").firstOrNull()
sizeStr?.toLongOrNull() ?: 0L
} else {
0L
}
} catch (e: Exception) {
Log.e("ModuleItem", "Error calculating module size with su for $dirId: ${e.message}")
0L
}
}
/**
* 递归计算目录大小(备用)
*/
private fun calculateDirectorySize(directory: File): Long {
var size = 0L
try {
directory.listFiles()?.forEach { file ->
size += if (file.isDirectory) {
calculateDirectorySize(file)
} else {
file.length()
}
}
} catch (e: Exception) {
Log.e("ModuleItem", "Error calculating directory size: ${e.message}")
}
return size
} }