android: spacing tokens - migrate padding/spacing literals and ScreenPadding to ShxSpacing
This commit is contained in:
1 parent
22e4082825
commit
0e5e28b4da
21 files changed
+141
-140
No files matched your search
@@ -51,6 +51,7 @@ import org.strongswan.android.data.LogContentProvider
|
||||
import org.strongswan.android.logic.CharonVpnService
|
||||
import org.strongswan.android.logic.DiagLog
|
||||
import org.strongswan.android.ui.compose.SecondaryScaffold
|
||||
import org.strongswan.android.ui.compose.theme.ShxSpacing
|
||||
import org.strongswan.android.ui.compose.theme.ShxTheme
|
||||
import java.io.BufferedReader
|
||||
import java.io.File
|
||||
@@ -194,7 +195,7 @@ private fun LogScreen(onBack: () -> Unit, onSend: () -> Unit, viewModel: LogView
|
||||
{
|
||||
Text(
|
||||
stringResource(R.string.empty_log),
|
||||
modifier = Modifier.padding(padding).padding(24.dp),
|
||||
modifier = Modifier.padding(padding).padding(ShxSpacing.xl),
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
}
|
||||
@@ -202,7 +203,7 @@ private fun LogScreen(onBack: () -> Unit, onSend: () -> Unit, viewModel: LogView
|
||||
{
|
||||
LazyColumn(
|
||||
state = listState,
|
||||
modifier = Modifier.fillMaxSize().padding(padding).padding(horizontal = 12.dp),
|
||||
modifier = Modifier.fillMaxSize().padding(padding).padding(horizontal = ShxSpacing.md),
|
||||
) {
|
||||
items(lines.size) { index ->
|
||||
val line = lines[index]
|
||||
|
||||
+11
-11
@@ -65,7 +65,7 @@ import org.strongswan.android.logic.imc.RemediationInstruction
|
||||
import org.strongswan.android.ui.compose.components.ShxCard
|
||||
import org.strongswan.android.ui.compose.components.ShxEmptyState
|
||||
import org.strongswan.android.ui.compose.components.ShxSectionDivider
|
||||
import org.strongswan.android.ui.compose.theme.ScreenPadding
|
||||
import org.strongswan.android.ui.compose.theme.ShxSpacing
|
||||
import org.strongswan.android.ui.compose.theme.ShxTheme
|
||||
|
||||
/**
|
||||
@@ -167,7 +167,7 @@ private fun RemediationUi(
|
||||
ShxEmptyState(
|
||||
icon = Icons.Rounded.CheckCircle,
|
||||
message = stringResource(R.string.remediation_instructions_title),
|
||||
modifier = Modifier.padding(ScreenPadding),
|
||||
modifier = Modifier.padding(ShxSpacing.lg),
|
||||
)
|
||||
}
|
||||
else
|
||||
@@ -179,19 +179,19 @@ private fun RemediationUi(
|
||||
itemsIndexed(instructions) { index, item ->
|
||||
ShxCard(
|
||||
modifier = Modifier
|
||||
.padding(horizontal = ScreenPadding, vertical = 6.dp)
|
||||
.padding(horizontal = ShxSpacing.lg, vertical = 6.dp)
|
||||
.animateItem(),
|
||||
) {
|
||||
Column(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable { onSelect(item) }
|
||||
.padding(16.dp),
|
||||
.padding(ShxSpacing.lg),
|
||||
) {
|
||||
Text(item.getTitle(), style = MaterialTheme.typography.titleMedium)
|
||||
if (!item.getDescription().isNullOrEmpty())
|
||||
{
|
||||
Spacer(Modifier.height(4.dp))
|
||||
Spacer(Modifier.height(ShxSpacing.xs))
|
||||
Text(
|
||||
item.getDescription(),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
@@ -210,12 +210,12 @@ private fun RemediationUi(
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.verticalScroll(rememberScrollState())
|
||||
.padding(horizontal = ScreenPadding),
|
||||
.padding(horizontal = ShxSpacing.lg),
|
||||
) {
|
||||
Text(
|
||||
instruction.getDescription(),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
modifier = Modifier.padding(top = 8.dp),
|
||||
modifier = Modifier.padding(top = ShxSpacing.sm),
|
||||
)
|
||||
if (!instruction.getHeader().isNullOrEmpty())
|
||||
{
|
||||
@@ -223,15 +223,15 @@ private fun RemediationUi(
|
||||
instruction.getHeader(),
|
||||
style = MaterialTheme.typography.titleSmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
modifier = Modifier.padding(top = 20.dp, bottom = 8.dp),
|
||||
modifier = Modifier.padding(top = 20.dp, bottom = ShxSpacing.sm),
|
||||
)
|
||||
ShxCard {
|
||||
Column(Modifier.padding(vertical = 4.dp)) {
|
||||
Column(Modifier.padding(vertical = ShxSpacing.xs)) {
|
||||
instruction.getItems().forEachIndexed { index, item ->
|
||||
Text(
|
||||
item,
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
modifier = Modifier.padding(horizontal = 16.dp, vertical = 10.dp),
|
||||
modifier = Modifier.padding(horizontal = ShxSpacing.lg, vertical = 10.dp),
|
||||
)
|
||||
if (index < instruction.getItems().lastIndex)
|
||||
{
|
||||
@@ -241,7 +241,7 @@ private fun RemediationUi(
|
||||
}
|
||||
}
|
||||
}
|
||||
Spacer(Modifier.height(24.dp))
|
||||
Spacer(Modifier.height(ShxSpacing.xl))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-2
@@ -52,6 +52,7 @@ import org.strongswan.android.R
|
||||
import org.strongswan.android.data.VpnProfileDataSource
|
||||
import org.strongswan.android.ui.adapter.SelectedApplicationEntry
|
||||
import org.strongswan.android.ui.compose.SecondaryScaffold
|
||||
import org.strongswan.android.ui.compose.theme.ShxSpacing
|
||||
import org.strongswan.android.ui.compose.theme.ShxTheme
|
||||
import java.util.TreeSet
|
||||
|
||||
@@ -161,11 +162,11 @@ private fun SelectedAppsScreen(
|
||||
onValueChange = { query = it },
|
||||
label = { Text(stringResource(R.string.search)) },
|
||||
singleLine = true,
|
||||
modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp).fillMaxWidth(),
|
||||
modifier = Modifier.padding(horizontal = ShxSpacing.lg, vertical = ShxSpacing.sm).fillMaxWidth(),
|
||||
)
|
||||
if (loading)
|
||||
{
|
||||
LoadingIndicator(Modifier.padding(24.dp).size(32.dp))
|
||||
LoadingIndicator(Modifier.padding(ShxSpacing.xl).size(32.dp))
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
+7
-7
@@ -61,7 +61,7 @@ import org.strongswan.android.logic.connectivity.HealthCheckManager
|
||||
import org.strongswan.android.logic.connectivity.HealthConfig
|
||||
import org.strongswan.android.logic.connectivity.ProbeTarget
|
||||
import org.strongswan.android.logic.connectivity.ServerCheckMode
|
||||
import org.strongswan.android.ui.compose.theme.ScreenPadding
|
||||
import org.strongswan.android.ui.compose.theme.ShxSpacing
|
||||
|
||||
/**
|
||||
* Connectivity check settings: what to probe, how often, and what to do when
|
||||
@@ -86,7 +86,7 @@ fun ConnectivityCheckScreen()
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.verticalScroll(rememberScrollState())
|
||||
.padding(bottom = 24.dp),
|
||||
.padding(bottom = ShxSpacing.xl),
|
||||
)
|
||||
{
|
||||
ShxSection(title = stringResource(R.string.settings_section_general))
|
||||
@@ -153,14 +153,14 @@ fun ConnectivityCheckScreen()
|
||||
|
||||
ShxSection(title = stringResource(R.string.health_check_server_down_title))
|
||||
{
|
||||
Column(Modifier.padding(horizontal = 16.dp, vertical = 10.dp))
|
||||
Column(Modifier.padding(horizontal = ShxSpacing.lg, vertical = 10.dp))
|
||||
{
|
||||
Text(
|
||||
stringResource(R.string.health_check_mode),
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
color = if (config.enabled) MaterialTheme.colorScheme.onSurface else MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
SingleChoiceSegmentedButtonRow(Modifier.fillMaxWidth().padding(top = 8.dp))
|
||||
SingleChoiceSegmentedButtonRow(Modifier.fillMaxWidth().padding(top = ShxSpacing.sm))
|
||||
{
|
||||
ServerCheckMode.entries.forEachIndexed { index, mode ->
|
||||
SegmentedButton(
|
||||
@@ -270,7 +270,7 @@ fun ConnectivityCheckScreen()
|
||||
)
|
||||
{
|
||||
RadioButton(selected = config.intervalSec == seconds, onClick = null)
|
||||
Text(intervalLabel(seconds, false), modifier = Modifier.padding(start = 12.dp))
|
||||
Text(intervalLabel(seconds, false), modifier = Modifier.padding(start = ShxSpacing.md))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -331,7 +331,7 @@ private fun AttemptsRow(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp, vertical = 10.dp),
|
||||
.padding(horizontal = ShxSpacing.lg, vertical = 10.dp),
|
||||
)
|
||||
{
|
||||
Text(
|
||||
@@ -346,7 +346,7 @@ private fun AttemptsRow(
|
||||
Text(
|
||||
text = attempts.toString(),
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
modifier = Modifier.padding(horizontal = 8.dp),
|
||||
modifier = Modifier.padding(horizontal = ShxSpacing.sm),
|
||||
)
|
||||
IconButton(onClick = onIncrement, enabled = enabled && attempts < 5) {
|
||||
Icon(Icons.Rounded.Add, contentDescription = stringResource(R.string.health_check_attempt_plus))
|
||||
|
||||
+17
-17
@@ -54,7 +54,7 @@ import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import org.strongswan.android.R
|
||||
import org.strongswan.android.ui.compose.components.ShxCard
|
||||
import org.strongswan.android.ui.compose.theme.ScreenPadding
|
||||
import org.strongswan.android.ui.compose.theme.ShxSpacing
|
||||
import org.strongswan.android.ui.compose.theme.ShxTheme
|
||||
|
||||
/**
|
||||
@@ -149,8 +149,8 @@ fun ImportScreen(
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.verticalScroll(rememberScrollState())
|
||||
.padding(horizontal = ScreenPadding)
|
||||
.padding(bottom = 24.dp),
|
||||
.padding(horizontal = ShxSpacing.lg)
|
||||
.padding(bottom = ShxSpacing.xl),
|
||||
)
|
||||
{
|
||||
if (model.existsWarning != null)
|
||||
@@ -161,7 +161,7 @@ fun ImportScreen(
|
||||
content = MaterialTheme.colorScheme.onErrorContainer,
|
||||
)
|
||||
}
|
||||
ShxCard(modifier = Modifier.padding(top = 12.dp))
|
||||
ShxCard(modifier = Modifier.padding(top = ShxSpacing.md))
|
||||
{
|
||||
ImportInfoRow(Icons.Rounded.Language, stringResource(R.string.profile_name_label_simple), model.name)
|
||||
ImportInfoRow(Icons.Rounded.Dns, stringResource(R.string.profile_gateway_label), model.gateway)
|
||||
@@ -174,10 +174,10 @@ fun ImportScreen(
|
||||
stringResource(R.string.profile_username_label).uppercase().replace(":", ""),
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
modifier = Modifier.padding(start = 16.dp, top = 20.dp, bottom = 8.dp),
|
||||
modifier = Modifier.padding(start = ShxSpacing.lg, top = 20.dp, bottom = ShxSpacing.sm),
|
||||
)
|
||||
ShxCard {
|
||||
Column(Modifier.padding(16.dp)) {
|
||||
Column(Modifier.padding(ShxSpacing.lg)) {
|
||||
OutlinedTextField(
|
||||
value = model.username,
|
||||
onValueChange = { model.username = it },
|
||||
@@ -187,7 +187,7 @@ fun ImportScreen(
|
||||
isError = model.usernameError,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
Spacer(Modifier.height(12.dp))
|
||||
Spacer(Modifier.height(ShxSpacing.md))
|
||||
OutlinedTextField(
|
||||
value = model.password,
|
||||
onValueChange = { model.password = it },
|
||||
@@ -205,7 +205,7 @@ fun ImportScreen(
|
||||
text = stringResource(R.string.profile_import_shared_secret),
|
||||
container = MaterialTheme.colorScheme.surfaceContainerHigh,
|
||||
content = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
modifier = Modifier.padding(top = 8.dp),
|
||||
modifier = Modifier.padding(top = ShxSpacing.sm),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -216,7 +216,7 @@ fun ImportScreen(
|
||||
stringResource(R.string.profile_user_certificate_label).uppercase().replace(":", ""),
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
modifier = Modifier.padding(start = 16.dp, top = 20.dp, bottom = 8.dp),
|
||||
modifier = Modifier.padding(start = ShxSpacing.lg, top = 20.dp, bottom = ShxSpacing.sm),
|
||||
)
|
||||
ShxCard {
|
||||
Column {
|
||||
@@ -225,7 +225,7 @@ fun ImportScreen(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable(onClick = onSelectUserCert)
|
||||
.padding(horizontal = 16.dp, vertical = 14.dp),
|
||||
.padding(horizontal = ShxSpacing.lg, vertical = 14.dp),
|
||||
) {
|
||||
Column(Modifier.weight(1f)) {
|
||||
Text(
|
||||
@@ -248,9 +248,9 @@ fun ImportScreen(
|
||||
}
|
||||
if (model.showImportUserCert)
|
||||
{
|
||||
TextButton(onClick = onImportPkcs12, modifier = Modifier.padding(start = 8.dp, bottom = 8.dp)) {
|
||||
TextButton(onClick = onImportPkcs12, modifier = Modifier.padding(start = ShxSpacing.sm, bottom = ShxSpacing.sm)) {
|
||||
Icon(Icons.Rounded.FileDownload, contentDescription = null, modifier = Modifier.size(18.dp))
|
||||
Spacer(Modifier.size(8.dp))
|
||||
Spacer(Modifier.size(ShxSpacing.sm))
|
||||
Text(stringResource(R.string.profile_cert_import))
|
||||
}
|
||||
}
|
||||
@@ -264,7 +264,7 @@ fun ImportScreen(
|
||||
stringResource(R.string.profile_ca_label).uppercase().replace(":", ""),
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
modifier = Modifier.padding(start = 16.dp, top = 20.dp, bottom = 8.dp),
|
||||
modifier = Modifier.padding(start = ShxSpacing.lg, top = 20.dp, bottom = ShxSpacing.sm),
|
||||
)
|
||||
ShxCard {
|
||||
ImportInfoRow(Icons.Rounded.Dns, model.remoteCertPrimary ?: "", model.remoteCertSecondary ?: "", divider = false)
|
||||
@@ -288,12 +288,12 @@ private fun ImportBanner(
|
||||
contentColor = content,
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.padding(top = 8.dp),
|
||||
.padding(top = ShxSpacing.sm),
|
||||
) {
|
||||
Text(
|
||||
text,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
modifier = Modifier.padding(horizontal = 16.dp, vertical = 10.dp),
|
||||
modifier = Modifier.padding(horizontal = ShxSpacing.lg, vertical = 10.dp),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -306,7 +306,7 @@ private fun ImportInfoRow(icon: ImageVector, label: String, value: String, divid
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp, vertical = 12.dp),
|
||||
.padding(horizontal = ShxSpacing.lg, vertical = ShxSpacing.md),
|
||||
) {
|
||||
Icon(
|
||||
icon,
|
||||
@@ -314,7 +314,7 @@ private fun ImportInfoRow(icon: ImageVector, label: String, value: String, divid
|
||||
tint = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
modifier = Modifier.size(20.dp),
|
||||
)
|
||||
Column(Modifier.padding(start = 16.dp)) {
|
||||
Column(Modifier.padding(start = ShxSpacing.lg)) {
|
||||
Text(
|
||||
label,
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
|
||||
+6
-5
@@ -41,6 +41,7 @@ import androidx.compose.ui.unit.dp
|
||||
import org.strongswan.android.R
|
||||
import org.strongswan.android.logic.routing.RuleSet
|
||||
import org.strongswan.android.logic.routing.RoutingPresets
|
||||
import org.strongswan.android.ui.compose.theme.ShxSpacing
|
||||
|
||||
/**
|
||||
* Searchable list of the built-in presets shown inside the rule set editor
|
||||
@@ -71,7 +72,7 @@ fun PresetPickerContent(
|
||||
{
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier.padding(start = 12.dp, end = 12.dp, bottom = 4.dp),
|
||||
modifier = Modifier.padding(start = ShxSpacing.md, end = ShxSpacing.md, bottom = ShxSpacing.xs),
|
||||
)
|
||||
{
|
||||
IconButton(onClick = onBack)
|
||||
@@ -103,7 +104,7 @@ fun PresetPickerContent(
|
||||
},
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 24.dp),
|
||||
.padding(horizontal = ShxSpacing.xl),
|
||||
shape = MaterialTheme.shapes.medium,
|
||||
)
|
||||
|
||||
@@ -111,7 +112,7 @@ fun PresetPickerContent(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.heightIn(max = 460.dp)
|
||||
.padding(top = 4.dp),
|
||||
.padding(top = ShxSpacing.xs),
|
||||
)
|
||||
{
|
||||
items(filtered, key = { it.name })
|
||||
@@ -123,7 +124,7 @@ fun PresetPickerContent(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable { onToggle(preset) }
|
||||
.padding(horizontal = 24.dp, vertical = 6.dp),
|
||||
.padding(horizontal = ShxSpacing.xl, vertical = 6.dp),
|
||||
)
|
||||
{
|
||||
Column(
|
||||
@@ -151,7 +152,7 @@ fun PresetPickerContent(
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 24.dp, vertical = 16.dp),
|
||||
.padding(horizontal = ShxSpacing.xl, vertical = ShxSpacing.lg),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+4
-3
@@ -91,6 +91,7 @@ import org.strongswan.android.data.VpnType
|
||||
import org.strongswan.android.data.VpnType.VpnTypeFeature
|
||||
import org.strongswan.android.ui.SelectedApplicationsActivity
|
||||
import org.strongswan.android.ui.TrustedCertificatesActivity
|
||||
import org.strongswan.android.ui.compose.theme.ShxSpacing
|
||||
import org.strongswan.android.utils.Constants
|
||||
import org.strongswan.android.utils.IPRangeSet
|
||||
import org.strongswan.android.utils.Utils
|
||||
@@ -356,8 +357,8 @@ fun ProfileFormScreen(
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 20.dp, vertical = 12.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(12.dp),
|
||||
.padding(horizontal = 20.dp, vertical = ShxSpacing.md),
|
||||
horizontalArrangement = Arrangement.spacedBy(ShxSpacing.md),
|
||||
) {
|
||||
OutlinedButton(
|
||||
onClick = onCancel,
|
||||
@@ -516,7 +517,7 @@ fun ProfileFormScreen(
|
||||
enter = expandVertically() + fadeIn(),
|
||||
exit = shrinkVertically() + fadeOut(),
|
||||
) {
|
||||
Column(verticalArrangement = Arrangement.spacedBy(12.dp)) {
|
||||
Column(verticalArrangement = Arrangement.spacedBy(ShxSpacing.md)) {
|
||||
OutlinedTextField(state.remoteId, { onChange(state.copy(remoteId = it)) },
|
||||
label = { Text(stringResource(R.string.profile_remote_id_label)) },
|
||||
supportingText = { Text(stringResource(R.string.profile_remote_id_hint)) },
|
||||
|
||||
+4
-3
@@ -38,6 +38,7 @@ import androidx.compose.ui.unit.dp
|
||||
import org.strongswan.android.R
|
||||
import org.strongswan.android.data.VpnProfile
|
||||
import org.strongswan.android.ui.compose.theme.LocalShxStatusColors
|
||||
import org.strongswan.android.ui.compose.theme.ShxSpacing
|
||||
|
||||
@Composable
|
||||
fun ProfileAvatar(icon: ImageVector, connected: Boolean, modifier: Modifier = Modifier)
|
||||
@@ -81,13 +82,13 @@ fun ShxProfileRow(
|
||||
onLongClick = onLongClick,
|
||||
onLongClickLabel = onLongClickLabel,
|
||||
)
|
||||
.padding(horizontal = 16.dp, vertical = 12.dp),
|
||||
.padding(horizontal = ShxSpacing.lg, vertical = ShxSpacing.md),
|
||||
) {
|
||||
ProfileAvatar(icon = leadingIcon, connected = active)
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.padding(horizontal = 12.dp),
|
||||
.padding(horizontal = ShxSpacing.md),
|
||||
) {
|
||||
Text(
|
||||
text = profile.name ?: "",
|
||||
@@ -128,7 +129,7 @@ fun ShxDivider(modifier: Modifier = Modifier, indent: Boolean = true)
|
||||
color = MaterialTheme.colorScheme.outlineVariant.copy(alpha = 0.6f),
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.padding(start = if (indent) 68.dp else 0.dp, end = if (indent) 16.dp else 0.dp)
|
||||
.padding(start = if (indent) 68.dp else 0.dp, end = if (indent) ShxSpacing.lg else 0.dp)
|
||||
.height(1.dp),
|
||||
) {}
|
||||
}
|
||||
+3
-5
@@ -61,7 +61,6 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import kotlinx.coroutines.launch
|
||||
import org.strongswan.android.R
|
||||
import org.strongswan.android.data.VpnProfile
|
||||
@@ -69,7 +68,6 @@ import org.strongswan.android.logic.VpnStateService.State
|
||||
import org.strongswan.android.ui.compose.components.ShxCard
|
||||
import org.strongswan.android.ui.compose.components.ShxEmptyState
|
||||
import org.strongswan.android.ui.compose.theme.LocalShxStatusColors
|
||||
import org.strongswan.android.ui.compose.theme.ScreenPadding
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
@@ -136,7 +134,7 @@ fun ProfilesScreen(
|
||||
SearchBar(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = ScreenPadding, vertical = 4.dp),
|
||||
.padding(horizontal = ShxSpacing.lg, vertical = ShxSpacing.xs),
|
||||
inputField = {
|
||||
SearchBarDefaults.InputField(
|
||||
query = query,
|
||||
@@ -170,7 +168,7 @@ fun ProfilesScreen(
|
||||
color = MaterialTheme.colorScheme.surfaceContainerLow,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = ScreenPadding, vertical = 12.dp),
|
||||
.padding(horizontal = ShxSpacing.lg, vertical = ShxSpacing.md),
|
||||
) {
|
||||
LazyColumn {
|
||||
itemsIndexed(filtered, key = { _, p -> p.getUUID().toString() }) { index, profile ->
|
||||
@@ -275,7 +273,7 @@ private fun EmptyProfilesState(query: String, onAdd: () -> Unit)
|
||||
ShxCard(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = ScreenPadding, vertical = 12.dp),
|
||||
.padding(horizontal = ShxSpacing.lg, vertical = ShxSpacing.md),
|
||||
)
|
||||
{
|
||||
if (query.isBlank())
|
||||
|
||||
+5
-5
@@ -36,7 +36,7 @@ import kotlinx.coroutines.launch
|
||||
import org.strongswan.android.R
|
||||
import org.strongswan.android.logic.CharonVpnService
|
||||
import org.strongswan.android.logic.routing.RouteCheck
|
||||
import org.strongswan.android.ui.compose.theme.ScreenPadding
|
||||
import org.strongswan.android.ui.compose.theme.ShxSpacing
|
||||
|
||||
/** Diagnostic: how a domain resolves and which route its addresses take. */
|
||||
@Composable
|
||||
@@ -52,7 +52,7 @@ fun RouteCheckScreen()
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.verticalScroll(rememberScrollState())
|
||||
.padding(horizontal = ScreenPadding, vertical = 12.dp),
|
||||
.padding(horizontal = ShxSpacing.lg, vertical = ShxSpacing.md),
|
||||
)
|
||||
{
|
||||
Text(
|
||||
@@ -98,7 +98,7 @@ fun RouteCheckScreen()
|
||||
@Composable
|
||||
private fun RouteCheckResult(report: RouteCheck.Report)
|
||||
{
|
||||
Column(modifier = Modifier.padding(top = 12.dp))
|
||||
Column(modifier = Modifier.padding(top = ShxSpacing.md))
|
||||
{
|
||||
if (!report.vpnNetworkFound)
|
||||
{
|
||||
@@ -141,7 +141,7 @@ private fun RouteCheckResult(report: RouteCheck.Report)
|
||||
)
|
||||
}
|
||||
}
|
||||
Spacer(Modifier.height(8.dp))
|
||||
Spacer(Modifier.height(ShxSpacing.sm))
|
||||
}
|
||||
|
||||
@Composable
|
||||
@@ -150,7 +150,7 @@ private fun RouteCheckRow(label: String, ips: List<String>)
|
||||
Text(
|
||||
text = label,
|
||||
style = MaterialTheme.typography.titleSmall,
|
||||
modifier = Modifier.padding(top = 8.dp),
|
||||
modifier = Modifier.padding(top = ShxSpacing.sm),
|
||||
)
|
||||
Text(
|
||||
text = ips.joinToString(", ").ifEmpty { stringResource(R.string.route_check_none) },
|
||||
|
||||
+9
-10
@@ -124,7 +124,6 @@ import org.strongswan.android.ui.compose.components.ShxIconBadge
|
||||
import org.strongswan.android.ui.compose.components.ShxSection
|
||||
import org.strongswan.android.ui.compose.components.ShxSectionDivider
|
||||
import org.strongswan.android.ui.compose.theme.LocalShxStatusColors
|
||||
import org.strongswan.android.ui.compose.theme.ScreenPadding
|
||||
import org.strongswan.android.ui.compose.theme.ShxSpacing
|
||||
import org.strongswan.android.ui.compose.routing.RoutingHeroCard
|
||||
import org.strongswan.android.ui.compose.routing.RuToggleRow
|
||||
@@ -236,7 +235,7 @@ private fun RoutingContent(snackbarHostState: SnackbarHostState)
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.verticalScroll(rememberScrollState())
|
||||
.padding(bottom = 24.dp),
|
||||
.padding(bottom = ShxSpacing.xl),
|
||||
)
|
||||
{
|
||||
TopAppBar(
|
||||
@@ -261,7 +260,7 @@ private fun RoutingContent(snackbarHostState: SnackbarHostState)
|
||||
setCount = config.ruleSets.count { it.enabled },
|
||||
appCount = excludedApps,
|
||||
onToggle = { manager.setGlobalEnabled(it) },
|
||||
modifier = Modifier.padding(horizontal = ScreenPadding),
|
||||
modifier = Modifier.padding(horizontal = ShxSpacing.lg),
|
||||
)
|
||||
|
||||
/* kill switch + excluded apps: excluded apps are added to the VPN's disallowed list
|
||||
@@ -273,7 +272,7 @@ private fun RoutingContent(snackbarHostState: SnackbarHostState)
|
||||
text = stringResource(R.string.routing_killswitch_note, excludedApps),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
modifier = Modifier.padding(horizontal = ScreenPadding + ShxSpacing.xs, vertical = ShxSpacing.sm),
|
||||
modifier = Modifier.padding(horizontal = ShxSpacing.lg + ShxSpacing.xs, vertical = ShxSpacing.sm),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -302,16 +301,16 @@ private fun RoutingContent(snackbarHostState: SnackbarHostState)
|
||||
text = stringResource(R.string.dead_targets_summary),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
modifier = Modifier.padding(horizontal = 16.dp, vertical = 6.dp),
|
||||
modifier = Modifier.padding(horizontal = ShxSpacing.lg, vertical = 6.dp),
|
||||
)
|
||||
deadTargets.forEachIndexed { index, target ->
|
||||
ShxSectionDivider()
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(12.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(ShxSpacing.md),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp, vertical = 10.dp),
|
||||
.padding(horizontal = ShxSpacing.lg, vertical = 10.dp),
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
@@ -400,7 +399,7 @@ private fun RoutingContent(snackbarHostState: SnackbarHostState)
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable { advancedOpen = !advancedOpen }
|
||||
.padding(horizontal = ScreenPadding + 16.dp, vertical = 16.dp),
|
||||
.padding(horizontal = ShxSpacing.lg + ShxSpacing.lg, vertical = ShxSpacing.lg),
|
||||
)
|
||||
{
|
||||
Text(
|
||||
@@ -433,7 +432,7 @@ private fun RoutingContent(snackbarHostState: SnackbarHostState)
|
||||
LinearWavyProgressIndicator(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp, vertical = 4.dp),
|
||||
.padding(horizontal = ShxSpacing.lg, vertical = ShxSpacing.xs),
|
||||
)
|
||||
}
|
||||
GeoipChipsRow(state = ruState)
|
||||
@@ -451,7 +450,7 @@ private fun RoutingContent(snackbarHostState: SnackbarHostState)
|
||||
text = stringResource(R.string.routing_force_summary),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
modifier = Modifier.padding(horizontal = 16.dp, vertical = 6.dp),
|
||||
modifier = Modifier.padding(horizontal = ShxSpacing.lg, vertical = 6.dp),
|
||||
)
|
||||
}
|
||||
else
|
||||
|
||||
+13
-12
@@ -68,6 +68,7 @@ import org.strongswan.android.R
|
||||
import org.strongswan.android.logic.routing.RuleSet
|
||||
import org.strongswan.android.logic.routing.RoutingPresets
|
||||
import org.strongswan.android.ui.compose.components.ShxIconBadge
|
||||
import org.strongswan.android.ui.compose.theme.ShxSpacing
|
||||
|
||||
/**
|
||||
* Editor of one rule set as a modal bottom sheet. The preset picker is a
|
||||
@@ -161,12 +162,12 @@ private fun EditorContent(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.verticalScroll(rememberScrollState())
|
||||
.padding(bottom = 24.dp),
|
||||
.padding(bottom = ShxSpacing.xl),
|
||||
)
|
||||
{
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier.padding(start = 24.dp, end = 12.dp, bottom = 8.dp),
|
||||
modifier = Modifier.padding(start = ShxSpacing.xl, end = ShxSpacing.md, bottom = ShxSpacing.sm),
|
||||
)
|
||||
{
|
||||
Text(
|
||||
@@ -188,7 +189,7 @@ private fun EditorContent(
|
||||
singleLine = true,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 24.dp)
|
||||
.padding(horizontal = ShxSpacing.xl)
|
||||
.focusRequester(nameFocusRequester),
|
||||
shape = MaterialTheme.shapes.medium,
|
||||
)
|
||||
@@ -232,7 +233,7 @@ private fun EditorContent(
|
||||
shape = MaterialTheme.shapes.medium,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 24.dp, vertical = 12.dp),
|
||||
.padding(horizontal = ShxSpacing.xl, vertical = ShxSpacing.md),
|
||||
)
|
||||
{
|
||||
Icon(
|
||||
@@ -240,7 +241,7 @@ private fun EditorContent(
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(18.dp),
|
||||
)
|
||||
Spacer(Modifier.width(8.dp))
|
||||
Spacer(Modifier.width(ShxSpacing.sm))
|
||||
Text(stringResource(R.string.routing_delete))
|
||||
}
|
||||
}
|
||||
@@ -262,14 +263,14 @@ private fun ChipGroup(
|
||||
text = label,
|
||||
style = MaterialTheme.typography.titleSmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
modifier = Modifier.padding(start = 24.dp, top = 16.dp),
|
||||
modifier = Modifier.padding(start = ShxSpacing.xl, top = ShxSpacing.lg),
|
||||
)
|
||||
FlowRow(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 24.dp, vertical = 4.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(4.dp),
|
||||
.padding(horizontal = ShxSpacing.xl, vertical = ShxSpacing.xs),
|
||||
horizontalArrangement = Arrangement.spacedBy(ShxSpacing.sm),
|
||||
verticalArrangement = Arrangement.spacedBy(ShxSpacing.xs),
|
||||
)
|
||||
{
|
||||
values.forEach { value ->
|
||||
@@ -294,11 +295,11 @@ private fun EditorRow(icon: ImageVector, title: String, subtitle: String, onClic
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable(onClick = onClick)
|
||||
.padding(horizontal = 24.dp, vertical = 14.dp),
|
||||
.padding(horizontal = ShxSpacing.xl, vertical = 14.dp),
|
||||
)
|
||||
{
|
||||
ShxIconBadge(icon)
|
||||
Spacer(Modifier.width(16.dp))
|
||||
Spacer(Modifier.width(ShxSpacing.lg))
|
||||
Column(Modifier.weight(1f))
|
||||
{
|
||||
Text(title, style = MaterialTheme.typography.bodyLarge)
|
||||
@@ -346,7 +347,7 @@ private fun AddChipField(
|
||||
},
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 24.dp, vertical = 4.dp),
|
||||
.padding(horizontal = ShxSpacing.xl, vertical = ShxSpacing.xs),
|
||||
shape = MaterialTheme.shapes.medium,
|
||||
)
|
||||
}
|
||||
|
||||
+2
-2
@@ -526,7 +526,7 @@ fun SettingsScreen(profiles: List<VpnProfile>, showTitle: Boolean = true)
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(top = 16.dp),
|
||||
.padding(top = ShxSpacing.lg),
|
||||
textAlign = androidx.compose.ui.text.style.TextAlign.Center,
|
||||
)
|
||||
}
|
||||
@@ -560,7 +560,7 @@ fun SettingsScreen(profiles: List<VpnProfile>, showTitle: Boolean = true)
|
||||
)
|
||||
{
|
||||
RadioButton(selected = defaultUuid == value, onClick = null)
|
||||
Text(label, modifier = Modifier.padding(start = 12.dp))
|
||||
Text(label, modifier = Modifier.padding(start = ShxSpacing.md))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,7 +66,6 @@ import androidx.compose.ui.graphics.compositeOver
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import org.strongswan.android.R
|
||||
@@ -76,6 +75,7 @@ import org.strongswan.android.logic.StrongSwanApplication
|
||||
import org.strongswan.android.logic.TrustedCertificateManager
|
||||
import org.strongswan.android.ui.LogActivity
|
||||
import org.strongswan.android.ui.VpnProfileDetailActivity
|
||||
import org.strongswan.android.ui.compose.theme.ShxSpacing
|
||||
import org.strongswan.android.ui.compose.theme.ShxTheme
|
||||
|
||||
fun ComponentActivity.installShxUi()
|
||||
@@ -209,13 +209,13 @@ private fun ShareProfileDialog(profile: VpnProfile, onDismiss: () -> Unit, onCon
|
||||
text = {
|
||||
Column {
|
||||
Text(stringResource(R.string.share_profile_password_warning), style = MaterialTheme.typography.bodyMedium)
|
||||
Spacer(Modifier.height(12.dp))
|
||||
Spacer(Modifier.height(ShxSpacing.md))
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier.clickable { includePassword = !includePassword },
|
||||
) {
|
||||
Checkbox(checked = includePassword, onCheckedChange = { includePassword = it })
|
||||
Spacer(Modifier.width(4.dp))
|
||||
Spacer(Modifier.width(ShxSpacing.xs))
|
||||
Text(stringResource(R.string.share_profile_include_password))
|
||||
}
|
||||
}
|
||||
|
||||
+13
-13
@@ -69,7 +69,7 @@ import org.strongswan.android.ui.compose.components.ShxSettingRow
|
||||
import org.strongswan.android.ui.compose.components.ShxSettingToggleRow
|
||||
import org.strongswan.android.data.VpnProfile
|
||||
import org.strongswan.android.logic.autoconnect.AutoConnectManager
|
||||
import org.strongswan.android.ui.compose.theme.ScreenPadding
|
||||
import org.strongswan.android.ui.compose.theme.ShxSpacing
|
||||
|
||||
/**
|
||||
* Trusted networks settings: when enabled, the VPN is started on cellular and untrusted
|
||||
@@ -159,7 +159,7 @@ fun TrustedNetworksScreen(
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.verticalScroll(rememberScrollState())
|
||||
.padding(bottom = 24.dp),
|
||||
.padding(bottom = ShxSpacing.xl),
|
||||
)
|
||||
{
|
||||
ShxSection(title = stringResource(R.string.settings_section_general))
|
||||
@@ -190,19 +190,19 @@ fun TrustedNetworksScreen(
|
||||
|
||||
if (enabled && !hasBackgroundLocation)
|
||||
{
|
||||
Spacer(Modifier.size(12.dp))
|
||||
Spacer(Modifier.size(ShxSpacing.md))
|
||||
Surface(
|
||||
shape = MaterialTheme.shapes.large,
|
||||
color = MaterialTheme.colorScheme.errorContainer,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = ScreenPadding)
|
||||
.padding(horizontal = ShxSpacing.lg)
|
||||
.clickable { requestSsidPermissions() },
|
||||
)
|
||||
{
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier.padding(horizontal = 16.dp, vertical = 12.dp),
|
||||
modifier = Modifier.padding(horizontal = ShxSpacing.lg, vertical = ShxSpacing.md),
|
||||
)
|
||||
{
|
||||
Text(
|
||||
@@ -226,7 +226,7 @@ fun TrustedNetworksScreen(
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp, vertical = 8.dp),
|
||||
.padding(horizontal = ShxSpacing.lg, vertical = ShxSpacing.sm),
|
||||
)
|
||||
if (config.trustedSsids.isEmpty())
|
||||
{
|
||||
@@ -236,7 +236,7 @@ fun TrustedNetworksScreen(
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp, vertical = 14.dp),
|
||||
.padding(horizontal = ShxSpacing.lg, vertical = 14.dp),
|
||||
)
|
||||
}
|
||||
else
|
||||
@@ -251,7 +251,7 @@ fun TrustedNetworksScreen(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp),
|
||||
.padding(horizontal = ShxSpacing.lg),
|
||||
)
|
||||
{
|
||||
Icon(
|
||||
@@ -265,7 +265,7 @@ fun TrustedNetworksScreen(
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.padding(horizontal = 16.dp, vertical = 14.dp),
|
||||
.padding(horizontal = ShxSpacing.lg, vertical = 14.dp),
|
||||
)
|
||||
IconButton(onClick = { pendingDeleteSsid = ssid }) {
|
||||
Icon(
|
||||
@@ -309,7 +309,7 @@ fun TrustedNetworksScreen(
|
||||
selected = config.profileUuid == profile.getUUID().toString(),
|
||||
onClick = null,
|
||||
)
|
||||
Text(profile.name ?: "", modifier = Modifier.padding(start = 12.dp))
|
||||
Text(profile.name ?: "", modifier = Modifier.padding(start = ShxSpacing.md))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -389,7 +389,7 @@ private fun TrustedAddNetworkRow(
|
||||
horizontalArrangement = androidx.compose.foundation.layout.Arrangement.Center,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp, vertical = 6.dp),
|
||||
.padding(horizontal = ShxSpacing.lg, vertical = 6.dp),
|
||||
)
|
||||
{
|
||||
if (currentSsid != null)
|
||||
@@ -397,7 +397,7 @@ private fun TrustedAddNetworkRow(
|
||||
TextButton(onClick = { onAddCurrent(currentSsid) })
|
||||
{
|
||||
Icon(Icons.Rounded.Add, contentDescription = null, modifier = Modifier.size(18.dp))
|
||||
Spacer(Modifier.size(8.dp))
|
||||
Spacer(Modifier.size(ShxSpacing.sm))
|
||||
Text(stringResource(R.string.auto_connect_add_current, currentSsid))
|
||||
}
|
||||
}
|
||||
@@ -406,7 +406,7 @@ private fun TrustedAddNetworkRow(
|
||||
TextButton(onClick = onAddManual)
|
||||
{
|
||||
Icon(Icons.Rounded.Add, contentDescription = null, modifier = Modifier.size(18.dp))
|
||||
Spacer(Modifier.size(8.dp))
|
||||
Spacer(Modifier.size(ShxSpacing.sm))
|
||||
Text(stringResource(R.string.auto_connect_add_network))
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -40,12 +40,12 @@ import androidx.compose.ui.text.input.ImeAction
|
||||
import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.text.input.PasswordVisualTransformation
|
||||
import androidx.compose.ui.text.input.VisualTransformation
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import org.strongswan.android.R
|
||||
import org.strongswan.android.ui.compose.theme.ShxSpacing
|
||||
import org.strongswan.android.ui.compose.theme.ShxTheme
|
||||
|
||||
/**
|
||||
@@ -147,7 +147,7 @@ private fun ConfirmationUi(dialog: VpnDialog.Confirmation)
|
||||
title = { Text(dialog.title) },
|
||||
text = { Text(stringResource(dialog.message)) },
|
||||
confirmButton = {
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(4.dp)) {
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(ShxSpacing.xs)) {
|
||||
if (dialog.reconnect)
|
||||
{
|
||||
TextButton(onClick = {
|
||||
@@ -193,7 +193,7 @@ private fun LoginUi(dialog: VpnDialog.Login)
|
||||
onDismissRequest = ::cancelDialog,
|
||||
title = { Text(stringResource(R.string.login_title)) },
|
||||
text = {
|
||||
Column(verticalArrangement = Arrangement.spacedBy(12.dp)) {
|
||||
Column(verticalArrangement = Arrangement.spacedBy(ShxSpacing.md)) {
|
||||
OutlinedTextField(
|
||||
value = username,
|
||||
onValueChange = { username = it },
|
||||
|
||||
+9
-9
@@ -40,7 +40,7 @@ import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import org.strongswan.android.ui.compose.theme.ScreenPadding
|
||||
import org.strongswan.android.ui.compose.theme.ShxSpacing
|
||||
|
||||
/** Uppercase section header + grouped card, the standard grouped-list building block. */
|
||||
@Composable
|
||||
@@ -52,9 +52,9 @@ fun ShxSection(title: String, content: @Composable () -> Unit)
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(start = ScreenPadding + 16.dp, top = 20.dp, bottom = 8.dp),
|
||||
.padding(start = ShxSpacing.lg + ShxSpacing.lg, top = 20.dp, bottom = ShxSpacing.sm),
|
||||
)
|
||||
ShxCard(modifier = Modifier.fillMaxWidth().padding(horizontal = ScreenPadding)) {
|
||||
ShxCard(modifier = Modifier.fillMaxWidth().padding(horizontal = ShxSpacing.lg)) {
|
||||
Column { content() }
|
||||
}
|
||||
}
|
||||
@@ -83,7 +83,7 @@ fun ShxIconBadge(icon: ImageVector, tint: Color = MaterialTheme.colorScheme.prim
|
||||
contentDescription = null,
|
||||
tint = tint,
|
||||
modifier = Modifier
|
||||
.padding(8.dp)
|
||||
.padding(ShxSpacing.sm)
|
||||
.size(20.dp),
|
||||
)
|
||||
}
|
||||
@@ -95,7 +95,7 @@ private fun RowScope.RowLabels(title: String, subtitle: String?, enabled: Boolea
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.padding(horizontal = 16.dp),
|
||||
.padding(horizontal = ShxSpacing.lg),
|
||||
)
|
||||
{
|
||||
Text(
|
||||
@@ -129,7 +129,7 @@ fun ShxSettingRow(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable(enabled = enabled, onClick = onClick)
|
||||
.padding(horizontal = 16.dp, vertical = 14.dp),
|
||||
.padding(horizontal = ShxSpacing.lg, vertical = 14.dp),
|
||||
)
|
||||
{
|
||||
ShxIconBadge(icon = icon, tint = if (enabled) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant)
|
||||
@@ -158,7 +158,7 @@ fun ShxSettingToggleRow(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable(enabled = enabled) { onCheckedChange(!checked) }
|
||||
.padding(horizontal = 16.dp, vertical = 14.dp),
|
||||
.padding(horizontal = ShxSpacing.lg, vertical = 14.dp),
|
||||
)
|
||||
{
|
||||
ShxIconBadge(icon = icon, tint = if (enabled) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant)
|
||||
@@ -198,7 +198,7 @@ fun ShxEmptyState(
|
||||
Column(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.padding(24.dp),
|
||||
.padding(ShxSpacing.xl),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.spacedBy(0.dp),
|
||||
)
|
||||
@@ -225,7 +225,7 @@ fun ShxEmptyState(
|
||||
)
|
||||
if (actionLabel != null && onAction != null)
|
||||
{
|
||||
Spacer(Modifier.height(16.dp))
|
||||
Spacer(Modifier.height(ShxSpacing.lg))
|
||||
OutlinedButton(onClick = onAction, shape = MaterialTheme.shapes.medium) { Text(actionLabel) }
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -21,6 +21,7 @@ import androidx.compose.ui.graphics.Shape
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.unit.dp
|
||||
import org.strongswan.android.ui.compose.theme.LocalShxStatusColors
|
||||
import org.strongswan.android.ui.compose.theme.ShxSpacing
|
||||
|
||||
/** Small rounded label with explicit colors, e.g. "Connected". */
|
||||
@Composable
|
||||
@@ -42,7 +43,7 @@ fun ShxStatusPill(
|
||||
Text(
|
||||
text = text,
|
||||
style = style,
|
||||
modifier = Modifier.padding(horizontal = 10.dp, vertical = 4.dp),
|
||||
modifier = Modifier.padding(horizontal = 10.dp, vertical = ShxSpacing.xs),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+15
-16
@@ -124,7 +124,6 @@ import org.strongswan.android.ui.compose.components.ShxIconBadge
|
||||
import org.strongswan.android.ui.compose.components.ShxSection
|
||||
import org.strongswan.android.ui.compose.components.ShxSectionDivider
|
||||
import org.strongswan.android.ui.compose.theme.LocalShxStatusColors
|
||||
import org.strongswan.android.ui.compose.theme.ScreenPadding
|
||||
import org.strongswan.android.ui.compose.theme.ShxSpacing
|
||||
|
||||
/** Geoip toggle row with a refresh/update slot in front of the switch. */
|
||||
@@ -143,11 +142,11 @@ internal fun RuToggleRow(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable { onCheckedChange(!checked) }
|
||||
.padding(horizontal = 16.dp, vertical = 14.dp),
|
||||
.padding(horizontal = ShxSpacing.lg, vertical = 14.dp),
|
||||
)
|
||||
{
|
||||
ShxIconBadge(Icons.Rounded.Block)
|
||||
Spacer(Modifier.width(16.dp))
|
||||
Spacer(Modifier.width(ShxSpacing.lg))
|
||||
Column(Modifier.weight(1f))
|
||||
{
|
||||
Text(title, style = MaterialTheme.typography.bodyLarge)
|
||||
@@ -160,7 +159,7 @@ internal fun RuToggleRow(
|
||||
if (updating)
|
||||
{
|
||||
LoadingIndicator(Modifier.size(14.dp))
|
||||
Spacer(Modifier.width(12.dp))
|
||||
Spacer(Modifier.width(ShxSpacing.md))
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -186,7 +185,7 @@ internal fun RuModeSelector(mode: String, onModeChange: (String) -> Unit)
|
||||
SingleChoiceSegmentedButtonRow(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp, vertical = 10.dp),
|
||||
.padding(horizontal = ShxSpacing.lg, vertical = 10.dp),
|
||||
)
|
||||
{
|
||||
SegmentedButton(
|
||||
@@ -218,7 +217,7 @@ internal fun RuDetailsDisclosure(mode: String)
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable { expanded = !expanded }
|
||||
.padding(horizontal = 16.dp, vertical = 10.dp),
|
||||
.padding(horizontal = ShxSpacing.lg, vertical = 10.dp),
|
||||
)
|
||||
{
|
||||
Text(
|
||||
@@ -226,7 +225,7 @@ internal fun RuDetailsDisclosure(mode: String)
|
||||
style = MaterialTheme.typography.labelLarge,
|
||||
color = MaterialTheme.colorScheme.primary,
|
||||
)
|
||||
Spacer(Modifier.width(4.dp))
|
||||
Spacer(Modifier.width(ShxSpacing.xs))
|
||||
Icon(
|
||||
if (expanded) Icons.Rounded.ExpandLess else Icons.Rounded.ExpandMore,
|
||||
contentDescription = null,
|
||||
@@ -242,7 +241,7 @@ internal fun RuDetailsDisclosure(mode: String)
|
||||
fadeOut(tween(90)),
|
||||
)
|
||||
{
|
||||
Column(Modifier.padding(start = 16.dp, end = 16.dp, bottom = 12.dp))
|
||||
Column(Modifier.padding(start = ShxSpacing.lg, end = ShxSpacing.lg, bottom = ShxSpacing.md))
|
||||
{
|
||||
Text(
|
||||
text = stringResource(
|
||||
@@ -268,7 +267,7 @@ internal fun RuDetailsDisclosure(mode: String)
|
||||
text = stringResource(R.string.rusplit_beta_note),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
modifier = Modifier.padding(top = 4.dp),
|
||||
modifier = Modifier.padding(top = ShxSpacing.xs),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -284,9 +283,9 @@ internal fun GeoipChipsRow(state: RuIpListState)
|
||||
FlowRow(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(start = 16.dp, end = 16.dp, bottom = 4.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(4.dp),
|
||||
.padding(start = ShxSpacing.lg, end = ShxSpacing.lg, bottom = ShxSpacing.xs),
|
||||
horizontalArrangement = Arrangement.spacedBy(ShxSpacing.sm),
|
||||
verticalArrangement = Arrangement.spacedBy(ShxSpacing.xs),
|
||||
)
|
||||
{
|
||||
InfoChip(text = stringResource(R.string.routing_geoip_ipv4, state.ipv4Ranges))
|
||||
@@ -341,14 +340,14 @@ internal fun ForcePrefixRow(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable(onClick = onEdit)
|
||||
.padding(horizontal = 16.dp, vertical = 8.dp),
|
||||
.padding(horizontal = ShxSpacing.lg, vertical = ShxSpacing.sm),
|
||||
)
|
||||
{
|
||||
ShxIconBadge(
|
||||
Icons.Rounded.Lan,
|
||||
tint = if (entry.enabled) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
Spacer(Modifier.width(16.dp))
|
||||
Spacer(Modifier.width(ShxSpacing.lg))
|
||||
Text(
|
||||
entry.prefix,
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
@@ -378,7 +377,7 @@ internal fun AddForcePrefixRow(onClick: () -> Unit)
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable(onClick = onClick)
|
||||
.padding(horizontal = 16.dp, vertical = 14.dp),
|
||||
.padding(horizontal = ShxSpacing.lg, vertical = 14.dp),
|
||||
)
|
||||
{
|
||||
Icon(
|
||||
@@ -387,7 +386,7 @@ internal fun AddForcePrefixRow(onClick: () -> Unit)
|
||||
tint = MaterialTheme.colorScheme.primary,
|
||||
modifier = Modifier.size(22.dp),
|
||||
)
|
||||
Spacer(Modifier.width(16.dp))
|
||||
Spacer(Modifier.width(ShxSpacing.lg))
|
||||
Text(
|
||||
stringResource(R.string.routing_force_add),
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
|
||||
+5
-6
@@ -124,7 +124,6 @@ import org.strongswan.android.ui.compose.components.ShxIconBadge
|
||||
import org.strongswan.android.ui.compose.components.ShxSection
|
||||
import org.strongswan.android.ui.compose.components.ShxSectionDivider
|
||||
import org.strongswan.android.ui.compose.theme.LocalShxStatusColors
|
||||
import org.strongswan.android.ui.compose.theme.ScreenPadding
|
||||
import org.strongswan.android.ui.compose.theme.ShxSpacing
|
||||
|
||||
/** Hero card: master switch plus a live summary of what the rules currently affect. */
|
||||
@@ -147,7 +146,7 @@ internal fun RoutingHeroCard(
|
||||
{
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier.padding(start = 16.dp, top = 14.dp, bottom = 14.dp, end = 8.dp),
|
||||
modifier = Modifier.padding(start = ShxSpacing.lg, top = 14.dp, bottom = 14.dp, end = ShxSpacing.sm),
|
||||
)
|
||||
{
|
||||
Icon(
|
||||
@@ -155,7 +154,7 @@ internal fun RoutingHeroCard(
|
||||
contentDescription = null,
|
||||
tint = if (enabled) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
Spacer(Modifier.width(16.dp))
|
||||
Spacer(Modifier.width(ShxSpacing.lg))
|
||||
Column(Modifier.weight(1f))
|
||||
{
|
||||
Text(
|
||||
@@ -184,7 +183,7 @@ internal fun RoutingHeroCard(
|
||||
)
|
||||
}
|
||||
Switch(checked = enabled, onCheckedChange = onToggle)
|
||||
Spacer(Modifier.width(8.dp))
|
||||
Spacer(Modifier.width(ShxSpacing.sm))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -198,11 +197,11 @@ internal fun RfActionRow(onClick: () -> Unit)
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable(onClick = onClick)
|
||||
.padding(horizontal = 16.dp, vertical = 14.dp),
|
||||
.padding(horizontal = ShxSpacing.lg, vertical = 14.dp),
|
||||
)
|
||||
{
|
||||
ShxIconBadge(Icons.Rounded.Block)
|
||||
Spacer(Modifier.width(16.dp))
|
||||
Spacer(Modifier.width(ShxSpacing.lg))
|
||||
Column(Modifier.weight(1f))
|
||||
{
|
||||
Text(
|
||||
|
||||
+4
-5
@@ -124,7 +124,6 @@ import org.strongswan.android.ui.compose.components.ShxIconBadge
|
||||
import org.strongswan.android.ui.compose.components.ShxSection
|
||||
import org.strongswan.android.ui.compose.components.ShxSectionDivider
|
||||
import org.strongswan.android.ui.compose.theme.LocalShxStatusColors
|
||||
import org.strongswan.android.ui.compose.theme.ScreenPadding
|
||||
import org.strongswan.android.ui.compose.theme.ShxSpacing
|
||||
|
||||
/** Collapsed rule set row: tap opens the editor sheet, the switch toggles in place. */
|
||||
@@ -140,14 +139,14 @@ internal fun RuleSetRow(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable(onClick = onOpen)
|
||||
.padding(horizontal = 16.dp, vertical = 14.dp),
|
||||
.padding(horizontal = ShxSpacing.lg, vertical = 14.dp),
|
||||
)
|
||||
{
|
||||
ShxIconBadge(
|
||||
Icons.Rounded.Rule,
|
||||
tint = if (ruleSet.enabled) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
Spacer(Modifier.width(16.dp))
|
||||
Spacer(Modifier.width(ShxSpacing.lg))
|
||||
Column(Modifier.weight(1f))
|
||||
{
|
||||
Text(
|
||||
@@ -179,7 +178,7 @@ internal fun AddRuleRow(onClick: () -> Unit)
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable(onClick = onClick)
|
||||
.padding(horizontal = 16.dp, vertical = 14.dp),
|
||||
.padding(horizontal = ShxSpacing.lg, vertical = 14.dp),
|
||||
)
|
||||
{
|
||||
Icon(
|
||||
@@ -188,7 +187,7 @@ internal fun AddRuleRow(onClick: () -> Unit)
|
||||
tint = MaterialTheme.colorScheme.primary,
|
||||
modifier = Modifier.size(22.dp),
|
||||
)
|
||||
Spacer(Modifier.width(16.dp))
|
||||
Spacer(Modifier.width(ShxSpacing.lg))
|
||||
Text(
|
||||
stringResource(R.string.routing_add_rule),
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
|
||||
Reference in new issue
Block a user