mirror of
https://github.com/topjohnwu/Magisk.git
synced 2026-07-03 14:08:39 +02:00
Redesign Home screen and improve SU request dialog
- Replace stacked Magisk/Manager cards with side-by-side Core/App cards featuring status-based colors, watermark icons, and update badges - Add Status card showing Ramdisk, Zygisk, and DenyList states - Restructure Support Us and Follow Us sections with SuperArrow and bottom sheets for donate links and developer social links - Redesign NoticeCard with subtle tertiary container styling - Move Hide/Restore app action from Settings to Home App card - Use primary color for SU request Grant button - Fix DevelopersCard crash caused by null selectedDev during sheet dismiss Made-with: Cursor
This commit is contained in:
@@ -11,11 +11,11 @@ import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.ExperimentalLayoutApi
|
||||
import androidx.compose.foundation.layout.FlowRow
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxHeight
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.IntrinsicSize
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
@@ -46,13 +46,18 @@ import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.DpSize
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.core.content.getSystemService
|
||||
import androidx.core.net.toUri
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.core.Config
|
||||
import com.topjohnwu.magisk.core.BuildConfig
|
||||
import com.topjohnwu.magisk.core.Const
|
||||
import com.topjohnwu.magisk.core.Info
|
||||
import com.topjohnwu.magisk.core.tasks.AppMigration
|
||||
import com.topjohnwu.magisk.core.ktx.reboot
|
||||
import com.topjohnwu.magisk.core.download.DownloadEngine
|
||||
import com.topjohnwu.magisk.core.download.Subject
|
||||
@@ -67,12 +72,15 @@ import com.topjohnwu.magisk.ui.component.rememberConfirmDialog
|
||||
import com.topjohnwu.magisk.ui.component.rememberLoadingDialog
|
||||
import com.topjohnwu.magisk.ui.component.ListPopupDefaults.MenuPositionProvider
|
||||
import com.topjohnwu.magisk.ui.flash.FlashUtils
|
||||
import com.topjohnwu.magisk.ui.theme.ThemeState
|
||||
import com.topjohnwu.magisk.ui.install.InstallViewModel
|
||||
import com.topjohnwu.magisk.ui.navigation.Route
|
||||
import kotlinx.coroutines.launch
|
||||
import com.topjohnwu.magisk.core.R as CoreR
|
||||
import top.yukonga.miuix.kmp.basic.ButtonDefaults
|
||||
import top.yukonga.miuix.kmp.basic.Card
|
||||
import top.yukonga.miuix.kmp.basic.HorizontalDivider
|
||||
import top.yukonga.miuix.kmp.basic.VerticalDivider
|
||||
import top.yukonga.miuix.kmp.basic.Checkbox
|
||||
import top.yukonga.miuix.kmp.basic.DropdownImpl
|
||||
import top.yukonga.miuix.kmp.basic.Icon
|
||||
@@ -82,6 +90,7 @@ import top.yukonga.miuix.kmp.basic.ListPopupColumn
|
||||
import top.yukonga.miuix.kmp.basic.MiuixScrollBehavior
|
||||
import top.yukonga.miuix.kmp.basic.PopupPositionProvider
|
||||
import top.yukonga.miuix.kmp.basic.Scaffold
|
||||
import top.yukonga.miuix.kmp.basic.SmallTitle
|
||||
import top.yukonga.miuix.kmp.basic.Text
|
||||
import top.yukonga.miuix.kmp.basic.TextButton
|
||||
import top.yukonga.miuix.kmp.basic.TopAppBar
|
||||
@@ -89,6 +98,22 @@ import top.yukonga.miuix.kmp.extra.SuperArrow
|
||||
import top.yukonga.miuix.kmp.extra.SuperBottomSheet
|
||||
import top.yukonga.miuix.kmp.extra.SuperListPopup
|
||||
import top.yukonga.miuix.kmp.theme.MiuixTheme
|
||||
import top.yukonga.miuix.kmp.theme.MiuixTheme.isDynamicColor
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.compose.foundation.layout.offset
|
||||
import androidx.compose.foundation.layout.wrapContentSize
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.ui.draw.clipToBounds
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import top.yukonga.miuix.kmp.basic.CardDefaults
|
||||
import top.yukonga.miuix.kmp.icon.MiuixIcons
|
||||
import top.yukonga.miuix.kmp.icon.extended.Close
|
||||
import top.yukonga.miuix.kmp.icon.extended.Delete
|
||||
import top.yukonga.miuix.kmp.icon.extended.Hide
|
||||
import top.yukonga.miuix.kmp.icon.extended.Info
|
||||
import top.yukonga.miuix.kmp.icon.extended.Ok
|
||||
import top.yukonga.miuix.kmp.icon.extended.Show
|
||||
|
||||
@Composable
|
||||
fun HomeScreen(viewModel: HomeViewModel, installVm: InstallViewModel) {
|
||||
@@ -104,6 +129,8 @@ fun HomeScreen(viewModel: HomeViewModel, installVm: InstallViewModel) {
|
||||
val showUninstallDialog = rememberSaveable { mutableStateOf(false) }
|
||||
val showManagerDialog = rememberSaveable { mutableStateOf(false) }
|
||||
val showEnvFixDialog = rememberSaveable { mutableStateOf(false) }
|
||||
var showHideDialog by rememberSaveable { mutableStateOf(false) }
|
||||
var showRestoreDialog by rememberSaveable { mutableStateOf(false) }
|
||||
val showInstallSheet = rememberSaveable { mutableStateOf(false) }
|
||||
var envFixCode by remember { mutableIntStateOf(0) }
|
||||
|
||||
@@ -151,6 +178,13 @@ fun HomeScreen(viewModel: HomeViewModel, installVm: InstallViewModel) {
|
||||
viewModel.onEnvFixConsumed()
|
||||
}
|
||||
}
|
||||
LaunchedEffect(uiState.showHideRestore) {
|
||||
if (uiState.showHideRestore) {
|
||||
val hidden = context.packageName != BuildConfig.APP_PACKAGE_NAME
|
||||
if (hidden) showRestoreDialog = true else showHideDialog = true
|
||||
viewModel.onHideRestoreConsumed()
|
||||
}
|
||||
}
|
||||
|
||||
if (showUninstallDialog.value) {
|
||||
UninstallComposableDialog(
|
||||
@@ -177,6 +211,34 @@ fun HomeScreen(viewModel: HomeViewModel, installVm: InstallViewModel) {
|
||||
)
|
||||
}
|
||||
|
||||
if (showHideDialog) {
|
||||
HideAppDialog(
|
||||
onDismiss = { showHideDialog = false },
|
||||
onConfirm = { name ->
|
||||
showHideDialog = false
|
||||
scope.launch {
|
||||
loadingDialog.withLoading {
|
||||
AppMigration.patchAndHide(context, name)
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
if (showRestoreDialog) {
|
||||
RestoreAppDialog(
|
||||
onDismiss = { showRestoreDialog = false },
|
||||
onConfirm = {
|
||||
showRestoreDialog = false
|
||||
scope.launch {
|
||||
loadingDialog.withLoading {
|
||||
AppMigration.restoreApp(context)
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
Scaffold(
|
||||
topBar = {
|
||||
TopAppBar(
|
||||
@@ -197,30 +259,66 @@ fun HomeScreen(viewModel: HomeViewModel, installVm: InstallViewModel) {
|
||||
.padding(padding)
|
||||
.verticalScroll(rememberScrollState())
|
||||
.padding(horizontal = 16.dp)
|
||||
.padding(bottom = 88.dp),
|
||||
.padding(top = 12.dp, bottom = 88.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(12.dp)
|
||||
) {
|
||||
if (uiState.isNoticeVisible) {
|
||||
NoticeCard(onHide = viewModel::hideNotice)
|
||||
}
|
||||
|
||||
MagiskCard(
|
||||
viewModel = viewModel,
|
||||
onInstallClicked = { showInstallSheet.value = true }
|
||||
)
|
||||
|
||||
ManagerCard(viewModel = viewModel, uiState = uiState)
|
||||
|
||||
if (Info.env.isActive) {
|
||||
TextButton(
|
||||
text = stringResource(CoreR.string.uninstall_magisk_title),
|
||||
onClick = { viewModel.onDeletePressed() },
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
Row(
|
||||
modifier = Modifier.height(IntrinsicSize.Max),
|
||||
horizontalArrangement = Arrangement.spacedBy(12.dp)
|
||||
) {
|
||||
CoreCard(
|
||||
modifier = Modifier.weight(1f).fillMaxHeight(),
|
||||
state = viewModel.magiskState,
|
||||
version = viewModel.magiskInstalledVersion,
|
||||
remoteVersion = if (viewModel.magiskState == HomeViewModel.State.OUTDATED)
|
||||
"${BuildConfig.APP_VERSION_NAME} (${BuildConfig.APP_VERSION_CODE})" else null,
|
||||
onInstallClicked = { showInstallSheet.value = true },
|
||||
onUninstallClicked = { viewModel.onDeletePressed() },
|
||||
)
|
||||
AppCard(
|
||||
modifier = Modifier.weight(1f).fillMaxHeight(),
|
||||
state = uiState.appState,
|
||||
version = viewModel.managerInstalledVersion,
|
||||
remoteVersion = if (uiState.appState == HomeViewModel.State.OUTDATED)
|
||||
uiState.managerRemoteVersion else null,
|
||||
progress = uiState.managerProgress,
|
||||
isHidden = context.packageName != BuildConfig.APP_PACKAGE_NAME,
|
||||
onManagerPressed = { viewModel.onManagerPressed() },
|
||||
onHideRestorePressed = viewModel::onHideRestorePressed,
|
||||
)
|
||||
}
|
||||
|
||||
SupportCard(onLinkClicked = { viewModel.onLinkPressed(it) })
|
||||
SmallTitle(text = stringResource(CoreR.string.home_status_title))
|
||||
StatusCard()
|
||||
|
||||
val showDonateSheet = rememberSaveable { mutableStateOf(false) }
|
||||
|
||||
SmallTitle(text = stringResource(CoreR.string.home_support_title))
|
||||
Card(modifier = Modifier.fillMaxWidth()) {
|
||||
SuperArrow(
|
||||
title = stringResource(CoreR.string.documents),
|
||||
onClick = { openLink(context, "https://topjohnwu.github.io/Magisk/") }
|
||||
)
|
||||
SuperArrow(
|
||||
title = stringResource(CoreR.string.report_bugs),
|
||||
onClick = { openLink(context, "${Const.Url.SOURCE_CODE_URL}/issues") }
|
||||
)
|
||||
SuperArrow(
|
||||
title = stringResource(CoreR.string.donate),
|
||||
onClick = { showDonateSheet.value = true }
|
||||
)
|
||||
}
|
||||
|
||||
SupportBottomSheet(
|
||||
show = showDonateSheet,
|
||||
onLinkClicked = { viewModel.onLinkPressed(it) }
|
||||
)
|
||||
|
||||
SmallTitle(text = stringResource(CoreR.string.home_follow_title))
|
||||
DevelopersCard(onLinkClicked = { openLink(context, it) })
|
||||
}
|
||||
}
|
||||
@@ -300,131 +398,326 @@ private class RebootOption(val labelRes: Int, val action: () -> Unit)
|
||||
|
||||
@Composable
|
||||
private fun NoticeCard(onHide: () -> Unit) {
|
||||
Card(modifier = Modifier.fillMaxWidth()) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.background(
|
||||
MiuixTheme.colorScheme.tertiaryContainer,
|
||||
RoundedCornerShape(16.dp)
|
||||
)
|
||||
.padding(start = 16.dp, top = 4.dp, bottom = 4.dp, end = 4.dp)
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.padding(16.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(CoreR.string.home_notice_content),
|
||||
style = MiuixTheme.textStyles.body2,
|
||||
modifier = Modifier.weight(1f)
|
||||
)
|
||||
TextButton(
|
||||
text = stringResource(CoreR.string.hide),
|
||||
onClick = onHide
|
||||
color = MiuixTheme.colorScheme.onTertiaryContainer,
|
||||
modifier = Modifier.weight(1f).padding(vertical = 8.dp)
|
||||
)
|
||||
IconButton(onClick = onHide) {
|
||||
Icon(
|
||||
imageVector = MiuixIcons.Close,
|
||||
contentDescription = stringResource(CoreR.string.hide),
|
||||
modifier = Modifier.size(15.dp),
|
||||
tint = MiuixTheme.colorScheme.onTertiaryContainer,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun MagiskCard(viewModel: HomeViewModel, onInstallClicked: () -> Unit) {
|
||||
Card(modifier = Modifier.fillMaxWidth()) {
|
||||
Column(modifier = Modifier.padding(16.dp)) {
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
private fun CoreCard(
|
||||
modifier: Modifier = Modifier,
|
||||
state: HomeViewModel.State,
|
||||
version: String,
|
||||
remoteVersion: String? = null,
|
||||
onInstallClicked: () -> Unit,
|
||||
onUninstallClicked: () -> Unit,
|
||||
) {
|
||||
val isDark = when (ThemeState.colorMode) {
|
||||
2, 5 -> true
|
||||
1, 4 -> false
|
||||
else -> isSystemInDarkTheme()
|
||||
}
|
||||
val cardBg = when (state) {
|
||||
HomeViewModel.State.UP_TO_DATE -> when {
|
||||
isDynamicColor -> MiuixTheme.colorScheme.secondaryContainer
|
||||
isDark -> Color(0xFF1E3026)
|
||||
else -> Color(0xFFDFFAE4)
|
||||
}
|
||||
HomeViewModel.State.OUTDATED -> when {
|
||||
isDynamicColor -> MiuixTheme.colorScheme.tertiaryContainer
|
||||
isDark -> Color(0xFF302920)
|
||||
else -> Color(0xFFFFF3E0)
|
||||
}
|
||||
else -> Color.Transparent
|
||||
}
|
||||
|
||||
val actionLabel = when (state) {
|
||||
HomeViewModel.State.OUTDATED -> stringResource(CoreR.string.update)
|
||||
HomeViewModel.State.INVALID -> stringResource(CoreR.string.install)
|
||||
HomeViewModel.State.UP_TO_DATE -> stringResource(CoreR.string.reinstall)
|
||||
HomeViewModel.State.LOADING -> null
|
||||
}
|
||||
val actionColor = when (state) {
|
||||
HomeViewModel.State.OUTDATED, HomeViewModel.State.INVALID -> MiuixTheme.colorScheme.primary
|
||||
else -> MiuixTheme.colorScheme.onSurfaceVariantActions
|
||||
}
|
||||
val uninstallEnabled = Info.env.isActive
|
||||
|
||||
Card(modifier = modifier) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.background(cardBg)
|
||||
.clipToBounds()
|
||||
) {
|
||||
Column(modifier = Modifier.padding(16.dp)) {
|
||||
Icon(
|
||||
painter = painterResource(CoreR.drawable.ic_magisk_outline),
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(32.dp),
|
||||
modifier = Modifier.size(24.dp),
|
||||
tint = MiuixTheme.colorScheme.primary
|
||||
)
|
||||
Spacer(Modifier.width(12.dp))
|
||||
Spacer(Modifier.height(8.dp))
|
||||
Text(
|
||||
text = stringResource(CoreR.string.magisk),
|
||||
text = stringResource(CoreR.string.home_core_title),
|
||||
style = MiuixTheme.textStyles.headline2,
|
||||
color = MiuixTheme.colorScheme.primary,
|
||||
modifier = Modifier.weight(1f)
|
||||
)
|
||||
when (viewModel.magiskState) {
|
||||
HomeViewModel.State.OUTDATED -> TextButton(
|
||||
text = stringResource(CoreR.string.update),
|
||||
onClick = onInstallClicked
|
||||
Text(
|
||||
text = version.ifEmpty { stringResource(CoreR.string.not_available) },
|
||||
style = MiuixTheme.textStyles.body2,
|
||||
color = MiuixTheme.colorScheme.onSurfaceVariantSummary
|
||||
)
|
||||
}
|
||||
|
||||
Column(
|
||||
modifier = Modifier.align(Alignment.TopEnd).padding(4.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(0.dp),
|
||||
) {
|
||||
IconButton(
|
||||
onClick = onUninstallClicked,
|
||||
enabled = uninstallEnabled,
|
||||
) {
|
||||
Icon(
|
||||
imageVector = MiuixIcons.Delete,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(18.dp),
|
||||
tint = if (uninstallEnabled) MiuixTheme.colorScheme.error
|
||||
else MiuixTheme.colorScheme.onSurfaceVariantActions,
|
||||
)
|
||||
else -> TextButton(
|
||||
text = stringResource(CoreR.string.install),
|
||||
onClick = onInstallClicked
|
||||
}
|
||||
if (remoteVersion != null) {
|
||||
UpdateBadge(
|
||||
version = remoteVersion,
|
||||
modifier = Modifier.align(Alignment.End).padding(end = 4.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(Modifier.height(8.dp))
|
||||
|
||||
InfoRow(
|
||||
label = stringResource(CoreR.string.home_installed_version),
|
||||
value = viewModel.magiskInstalledVersion.ifEmpty {
|
||||
stringResource(CoreR.string.not_available)
|
||||
if (state != HomeViewModel.State.LOADING) {
|
||||
val watermarkIcon = when (state) {
|
||||
HomeViewModel.State.UP_TO_DATE -> MiuixIcons.Ok
|
||||
HomeViewModel.State.OUTDATED -> MiuixIcons.Info
|
||||
else -> MiuixIcons.Close
|
||||
}
|
||||
)
|
||||
InfoRow(
|
||||
label = stringResource(CoreR.string.zygisk),
|
||||
value = stringResource(if (Info.isZygiskEnabled) CoreR.string.yes else CoreR.string.no)
|
||||
)
|
||||
InfoRow(
|
||||
label = "Ramdisk",
|
||||
value = stringResource(if (Info.ramdisk) CoreR.string.yes else CoreR.string.no)
|
||||
val watermarkTint = when (state) {
|
||||
HomeViewModel.State.UP_TO_DATE -> when {
|
||||
isDynamicColor -> MiuixTheme.colorScheme.primary
|
||||
isDark -> Color(0xFF4CAF50)
|
||||
else -> Color(0xFF66BB6A)
|
||||
}
|
||||
HomeViewModel.State.OUTDATED -> when {
|
||||
isDynamicColor -> MiuixTheme.colorScheme.onTertiaryContainer
|
||||
isDark -> Color(0xFFFF9800)
|
||||
else -> Color(0xFFFFA726)
|
||||
}
|
||||
else -> MiuixTheme.colorScheme.onSurfaceVariantSummary
|
||||
}
|
||||
Icon(
|
||||
imageVector = watermarkIcon,
|
||||
contentDescription = null,
|
||||
modifier = Modifier
|
||||
.matchParentSize()
|
||||
.wrapContentSize(Alignment.TopEnd, unbounded = true)
|
||||
.size(128.dp)
|
||||
.offset(x = 24.dp, y = (-12).dp),
|
||||
tint = watermarkTint.copy(alpha = 0.15f)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (actionLabel != null) {
|
||||
HorizontalDivider(thickness = 0.75.dp)
|
||||
Text(
|
||||
text = actionLabel,
|
||||
style = MiuixTheme.textStyles.body2,
|
||||
color = actionColor,
|
||||
textAlign = TextAlign.Center,
|
||||
maxLines = 1,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable(onClick = onInstallClicked)
|
||||
.padding(horizontal = 12.dp, vertical = 12.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ManagerCard(viewModel: HomeViewModel, uiState: HomeViewModel.UiState) {
|
||||
Card(modifier = Modifier.fillMaxWidth()) {
|
||||
Column(modifier = Modifier.padding(16.dp)) {
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
private fun AppCard(
|
||||
modifier: Modifier = Modifier,
|
||||
state: HomeViewModel.State,
|
||||
version: String,
|
||||
remoteVersion: String? = null,
|
||||
progress: Int,
|
||||
isHidden: Boolean,
|
||||
onManagerPressed: () -> Unit,
|
||||
onHideRestorePressed: () -> Unit,
|
||||
) {
|
||||
val actionLabel = when (state) {
|
||||
HomeViewModel.State.OUTDATED -> stringResource(CoreR.string.update)
|
||||
HomeViewModel.State.UP_TO_DATE -> stringResource(CoreR.string.reinstall)
|
||||
else -> null
|
||||
}
|
||||
val actionColor = when (state) {
|
||||
HomeViewModel.State.OUTDATED -> MiuixTheme.colorScheme.primary
|
||||
else -> MiuixTheme.colorScheme.onSurfaceVariantActions
|
||||
}
|
||||
val hideRestoreIcon = if (isHidden) MiuixIcons.Show else MiuixIcons.Hide
|
||||
|
||||
Card(modifier = modifier) {
|
||||
Box(modifier = Modifier.fillMaxWidth()) {
|
||||
Column(modifier = Modifier.padding(16.dp)) {
|
||||
Icon(
|
||||
painter = painterResource(R.drawable.ic_manager),
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(32.dp),
|
||||
modifier = Modifier.size(24.dp),
|
||||
tint = MiuixTheme.colorScheme.primary
|
||||
)
|
||||
Spacer(Modifier.width(12.dp))
|
||||
Spacer(Modifier.height(8.dp))
|
||||
Text(
|
||||
text = stringResource(CoreR.string.home_app_title),
|
||||
style = MiuixTheme.textStyles.headline2,
|
||||
color = MiuixTheme.colorScheme.primary,
|
||||
modifier = Modifier.weight(1f)
|
||||
)
|
||||
when (uiState.appState) {
|
||||
HomeViewModel.State.OUTDATED -> TextButton(
|
||||
text = stringResource(CoreR.string.update),
|
||||
onClick = { viewModel.onManagerPressed() }
|
||||
Text(
|
||||
text = version,
|
||||
style = MiuixTheme.textStyles.body2,
|
||||
color = MiuixTheme.colorScheme.onSurfaceVariantSummary
|
||||
)
|
||||
if (progress in 1..99) {
|
||||
Spacer(Modifier.height(8.dp))
|
||||
LinearProgressIndicator(
|
||||
progress = progress / 100f,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
HomeViewModel.State.UP_TO_DATE -> TextButton(
|
||||
text = stringResource(CoreR.string.install),
|
||||
onClick = { viewModel.onManagerPressed() }
|
||||
)
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(Modifier.height(8.dp))
|
||||
|
||||
InfoRow(
|
||||
label = stringResource(CoreR.string.home_latest_version),
|
||||
value = uiState.managerRemoteVersion.ifEmpty {
|
||||
stringResource(
|
||||
if (uiState.appState == HomeViewModel.State.LOADING) CoreR.string.loading
|
||||
else CoreR.string.not_available
|
||||
Column(
|
||||
modifier = Modifier.align(Alignment.TopEnd).padding(4.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(0.dp),
|
||||
) {
|
||||
if (Info.env.isActive) {
|
||||
IconButton(onClick = onHideRestorePressed) {
|
||||
Icon(
|
||||
imageVector = hideRestoreIcon,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(18.dp),
|
||||
tint = MiuixTheme.colorScheme.primary,
|
||||
)
|
||||
}
|
||||
}
|
||||
if (remoteVersion != null) {
|
||||
UpdateBadge(
|
||||
version = remoteVersion,
|
||||
modifier = Modifier.align(Alignment.End).padding(end = 4.dp)
|
||||
)
|
||||
}
|
||||
)
|
||||
InfoRow(
|
||||
label = stringResource(CoreR.string.home_installed_version),
|
||||
value = viewModel.managerInstalledVersion
|
||||
)
|
||||
val context = LocalContext.current
|
||||
InfoRow(
|
||||
label = stringResource(CoreR.string.home_package),
|
||||
value = context.packageName
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (uiState.managerProgress in 1..99) {
|
||||
Spacer(Modifier.height(8.dp))
|
||||
LinearProgressIndicator(
|
||||
progress = uiState.managerProgress / 100f,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
if (actionLabel != null) {
|
||||
HorizontalDivider(thickness = 0.75.dp)
|
||||
Text(
|
||||
text = actionLabel,
|
||||
style = MiuixTheme.textStyles.body2,
|
||||
color = actionColor,
|
||||
textAlign = TextAlign.Center,
|
||||
maxLines = 1,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable(onClick = onManagerPressed)
|
||||
.padding(horizontal = 12.dp, vertical = 12.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun UpdateBadge(version: String, modifier: Modifier = Modifier) {
|
||||
Text(
|
||||
text = version,
|
||||
color = MiuixTheme.colorScheme.onPrimary,
|
||||
fontSize = 10.sp,
|
||||
maxLines = 1,
|
||||
modifier = modifier
|
||||
.background(MiuixTheme.colorScheme.primary, RoundedCornerShape(6.dp))
|
||||
.padding(horizontal = 6.dp, vertical = 2.dp)
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun StatusCard() {
|
||||
Card(modifier = Modifier.fillMaxWidth()) {
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth().height(IntrinsicSize.Min),
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.weight(1f).padding(16.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(CoreR.string.ramdisk),
|
||||
style = MiuixTheme.textStyles.headline2,
|
||||
)
|
||||
Text(
|
||||
text = stringResource(if (Info.ramdisk) CoreR.string.yes else CoreR.string.no),
|
||||
style = MiuixTheme.textStyles.body2,
|
||||
color = MiuixTheme.colorScheme.onSurfaceVariantSummary,
|
||||
)
|
||||
}
|
||||
VerticalDivider(thickness = 0.75.dp)
|
||||
Column(
|
||||
modifier = Modifier.weight(1f).padding(16.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(CoreR.string.zygisk),
|
||||
style = MiuixTheme.textStyles.headline2,
|
||||
)
|
||||
Text(
|
||||
text = stringResource(if (Info.isZygiskEnabled) CoreR.string.yes else CoreR.string.no),
|
||||
style = MiuixTheme.textStyles.body2,
|
||||
color = MiuixTheme.colorScheme.onSurfaceVariantSummary,
|
||||
)
|
||||
}
|
||||
VerticalDivider(thickness = 0.75.dp)
|
||||
Column(
|
||||
modifier = Modifier.weight(1f).padding(16.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(CoreR.string.denylist),
|
||||
style = MiuixTheme.textStyles.headline2,
|
||||
)
|
||||
Text(
|
||||
text = stringResource(if (Config.denyList) CoreR.string.enabled else CoreR.string.disabled),
|
||||
style = MiuixTheme.textStyles.body2,
|
||||
color = MiuixTheme.colorScheme.onSurfaceVariantSummary,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -432,144 +725,134 @@ private fun ManagerCard(viewModel: HomeViewModel, uiState: HomeViewModel.UiState
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun InfoRow(label: String, value: String) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(vertical = 2.dp),
|
||||
horizontalArrangement = Arrangement.SpaceBetween
|
||||
private fun SupportBottomSheet(
|
||||
show: MutableState<Boolean>,
|
||||
onLinkClicked: (String) -> Unit,
|
||||
) {
|
||||
SuperBottomSheet(
|
||||
show = show,
|
||||
onDismissRequest = { show.value = false },
|
||||
title = stringResource(CoreR.string.home_support_title),
|
||||
) {
|
||||
Text(
|
||||
text = label,
|
||||
style = MiuixTheme.textStyles.body2,
|
||||
color = MiuixTheme.colorScheme.onSurfaceVariantSummary
|
||||
)
|
||||
Text(
|
||||
text = value,
|
||||
style = MiuixTheme.textStyles.body2,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SupportCard(onLinkClicked: (String) -> Unit) {
|
||||
Card(modifier = Modifier.fillMaxWidth()) {
|
||||
Column(modifier = Modifier.padding(16.dp)) {
|
||||
Text(
|
||||
text = stringResource(CoreR.string.home_support_title),
|
||||
style = MiuixTheme.textStyles.headline2,
|
||||
)
|
||||
Spacer(Modifier.height(4.dp))
|
||||
Column(modifier = Modifier.padding(bottom = 16.dp)) {
|
||||
Text(
|
||||
text = stringResource(CoreR.string.home_support_content),
|
||||
style = MiuixTheme.textStyles.body2,
|
||||
color = MiuixTheme.colorScheme.onSurfaceVariantSummary
|
||||
color = MiuixTheme.colorScheme.onSurfaceVariantSummary,
|
||||
modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp)
|
||||
)
|
||||
SuperArrow(
|
||||
title = stringResource(CoreR.string.patreon),
|
||||
onClick = {
|
||||
show.value = false
|
||||
onLinkClicked(Const.Url.PATREON_URL)
|
||||
},
|
||||
startAction = {
|
||||
Icon(
|
||||
painter = painterResource(CoreR.drawable.ic_patreon),
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(24.dp),
|
||||
tint = MiuixTheme.colorScheme.onSurfaceVariantActions
|
||||
)
|
||||
}
|
||||
)
|
||||
SuperArrow(
|
||||
title = stringResource(CoreR.string.paypal),
|
||||
onClick = {
|
||||
show.value = false
|
||||
onLinkClicked("https://paypal.me/magiskdonate")
|
||||
},
|
||||
startAction = {
|
||||
Icon(
|
||||
painter = painterResource(CoreR.drawable.ic_paypal),
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(24.dp),
|
||||
tint = MiuixTheme.colorScheme.onSurfaceVariantActions
|
||||
)
|
||||
}
|
||||
)
|
||||
Spacer(Modifier.height(8.dp))
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
LinkChip(
|
||||
icon = CoreR.drawable.ic_patreon,
|
||||
label = stringResource(CoreR.string.patreon),
|
||||
onClick = { onLinkClicked(com.topjohnwu.magisk.core.Const.Url.PATREON_URL) }
|
||||
)
|
||||
LinkChip(
|
||||
icon = CoreR.drawable.ic_paypal,
|
||||
label = stringResource(CoreR.string.paypal),
|
||||
onClick = { onLinkClicked("https://paypal.me/magiskdonate") }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalLayoutApi::class)
|
||||
private data class LinkInfo(val label: String, val icon: Int, val url: String)
|
||||
private data class DeveloperInfo(val name: String, val links: List<LinkInfo>)
|
||||
|
||||
private val developers = listOf(
|
||||
DeveloperInfo("topjohnwu", listOf(
|
||||
LinkInfo("Twitter", CoreR.drawable.ic_twitter, "https://twitter.com/topjohnwu"),
|
||||
LinkInfo("GitHub", CoreR.drawable.ic_github, Const.Url.SOURCE_CODE_URL),
|
||||
)),
|
||||
DeveloperInfo("vvb2060", listOf(
|
||||
LinkInfo("Twitter", CoreR.drawable.ic_twitter, "https://twitter.com/vvb2060"),
|
||||
LinkInfo("GitHub", CoreR.drawable.ic_github, "https://github.com/vvb2060"),
|
||||
)),
|
||||
DeveloperInfo("yujincheng08", listOf(
|
||||
LinkInfo("Twitter", CoreR.drawable.ic_twitter, "https://twitter.com/shanasaimoe"),
|
||||
LinkInfo("GitHub", CoreR.drawable.ic_github, "https://github.com/yujincheng08"),
|
||||
LinkInfo("Sponsor", CoreR.drawable.ic_favorite, "https://github.com/sponsors/yujincheng08"),
|
||||
)),
|
||||
DeveloperInfo("rikkawww", listOf(
|
||||
LinkInfo("Twitter", CoreR.drawable.ic_twitter, "https://twitter.com/rikkawww"),
|
||||
LinkInfo("GitHub", CoreR.drawable.ic_github, "https://github.com/rikkawww"),
|
||||
)),
|
||||
DeveloperInfo("canyie", listOf(
|
||||
LinkInfo("Twitter", CoreR.drawable.ic_twitter, "https://twitter.com/canyie2977"),
|
||||
LinkInfo("GitHub", CoreR.drawable.ic_github, "https://github.com/canyie"),
|
||||
)),
|
||||
)
|
||||
|
||||
@Composable
|
||||
private fun DevelopersCard(onLinkClicked: (String) -> Unit) {
|
||||
val developers = listOf(
|
||||
DeveloperInfo("topjohnwu", listOf(
|
||||
LinkInfo("Twitter", CoreR.drawable.ic_twitter, "https://twitter.com/topjohnwu"),
|
||||
LinkInfo("GitHub", CoreR.drawable.ic_github, com.topjohnwu.magisk.core.Const.Url.SOURCE_CODE_URL),
|
||||
)),
|
||||
DeveloperInfo("vvb2060", listOf(
|
||||
LinkInfo("Twitter", CoreR.drawable.ic_twitter, "https://twitter.com/vvb2060"),
|
||||
LinkInfo("GitHub", CoreR.drawable.ic_github, "https://github.com/vvb2060"),
|
||||
)),
|
||||
DeveloperInfo("yujincheng08", listOf(
|
||||
LinkInfo("Twitter", CoreR.drawable.ic_twitter, "https://twitter.com/shanasaimoe"),
|
||||
LinkInfo("GitHub", CoreR.drawable.ic_github, "https://github.com/yujincheng08"),
|
||||
LinkInfo("Sponsor", CoreR.drawable.ic_favorite, "https://github.com/sponsors/yujincheng08"),
|
||||
)),
|
||||
DeveloperInfo("rikkawww", listOf(
|
||||
LinkInfo("Twitter", CoreR.drawable.ic_twitter, "https://twitter.com/rikkawww"),
|
||||
LinkInfo("GitHub", CoreR.drawable.ic_github, "https://github.com/rikkawww"),
|
||||
)),
|
||||
DeveloperInfo("canyie", listOf(
|
||||
LinkInfo("Twitter", CoreR.drawable.ic_twitter, "https://twitter.com/canyie2977"),
|
||||
LinkInfo("GitHub", CoreR.drawable.ic_github, "https://github.com/canyie"),
|
||||
)),
|
||||
)
|
||||
var selectedDev by remember { mutableStateOf<DeveloperInfo?>(null) }
|
||||
val showSheet = rememberSaveable { mutableStateOf(false) }
|
||||
|
||||
Card(modifier = Modifier.fillMaxWidth()) {
|
||||
Column(modifier = Modifier.padding(16.dp)) {
|
||||
Text(
|
||||
text = stringResource(CoreR.string.home_follow_title),
|
||||
style = MiuixTheme.textStyles.headline2,
|
||||
developers.forEach { dev ->
|
||||
SuperArrow(
|
||||
title = "@${dev.name}",
|
||||
onClick = {
|
||||
selectedDev = dev
|
||||
showSheet.value = true
|
||||
}
|
||||
)
|
||||
Spacer(Modifier.height(8.dp))
|
||||
developers.forEach { dev ->
|
||||
DeveloperRow(dev = dev, onLinkClicked = onLinkClicked)
|
||||
Spacer(Modifier.height(4.dp))
|
||||
}
|
||||
}
|
||||
|
||||
val currentDev = selectedDev
|
||||
if (currentDev != null) {
|
||||
SuperBottomSheet(
|
||||
show = showSheet,
|
||||
onDismissRequest = {
|
||||
showSheet.value = false
|
||||
selectedDev = null
|
||||
},
|
||||
title = "@${currentDev.name}",
|
||||
) {
|
||||
Column(modifier = Modifier.padding(bottom = 16.dp)) {
|
||||
currentDev.links.forEach { link ->
|
||||
SuperArrow(
|
||||
title = link.label,
|
||||
onClick = {
|
||||
showSheet.value = false
|
||||
onLinkClicked(link.url)
|
||||
selectedDev = null
|
||||
},
|
||||
startAction = {
|
||||
Icon(
|
||||
painter = painterResource(link.icon),
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(24.dp),
|
||||
tint = MiuixTheme.colorScheme.onSurfaceVariantActions
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalLayoutApi::class)
|
||||
@Composable
|
||||
private fun DeveloperRow(dev: DeveloperInfo, onLinkClicked: (String) -> Unit) {
|
||||
Column(modifier = Modifier.fillMaxWidth()) {
|
||||
Text(
|
||||
text = "@${dev.name}",
|
||||
style = MiuixTheme.textStyles.body1,
|
||||
)
|
||||
FlowRow(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
dev.links.forEach { link ->
|
||||
LinkChip(
|
||||
icon = link.icon,
|
||||
label = link.label,
|
||||
onClick = { onLinkClicked(link.url) }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun LinkChip(icon: Int, label: String, onClick: () -> Unit) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.clickable(onClick = onClick)
|
||||
.padding(vertical = 6.dp, horizontal = 4.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(4.dp)
|
||||
) {
|
||||
Icon(
|
||||
painter = painterResource(icon),
|
||||
contentDescription = label,
|
||||
modifier = Modifier.size(18.dp),
|
||||
tint = MiuixTheme.colorScheme.onSurfaceVariantActions
|
||||
)
|
||||
Text(
|
||||
text = label,
|
||||
style = MiuixTheme.textStyles.body2,
|
||||
color = MiuixTheme.colorScheme.onSurfaceVariantActions
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private data class DeveloperInfo(val name: String, val links: List<LinkInfo>)
|
||||
private data class LinkInfo(val label: String, val icon: Int, val url: String)
|
||||
|
||||
private fun openLink(context: Context, url: String) {
|
||||
try {
|
||||
context.startActivity(Intent(Intent.ACTION_VIEW, url.toUri()).apply {
|
||||
@@ -597,6 +880,7 @@ private fun InstallBottomSheet(
|
||||
color = MiuixTheme.colorScheme.onSurfaceVariantSummary,
|
||||
modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp)
|
||||
)
|
||||
HorizontalDivider(thickness = 0.75.dp)
|
||||
}
|
||||
|
||||
if (!installVm.skipOptions) {
|
||||
@@ -863,3 +1147,76 @@ private fun EnvFixComposableDialog(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun HideAppDialog(onDismiss: () -> Unit, onConfirm: (String) -> Unit) {
|
||||
val showState = rememberSaveable { mutableStateOf(true) }
|
||||
var appName by rememberSaveable { mutableStateOf("Settings") }
|
||||
val isError = appName.length > AppMigration.MAX_LABEL_LENGTH || appName.isBlank()
|
||||
|
||||
top.yukonga.miuix.kmp.extra.SuperDialog(
|
||||
show = showState,
|
||||
title = stringResource(CoreR.string.settings_hide_app_title),
|
||||
onDismissRequest = onDismiss,
|
||||
insideMargin = DpSize(24.dp, 24.dp)
|
||||
) {
|
||||
Column(modifier = Modifier.padding(top = 8.dp)) {
|
||||
top.yukonga.miuix.kmp.basic.TextField(
|
||||
value = appName,
|
||||
onValueChange = { appName = it },
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
label = stringResource(CoreR.string.settings_app_name_hint),
|
||||
)
|
||||
Spacer(Modifier.height(16.dp))
|
||||
Row(horizontalArrangement = Arrangement.SpaceBetween) {
|
||||
TextButton(
|
||||
text = stringResource(android.R.string.cancel),
|
||||
onClick = onDismiss,
|
||||
modifier = Modifier.weight(1f)
|
||||
)
|
||||
Spacer(Modifier.width(20.dp))
|
||||
TextButton(
|
||||
text = stringResource(android.R.string.ok),
|
||||
onClick = { if (!isError) onConfirm(appName) },
|
||||
modifier = Modifier.weight(1f),
|
||||
colors = ButtonDefaults.textButtonColorsPrimary()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun RestoreAppDialog(onDismiss: () -> Unit, onConfirm: () -> Unit) {
|
||||
val showState = rememberSaveable { mutableStateOf(true) }
|
||||
|
||||
top.yukonga.miuix.kmp.extra.SuperDialog(
|
||||
show = showState,
|
||||
title = stringResource(CoreR.string.settings_restore_app_title),
|
||||
onDismissRequest = onDismiss,
|
||||
insideMargin = DpSize(24.dp, 24.dp)
|
||||
) {
|
||||
Column(modifier = Modifier.padding(top = 8.dp)) {
|
||||
Text(
|
||||
text = stringResource(CoreR.string.restore_app_confirmation),
|
||||
style = MiuixTheme.textStyles.body1,
|
||||
color = MiuixTheme.colorScheme.onSurface,
|
||||
)
|
||||
Spacer(Modifier.height(16.dp))
|
||||
Row(horizontalArrangement = Arrangement.SpaceBetween) {
|
||||
TextButton(
|
||||
text = stringResource(android.R.string.cancel),
|
||||
onClick = onDismiss,
|
||||
modifier = Modifier.weight(1f)
|
||||
)
|
||||
Spacer(Modifier.width(20.dp))
|
||||
TextButton(
|
||||
text = stringResource(android.R.string.ok),
|
||||
onClick = onConfirm,
|
||||
modifier = Modifier.weight(1f),
|
||||
colors = ButtonDefaults.textButtonColorsPrimary()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ class HomeViewModel(
|
||||
val managerProgress: Int = 0,
|
||||
val showUninstall: Boolean = false,
|
||||
val showManagerInstall: Boolean = false,
|
||||
val showHideRestore: Boolean = false,
|
||||
val envFixCode: Int = 0,
|
||||
)
|
||||
|
||||
@@ -133,6 +134,14 @@ class HomeViewModel(
|
||||
_uiState.update { it.copy(showManagerInstall = false) }
|
||||
}
|
||||
|
||||
fun onHideRestorePressed() {
|
||||
_uiState.update { it.copy(showHideRestore = true) }
|
||||
}
|
||||
|
||||
fun onHideRestoreConsumed() {
|
||||
_uiState.update { it.copy(showHideRestore = false) }
|
||||
}
|
||||
|
||||
fun onEnvFixConsumed() {
|
||||
_uiState.update { it.copy(envFixCode = 0) }
|
||||
}
|
||||
|
||||
@@ -249,46 +249,6 @@ private fun AppSettingsSection(viewModel: SettingsViewModel) {
|
||||
}
|
||||
)
|
||||
|
||||
// Hide / Restore
|
||||
if (Info.env.isActive && Const.USER_ID == 0) {
|
||||
val loadingDialog = rememberLoadingDialog()
|
||||
val scope = rememberCoroutineScope()
|
||||
if (hidden) {
|
||||
var showRestoreDialog by remember { mutableStateOf(false) }
|
||||
RestoreDialog(
|
||||
show = showRestoreDialog,
|
||||
onDismiss = { showRestoreDialog = false },
|
||||
onConfirm = {
|
||||
showRestoreDialog = false
|
||||
scope.launch {
|
||||
loadingDialog.withLoading { viewModel.restoreApp(context) }
|
||||
}
|
||||
}
|
||||
)
|
||||
SuperArrow(
|
||||
title = stringResource(CoreR.string.settings_restore_app_title),
|
||||
summary = stringResource(CoreR.string.settings_restore_app_summary),
|
||||
onClick = { showRestoreDialog = true }
|
||||
)
|
||||
} else {
|
||||
var showHideDialog by remember { mutableStateOf(false) }
|
||||
HideAppDialog(
|
||||
show = showHideDialog,
|
||||
onDismiss = { showHideDialog = false },
|
||||
onConfirm = { name ->
|
||||
showHideDialog = false
|
||||
scope.launch {
|
||||
loadingDialog.withLoading { viewModel.hideApp(context, name) }
|
||||
}
|
||||
}
|
||||
)
|
||||
SuperArrow(
|
||||
title = stringResource(CoreR.string.settings_hide_app_title),
|
||||
summary = stringResource(CoreR.string.settings_hide_app_summary),
|
||||
onClick = { showHideDialog = true }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ import androidx.compose.ui.unit.dp
|
||||
import com.topjohnwu.magisk.core.ktx.toast
|
||||
import com.topjohnwu.magisk.core.R as CoreR
|
||||
import com.topjohnwu.magisk.ui.util.rememberDrawablePainter
|
||||
import top.yukonga.miuix.kmp.basic.ButtonDefaults
|
||||
import top.yukonga.miuix.kmp.basic.Card
|
||||
import top.yukonga.miuix.kmp.basic.Text
|
||||
import top.yukonga.miuix.kmp.basic.TextButton
|
||||
@@ -145,6 +146,7 @@ fun SuRequestScreen(viewModel: SuRequestViewModel) {
|
||||
TextButton(
|
||||
text = stringResource(CoreR.string.grant),
|
||||
enabled = grantEnabled,
|
||||
colors = ButtonDefaults.textButtonColorsPrimary(),
|
||||
onClick = { viewModel.grantPressed() },
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
<!-- Static strings -->
|
||||
<string name="magisk" translatable="false">Magisk</string>
|
||||
<string name="zygisk" translatable="false">Zygisk</string>
|
||||
<string name="ramdisk" translatable="false">Ramdisk</string>
|
||||
<string name="empty" translatable="false"/>
|
||||
|
||||
<string name="paypal" translatable="false">PayPal</string>
|
||||
|
||||
@@ -17,16 +17,24 @@
|
||||
<string name="update">Update</string>
|
||||
<string name="not_available">N/A</string>
|
||||
<string name="hide">Hide</string>
|
||||
<string name="restore">Restore</string>
|
||||
<string name="home_package">Package</string>
|
||||
<string name="home_app_title">App</string>
|
||||
<string name="home_core_title">Core</string>
|
||||
<string name="reinstall">Reinstall</string>
|
||||
<string name="home_notice_content">Download Magisk ONLY from the official GitHub page. Files from unknown sources can be malicious!</string>
|
||||
<string name="home_support_title">Support Us</string>
|
||||
<string name="home_follow_title">Follow Us</string>
|
||||
<string name="home_item_source">Source</string>
|
||||
<string name="home_support_content">Magisk is, and always will be, free, and open source. However, you can show us that you care by making a donation.</string>
|
||||
<string name="donate">Donate</string>
|
||||
<string name="documents">Documents</string>
|
||||
<string name="report_bugs">Report Bugs</string>
|
||||
<string name="home_status_title">Status</string>
|
||||
<string name="home_installed_version">Installed</string>
|
||||
<string name="home_latest_version">Latest</string>
|
||||
<string name="invalid_update_channel">Invalid update channel</string>
|
||||
<string name="uninstall">Uninstall</string>
|
||||
<string name="uninstall_magisk_title">Uninstall Magisk</string>
|
||||
<string name="uninstall_magisk_msg">All modules will be disabled/removed!\nRoot will be removed!\nAny internal storage unencrypted through the use of Magisk will be re-encrypted!</string>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user