* fix(#548): stop System tab button text truncation + fix two wrong labels * fix(system): remove inline icons from narrow system action buttons to prevent text cutoff * fix(system): restore action icons and implement dynamic font scaling for button text * fix: stack icon above text in system buttons to prevent label clipping Replace horizontal Icon+Text layout with vertical Column stacking (icon on top, text centered below) — the same pattern Material 3 NavigationBar items use. Gives text the full button width so labels like 'Security Audit' and 'Config Migrate' never get cut off. * fix: add missing ImageVector import for system buttons fix --------- Co-authored-by: M57 <m57@hermes-control.app>
This commit is contained in:
1 parent
9156064d2b
commit
cc917afcbd
2 files changed
+150
-89
No files matched your search
@@ -59,12 +59,15 @@ import androidx.compose.runtime.remember
|
|||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.vector.ImageVector
|
||||||
import androidx.compose.ui.platform.LocalClipboardManager
|
import androidx.compose.ui.platform.LocalClipboardManager
|
||||||
import androidx.compose.ui.platform.LocalUriHandler
|
import androidx.compose.ui.platform.LocalUriHandler
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.AnnotatedString
|
import androidx.compose.ui.text.AnnotatedString
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.text.input.KeyboardType
|
import androidx.compose.ui.text.input.KeyboardType
|
||||||
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
@@ -378,32 +381,32 @@ private fun LazyListScope.hostSection(
|
|||||||
onClick = { viewModel.checkForUpdate(false) },
|
onClick = { viewModel.checkForUpdate(false) },
|
||||||
enabled = !state.checkingUpdate,
|
enabled = !state.checkingUpdate,
|
||||||
modifier = Modifier.weight(1f),
|
modifier = Modifier.weight(1f),
|
||||||
|
contentPadding = actionButtonPadding,
|
||||||
) {
|
) {
|
||||||
if (state.checkingUpdate) {
|
if (state.checkingUpdate) {
|
||||||
androidx.compose.material3.CircularProgressIndicator(
|
ActionButtonContent(
|
||||||
modifier = Modifier.size(16.dp),
|
icon = null,
|
||||||
strokeWidth = 2.dp,
|
text = stringResource(R.string.system_action_check_updates),
|
||||||
|
loading = true,
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.size(spacing.sm))
|
|
||||||
} else {
|
} else {
|
||||||
Icon(Icons.Filled.Update, contentDescription = null, modifier = Modifier.size(18.dp))
|
ActionButtonContent(
|
||||||
Spacer(modifier = Modifier.size(spacing.xs))
|
icon = Icons.Filled.Update,
|
||||||
|
text = stringResource(R.string.system_action_check_updates),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
Text(stringResource(R.string.system_action_check_updates), maxLines = 1)
|
|
||||||
}
|
}
|
||||||
state.updateInfo?.let { info ->
|
state.updateInfo?.let { info ->
|
||||||
if (info.update_available == true && info.can_apply == true) {
|
if (info.update_available == true && info.can_apply == true) {
|
||||||
Button(
|
Button(
|
||||||
onClick = { viewModel.openUpdateConfirm() },
|
onClick = { viewModel.openUpdateConfirm() },
|
||||||
modifier = Modifier.weight(1f),
|
modifier = Modifier.weight(1f),
|
||||||
|
contentPadding = actionButtonPadding,
|
||||||
) {
|
) {
|
||||||
Icon(
|
ActionButtonContent(
|
||||||
Icons.Filled.PlayArrow,
|
icon = Icons.Filled.PlayArrow,
|
||||||
contentDescription = null,
|
text = stringResource(R.string.system_action_update_now),
|
||||||
modifier = Modifier.size(18.dp),
|
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.size(spacing.xs))
|
|
||||||
Text(stringResource(R.string.system_action_update_now), maxLines = 1)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -571,7 +574,11 @@ private fun LazyListScope.portalSection(
|
|||||||
) {
|
) {
|
||||||
Icon(Icons.Filled.Link, contentDescription = null, modifier = Modifier.size(16.dp))
|
Icon(Icons.Filled.Link, contentDescription = null, modifier = Modifier.size(16.dp))
|
||||||
Spacer(modifier = Modifier.size(spacing.xs))
|
Spacer(modifier = Modifier.size(spacing.xs))
|
||||||
Text(stringResource(R.string.system_portal_manage_subscription))
|
Text(
|
||||||
|
stringResource(R.string.system_portal_manage_subscription),
|
||||||
|
maxLines = 1,
|
||||||
|
softWrap = false,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -668,28 +675,29 @@ private fun LazyListScope.curatorSection(
|
|||||||
OutlinedButton(
|
OutlinedButton(
|
||||||
onClick = { viewModel.toggleCuratorPaused() },
|
onClick = { viewModel.toggleCuratorPaused() },
|
||||||
modifier = Modifier.weight(1f),
|
modifier = Modifier.weight(1f),
|
||||||
|
contentPadding = actionButtonPadding,
|
||||||
) {
|
) {
|
||||||
if (curator.paused == true) {
|
if (curator.paused == true) {
|
||||||
Icon(
|
ActionButtonContent(
|
||||||
Icons.Filled.PlayArrow,
|
icon = Icons.Filled.PlayArrow,
|
||||||
contentDescription = null,
|
text = stringResource(R.string.system_curator_resume),
|
||||||
modifier = Modifier.size(18.dp),
|
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.size(spacing.xs))
|
|
||||||
Text(stringResource(R.string.system_curator_resume), maxLines = 1)
|
|
||||||
} else {
|
} else {
|
||||||
Icon(Icons.Filled.Pause, contentDescription = null, modifier = Modifier.size(18.dp))
|
ActionButtonContent(
|
||||||
Spacer(modifier = Modifier.size(spacing.xs))
|
icon = Icons.Filled.Pause,
|
||||||
Text(stringResource(R.string.system_curator_pause), maxLines = 1)
|
text = stringResource(R.string.system_curator_pause),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Button(
|
Button(
|
||||||
onClick = { viewModel.runCuratorNow() },
|
onClick = { viewModel.runCuratorNow() },
|
||||||
modifier = Modifier.weight(1f),
|
modifier = Modifier.weight(1f),
|
||||||
|
contentPadding = actionButtonPadding,
|
||||||
) {
|
) {
|
||||||
Icon(Icons.Filled.Refresh, contentDescription = null, modifier = Modifier.size(18.dp))
|
ActionButtonContent(
|
||||||
Spacer(modifier = Modifier.size(spacing.xs))
|
icon = Icons.Filled.Refresh,
|
||||||
Text(stringResource(R.string.system_curator_run_now), maxLines = 1)
|
text = stringResource(R.string.system_curator_run_now),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -812,40 +820,35 @@ private fun LazyListScope.gatewaySection(
|
|||||||
Button(
|
Button(
|
||||||
onClick = { viewModel.startGateway() },
|
onClick = { viewModel.startGateway() },
|
||||||
modifier = Modifier.weight(1f),
|
modifier = Modifier.weight(1f),
|
||||||
|
contentPadding = actionButtonPadding,
|
||||||
) {
|
) {
|
||||||
Icon(Icons.Filled.PlayArrow, contentDescription = null, modifier = Modifier.size(18.dp))
|
ActionButtonContent(
|
||||||
Spacer(modifier = Modifier.size(spacing.xs))
|
icon = Icons.Filled.PlayArrow,
|
||||||
Text(stringResource(R.string.system_gateway_start), maxLines = 1)
|
text = stringResource(R.string.system_gateway_start),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isRunning) {
|
if (isRunning) {
|
||||||
Button(
|
Button(
|
||||||
onClick = { viewModel.restartGateway() },
|
onClick = { viewModel.restartGateway() },
|
||||||
modifier = Modifier.weight(1f),
|
modifier = Modifier.weight(1f),
|
||||||
|
contentPadding = actionButtonPadding,
|
||||||
) {
|
) {
|
||||||
Icon(
|
ActionButtonContent(
|
||||||
Icons.Filled.RestartAlt,
|
icon = Icons.Filled.RestartAlt,
|
||||||
contentDescription = null,
|
text = stringResource(R.string.system_gateway_restart),
|
||||||
modifier = Modifier.size(18.dp),
|
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.size(spacing.xs))
|
|
||||||
Text(stringResource(R.string.system_gateway_restart), maxLines = 1)
|
|
||||||
}
|
}
|
||||||
OutlinedButton(
|
OutlinedButton(
|
||||||
onClick = { viewModel.stopGateway() },
|
onClick = { viewModel.stopGateway() },
|
||||||
modifier = Modifier.weight(1f),
|
modifier = Modifier.weight(1f),
|
||||||
|
contentPadding = actionButtonPadding,
|
||||||
) {
|
) {
|
||||||
Icon(
|
ActionButtonContent(
|
||||||
Icons.Filled.Stop,
|
icon = Icons.Filled.Stop,
|
||||||
contentDescription = null,
|
text = stringResource(R.string.system_gateway_stop),
|
||||||
modifier = Modifier.size(18.dp),
|
iconTint = MaterialTheme.colorScheme.error,
|
||||||
tint = MaterialTheme.colorScheme.error,
|
textColor = MaterialTheme.colorScheme.error,
|
||||||
)
|
|
||||||
Spacer(modifier = Modifier.size(spacing.xs))
|
|
||||||
Text(
|
|
||||||
stringResource(R.string.system_gateway_stop),
|
|
||||||
color = MaterialTheme.colorScheme.error,
|
|
||||||
maxLines = 1,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -915,30 +918,32 @@ private fun LazyListScope.memorySection(
|
|||||||
FilledTonalButton(
|
FilledTonalButton(
|
||||||
onClick = { onResetRequest("memory") },
|
onClick = { onResetRequest("memory") },
|
||||||
modifier = Modifier.weight(1f),
|
modifier = Modifier.weight(1f),
|
||||||
|
contentPadding = actionButtonPadding,
|
||||||
) {
|
) {
|
||||||
Icon(Icons.Filled.Delete, contentDescription = null, modifier = Modifier.size(14.dp))
|
ActionButtonContent(
|
||||||
Spacer(modifier = Modifier.size(spacing.xs))
|
icon = Icons.Filled.Delete,
|
||||||
Text(stringResource(R.string.system_memory_reset_memory), maxLines = 1)
|
text = stringResource(R.string.system_memory_reset_memory),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
FilledTonalButton(
|
FilledTonalButton(
|
||||||
onClick = { onResetRequest("user") },
|
onClick = { onResetRequest("user") },
|
||||||
modifier = Modifier.weight(1f),
|
modifier = Modifier.weight(1f),
|
||||||
|
contentPadding = actionButtonPadding,
|
||||||
) {
|
) {
|
||||||
Icon(Icons.Filled.Delete, contentDescription = null, modifier = Modifier.size(14.dp))
|
ActionButtonContent(
|
||||||
Spacer(modifier = Modifier.size(spacing.xs))
|
icon = Icons.Filled.Delete,
|
||||||
Text(stringResource(R.string.system_memory_reset_user), maxLines = 1)
|
text = stringResource(R.string.system_memory_reset_user),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
FilledTonalButton(
|
FilledTonalButton(
|
||||||
onClick = { onResetRequest("all") },
|
onClick = { onResetRequest("all") },
|
||||||
modifier = Modifier.weight(1f),
|
modifier = Modifier.weight(1f),
|
||||||
|
contentPadding = actionButtonPadding,
|
||||||
) {
|
) {
|
||||||
Icon(
|
ActionButtonContent(
|
||||||
Icons.Filled.DeleteForever,
|
icon = Icons.Filled.DeleteForever,
|
||||||
contentDescription = null,
|
text = stringResource(R.string.system_memory_reset_all),
|
||||||
modifier = Modifier.size(14.dp),
|
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.size(spacing.xs))
|
|
||||||
Text(stringResource(R.string.system_memory_reset_all), maxLines = 1)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1032,7 +1037,7 @@ private fun LazyListScope.credentialsSection(
|
|||||||
Icon(Icons.Filled.Add, contentDescription = null, modifier = Modifier.size(18.dp))
|
Icon(Icons.Filled.Add, contentDescription = null, modifier = Modifier.size(18.dp))
|
||||||
Spacer(modifier = Modifier.size(spacing.xs))
|
Spacer(modifier = Modifier.size(spacing.xs))
|
||||||
}
|
}
|
||||||
Text(stringResource(R.string.system_credentials_add_key))
|
Text(stringResource(R.string.system_credentials_add_key), maxLines = 1, softWrap = false)
|
||||||
}
|
}
|
||||||
|
|
||||||
HorizontalDivider(modifier = Modifier.padding(vertical = spacing.sm))
|
HorizontalDivider(modifier = Modifier.padding(vertical = spacing.sm))
|
||||||
@@ -1098,26 +1103,32 @@ private fun LazyListScope.operationsSection(
|
|||||||
viewModel.loadAll()
|
viewModel.loadAll()
|
||||||
},
|
},
|
||||||
modifier = Modifier.weight(1f),
|
modifier = Modifier.weight(1f),
|
||||||
|
contentPadding = actionButtonPadding,
|
||||||
) {
|
) {
|
||||||
Icon(Icons.Filled.HealthAndSafety, contentDescription = null, modifier = Modifier.size(16.dp))
|
ActionButtonContent(
|
||||||
Spacer(modifier = Modifier.size(spacing.xs))
|
icon = Icons.Filled.HealthAndSafety,
|
||||||
Text(stringResource(R.string.system_op_doctor), maxLines = 1)
|
text = stringResource(R.string.system_op_doctor),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
FilledTonalButton(
|
FilledTonalButton(
|
||||||
onClick = { viewModel.runSecurityAudit() },
|
onClick = { viewModel.runSecurityAudit() },
|
||||||
modifier = Modifier.weight(1f),
|
modifier = Modifier.weight(1f),
|
||||||
|
contentPadding = actionButtonPadding,
|
||||||
) {
|
) {
|
||||||
Icon(Icons.Filled.VerifiedUser, contentDescription = null, modifier = Modifier.size(16.dp))
|
ActionButtonContent(
|
||||||
Spacer(modifier = Modifier.size(spacing.xs))
|
icon = Icons.Filled.VerifiedUser,
|
||||||
Text(stringResource(R.string.system_op_security_audit), maxLines = 1)
|
text = stringResource(R.string.system_op_security_audit),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
FilledTonalButton(
|
FilledTonalButton(
|
||||||
onClick = { viewModel.runUpdateSkills() },
|
onClick = { viewModel.runUpdateSkills() },
|
||||||
modifier = Modifier.weight(1f),
|
modifier = Modifier.weight(1f),
|
||||||
|
contentPadding = actionButtonPadding,
|
||||||
) {
|
) {
|
||||||
Icon(Icons.Filled.Refresh, contentDescription = null, modifier = Modifier.size(16.dp))
|
ActionButtonContent(
|
||||||
Spacer(modifier = Modifier.size(spacing.xs))
|
icon = Icons.Filled.Refresh,
|
||||||
Text(stringResource(R.string.system_op_update_skills), maxLines = 1)
|
text = stringResource(R.string.system_op_update_skills),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1131,26 +1142,32 @@ private fun LazyListScope.operationsSection(
|
|||||||
FilledTonalButton(
|
FilledTonalButton(
|
||||||
onClick = { viewModel.runPromptSize() },
|
onClick = { viewModel.runPromptSize() },
|
||||||
modifier = Modifier.weight(1f),
|
modifier = Modifier.weight(1f),
|
||||||
|
contentPadding = actionButtonPadding,
|
||||||
) {
|
) {
|
||||||
Icon(Icons.Filled.HealthAndSafety, contentDescription = null, modifier = Modifier.size(16.dp))
|
ActionButtonContent(
|
||||||
Spacer(modifier = Modifier.size(spacing.xs))
|
icon = Icons.Filled.HealthAndSafety,
|
||||||
Text(stringResource(R.string.system_op_prompt_size), maxLines = 1)
|
text = stringResource(R.string.system_op_prompt_size),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
FilledTonalButton(
|
FilledTonalButton(
|
||||||
onClick = { viewModel.runDump() },
|
onClick = { viewModel.runDump() },
|
||||||
modifier = Modifier.weight(1f),
|
modifier = Modifier.weight(1f),
|
||||||
|
contentPadding = actionButtonPadding,
|
||||||
) {
|
) {
|
||||||
Icon(Icons.Filled.Build, contentDescription = null, modifier = Modifier.size(16.dp))
|
ActionButtonContent(
|
||||||
Spacer(modifier = Modifier.size(spacing.xs))
|
icon = Icons.Filled.Build,
|
||||||
Text(stringResource(R.string.system_op_dump), maxLines = 1)
|
text = stringResource(R.string.system_op_dump),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
FilledTonalButton(
|
FilledTonalButton(
|
||||||
onClick = { viewModel.runConfigMigrate() },
|
onClick = { viewModel.runConfigMigrate() },
|
||||||
modifier = Modifier.weight(1f),
|
modifier = Modifier.weight(1f),
|
||||||
|
contentPadding = actionButtonPadding,
|
||||||
) {
|
) {
|
||||||
Icon(Icons.Filled.Build, contentDescription = null, modifier = Modifier.size(16.dp))
|
ActionButtonContent(
|
||||||
Spacer(modifier = Modifier.size(spacing.xs))
|
icon = Icons.Filled.Build,
|
||||||
Text(stringResource(R.string.system_op_config_migrate), maxLines = 1)
|
text = stringResource(R.string.system_op_config_migrate),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1158,7 +1175,7 @@ private fun LazyListScope.operationsSection(
|
|||||||
|
|
||||||
// Backup section
|
// Backup section
|
||||||
Text(
|
Text(
|
||||||
text = stringResource(R.string.system_op_backup_create),
|
text = stringResource(R.string.system_sec_backup),
|
||||||
style = MaterialTheme.typography.titleSmall,
|
style = MaterialTheme.typography.titleSmall,
|
||||||
fontWeight = FontWeight.SemiBold,
|
fontWeight = FontWeight.SemiBold,
|
||||||
)
|
)
|
||||||
@@ -1171,26 +1188,30 @@ private fun LazyListScope.operationsSection(
|
|||||||
Button(
|
Button(
|
||||||
onClick = { viewModel.triggerBackup() },
|
onClick = { viewModel.triggerBackup() },
|
||||||
modifier = Modifier.weight(1f),
|
modifier = Modifier.weight(1f),
|
||||||
|
contentPadding = actionButtonPadding,
|
||||||
) {
|
) {
|
||||||
Icon(Icons.Filled.Backup, contentDescription = null, modifier = Modifier.size(18.dp))
|
ActionButtonContent(
|
||||||
Spacer(modifier = Modifier.size(spacing.xs))
|
icon = Icons.Filled.Backup,
|
||||||
Text(stringResource(R.string.system_op_backup_create), maxLines = 1)
|
text = stringResource(R.string.system_op_backup_create),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
OutlinedButton(
|
OutlinedButton(
|
||||||
onClick = { viewModel.downloadBackup() },
|
onClick = { viewModel.downloadBackup() },
|
||||||
enabled = state.backupArchive != null,
|
enabled = state.backupArchive != null,
|
||||||
modifier = Modifier.weight(1f),
|
modifier = Modifier.weight(1f),
|
||||||
|
contentPadding = actionButtonPadding,
|
||||||
) {
|
) {
|
||||||
Icon(Icons.Filled.CloudDownload, contentDescription = null, modifier = Modifier.size(18.dp))
|
ActionButtonContent(
|
||||||
Spacer(modifier = Modifier.size(spacing.xs))
|
icon = Icons.Filled.CloudDownload,
|
||||||
Text(stringResource(R.string.system_op_backup_download), maxLines = 1)
|
text = stringResource(R.string.system_op_backup_download),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restore from uploaded zip
|
// Restore from uploaded zip
|
||||||
Spacer(modifier = Modifier.height(spacing.sm))
|
Spacer(modifier = Modifier.height(spacing.sm))
|
||||||
Text(
|
Text(
|
||||||
text = stringResource(R.string.system_op_backup_restore_upload),
|
text = stringResource(R.string.system_sec_restore),
|
||||||
style = MaterialTheme.typography.titleSmall,
|
style = MaterialTheme.typography.titleSmall,
|
||||||
fontWeight = FontWeight.SemiBold,
|
fontWeight = FontWeight.SemiBold,
|
||||||
)
|
)
|
||||||
@@ -1219,7 +1240,7 @@ private fun LazyListScope.operationsSection(
|
|||||||
) {
|
) {
|
||||||
Icon(Icons.Filled.RestartAlt, contentDescription = null, modifier = Modifier.size(18.dp))
|
Icon(Icons.Filled.RestartAlt, contentDescription = null, modifier = Modifier.size(18.dp))
|
||||||
Spacer(modifier = Modifier.size(spacing.xs))
|
Spacer(modifier = Modifier.size(spacing.xs))
|
||||||
Text(stringResource(R.string.system_op_restore_upload))
|
Text(stringResource(R.string.system_op_restore_upload), maxLines = 1, softWrap = false)
|
||||||
}
|
}
|
||||||
|
|
||||||
HorizontalDivider(modifier = Modifier.padding(vertical = spacing.sm))
|
HorizontalDivider(modifier = Modifier.padding(vertical = spacing.sm))
|
||||||
@@ -1270,6 +1291,8 @@ private fun LazyListScope.operationsSection(
|
|||||||
} else {
|
} else {
|
||||||
stringResource(R.string.system_debug_share_generate)
|
stringResource(R.string.system_debug_share_generate)
|
||||||
},
|
},
|
||||||
|
maxLines = 1,
|
||||||
|
softWrap = false,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1288,7 +1311,7 @@ private fun LazyListScope.operationsSection(
|
|||||||
if (share.ok == true) {
|
if (share.ok == true) {
|
||||||
stringResource(R.string.system_debug_share_uploaded)
|
stringResource(R.string.system_debug_share_uploaded)
|
||||||
} else {
|
} else {
|
||||||
stringResource(R.string.system_status_stopped)
|
stringResource(R.string.system_debug_share_failed)
|
||||||
},
|
},
|
||||||
status = if (share.ok == true) StatusBadgeType.SUCCESS else StatusBadgeType.ERROR,
|
status = if (share.ok == true) StatusBadgeType.SUCCESS else StatusBadgeType.ERROR,
|
||||||
)
|
)
|
||||||
@@ -1384,7 +1407,7 @@ private fun LazyListScope.checkpointsSection(
|
|||||||
) {
|
) {
|
||||||
Icon(Icons.Filled.DeleteForever, contentDescription = null, modifier = Modifier.size(18.dp))
|
Icon(Icons.Filled.DeleteForever, contentDescription = null, modifier = Modifier.size(18.dp))
|
||||||
Spacer(modifier = Modifier.size(spacing.xs))
|
Spacer(modifier = Modifier.size(spacing.xs))
|
||||||
Text(stringResource(R.string.system_checkpoints_prune))
|
Text(stringResource(R.string.system_checkpoints_prune), maxLines = 1, softWrap = false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1406,7 +1429,7 @@ private fun LazyListScope.shellHooksSection(
|
|||||||
FilledTonalButton(onClick = { viewModel.toggleHookModal() }) {
|
FilledTonalButton(onClick = { viewModel.toggleHookModal() }) {
|
||||||
Icon(Icons.Filled.Add, contentDescription = null, modifier = Modifier.size(16.dp))
|
Icon(Icons.Filled.Add, contentDescription = null, modifier = Modifier.size(16.dp))
|
||||||
Spacer(modifier = Modifier.size(spacing.xs))
|
Spacer(modifier = Modifier.size(spacing.xs))
|
||||||
Text(stringResource(R.string.system_hooks_new))
|
Text(stringResource(R.string.system_hooks_new), maxLines = 1, softWrap = false)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@@ -1612,3 +1635,38 @@ private fun LazyListScope.actionLogSection(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val actionButtonPadding =
|
||||||
|
androidx.compose.foundation.layout.PaddingValues(horizontal = 8.dp, vertical = 8.dp)
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun ActionButtonContent(
|
||||||
|
icon: ImageVector?,
|
||||||
|
text: String,
|
||||||
|
iconTint: androidx.compose.ui.graphics.Color = androidx.compose.material3.LocalContentColor.current,
|
||||||
|
textColor: androidx.compose.ui.graphics.Color = androidx.compose.ui.graphics.Color.Unspecified,
|
||||||
|
loading: Boolean = false,
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
) {
|
||||||
|
if (loading) {
|
||||||
|
androidx.compose.material3.CircularProgressIndicator(
|
||||||
|
modifier = Modifier.size(18.dp),
|
||||||
|
strokeWidth = 2.dp,
|
||||||
|
)
|
||||||
|
} else if (icon != null) {
|
||||||
|
Icon(icon, contentDescription = null, modifier = Modifier.size(18.dp), tint = iconTint)
|
||||||
|
}
|
||||||
|
Spacer(modifier = Modifier.height(2.dp))
|
||||||
|
Text(
|
||||||
|
text = text,
|
||||||
|
style = MaterialTheme.typography.labelSmall,
|
||||||
|
color = textColor,
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
maxLines = 2,
|
||||||
|
overflow = TextOverflow.Ellipsis,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -396,6 +396,8 @@
|
|||||||
<string name="system_op_backup_create">Create backup</string>
|
<string name="system_op_backup_create">Create backup</string>
|
||||||
<string name="system_op_backup_download">Download backup</string>
|
<string name="system_op_backup_download">Download backup</string>
|
||||||
<string name="system_op_backup_restore_upload">Restore from backup upload</string>
|
<string name="system_op_backup_restore_upload">Restore from backup upload</string>
|
||||||
|
<string name="system_sec_backup">Backup</string>
|
||||||
|
<string name="system_sec_restore">Restore from upload</string>
|
||||||
<string name="system_op_choose_zip">Choose restore zip</string>
|
<string name="system_op_choose_zip">Choose restore zip</string>
|
||||||
<string name="system_op_restore_upload">Restore upload</string>
|
<string name="system_op_restore_upload">Restore upload</string>
|
||||||
<string name="system_op_restore_path_label">Restore from backups path</string>
|
<string name="system_op_restore_path_label">Restore from backups path</string>
|
||||||
@@ -416,6 +418,7 @@
|
|||||||
<string name="system_debug_share_not_redacted">not redacted</string>
|
<string name="system_debug_share_not_redacted">not redacted</string>
|
||||||
<string name="system_debug_share_auto_delete">auto-deletes in %1$dh</string>
|
<string name="system_debug_share_auto_delete">auto-deletes in %1$dh</string>
|
||||||
<string name="system_debug_share_copy_all">Copy all</string>
|
<string name="system_debug_share_copy_all">Copy all</string>
|
||||||
|
<string name="system_debug_share_failed">upload failed</string>
|
||||||
|
|
||||||
<!-- Checkpoints section -->
|
<!-- Checkpoints section -->
|
||||||
<string name="system_sec_checkpoints">Checkpoints</string>
|
<string name="system_sec_checkpoints">Checkpoints</string>
|
||||||
|
|||||||
Reference in new issue
Block a user