package solutions.tretter.githugandroid import androidx.compose.foundation.background import androidx.compose.foundation.horizontalScroll import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.imePadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.sizeIn import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.BasicTextField import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.verticalScroll import androidx.compose.material3.Button import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.remember 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.platform.LocalSoftwareKeyboardController import androidx.compose.ui.platform.testTag import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.compose.ui.window.Dialog import androidx.compose.ui.window.DialogProperties data class GitMessageEditorState( val invocation: GitEditorInvocation, val content: String, ) @Composable fun GitMessageEditorDialog( state: GitMessageEditorState, onContentChange: (String) -> Unit, onClose: () -> Unit, onSave: () -> Unit, ) { val horizontalScroll = rememberScrollState() val verticalScroll = rememberScrollState() val dialogScroll = rememberScrollState() val contentFocusRequester = remember { FocusRequester() } val keyboardController = LocalSoftwareKeyboardController.current LaunchedEffect(state.invocation.command) { runCatching { contentFocusRequester.requestFocus() } keyboardController?.show() } Dialog( onDismissRequest = onClose, properties = DialogProperties(usePlatformDefaultWidth = false), ) { Box( modifier = Modifier .fillMaxSize() .imePadding() .verticalScroll(dialogScroll) .padding(12.dp), ) { Surface( modifier = Modifier .fillMaxWidth() .heightIn(min = 360.dp, max = 720.dp), color = PanelPrimary, shape = RoundedCornerShape(8.dp), ) { Column( modifier = Modifier.padding(12.dp), verticalArrangement = Arrangement.spacedBy(10.dp), ) { Text( text = state.invocation.title, modifier = Modifier.testTag("git-message-editor-title"), color = TextPrimary, fontWeight = FontWeight.Bold, fontSize = 20.sp, ) Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(8.dp), ) { EditorButton( label = "Save", enabled = state.content.isNotBlank(), modifier = Modifier.testTag("git-message-editor-save"), onClick = onSave, ) EditorButton( label = "Dismiss", modifier = Modifier.testTag("git-message-editor-dismiss"), onClick = onClose, ) } Text( text = state.invocation.displayPath, modifier = Modifier.testTag("git-message-editor-path"), color = TextSecondary, fontFamily = FontFamily.Monospace, fontSize = 13.sp, ) Box( modifier = Modifier .fillMaxWidth() .weight(1f) .heightIn(min = 260.dp) .background(TerminalBackground, RoundedCornerShape(6.dp)) .padding(10.dp) .horizontalScroll(horizontalScroll) .verticalScroll(verticalScroll), ) { BasicTextField( value = state.content, onValueChange = onContentChange, modifier = Modifier .sizeIn(minWidth = 1200.dp, minHeight = 1200.dp) .focusRequester(contentFocusRequester) .testTag("git-message-editor-content"), textStyle = TextStyle( color = TextPrimary, fontFamily = FontFamily.Monospace, fontSize = 14.sp, ), cursorBrush = SolidColor(Accent), keyboardOptions = KeyboardOptions( autoCorrect = false, keyboardType = KeyboardType.Ascii, ), ) } } } } } } @Composable private fun EditorButton( label: String, enabled: Boolean = true, modifier: Modifier = Modifier, onClick: () -> Unit, ) { Button( onClick = onClick, enabled = enabled, modifier = modifier, colors = ButtonDefaults.buttonColors( containerColor = Accent, contentColor = AppBackground, disabledContainerColor = PanelTertiary, disabledContentColor = TextMuted, ), ) { Text(label) } }