You've already forked KernelSU-Next
mirror of
https://github.com/KernelSU-Next/KernelSU-Next.git
synced 2025-08-27 23:46:34 +00:00
manager: fully polish and refactor module card ui
This commit is contained in:
@@ -9,6 +9,11 @@ import android.util.Log
|
|||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
|
import androidx.compose.animation.expandVertically
|
||||||
|
import androidx.compose.animation.shrinkVertically
|
||||||
|
import androidx.compose.animation.fadeIn
|
||||||
|
import androidx.compose.animation.fadeOut
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.Image
|
import androidx.compose.foundation.Image
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
@@ -443,6 +448,8 @@ private fun ModuleList(
|
|||||||
val loadingDialog = rememberLoadingDialog()
|
val loadingDialog = rememberLoadingDialog()
|
||||||
val confirmDialog = rememberConfirmDialog()
|
val confirmDialog = rememberConfirmDialog()
|
||||||
|
|
||||||
|
var expandedModuleId by rememberSaveable { mutableStateOf<String?>(null) }
|
||||||
|
|
||||||
suspend fun onModuleUpdate(
|
suspend fun onModuleUpdate(
|
||||||
module: ModuleViewModel.ModuleInfo,
|
module: ModuleViewModel.ModuleInfo,
|
||||||
changelogUrl: String,
|
changelogUrl: String,
|
||||||
@@ -665,6 +672,10 @@ private fun ModuleList(
|
|||||||
},
|
},
|
||||||
onClick = {
|
onClick = {
|
||||||
onClickModule(it.dirId, it.name, it.hasWebUi)
|
onClickModule(it.dirId, it.name, it.hasWebUi)
|
||||||
|
},
|
||||||
|
expanded = expandedModuleId == module.id,
|
||||||
|
onExpandToggle = {
|
||||||
|
expandedModuleId = if (expandedModuleId == module.id) null else module.id
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -690,6 +701,8 @@ fun ModuleItem(
|
|||||||
onCheckChanged: (Boolean) -> Unit,
|
onCheckChanged: (Boolean) -> Unit,
|
||||||
onUpdate: (ModuleViewModel.ModuleInfo) -> Unit,
|
onUpdate: (ModuleViewModel.ModuleInfo) -> Unit,
|
||||||
onClick: (ModuleViewModel.ModuleInfo) -> Unit,
|
onClick: (ModuleViewModel.ModuleInfo) -> Unit,
|
||||||
|
expanded: Boolean,
|
||||||
|
onExpandToggle: () -> Unit,
|
||||||
) {
|
) {
|
||||||
val viewModel = viewModel<ModuleViewModel>()
|
val viewModel = viewModel<ModuleViewModel>()
|
||||||
|
|
||||||
@@ -698,12 +711,7 @@ fun ModuleItem(
|
|||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.clip(MaterialTheme.shapes.medium)
|
.clip(MaterialTheme.shapes.medium)
|
||||||
.clickable(
|
.clickable(
|
||||||
enabled = (module.enabled && !module.remove && (module.hasWebUi)),
|
onClick = onExpandToggle
|
||||||
onClick = {
|
|
||||||
if (module.hasWebUi) {
|
|
||||||
onClick(module)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
Box(
|
Box(
|
||||||
@@ -866,6 +874,15 @@ fun ModuleItem(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
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
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -945,76 +962,142 @@ fun ModuleItem(
|
|||||||
maxLines = 4
|
maxLines = 4
|
||||||
)
|
)
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(12.dp))
|
Spacer(modifier = Modifier.height(2.dp))
|
||||||
|
|
||||||
Row(
|
if (expanded) {
|
||||||
horizontalArrangement = Arrangement.SpaceBetween,
|
Spacer(modifier = Modifier.height(10.dp))
|
||||||
verticalAlignment = Alignment.CenterVertically
|
}
|
||||||
|
|
||||||
|
AnimatedVisibility(
|
||||||
|
visible = expanded,
|
||||||
|
enter = fadeIn() + expandVertically(),
|
||||||
|
exit = shrinkVertically() + fadeOut()
|
||||||
) {
|
) {
|
||||||
if (module.hasActionScript) {
|
Row(
|
||||||
FilledTonalButton(
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
modifier = Modifier.defaultMinSize(52.dp, 32.dp),
|
verticalAlignment = Alignment.CenterVertically
|
||||||
enabled = !module.remove && module.enabled,
|
) {
|
||||||
onClick = {
|
if (module.hasActionScript) {
|
||||||
navigator.navigate(ExecuteModuleActionScreenDestination(module.dirId))
|
FilledTonalButton(
|
||||||
viewModel.markNeedRefresh()
|
modifier = Modifier.defaultMinSize(52.dp, 32.dp),
|
||||||
},
|
enabled = !module.remove && module.enabled,
|
||||||
contentPadding = ButtonDefaults.TextButtonContentPadding
|
onClick = {
|
||||||
) {
|
navigator.navigate(ExecuteModuleActionScreenDestination(module.dirId))
|
||||||
Icon(
|
viewModel.markNeedRefresh()
|
||||||
modifier = Modifier.size(20.dp),
|
},
|
||||||
imageVector = Icons.Outlined.Terminal,
|
contentPadding = ButtonDefaults.TextButtonContentPadding
|
||||||
contentDescription = null
|
) {
|
||||||
)
|
Icon(
|
||||||
|
modifier = Modifier.size(20.dp),
|
||||||
|
imageVector = Icons.Outlined.Terminal,
|
||||||
|
contentDescription = null
|
||||||
|
)
|
||||||
|
if (!module.hasWebUi && updateUrl.isEmpty()) {
|
||||||
|
Text(
|
||||||
|
modifier = Modifier.padding(start = 7.dp),
|
||||||
|
text = stringResource(R.string.action),
|
||||||
|
fontFamily = MaterialTheme.typography.labelMedium.fontFamily,
|
||||||
|
fontSize = MaterialTheme.typography.labelMedium.fontSize
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.weight(0.1f, true))
|
||||||
}
|
}
|
||||||
|
|
||||||
Spacer(modifier = Modifier.weight(0.1f, true))
|
if (module.hasWebUi) {
|
||||||
}
|
FilledTonalButton(
|
||||||
|
modifier = Modifier.defaultMinSize(52.dp, 32.dp),
|
||||||
Spacer(modifier = Modifier.weight(1f, true))
|
enabled = !module.remove && module.enabled,
|
||||||
|
onClick = { onClick(module) },
|
||||||
if (updateUrl.isNotEmpty()) {
|
interactionSource = interactionSource,
|
||||||
Button(
|
contentPadding = ButtonDefaults.TextButtonContentPadding
|
||||||
modifier = Modifier.defaultMinSize(52.dp, 32.dp),
|
) {
|
||||||
enabled = !module.remove,
|
Icon(
|
||||||
onClick = { onUpdate(module) },
|
modifier = Modifier.size(20.dp),
|
||||||
shape = ButtonDefaults.textShape,
|
imageVector = Icons.AutoMirrored.Outlined.Wysiwyg,
|
||||||
contentPadding = ButtonDefaults.TextButtonContentPadding
|
contentDescription = null
|
||||||
) {
|
)
|
||||||
Icon(
|
if (!module.hasActionScript && updateUrl.isEmpty()) {
|
||||||
modifier = Modifier.size(20.dp),
|
Text(
|
||||||
imageVector = Icons.Outlined.Download,
|
modifier = Modifier.padding(start = 7.dp),
|
||||||
contentDescription = null
|
fontFamily = MaterialTheme.typography.labelMedium.fontFamily,
|
||||||
)
|
fontSize = MaterialTheme.typography.labelMedium.fontSize,
|
||||||
|
text = stringResource(R.string.open)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Spacer(modifier = Modifier.weight(0.1f, true))
|
Spacer(modifier = Modifier.weight(1f, true))
|
||||||
}
|
|
||||||
|
|
||||||
if (module.remove) {
|
if (updateUrl.isNotEmpty()) {
|
||||||
FilledTonalButton(
|
Button(
|
||||||
modifier = Modifier.defaultMinSize(52.dp, 32.dp),
|
modifier = Modifier.defaultMinSize(52.dp, 32.dp),
|
||||||
onClick = { onRestore(module) },
|
enabled = !module.remove,
|
||||||
contentPadding = ButtonDefaults.TextButtonContentPadding
|
onClick = { onUpdate(module) },
|
||||||
) {
|
shape = ButtonDefaults.textShape,
|
||||||
Icon(
|
contentPadding = ButtonDefaults.TextButtonContentPadding
|
||||||
modifier = Modifier.size(20.dp),
|
) {
|
||||||
imageVector = Icons.Outlined.Restore,
|
Icon(
|
||||||
contentDescription = null
|
modifier = Modifier.size(20.dp),
|
||||||
)
|
imageVector = Icons.Outlined.Download,
|
||||||
|
contentDescription = null
|
||||||
|
)
|
||||||
|
if (!module.hasActionScript || !module.hasWebUi) {
|
||||||
|
Text(
|
||||||
|
modifier = Modifier.padding(start = 7.dp),
|
||||||
|
fontFamily = MaterialTheme.typography.labelMedium.fontFamily,
|
||||||
|
fontSize = MaterialTheme.typography.labelMedium.fontSize,
|
||||||
|
text = stringResource(R.string.module_update)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.weight(0.1f, true))
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
FilledTonalButton(
|
if (module.remove) {
|
||||||
modifier = Modifier.defaultMinSize(52.dp, 32.dp),
|
FilledTonalButton(
|
||||||
enabled = true,
|
modifier = Modifier.defaultMinSize(52.dp, 32.dp),
|
||||||
onClick = { onUninstall(module) },
|
onClick = { onRestore(module) },
|
||||||
contentPadding = ButtonDefaults.TextButtonContentPadding
|
contentPadding = ButtonDefaults.TextButtonContentPadding
|
||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
modifier = Modifier.size(20.dp),
|
modifier = Modifier.size(20.dp),
|
||||||
imageVector = Icons.Outlined.Delete,
|
imageVector = Icons.Outlined.Restore,
|
||||||
contentDescription = null
|
contentDescription = null
|
||||||
)
|
)
|
||||||
|
if (!module.hasActionScript && !module.hasWebUi && updateUrl.isEmpty()) {
|
||||||
|
Text(
|
||||||
|
modifier = Modifier.padding(start = 7.dp),
|
||||||
|
fontFamily = MaterialTheme.typography.labelMedium.fontFamily,
|
||||||
|
fontSize = MaterialTheme.typography.labelMedium.fontSize,
|
||||||
|
text = stringResource(R.string.restore)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
FilledTonalButton(
|
||||||
|
modifier = Modifier.defaultMinSize(52.dp, 32.dp),
|
||||||
|
enabled = true,
|
||||||
|
onClick = { onUninstall(module) },
|
||||||
|
contentPadding = ButtonDefaults.TextButtonContentPadding
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
modifier = Modifier.size(20.dp),
|
||||||
|
imageVector = Icons.Outlined.Delete,
|
||||||
|
contentDescription = null
|
||||||
|
)
|
||||||
|
if (!module.hasActionScript && !module.hasWebUi && updateUrl.isEmpty()) {
|
||||||
|
Text(
|
||||||
|
modifier = Modifier.padding(start = 7.dp),
|
||||||
|
fontFamily = MaterialTheme.typography.labelMedium.fontFamily,
|
||||||
|
fontSize = MaterialTheme.typography.labelMedium.fontSize,
|
||||||
|
text = stringResource(R.string.uninstall)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1056,5 +1139,5 @@ fun ModuleItemPreview() {
|
|||||||
size = 12345678L,
|
size = 12345678L,
|
||||||
banner = ""
|
banner = ""
|
||||||
)
|
)
|
||||||
ModuleItem(EmptyDestinationsNavigator, module, "", {}, {}, {}, {}, {})
|
ModuleItem(EmptyDestinationsNavigator, module, "", {}, {}, {}, {}, {}, false, {})
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user