Browse Source

android: move advanced settings into a developer tab

master
evgeny 3 days ago
parent
commit
f408abcf4e
  1. 51
      tools/chatgui-android/app/src/main/java/com/utun/chat/ui/screens/SettingsScreen.kt
  2. 1
      tools/chatgui-android/app/src/main/res/values/strings.xml

51
tools/chatgui-android/app/src/main/java/com/utun/chat/ui/screens/SettingsScreen.kt

@ -72,7 +72,7 @@ fun SettingsScreen(vm: ChatViewModel, onBack: () -> Unit, onExit: () -> Unit = {
var dirty by rememberSaveable { mutableStateOf(false) }
var tabIndex by rememberSaveable { mutableStateOf(0) }
val tabs = listOf(R.string.settings, R.string.audio, R.string.storage, R.string.radio)
val tabs = listOf(R.string.settings, R.string.audio, R.string.storage, R.string.radio, R.string.dev)
val handleBack = {
if (dirty && NativeLib.isReady()) {
@ -101,25 +101,52 @@ fun SettingsScreen(vm: ChatViewModel, onBack: () -> Unit, onExit: () -> Unit = {
}
}
when (tabIndex) {
0 -> GeneralSettingsTab(vm, dirty, onDirty = { dirty = it }, onExit)
0 -> GeneralSettingsTab(onDirty = { dirty = it })
1 -> AudioSettingsTab(vm)
2 -> StorageSettingsTab()
3 -> RadioSettingsTab()
4 -> DeveloperSettingsTab(vm, onDirty = { dirty = it }, onExit)
}
}
}
}
/* ── General Settings Tab ── */
/* Основные настройки профиля и приложения. */
@Composable
private fun GeneralSettingsTab(onDirty: (Boolean) -> Unit) {
val provider = ChatApplication.instance.configProvider
val scope = rememberCoroutineScope()
var nodeName by remember { mutableStateOf("") }
LaunchedEffect(Unit) {
nodeName = provider.getString("node.name") ?: provider.getDeviceName()
LogManager.addLog("INFO", "SETTINGS", "General settings opened")
}
LazyColumn(
modifier = Modifier.fillMaxSize(),
contentPadding = PaddingValues(16.dp),
verticalArrangement = Arrangement.spacedBy(12.dp)
) {
item(key = "language") { LanguageSetting() }
item(key = "battery") { BatteryOptimizationSetting(source = "settings") }
item(key = "node-name") {
OutlinedTextField(nodeName, { v -> onDirty(true); nodeName = v; scope.launch { provider.setValue("node.name", v) } },
label = { Text(stringResource(R.string.node_name)) }, singleLine = true, modifier = Modifier.heightIn(min = 40.dp))
}
item(key = "profile-avatar") { ProfileAvatarControls() }
}
}
/* Настройки разработчика: сеть, ключи, standby, диагностика и управление сервисом. */
@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun GeneralSettingsTab(vm: ChatViewModel, dirty: Boolean, onDirty: (Boolean) -> Unit,
onExit: () -> Unit) {
private fun DeveloperSettingsTab(vm: ChatViewModel, onDirty: (Boolean) -> Unit, onExit: () -> Unit) {
val provider = ChatApplication.instance.configProvider
val scope = rememberCoroutineScope()
var nodeName by remember { mutableStateOf("") }
var listenPort by remember { mutableStateOf("12345") }
var controlPort by remember { mutableStateOf("9999") }
var controlBindIp by remember { mutableStateOf("127.0.0.1") }
@ -152,7 +179,6 @@ private fun GeneralSettingsTab(vm: ChatViewModel, dirty: Boolean, onDirty: (Bool
var startOnBootError by remember { mutableStateOf(false) }
LaunchedEffect(Unit) {
nodeName = provider.getString("node.name") ?: provider.getDeviceName()
listenPort = provider.getInt("node.listen_port").toString()
controlPort = provider.getInt("control.port").toString()
controlBindIp = provider.getString("control.bind_ip") ?: "127.0.0.1"
@ -206,7 +232,7 @@ private fun GeneralSettingsTab(vm: ChatViewModel, dirty: Boolean, onDirty: (Bool
val openedAt = remember { android.os.SystemClock.uptimeMillis() }
LaunchedEffect(Unit) {
withFrameNanos { }
LogManager.addLog("INFO", "SETTINGS", "General settings displayed: elapsedMs=${android.os.SystemClock.uptimeMillis() - openedAt} " +
LogManager.addLog("INFO", "SETTINGS", "Dev settings displayed: elapsedMs=${android.os.SystemClock.uptimeMillis() - openedAt} " +
"visibleItems=${listState.layoutInfo.visibleItemsInfo.size} totalItems=${listState.layoutInfo.totalItemsCount}")
}
@ -217,15 +243,8 @@ private fun GeneralSettingsTab(vm: ChatViewModel, dirty: Boolean, onDirty: (Bool
contentPadding = PaddingValues(16.dp),
verticalArrangement = Arrangement.spacedBy(12.dp)
) {
item(key = "language") { LanguageSetting() }
item(key = "battery") { BatteryOptimizationSetting(source = "settings") }
/* Node */
item(key = "node-title") { Text(stringResource(R.string.node), style = MaterialTheme.typography.titleMedium) }
item(key = "node-name") {
OutlinedTextField(nodeName, { v -> onDirty(true); nodeName = v; scope.launch { provider.setValue("node.name", v) } },
label = { Text(stringResource(R.string.node_name)) }, singleLine = true, modifier = Modifier.heightIn(min = 40.dp))
}
item(key = "listen-port") {
OutlinedTextField(listenPort, { v -> onDirty(true); listenPort = v; scope.launch { provider.setValue("node.listen_port", v) } },
label = { Text(stringResource(R.string.listen_port)) }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
@ -256,8 +275,6 @@ private fun GeneralSettingsTab(vm: ChatViewModel, dirty: Boolean, onDirty: (Bool
}
}
item(key = "profile-avatar") { ProfileAvatarControls() }
/* Keys */
item(key = "keys-title") { Text(stringResource(R.string.keys), style = MaterialTheme.typography.titleMedium) }
item(key = "public-key") { OutlinedTextField(pubKey, {}, label = { Text(stringResource(R.string.public_key)) }, readOnly = true, singleLine = true) }

1
tools/chatgui-android/app/src/main/res/values/strings.xml

@ -4,6 +4,7 @@
<string name="microphone_request_failed">"Could not request microphone access"</string>
<string name="microphone_permission_settings">"Microphone access is denied. Allow it in app settings, then try the call or PTT again."</string>
<string name="settings">"Settings"</string>
<string name="dev" translatable="false">Dev</string>
<string name="cancel">"Cancel"</string>
<string name="invalid_channel_id">"Invalid channel ID"</string>
<string name="microphone_ptt_retry">"Microphone allowed. Press PTT again"</string>

Loading…
Cancel
Save