diff --git a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/Settings.kt b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/Settings.kt index 6abdbc4f..963e1c11 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/Settings.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/Settings.kt @@ -9,10 +9,27 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.* -import androidx.compose.material3.* -import androidx.compose.runtime.* +import androidx.compose.material.icons.filled.ArrowBack +import androidx.compose.material.icons.filled.BugReport +import androidx.compose.material.icons.filled.Compress +import androidx.compose.material.icons.filled.ContactPage +import androidx.compose.material.icons.filled.DeveloperMode +import androidx.compose.material.icons.filled.Fence +import androidx.compose.material.icons.filled.RemoveModerator +import androidx.compose.material.icons.filled.Update +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.ListItem +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource @@ -28,11 +45,14 @@ import me.weishu.kernelsu.BuildConfig import me.weishu.kernelsu.Natives import me.weishu.kernelsu.R import me.weishu.kernelsu.ui.component.AboutDialog +import me.weishu.kernelsu.ui.component.ConfirmResult import me.weishu.kernelsu.ui.component.SwitchItem +import me.weishu.kernelsu.ui.component.rememberConfirmDialog import me.weishu.kernelsu.ui.component.rememberCustomDialog import me.weishu.kernelsu.ui.component.rememberLoadingDialog import me.weishu.kernelsu.ui.screen.destinations.AppProfileTemplateScreenDestination import me.weishu.kernelsu.ui.util.getBugreportFile +import me.weishu.kernelsu.ui.util.shrinkModules /** * @author weishu @@ -52,6 +72,7 @@ fun SettingScreen(navigator: DestinationsNavigator) { AboutDialog(it) } val loadingDialog = rememberLoadingDialog() + val shrinkDialog = rememberConfirmDialog() Column( modifier = Modifier @@ -156,6 +177,29 @@ fun SettingScreen(navigator: DestinationsNavigator) { } ) + val shrink = stringResource(id = R.string.shrink_sparse_image) + val shrinkMessage = stringResource(id = R.string.shrink_sparse_image_message) + ListItem( + leadingContent = { + Icon( + Icons.Filled.Compress, + shrink + ) + }, + headlineContent = { Text(shrink) }, + modifier = Modifier.clickable { + scope.launch { + val result = + shrinkDialog.awaitConfirm(title = shrink, content = shrinkMessage) + if (result == ConfirmResult.Confirmed) { + loadingDialog.withLoading { + shrinkModules() + } + } + } + } + ) + val about = stringResource(id = R.string.about) ListItem( leadingContent = { diff --git a/manager/app/src/main/java/me/weishu/kernelsu/ui/util/KsuCli.kt b/manager/app/src/main/java/me/weishu/kernelsu/ui/util/KsuCli.kt index 9c1ce554..709d20af 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/ui/util/KsuCli.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/ui/util/KsuCli.kt @@ -56,8 +56,8 @@ fun createRootShell(globalMnt: Boolean = false): Shell { } } -fun execKsud(args: String): Boolean { - val shell = getRootShell() +fun execKsud(args: String, newShell: Boolean = false): Boolean { + val shell = if (newShell) createRootShell() else getRootShell() return ShellUtils.fastCmdResult(shell, "${getKsuDaemonPath()} $args") } @@ -142,6 +142,10 @@ fun installModule( } } +suspend fun shrinkModules(): Boolean = withContext(Dispatchers.IO) { + execKsud("module shrink", true) +} + @Parcelize sealed class LkmSelection : Parcelable { data class LkmUri(val uri: Uri) : LkmSelection() diff --git a/manager/app/src/main/res/values-zh-rCN/strings.xml b/manager/app/src/main/res/values-zh-rCN/strings.xml index d50b46d8..6d6b3c6e 100644 --- a/manager/app/src/main/res/values-zh-rCN/strings.xml +++ b/manager/app/src/main/res/values-zh-rCN/strings.xml @@ -115,4 +115,6 @@ 下一步 建议选择 %1$s 分区镜像 选择 KMI + 最小化稀疏文件 + 将模块所在的稀疏文件镜像调整为其实际大小,注意这可能导致模块工作异常,请仅在必要时(如备份)使用。 \ No newline at end of file diff --git a/manager/app/src/main/res/values/strings.xml b/manager/app/src/main/res/values/strings.xml index 53c105b6..2cb48b3a 100644 --- a/manager/app/src/main/res/values/strings.xml +++ b/manager/app/src/main/res/values/strings.xml @@ -117,4 +117,6 @@ Next %1$s partition image is recommended Select KMI + Minimize sparse image + Adjust the sparse file mirror where the module is located to its actual size. Note that this may cause the module to function abnormally, please only use when necessary (such as for backup)