diff --git a/src/main/kotlin/org/briarproject/briar/desktop/dialogs/Login.kt b/src/main/kotlin/org/briarproject/briar/desktop/dialogs/Login.kt index 427a55c238ff6faf72821b5efe900ce888fb5c08..a95aae7d49adddcde78547227f63fd3d4d60de75 100644 --- a/src/main/kotlin/org/briarproject/briar/desktop/dialogs/Login.kt +++ b/src/main/kotlin/org/briarproject/briar/desktop/dialogs/Login.kt @@ -9,30 +9,45 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.text.KeyboardActions +import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material.Button import androidx.compose.material.OutlinedTextField import androidx.compose.material.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.DisposableEffect 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.ExperimentalComposeUiApi import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip +import androidx.compose.ui.focus.FocusRequester +import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.graphics.Color +import androidx.compose.ui.input.key.Key +import androidx.compose.ui.input.key.KeyEventType +import androidx.compose.ui.input.key.key +import androidx.compose.ui.input.key.onPreviewKeyEvent +import androidx.compose.ui.input.key.type import androidx.compose.ui.res.svgResource import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.input.ImeAction +import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.PasswordVisualTransformation import androidx.compose.ui.unit.dp // TODO: Error handling +@OptIn(ExperimentalComposeUiApi::class) @Composable fun Login( modifier: Modifier = Modifier, onResult: (result: String) -> Unit ) { var password by remember { mutableStateOf("") } + val initialFocusRequester = remember { FocusRequester() } Column( modifier = modifier.padding(16.dp).fillMaxSize(), verticalArrangement = Arrangement.Center, @@ -46,12 +61,27 @@ fun Login( label = { Text("Password") }, singleLine = true, textStyle = TextStyle(color = Color.White), - visualTransformation = PasswordVisualTransformation() + visualTransformation = PasswordVisualTransformation(), + keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password, imeAction = ImeAction.Done), + keyboardActions = KeyboardActions(onDone = { onResult.invoke(password) }), + modifier = Modifier + .focusRequester(initialFocusRequester) + .onPreviewKeyEvent { + if (it.type == KeyEventType.KeyUp && it.key == Key.Enter) { + onResult.invoke(password) + } + false + }, ) Spacer(Modifier.height(16.dp)) Button(onClick = { onResult.invoke(password) }) { Text("Login", color = Color.Black) } + + DisposableEffect(Unit) { + initialFocusRequester.requestFocus() + onDispose { } + } } } diff --git a/src/main/kotlin/org/briarproject/briar/desktop/dialogs/Registration.kt b/src/main/kotlin/org/briarproject/briar/desktop/dialogs/Registration.kt index 523523391fd141f67af2922fb133f38e5da3dbc2..afab8ce46adc62a904ffdb9638ae118cd411ad41 100644 --- a/src/main/kotlin/org/briarproject/briar/desktop/dialogs/Registration.kt +++ b/src/main/kotlin/org/briarproject/briar/desktop/dialogs/Registration.kt @@ -6,22 +6,38 @@ import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.text.KeyboardActions +import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material.Button import androidx.compose.material.OutlinedTextField import androidx.compose.material.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.DisposableEffect 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.ExperimentalComposeUiApi import androidx.compose.ui.Modifier +import androidx.compose.ui.focus.FocusDirection +import androidx.compose.ui.focus.FocusRequester +import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.graphics.Color +import androidx.compose.ui.input.key.Key +import androidx.compose.ui.input.key.KeyEventType +import androidx.compose.ui.input.key.key +import androidx.compose.ui.input.key.onPreviewKeyEvent +import androidx.compose.ui.input.key.type +import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.input.ImeAction +import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.PasswordVisualTransformation import androidx.compose.ui.unit.dp // TODO: Error handling and password strength +@OptIn(ExperimentalComposeUiApi::class) @Composable fun Registration( modifier: Modifier = Modifier, @@ -29,6 +45,8 @@ fun Registration( ) { var username by remember { mutableStateOf("") } var password by remember { mutableStateOf("") } + val initialFocusRequester = remember { FocusRequester() } + val focusManager = LocalFocusManager.current Column( modifier = modifier.padding(16.dp).fillMaxSize(), verticalArrangement = Arrangement.Center, @@ -42,6 +60,16 @@ fun Registration( label = { Text("Username") }, singleLine = true, textStyle = TextStyle(color = Color.White), + keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next), + keyboardActions = KeyboardActions(onNext = { focusManager.moveFocus(FocusDirection.Next) }), + modifier = Modifier + .focusRequester(initialFocusRequester) + .onPreviewKeyEvent { + if (it.type == KeyEventType.KeyUp && it.key == Key.Enter) { + focusManager.moveFocus(FocusDirection.Next) + } + false + }, ) OutlinedTextField( value = password, @@ -50,10 +78,23 @@ fun Registration( singleLine = true, textStyle = TextStyle(color = Color.White), visualTransformation = PasswordVisualTransformation(), + keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password, imeAction = ImeAction.Done), + keyboardActions = KeyboardActions(onDone = { onSubmit.invoke(username, password) }), + modifier = Modifier.onPreviewKeyEvent { + if (it.type == KeyEventType.KeyUp && it.key == Key.Enter) { + onSubmit.invoke(username, password) + } + false + }, ) Spacer(Modifier.height(16.dp)) Button(onClick = { onSubmit.invoke(username, password) }) { - Text("Register") + Text("Register", color = Color.Black) + } + + DisposableEffect(Unit) { + initialFocusRequester.requestFocus() + onDispose { } } } }