Skip to content

Commit

Permalink
perf: unify dialog input behavior
Browse files Browse the repository at this point in the history
  • Loading branch information
lisonge committed Jan 26, 2025
1 parent 6168b7e commit 4d6c50c
Show file tree
Hide file tree
Showing 14 changed files with 224 additions and 317 deletions.
5 changes: 4 additions & 1 deletion app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ android {
vectorDrawables {
useSupportLibrary = true
}
resourceConfigurations.addAll(listOf("zh", "en"))
androidResources {
localeFilters += listOf("zh", "en")
}
ndk {
// noinspection ChromeOsAbiSupport
abiFilters += listOf("arm64-v8a", "x86_64")
Expand Down Expand Up @@ -154,6 +156,7 @@ android {
"-opt-in=androidx.compose.foundation.ExperimentalFoundationApi",
"-opt-in=androidx.compose.animation.graphics.ExperimentalAnimationGraphicsApi",
"-opt-in=androidx.compose.ui.ExperimentalComposeUiApi",
"-opt-in=androidx.compose.foundation.layout.ExperimentalLayoutApi"
)
}
dependenciesInfo.includeInApk = false
Expand Down
114 changes: 56 additions & 58 deletions app/src/main/kotlin/li/songe/gkd/ui/AdvancedPage.kt
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,15 @@ import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.onFocusChanged
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.DialogProperties
import androidx.lifecycle.viewModelScope
import androidx.lifecycle.viewmodel.compose.viewModel
import com.blankj.utilcode.util.LogUtils
Expand All @@ -76,6 +75,7 @@ import li.songe.gkd.shizuku.shizukuCheckWorkProfile
import li.songe.gkd.ui.component.AuthCard
import li.songe.gkd.ui.component.SettingItem
import li.songe.gkd.ui.component.TextSwitch
import li.songe.gkd.ui.component.autoFocus
import li.songe.gkd.ui.component.updateDialogOptions
import li.songe.gkd.ui.style.EmptyHeight
import li.songe.gkd.ui.style.itemPadding
Expand Down Expand Up @@ -108,68 +108,66 @@ fun AdvancedPage() {
var value by remember {
mutableStateOf(store.httpServerPort.toString())
}
val inputFocused = rememberSaveable { mutableStateOf(false) }
AlertDialog(title = { Text(text = "服务端口") }, text = {
OutlinedTextField(
value = value,
placeholder = {
Text(text = "请输入 5000-65535 的整数")
},
onValueChange = {
value = it.filter { c -> c.isDigit() }.take(5)
},
singleLine = true,
modifier = Modifier
.fillMaxWidth()
.onFocusChanged {
if (it.isFocused) {
inputFocused.value = true
}
AlertDialog(
properties = DialogProperties(dismissOnClickOutside = false),
title = { Text(text = "服务端口") },
text = {
OutlinedTextField(
value = value,
placeholder = {
Text(text = "请输入 5000-65535 的整数")
},
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
supportingText = {
Text(
text = "${value.length} / 5",
modifier = Modifier.fillMaxWidth(),
textAlign = TextAlign.End,
)
},
)
}, onDismissRequest = {
if (!inputFocused.value) {
onValueChange = {
value = it.filter { c -> c.isDigit() }.take(5)
},
singleLine = true,
modifier = Modifier.autoFocus(),
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
supportingText = {
Text(
text = "${value.length} / 5",
modifier = Modifier.fillMaxWidth(),
textAlign = TextAlign.End,
)
},
)
},
onDismissRequest = {
showEditPortDlg = false
}
}, confirmButton = {
TextButton(
enabled = value.isNotEmpty(),
onClick = {
val newPort = value.toIntOrNull()
if (newPort == null || !(5000 <= newPort && newPort <= 65535)) {
toast("请输入 5000-65535 的整数")
return@TextButton
},
confirmButton = {
TextButton(
enabled = value.isNotEmpty(),
onClick = {
val newPort = value.toIntOrNull()
if (newPort == null || !(5000 <= newPort && newPort <= 65535)) {
toast("请输入 5000-65535 的整数")
return@TextButton
}
storeFlow.value = store.copy(
httpServerPort = newPort
)
showEditPortDlg = false
if (HttpService.httpServerFlow.value != null) {
toast("已更新, 重启服务")
} else {
toast("已更新")
}
}
storeFlow.value = store.copy(
httpServerPort = newPort
) {
Text(
text = "确认", modifier = Modifier
)
}
},
dismissButton = {
TextButton(onClick = { showEditPortDlg = false }) {
Text(
text = "取消"
)
showEditPortDlg = false
if (HttpService.httpServerFlow.value != null) {
toast("已更新, 重启服务")
} else {
toast("已更新")
}
}
) {
Text(
text = "确认", modifier = Modifier
)
}
}, dismissButton = {
TextButton(onClick = { showEditPortDlg = false }) {
Text(
text = "取消"
)
}
})
)
}

val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior()
Expand Down
29 changes: 6 additions & 23 deletions app/src/main/kotlin/li/songe/gkd/ui/GlobalGroupExcludePage.kt
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,11 @@ import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.focus.onFocusChanged
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.DialogProperties
import androidx.lifecycle.viewModelScope
import androidx.lifecycle.viewmodel.compose.viewModel
import com.blankj.utilcode.util.KeyboardUtils
Expand All @@ -73,6 +71,7 @@ import li.songe.gkd.ui.component.EmptyText
import li.songe.gkd.ui.component.InnerDisableSwitch
import li.songe.gkd.ui.component.QueryPkgAuthCard
import li.songe.gkd.ui.component.TowLineText
import li.songe.gkd.ui.component.autoFocus
import li.songe.gkd.ui.style.EmptyHeight
import li.songe.gkd.ui.style.itemFlagPadding
import li.songe.gkd.ui.style.menuPadding
Expand Down Expand Up @@ -109,11 +108,7 @@ fun GlobalGroupExcludePage(subsItemId: Long, groupKey: Int) {
var showSearchBar by rememberSaveable {
mutableStateOf(false)
}
val focusRequester = remember { FocusRequester() }
LaunchedEffect(key1 = showSearchBar, block = {
if (showSearchBar && searchStr.isEmpty()) {
focusRequester.requestFocus()
}
if (!showSearchBar) {
vm.searchStrFlow.value = ""
}
Expand Down Expand Up @@ -155,7 +150,7 @@ fun GlobalGroupExcludePage(subsItemId: Long, groupKey: Int) {
value = searchStr,
onValueChange = { newValue -> vm.searchStrFlow.value = newValue.trim() },
hint = "请输入应用名称/ID",
modifier = Modifier.focusRequester(focusRequester)
modifier = Modifier.autoFocus()
)
} else {
TowLineText(
Expand Down Expand Up @@ -360,22 +355,15 @@ fun GlobalGroupExcludePage(subsItemId: Long, groupKey: Int) {
excludeData.stringify()
)
}
val inputFocused = rememberSaveable { mutableStateOf(false) }
val oldSource = remember { source }
AlertDialog(
properties = DialogProperties(dismissOnClickOutside = false),
title = { Text(text = "编辑禁用") },
text = {
OutlinedTextField(
value = source,
onValueChange = { source = it },
modifier = Modifier
.fillMaxWidth()
.focusRequester(focusRequester)
.onFocusChanged {
if (it.isFocused) {
inputFocused.value = true
}
},
modifier = Modifier.autoFocus(),
placeholder = {
Text(
text = tipText,
Expand All @@ -386,14 +374,9 @@ fun GlobalGroupExcludePage(subsItemId: Long, groupKey: Int) {
maxLines = 12,
textStyle = MaterialTheme.typography.bodySmall
)
LaunchedEffect(null) {
focusRequester.requestFocus()
}
},
onDismissRequest = {
if (!inputFocused.value) {
showEditDlg = false
}
showEditDlg = false
},
dismissButton = {
TextButton(onClick = { showEditDlg = false }) {
Expand Down
9 changes: 2 additions & 7 deletions app/src/main/kotlin/li/songe/gkd/ui/SubsAppListPage.kt
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@ import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.lifecycle.viewModelScope
Expand All @@ -55,6 +53,7 @@ import li.songe.gkd.ui.component.EmptyText
import li.songe.gkd.ui.component.QueryPkgAuthCard
import li.songe.gkd.ui.component.SubsAppCard
import li.songe.gkd.ui.component.TowLineText
import li.songe.gkd.ui.component.autoFocus
import li.songe.gkd.ui.component.useSubs
import li.songe.gkd.ui.style.EmptyHeight
import li.songe.gkd.ui.style.menuPadding
Expand Down Expand Up @@ -85,11 +84,7 @@ fun SubsAppListPage(
var showSearchBar by rememberSaveable {
mutableStateOf(false)
}
val focusRequester = remember { FocusRequester() }
LaunchedEffect(key1 = showSearchBar, block = {
if (showSearchBar && searchStr.isEmpty()) {
focusRequester.requestFocus()
}
if (!showSearchBar) {
vm.searchStrFlow.value = ""
}
Expand Down Expand Up @@ -136,7 +131,7 @@ fun SubsAppListPage(
value = searchStr,
onValueChange = { newValue -> vm.searchStrFlow.value = newValue.trim() },
hint = "请输入应用名称/ID",
modifier = Modifier.focusRequester(focusRequester)
modifier = Modifier.autoFocus()
)
} else {
TowLineText(
Expand Down
15 changes: 4 additions & 11 deletions app/src/main/kotlin/li/songe/gkd/ui/SubsCategoryPage.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentSize
Expand All @@ -33,18 +32,16 @@ import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.TriStateCheckbox
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.DialogProperties
import androidx.lifecycle.viewModelScope
import androidx.lifecycle.viewmodel.compose.viewModel
import com.ramcosta.composedestinations.annotation.Destination
Expand All @@ -57,6 +54,7 @@ import li.songe.gkd.db.DbSet
import li.songe.gkd.ui.component.CardFlagBar
import li.songe.gkd.ui.component.EmptyText
import li.songe.gkd.ui.component.TowLineText
import li.songe.gkd.ui.component.autoFocus
import li.songe.gkd.ui.component.updateDialogOptions
import li.songe.gkd.ui.component.waitResult
import li.songe.gkd.ui.icon.ResetSettings
Expand Down Expand Up @@ -361,22 +359,17 @@ private fun AddOrEditCategoryDialog(
toast("添加成功")
}
}
val focusRequester = remember { FocusRequester() }
AlertDialog(
properties = DialogProperties(dismissOnClickOutside = false),
title = { Text(text = if (category == null) "添加类别" else "编辑类别") },
text = {
OutlinedTextField(
value = value,
onValueChange = { value = it.trim() },
modifier = Modifier
.fillMaxWidth()
.focusRequester(focusRequester),
modifier = Modifier.autoFocus(),
placeholder = { Text(text = "请输入类别名称") },
singleLine = true
)
LaunchedEffect(null) {
focusRequester.requestFocus()
}
},
onDismissRequest = {},
dismissButton = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,6 @@ fun AppBarTextField(
val mergedTextStyle = LocalTextStyle.current.merge(MaterialTheme.typography.titleMedium)
.merge(color = LocalContentColor.current)

// request focus when this composable is first initialized
// val focusRequester = FocusRequester()
// SideEffect {
// focusRequester.requestFocus()
// }

// set the correct cursor position when this composable is first initialized
var textFieldValue by remember {
mutableStateOf(TextFieldValue(value, TextRange(value.length)))
Expand Down
Loading

0 comments on commit 4d6c50c

Please sign in to comment.