Add app-native interactive Git dialogs
- Open an interactive staging dialog for `git add -i`, `git stage -i`, and `git add --interactive`, allowing paths to be selected before staging. - Open an interactive rebase dialog for `git rebase -i` / `--interactive`, with pick, squash, drop, commit-message editing, and reorder controls. - Keep the existing synthetic runtime behavior available for direct engine/test calls, while making app-entered interactive commands show real UI instead of auto-staging. - Center manpage search navigation using actual text-layout highlight bounds instead of approximate line and column math. - Make editor dialogs use a full-screen IME-padded outer scroll container so controls remain reachable when the keyboard pans or resizes the dialog.
This commit is contained in:
@@ -6,6 +6,7 @@ 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
|
||||
@@ -31,6 +32,7 @@ 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,
|
||||
@@ -46,64 +48,75 @@ fun GitMessageEditorDialog(
|
||||
) {
|
||||
val horizontalScroll = rememberScrollState()
|
||||
val verticalScroll = rememberScrollState()
|
||||
val dialogScroll = rememberScrollState()
|
||||
|
||||
Dialog(onDismissRequest = onClose) {
|
||||
Surface(
|
||||
Dialog(
|
||||
onDismissRequest = onClose,
|
||||
properties = DialogProperties(usePlatformDefaultWidth = false),
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.fillMaxHeight(0.72f)
|
||||
.imePadding(),
|
||||
color = PanelPrimary,
|
||||
shape = RoundedCornerShape(8.dp),
|
||||
.fillMaxSize()
|
||||
.imePadding()
|
||||
.verticalScroll(dialogScroll)
|
||||
.padding(12.dp),
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.padding(12.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(10.dp),
|
||||
Surface(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.heightIn(min = 320.dp, max = 620.dp),
|
||||
color = PanelPrimary,
|
||||
shape = RoundedCornerShape(8.dp),
|
||||
) {
|
||||
Text(
|
||||
text = state.invocation.title,
|
||||
color = TextPrimary,
|
||||
fontWeight = FontWeight.Bold,
|
||||
fontSize = 20.sp,
|
||||
)
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
||||
Column(
|
||||
modifier = Modifier.padding(12.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(10.dp),
|
||||
) {
|
||||
EditorButton(label = "Close", onClick = onClose)
|
||||
EditorButton(label = "Save", enabled = state.content.isNotBlank(), onClick = onSave)
|
||||
}
|
||||
Text(
|
||||
text = state.invocation.command,
|
||||
color = TextSecondary,
|
||||
fontFamily = FontFamily.Monospace,
|
||||
fontSize = 13.sp,
|
||||
)
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.weight(1f)
|
||||
.heightIn(min = 220.dp)
|
||||
.background(TerminalBackground, RoundedCornerShape(6.dp))
|
||||
.padding(10.dp)
|
||||
.horizontalScroll(horizontalScroll)
|
||||
.verticalScroll(verticalScroll),
|
||||
) {
|
||||
BasicTextField(
|
||||
value = state.content,
|
||||
onValueChange = onContentChange,
|
||||
modifier = Modifier.sizeIn(minWidth = 1000.dp, minHeight = 700.dp),
|
||||
textStyle = TextStyle(
|
||||
color = TextPrimary,
|
||||
fontFamily = FontFamily.Monospace,
|
||||
fontSize = 14.sp,
|
||||
),
|
||||
cursorBrush = SolidColor(Accent),
|
||||
keyboardOptions = KeyboardOptions(
|
||||
autoCorrect = false,
|
||||
keyboardType = KeyboardType.Ascii,
|
||||
),
|
||||
Text(
|
||||
text = state.invocation.title,
|
||||
color = TextPrimary,
|
||||
fontWeight = FontWeight.Bold,
|
||||
fontSize = 20.sp,
|
||||
)
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
||||
) {
|
||||
EditorButton(label = "Close", onClick = onClose)
|
||||
EditorButton(label = "Save", enabled = state.content.isNotBlank(), onClick = onSave)
|
||||
}
|
||||
Text(
|
||||
text = state.invocation.command,
|
||||
color = TextSecondary,
|
||||
fontFamily = FontFamily.Monospace,
|
||||
fontSize = 13.sp,
|
||||
)
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.weight(1f)
|
||||
.heightIn(min = 220.dp)
|
||||
.background(TerminalBackground, RoundedCornerShape(6.dp))
|
||||
.padding(10.dp)
|
||||
.horizontalScroll(horizontalScroll)
|
||||
.verticalScroll(verticalScroll),
|
||||
) {
|
||||
BasicTextField(
|
||||
value = state.content,
|
||||
onValueChange = onContentChange,
|
||||
modifier = Modifier.sizeIn(minWidth = 1000.dp, minHeight = 700.dp),
|
||||
textStyle = TextStyle(
|
||||
color = TextPrimary,
|
||||
fontFamily = FontFamily.Monospace,
|
||||
fontSize = 14.sp,
|
||||
),
|
||||
cursorBrush = SolidColor(Accent),
|
||||
keyboardOptions = KeyboardOptions(
|
||||
autoCorrect = false,
|
||||
keyboardType = KeyboardType.Ascii,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user