Skip to content

Commit 8779647

Browse files
committed
feat(settings): add collapsible sections to reduce profile settings screen clutter
1 parent 93bfd8c commit 8779647

File tree

2 files changed

+49
-37
lines changed

2 files changed

+49
-37
lines changed

android/app/src/main/java/com/masterdns/vpn/ui/settings/GlobalSettingsScreen.kt

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -353,16 +353,26 @@ fun GlobalSettingsScreen(vm: GlobalSettingsViewModel = viewModel()) {
353353

354354
@Composable
355355
private fun LinkRow(title: String, link: String, onOpen: () -> Unit) {
356-
Row(
357-
modifier = Modifier.fillMaxWidth(),
358-
horizontalArrangement = Arrangement.spacedBy(6.dp)
356+
Column(
357+
modifier = Modifier
358+
.fillMaxWidth()
359+
.clickable(onClick = onOpen)
360+
.padding(vertical = 6.dp)
359361
) {
360-
Text(title, style = MaterialTheme.typography.bodyMedium)
361362
Text(
362-
text = link,
363+
text = title,
363364
style = MaterialTheme.typography.bodyMedium,
365+
color = MaterialTheme.colorScheme.onSurfaceVariant
366+
)
367+
Text(
368+
text = link,
369+
style = MaterialTheme.typography.bodyMedium.copy(
370+
textDecoration = TextDecoration.Underline,
371+
fontWeight = FontWeight.Medium
372+
),
364373
color = MaterialTheme.colorScheme.primary,
365-
modifier = Modifier.clickable(onClick = onOpen)
374+
maxLines = 3,
375+
overflow = TextOverflow.Ellipsis
366376
)
367377
}
368378
}

android/app/src/main/java/com/masterdns/vpn/ui/settings/SettingsScreen.kt

Lines changed: 33 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -170,17 +170,10 @@ fun SettingsScreen(
170170
val snackbarHostState = remember { SnackbarHostState() }
171171
val listState = rememberLazyListState()
172172
val scope = rememberCoroutineScope()
173-
174-
val listItems = remember {
175-
buildList<Any> {
176-
var section = ""
177-
configFields.forEach { field ->
178-
if (field.section != section) {
179-
section = field.section
180-
add(section)
181-
}
182-
add(field)
183-
}
173+
val sections = remember { configFields.groupBy { it.section } }
174+
val sectionExpanded = remember {
175+
mutableStateMapOf<String, Boolean>().apply {
176+
sections.keys.forEach { put(it, it == "Identity" || it == "Proxy") }
184177
}
185178
}
186179

@@ -328,32 +321,41 @@ fun SettingsScreen(
328321
}
329322

330323
val socksAuthEnabled = fieldsState["SOCKS5_AUTH"].equals("true", ignoreCase = true)
331-
items(listItems, key = { item ->
332-
when (item) {
333-
is String -> "header_$item"
334-
is SettingField -> item.key
335-
else -> item.hashCode().toString()
336-
}
337-
}) { item ->
338-
when (item) {
339-
is String -> {
324+
items(sections.keys.toList(), key = { "section_$it" }) { section ->
325+
val expanded = sectionExpanded[section] ?: false
326+
Card(
327+
onClick = { sectionExpanded[section] = !expanded },
328+
modifier = Modifier.fillMaxWidth(),
329+
colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.45f))
330+
) {
331+
Row(
332+
modifier = Modifier
333+
.fillMaxWidth()
334+
.padding(horizontal = 12.dp, vertical = 10.dp),
335+
horizontalArrangement = Arrangement.SpaceBetween,
336+
verticalAlignment = Alignment.CenterVertically
337+
) {
340338
Text(
341-
text = item,
339+
text = section,
342340
style = MaterialTheme.typography.titleSmall.copy(fontWeight = FontWeight.Bold),
343341
color = MaterialTheme.colorScheme.primary
344342
)
343+
Text(if (expanded) "Hide" else "Show", color = MaterialTheme.colorScheme.primary)
345344
}
346-
is SettingField -> {
347-
if ((item.key == "SOCKS5_USER" || item.key == "SOCKS5_PASS") && !socksAuthEnabled) {
348-
return@items
349-
}
350-
ConfigFieldCard(
351-
field = item,
352-
value = fieldsState[item.key].orEmpty(),
353-
onChange = { fieldsState[item.key] = it }
354-
)
345+
}
346+
if (!expanded) return@items
347+
348+
Spacer(modifier = Modifier.height(6.dp))
349+
sections[section].orEmpty().forEach { field ->
350+
if ((field.key == "SOCKS5_USER" || field.key == "SOCKS5_PASS") && !socksAuthEnabled) {
351+
return@forEach
355352
}
356-
else -> Unit
353+
ConfigFieldCard(
354+
field = field,
355+
value = fieldsState[field.key].orEmpty(),
356+
onChange = { fieldsState[field.key] = it }
357+
)
358+
Spacer(modifier = Modifier.height(8.dp))
357359
}
358360
}
359361

0 commit comments

Comments
 (0)