Add git pushing after every commit.

Improve hardware keyboard and editor focus handling

- Map physical Tab, arrow, and Enter keys to the terminal actions used by the on-screen controls.
- Keep focus in the terminal input after command submission.
- Focus editor content fields when editor dialogs open.
This commit is contained in:
Joe Tretter
2026-05-12 18:02:39 -05:00
parent 75c8396f00
commit e8bcf660d9
5 changed files with 83 additions and 9 deletions

View File

@@ -118,6 +118,7 @@ auto_commit_if_needed() {
git -C "$PROJECT_DIR" commit -m "Misc Changes" git -C "$PROJECT_DIR" commit -m "Misc Changes"
fi fi
: > "$COMMIT_SUMMARY_FILE" : > "$COMMIT_SUMMARY_FILE"
git push
} }
download_if_missing() { download_if_missing() {

View File

@@ -19,8 +19,8 @@ android {
applicationId = "solutions.tretter.githugandroid" applicationId = "solutions.tretter.githugandroid"
minSdk = 26 minSdk = 26
targetSdk = 35 targetSdk = 35
versionCode = 137 versionCode = 138
versionName = "0.1.136" versionName = "0.1.137"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true vectorDrawables.useSupportLibrary = true

View File

@@ -23,8 +23,13 @@ import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Surface import androidx.compose.material3.Surface
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.SolidColor import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
@@ -49,6 +54,13 @@ fun GitMessageEditorDialog(
val horizontalScroll = rememberScrollState() val horizontalScroll = rememberScrollState()
val verticalScroll = rememberScrollState() val verticalScroll = rememberScrollState()
val dialogScroll = rememberScrollState() val dialogScroll = rememberScrollState()
val contentFocusRequester = remember { FocusRequester() }
val keyboardController = LocalSoftwareKeyboardController.current
LaunchedEffect(state.invocation.command) {
contentFocusRequester.requestFocus()
keyboardController?.show()
}
Dialog( Dialog(
onDismissRequest = onClose, onDismissRequest = onClose,
@@ -104,7 +116,9 @@ fun GitMessageEditorDialog(
BasicTextField( BasicTextField(
value = state.content, value = state.content,
onValueChange = onContentChange, onValueChange = onContentChange,
modifier = Modifier.sizeIn(minWidth = 1000.dp, minHeight = 700.dp), modifier = Modifier
.sizeIn(minWidth = 1000.dp, minHeight = 700.dp)
.focusRequester(contentFocusRequester),
textStyle = TextStyle( textStyle = TextStyle(
color = TextPrimary, color = TextPrimary,
fontFamily = FontFamily.Monospace, fontFamily = FontFamily.Monospace,

View File

@@ -41,8 +41,12 @@ import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.layout.boundsInRoot import androidx.compose.ui.layout.boundsInRoot
import androidx.compose.ui.layout.onGloballyPositioned import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.platform.LocalSoftwareKeyboardController import androidx.compose.ui.platform.LocalSoftwareKeyboardController
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.text.TextRange import androidx.compose.ui.text.TextRange
import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontFamily
@@ -73,7 +77,6 @@ fun TerminalPane(
) { ) {
val configuration = LocalConfiguration.current val configuration = LocalConfiguration.current
val focusRequester = remember { FocusRequester() } val focusRequester = remember { FocusRequester() }
val focusManager = LocalFocusManager.current
val keyboardController = LocalSoftwareKeyboardController.current val keyboardController = LocalSoftwareKeyboardController.current
val outputHorizontalScroll = rememberScrollState() val outputHorizontalScroll = rememberScrollState()
val outputVerticalScroll = rememberScrollState() val outputVerticalScroll = rememberScrollState()
@@ -86,6 +89,8 @@ fun TerminalPane(
LaunchedEffect(inputFieldVersion) { LaunchedEffect(inputFieldVersion) {
outputHorizontalScroll.scrollTo(0) outputHorizontalScroll.scrollTo(0)
focusRequester.requestFocus()
keyboardController?.show()
} }
LaunchedEffect(output.size) { LaunchedEffect(output.size) {
@@ -93,8 +98,6 @@ fun TerminalPane(
} }
fun submitCommand() { fun submitCommand() {
focusManager.clearFocus(force = true)
keyboardController?.hide()
onRun() onRun()
} }
@@ -184,6 +187,11 @@ fun TerminalPane(
keyboardController = keyboardController, keyboardController = keyboardController,
onFocused = onInputHintDismiss, onFocused = onInputHintDismiss,
onSubmit = { submitCommand() }, onSubmit = { submitCommand() },
onTab = onTab,
onCursorLeft = onCursorLeft,
onCursorRight = onCursorRight,
onHistoryUp = onHistoryUp,
onHistoryDown = onHistoryDown,
) )
} }
} }
@@ -200,6 +208,11 @@ private fun RowScope.TerminalInputField(
keyboardController: androidx.compose.ui.platform.SoftwareKeyboardController?, keyboardController: androidx.compose.ui.platform.SoftwareKeyboardController?,
onFocused: () -> Unit, onFocused: () -> Unit,
onSubmit: () -> Unit, onSubmit: () -> Unit,
onTab: () -> Unit,
onCursorLeft: () -> Unit,
onCursorRight: () -> Unit,
onHistoryUp: () -> Unit,
onHistoryDown: () -> Unit,
) { ) {
key(inputFieldVersion) { key(inputFieldVersion) {
BasicTextField( BasicTextField(
@@ -213,6 +226,38 @@ private fun RowScope.TerminalInputField(
onFocused() onFocused()
keyboardController?.show() keyboardController?.show()
} }
}
.onPreviewKeyEvent { event ->
if (event.type != KeyEventType.KeyDown) {
return@onPreviewKeyEvent false
}
when (event.key) {
Key.Tab -> {
onTab()
true
}
Key.DirectionLeft -> {
onCursorLeft()
true
}
Key.DirectionRight -> {
onCursorRight()
true
}
Key.DirectionUp -> {
onHistoryUp()
true
}
Key.DirectionDown -> {
onHistoryDown()
true
}
Key.Enter -> {
onSubmit()
true
}
else -> false
}
}, },
singleLine = true, singleLine = true,
textStyle = TextStyle( textStyle = TextStyle(

View File

@@ -17,6 +17,7 @@ import androidx.compose.foundation.layout.widthIn
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.BasicTextField import androidx.compose.foundation.text.BasicTextField
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Button import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.ButtonDefaults
@@ -24,8 +25,13 @@ import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Surface import androidx.compose.material3.Surface
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.SolidColor import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
@@ -35,7 +41,6 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import androidx.compose.ui.window.Dialog import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties import androidx.compose.ui.window.DialogProperties
import androidx.compose.foundation.text.KeyboardOptions
data class TextEditorState( data class TextEditorState(
val editor: String, val editor: String,
@@ -56,6 +61,13 @@ fun TextEditorDialog(
val editorHorizontalScroll = rememberScrollState() val editorHorizontalScroll = rememberScrollState()
val editorVerticalScroll = rememberScrollState() val editorVerticalScroll = rememberScrollState()
val dialogScroll = rememberScrollState() val dialogScroll = rememberScrollState()
val contentFocusRequester = remember { FocusRequester() }
val keyboardController = LocalSoftwareKeyboardController.current
LaunchedEffect(state.originalCommand, state.path) {
contentFocusRequester.requestFocus()
keyboardController?.show()
}
Dialog( Dialog(
onDismissRequest = onClose, onDismissRequest = onClose,
@@ -122,7 +134,9 @@ fun TextEditorDialog(
BasicTextField( BasicTextField(
value = state.content, value = state.content,
onValueChange = onContentChange, onValueChange = onContentChange,
modifier = Modifier.sizeIn(minWidth = 1200.dp, minHeight = 1200.dp), modifier = Modifier
.sizeIn(minWidth = 1200.dp, minHeight = 1200.dp)
.focusRequester(contentFocusRequester),
textStyle = TextStyle( textStyle = TextStyle(
color = TextPrimary, color = TextPrimary,
fontFamily = FontFamily.Monospace, fontFamily = FontFamily.Monospace,