Make settings groups collapsible (#5939)
This commit is contained in:
1 parent
c9e1501d39
commit
ce75aad55e
3 files changed
+110
-9
No files matched your search
@@ -21,11 +21,14 @@ import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.rotate
|
||||
import androidx.compose.ui.draw.scale
|
||||
import androidx.compose.ui.graphics.painter.Painter
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.input.VisualTransformation
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.v2ray.ang.R
|
||||
|
||||
@Composable
|
||||
fun PreferenceGroupHeader(title: String, modifier: Modifier = Modifier) {
|
||||
@@ -39,6 +42,37 @@ fun PreferenceGroupHeader(title: String, modifier: Modifier = Modifier) {
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun CollapsiblePreferenceGroupHeader(
|
||||
title: String,
|
||||
expanded: Boolean,
|
||||
onExpandedChange: (Boolean) -> Unit,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
Row(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.clickable { onExpandedChange(!expanded) }
|
||||
.padding(horizontal = 16.dp, vertical = 12.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Text(
|
||||
text = title,
|
||||
style = MaterialTheme.typography.titleSmall,
|
||||
color = colorFabActive,
|
||||
modifier = Modifier.weight(1f)
|
||||
)
|
||||
Icon(
|
||||
painter = painterResource(R.drawable.ic_expand_more_24dp),
|
||||
contentDescription = null,
|
||||
tint = colorFabActive,
|
||||
modifier = Modifier
|
||||
.size(24.dp)
|
||||
.rotate(if (expanded) 180f else 0f)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SettingsItemRow(
|
||||
icon: Painter?,
|
||||
|
||||
@@ -14,6 +14,8 @@ import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.ScaffoldDefaults
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringArrayResource
|
||||
@@ -24,7 +26,7 @@ import com.v2ray.ang.AppConfig
|
||||
import com.v2ray.ang.AppConfig.VPN
|
||||
import com.v2ray.ang.R
|
||||
import com.v2ray.ang.compose.AppTopBar
|
||||
import com.v2ray.ang.compose.PreferenceGroupHeader
|
||||
import com.v2ray.ang.compose.CollapsiblePreferenceGroupHeader
|
||||
import com.v2ray.ang.compose.SettingsEditItem
|
||||
import com.v2ray.ang.compose.SettingsListItem
|
||||
import com.v2ray.ang.compose.SettingsMenuItem
|
||||
@@ -65,6 +67,14 @@ fun SettingsScreen(
|
||||
) {
|
||||
val scrollState = rememberScrollState()
|
||||
val isLoading by viewModel.isLoading.collectAsStateWithLifecycle()
|
||||
var uiSettingsExpanded by rememberSaveable { mutableStateOf(true) }
|
||||
var vpnSettingsExpanded by rememberSaveable { mutableStateOf(true) }
|
||||
var coreSettingsExpanded by rememberSaveable { mutableStateOf(true) }
|
||||
var muxSettingsExpanded by rememberSaveable { mutableStateOf(false) }
|
||||
var fragmentSettingsExpanded by rememberSaveable { mutableStateOf(false) }
|
||||
var observatorySettingsExpanded by rememberSaveable { mutableStateOf(false) }
|
||||
var advancedSettingsExpanded by rememberSaveable { mutableStateOf(false) }
|
||||
var modeSettingsExpanded by rememberSaveable { mutableStateOf(false) }
|
||||
|
||||
var localDns by rememberMmkvBool(AppConfig.PREF_LOCAL_DNS_ENABLED, false)
|
||||
var fakeDns by rememberMmkvBool(AppConfig.PREF_FAKE_DNS_ENABLED, false)
|
||||
@@ -174,7 +184,12 @@ fun SettingsScreen(
|
||||
.verticalScrollbar(scrollState)
|
||||
.verticalScroll(scrollState)
|
||||
) {
|
||||
PreferenceGroupHeader(title = stringResource(R.string.title_ui_settings))
|
||||
CollapsiblePreferenceGroupHeader(
|
||||
title = stringResource(R.string.title_ui_settings),
|
||||
expanded = uiSettingsExpanded,
|
||||
onExpandedChange = { uiSettingsExpanded = it }
|
||||
)
|
||||
if (uiSettingsExpanded) {
|
||||
SettingsSwitchItem(
|
||||
title = stringResource(R.string.title_pref_speed_enabled),
|
||||
summary = stringResource(R.string.summary_pref_speed_enabled),
|
||||
@@ -222,8 +237,14 @@ fun SettingsScreen(
|
||||
ThemeManager.setThemeMode(it)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
PreferenceGroupHeader(title = stringResource(R.string.title_vpn_settings))
|
||||
CollapsiblePreferenceGroupHeader(
|
||||
title = stringResource(R.string.title_vpn_settings),
|
||||
expanded = vpnSettingsExpanded,
|
||||
onExpandedChange = { vpnSettingsExpanded = it }
|
||||
)
|
||||
if (vpnSettingsExpanded) {
|
||||
SettingsSwitchItem(
|
||||
title = stringResource(R.string.title_pref_ipv6_enabled),
|
||||
summary = stringResource(R.string.summary_pref_ipv6_enabled),
|
||||
@@ -313,8 +334,14 @@ fun SettingsScreen(
|
||||
keyboardNumber = true,
|
||||
onValueChanged = { hevTunRwTimeout = it }
|
||||
)
|
||||
}
|
||||
|
||||
PreferenceGroupHeader(title = stringResource(R.string.title_core_settings))
|
||||
CollapsiblePreferenceGroupHeader(
|
||||
title = stringResource(R.string.title_core_settings),
|
||||
expanded = coreSettingsExpanded,
|
||||
onExpandedChange = { coreSettingsExpanded = it }
|
||||
)
|
||||
if (coreSettingsExpanded) {
|
||||
SettingsSwitchItem(
|
||||
title = stringResource(R.string.title_pref_sniffing_enabled),
|
||||
summary = stringResource(R.string.summary_pref_sniffing_enabled),
|
||||
@@ -411,8 +438,14 @@ fun SettingsScreen(
|
||||
selectedValue = outboundResolveMethod,
|
||||
onSelected = { outboundResolveMethod = it }
|
||||
)
|
||||
}
|
||||
|
||||
PreferenceGroupHeader(title = stringResource(R.string.title_mux_settings))
|
||||
CollapsiblePreferenceGroupHeader(
|
||||
title = stringResource(R.string.title_mux_settings),
|
||||
expanded = muxSettingsExpanded,
|
||||
onExpandedChange = { muxSettingsExpanded = it }
|
||||
)
|
||||
if (muxSettingsExpanded) {
|
||||
SettingsSwitchItem(
|
||||
title = stringResource(R.string.title_pref_mux_enabled),
|
||||
summary = stringResource(R.string.summary_pref_mux_enabled),
|
||||
@@ -441,8 +474,14 @@ fun SettingsScreen(
|
||||
enabled = mux && muxXudpConcurrencyInt >= 0,
|
||||
onSelected = { muxXudpQuic = it }
|
||||
)
|
||||
}
|
||||
|
||||
PreferenceGroupHeader(title = stringResource(R.string.title_fragment_settings))
|
||||
CollapsiblePreferenceGroupHeader(
|
||||
title = stringResource(R.string.title_fragment_settings),
|
||||
expanded = fragmentSettingsExpanded,
|
||||
onExpandedChange = { fragmentSettingsExpanded = it }
|
||||
)
|
||||
if (fragmentSettingsExpanded) {
|
||||
SettingsSwitchItem(
|
||||
title = stringResource(R.string.title_pref_fragment_enabled),
|
||||
checked = fragment,
|
||||
@@ -475,8 +514,14 @@ fun SettingsScreen(
|
||||
keyboardNumber = true,
|
||||
onValueChanged = { fragmentMaxSplit = it }
|
||||
)
|
||||
}
|
||||
|
||||
PreferenceGroupHeader(title = stringResource(R.string.title_observatory_settings))
|
||||
CollapsiblePreferenceGroupHeader(
|
||||
title = stringResource(R.string.title_observatory_settings),
|
||||
expanded = observatorySettingsExpanded,
|
||||
onExpandedChange = { observatorySettingsExpanded = it }
|
||||
)
|
||||
if (observatorySettingsExpanded) {
|
||||
SettingsEditItem(
|
||||
title = stringResource(R.string.title_pref_observatory_least_ping_interval),
|
||||
value = observatoryLeastPingInterval,
|
||||
@@ -521,8 +566,14 @@ fun SettingsScreen(
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
PreferenceGroupHeader(title = stringResource(R.string.title_advanced))
|
||||
CollapsiblePreferenceGroupHeader(
|
||||
title = stringResource(R.string.title_advanced),
|
||||
expanded = advancedSettingsExpanded,
|
||||
onExpandedChange = { advancedSettingsExpanded = it }
|
||||
)
|
||||
if (advancedSettingsExpanded) {
|
||||
SettingsSwitchItem(
|
||||
title = stringResource(R.string.title_pref_is_booted),
|
||||
summary = stringResource(R.string.summary_pref_is_booted),
|
||||
@@ -545,8 +596,14 @@ fun SettingsScreen(
|
||||
value = ipApiUrl,
|
||||
onValueChanged = { ipApiUrl = it }
|
||||
)
|
||||
}
|
||||
|
||||
PreferenceGroupHeader(title = stringResource(R.string.title_mode_settings))
|
||||
CollapsiblePreferenceGroupHeader(
|
||||
title = stringResource(R.string.title_mode_settings),
|
||||
expanded = modeSettingsExpanded,
|
||||
onExpandedChange = { modeSettingsExpanded = it }
|
||||
)
|
||||
if (modeSettingsExpanded) {
|
||||
SettingsListItem(
|
||||
title = stringResource(R.string.title_mode),
|
||||
entries = modeEntries,
|
||||
@@ -586,6 +643,7 @@ fun SettingsScreen(
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(24.dp))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M7.41,8.59 12,13.17 16.59,8.59 18,10l-6,6 -6,-6z" />
|
||||
</vector>
|
||||
Reference in new issue
Block a user