v1.2.3: fix keyboard order, empty password, new logo

This commit is contained in:
茂之钳
2026-05-24 10:40:11 +00:00
parent b3281928f1
commit 9bf76bfed7
22 changed files with 43 additions and 26 deletions
@@ -65,6 +65,12 @@ fun SshHost(modifier: Modifier = Modifier) {
val coroutineScope = rememberCoroutineScope()
fun openSession(config: SshConfig) {
// Bug 3: 如果密码为空,弹出连接对话框让用户输入密码
if (config.password.isBlank() && config.authMode != "key") {
pendingConfig = config
showConnectDialog = true
return
}
// 立即创建 tab 显示"连接中"
val mgr = SshTerminalManager(sessionId = "${config.host}:${config.port}")
activeSessions.add(mgr)
@@ -242,12 +248,25 @@ fun SshHost(modifier: Modifier = Modifier) {
}
if (showConnectDialog) {
SshConnectDialog(
onDismiss = { showConnectDialog = false },
onConnectPassword = { config -> showConnectDialog = false; pendingConfig = config },
onConnectKey = { config, passphrase -> showConnectDialog = false; pendingKeyConnect = KeyAuthConnect(config, passphrase) },
savedConfigs = savedConfigs
)
// Bug 3: 如果是从空密码连接触发的,预填配置给用户输入密码
val prefillConfig = pendingConfig
if (prefillConfig != null && prefillConfig.password.isBlank()) {
// 预填配置到 dialog 后清除 pending 标记
SshConnectDialog(
onDismiss = { showConnectDialog = false; pendingConfig = null },
onConnectPassword = { config -> showConnectDialog = false; pendingConfig = config },
onConnectKey = { config, passphrase -> showConnectDialog = false; pendingKeyConnect = KeyAuthConnect(config, passphrase) },
savedConfigs = savedConfigs,
initialConfig = prefillConfig
)
} else {
SshConnectDialog(
onDismiss = { showConnectDialog = false },
onConnectPassword = { config -> showConnectDialog = false; pendingConfig = config },
onConnectKey = { config, passphrase -> showConnectDialog = false; pendingKeyConnect = KeyAuthConnect(config, passphrase) },
savedConfigs = savedConfigs
)
}
}
}
}
@@ -69,16 +69,17 @@ fun SshConnectDialog(
onConnectPassword: (SshConfig) -> Unit,
onConnectKey: (config: SshConfig, passphrase: String?) -> Unit,
savedConfigs: List<SshConfig> = emptyList(),
onFillConfig: (SshConfig) -> Unit = {}
onFillConfig: (SshConfig) -> Unit = {},
initialConfig: SshConfig? = null
) {
var host by remember { mutableStateOf("") }
var port by remember { mutableStateOf("22") }
var username by remember { mutableStateOf("") }
var password by remember { mutableStateOf("") }
var displayName by remember { mutableStateOf("") }
var authMethod by remember { mutableStateOf("password") }
var host by remember { mutableStateOf(initialConfig?.host ?: "") }
var port by remember { mutableStateOf((initialConfig?.port ?: 22).toString()) }
var username by remember { mutableStateOf(initialConfig?.username ?: "") }
var password by remember { mutableStateOf(initialConfig?.password ?: "") }
var displayName by remember { mutableStateOf(initialConfig?.displayName ?: "") }
var authMethod by remember { mutableStateOf(initialConfig?.authMode ?: "password") }
var keyPassphrase by remember { mutableStateOf("") }
var selectedKeyPath by remember { mutableStateOf("") }
var selectedKeyPath by remember { mutableStateOf(initialConfig?.savedKeyPath ?: "") }
var passwordVisible by remember { mutableStateOf(false) }
var keyPassVisible by remember { mutableStateOf(false) }
@@ -417,8 +418,7 @@ fun SshTerminalScreen(
modifier: Modifier = Modifier
) {
val state by manager.connectionState.collectAsState()
val inputState = remember { mutableStateOf(TextFieldValue("")) }
var currentInput by inputState
var currentInput by remember { mutableStateOf("") }
val coroutineScope = rememberCoroutineScope()
val listState = rememberLazyListState()
var showFontPicker by remember { mutableStateOf(false) }
@@ -437,7 +437,7 @@ fun SshTerminalScreen(
}
// 获取当前输入的纯文本(用于显示)
val currentInputText = currentInput.text
val currentInputText = currentInput
// 硬件键盘处理
fun handleKeyEvent(event: KeyEvent): Boolean {
@@ -452,13 +452,13 @@ fun SshTerminalScreen(
manager.sendCommand(cmd)
}
}
currentInput = TextFieldValue("")
currentInput = ""
true
}
Key.Backspace -> {
val t = currentInputText
if (t.isNotEmpty()) {
currentInput = TextFieldValue(t.substring(0, t.length - 1))
currentInput = t.substring(0, t.length - 1)
}
true
}
@@ -488,19 +488,17 @@ fun SshTerminalScreen(
) {
// 透明输入框 — 极小的 1x30 dp,仅用来弹出软键盘
BasicTextField(
value = currentInput,
value = TextFieldValue(currentInput),
onValueChange = { newVal ->
val t = newVal.text
if (t.endsWith('\n')) {
val cmd = t.dropLast(1).trim()
currentInput = newVal.text
if (newVal.text.endsWith('\n')) {
val cmd = newVal.text.dropLast(1).trim()
if (cmd.isNotEmpty()) {
coroutineScope.launch {
manager.sendCommand(cmd)
}
}
currentInput = TextFieldValue("")
} else {
currentInput = newVal
currentInput = ""
}
},
modifier = Modifier
Binary file not shown.

Before

Width:  |  Height:  |  Size: 366 B

After

Width:  |  Height:  |  Size: 641 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 189 B

After

Width:  |  Height:  |  Size: 189 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 366 B

After

Width:  |  Height:  |  Size: 641 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 366 B

After

Width:  |  Height:  |  Size: 641 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 277 B

After

Width:  |  Height:  |  Size: 269 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 158 B

After

Width:  |  Height:  |  Size: 158 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 277 B

After

Width:  |  Height:  |  Size: 269 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 277 B

After

Width:  |  Height:  |  Size: 269 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 502 B

After

Width:  |  Height:  |  Size: 816 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 254 B

After

Width:  |  Height:  |  Size: 254 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 502 B

After

Width:  |  Height:  |  Size: 816 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 502 B

After

Width:  |  Height:  |  Size: 816 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 864 B

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 435 B

After

Width:  |  Height:  |  Size: 435 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 864 B

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 864 B

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 593 B

After

Width:  |  Height:  |  Size: 593 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB