Auto-commit after successful build: update app gameplay/UI, improve build setup
Changed files:\napp/build.gradle.kts app/src/main/java/solutions/tretter/githugandroid/EditorCommands.kt app/src/main/java/solutions/tretter/githugandroid/GitHugApp.kt app/src/main/java/solutions/tretter/githugandroid/GitRuntime.kt app/src/main/java/solutions/tretter/githugandroid/TextEditorDialog.kt app/src/test/java/solutions/tretter/githugandroid/EditorCommandsTest.kt
This commit is contained in:
@@ -60,6 +60,7 @@ fun GitHugApp() {
|
||||
var historyIndex by remember { mutableStateOf(-1) }
|
||||
var historyDraft by remember { mutableStateOf("") }
|
||||
var hasRestoredProgress by remember { mutableStateOf(false) }
|
||||
var editorState by remember { mutableStateOf<TextEditorState?>(null) }
|
||||
val currentLevel = levels[currentLevelIndex]
|
||||
|
||||
LaunchedEffect(persistedPaneLayout) {
|
||||
@@ -166,6 +167,7 @@ fun GitHugApp() {
|
||||
visibleHint = null
|
||||
historyIndex = -1
|
||||
historyDraft = ""
|
||||
editorState = null
|
||||
applyRecommendedPaneWeights(persist = false)
|
||||
}
|
||||
|
||||
@@ -181,6 +183,7 @@ fun GitHugApp() {
|
||||
visibleHint = null
|
||||
historyIndex = -1
|
||||
historyDraft = ""
|
||||
editorState = null
|
||||
paneLayout = paneLayout.copy(
|
||||
weights = paneLayout.weights + recommendedPaneWeights(
|
||||
heights = recommendedPaneHeights(
|
||||
@@ -247,6 +250,87 @@ fun GitHugApp() {
|
||||
commandInput = TextFieldValue(newText, selection = TextRange(newCursor))
|
||||
}
|
||||
|
||||
fun applyCommandResult(raw: String, newRepo: RepoState, lines: List<String>, echoCommand: Boolean) {
|
||||
val levelForResult = currentLevel
|
||||
val solvedAfterCommand = levelForResult.validator(newRepo, raw)
|
||||
val wasAlreadyCompleted = currentLevel.id in completedLevels
|
||||
AppLog.d(
|
||||
"GitHugApp",
|
||||
"Command='$raw' level=${levelForResult.id} solved=$solvedAfterCommand alreadyCompleted=$wasAlreadyCompleted completedBefore=${completedLevels.sorted()}",
|
||||
)
|
||||
val newOutput = buildList {
|
||||
addAll(output)
|
||||
if (echoCommand) {
|
||||
add("$ $raw")
|
||||
}
|
||||
addAll(lines)
|
||||
if (solvedAfterCommand && !wasAlreadyCompleted) {
|
||||
add("✔ Level solved: ${levelForResult.title}")
|
||||
}
|
||||
}
|
||||
if (solvedAfterCommand && !wasAlreadyCompleted) {
|
||||
val updatedCompletedLevels = completedLevels + levelForResult.id
|
||||
completedLevels = updatedCompletedLevels
|
||||
val nextLevelIndex = levels.indexOfFirst { it.id !in updatedCompletedLevels }
|
||||
if (nextLevelIndex >= 0) {
|
||||
val nextLevelId = levels[nextLevelIndex].id
|
||||
AppLog.d(
|
||||
"GitHugApp",
|
||||
"Level solved ${levelForResult.id}; advancing to next incomplete index=$nextLevelIndex id=$nextLevelId",
|
||||
)
|
||||
scope.launch { persistProgress(updatedCompletedLevels, nextLevelId) }
|
||||
loadLevel(nextLevelIndex)
|
||||
} else {
|
||||
AppLog.d("GitHugApp", "All levels completed")
|
||||
scope.launch { persistProgress(updatedCompletedLevels, levels.lastOrNull()?.id) }
|
||||
repo = newRepo
|
||||
output = listOf("🏁 All Githug levels completed.")
|
||||
clearCommandInput()
|
||||
suppressedImeEcho = null
|
||||
}
|
||||
} else {
|
||||
AppLog.d("GitHugApp", "Staying on level=${levelForResult.id}")
|
||||
repo = newRepo
|
||||
output = newOutput
|
||||
applyRecommendedPaneWeights(persist = false)
|
||||
}
|
||||
}
|
||||
|
||||
fun openEditor(invocation: VisualEditorInvocation) {
|
||||
val path = invocation.path.orEmpty()
|
||||
val (content, lines) = if (path.isBlank()) {
|
||||
"" to emptyList()
|
||||
} else {
|
||||
runtime.readEditorFile(currentLevel, repo, path)
|
||||
}
|
||||
output = buildList {
|
||||
addAll(output)
|
||||
add("$ ${invocation.command}")
|
||||
addAll(lines)
|
||||
if (lines.isEmpty()) {
|
||||
add("Opened ${invocation.editor} editor${if (path.isBlank()) "" else " for $path"}")
|
||||
}
|
||||
}
|
||||
if (lines.isEmpty()) {
|
||||
editorState = TextEditorState(
|
||||
editor = invocation.editor,
|
||||
originalCommand = invocation.command,
|
||||
path = path,
|
||||
content = content,
|
||||
saveAsPath = path,
|
||||
)
|
||||
}
|
||||
applyRecommendedPaneWeights(persist = false)
|
||||
}
|
||||
|
||||
fun saveEditor(targetPath: String) {
|
||||
val state = editorState ?: return
|
||||
if (targetPath.isBlank()) return
|
||||
val (newRepo, lines) = runtime.writeEditorFile(currentLevel, repo, targetPath, state.content)
|
||||
editorState = null
|
||||
applyCommandResult(state.originalCommand, newRepo, lines, echoCommand = false)
|
||||
}
|
||||
|
||||
fun runCommand() {
|
||||
val submittedText = commandInput.text
|
||||
val raw = submittedText.trim()
|
||||
@@ -261,47 +345,14 @@ fun GitHugApp() {
|
||||
historyIndex = -1
|
||||
historyDraft = ""
|
||||
|
||||
val editorInvocation = parseVisualEditorInvocation(raw)
|
||||
if (editorInvocation != null) {
|
||||
openEditor(editorInvocation)
|
||||
return
|
||||
}
|
||||
|
||||
val (newRepo, lines) = runtime.execute(currentLevel, repo, raw)
|
||||
val solvedAfterCommand = currentLevel.validator(newRepo, raw)
|
||||
val wasAlreadyCompleted = currentLevel.id in completedLevels
|
||||
AppLog.d(
|
||||
"GitHugApp",
|
||||
"Command='$raw' level=${currentLevel.id} solved=$solvedAfterCommand alreadyCompleted=$wasAlreadyCompleted completedBefore=${completedLevels.sorted()}",
|
||||
)
|
||||
val newOutput = buildList {
|
||||
addAll(output)
|
||||
add("$ $raw")
|
||||
addAll(lines)
|
||||
if (solvedAfterCommand && !wasAlreadyCompleted) {
|
||||
add("✔ Level solved: ${currentLevel.title}")
|
||||
}
|
||||
}
|
||||
if (solvedAfterCommand && !wasAlreadyCompleted) {
|
||||
val updatedCompletedLevels = completedLevels + currentLevel.id
|
||||
completedLevels = updatedCompletedLevels
|
||||
val nextLevelIndex = levels.indexOfFirst { it.id !in updatedCompletedLevels }
|
||||
if (nextLevelIndex >= 0) {
|
||||
val nextLevelId = levels[nextLevelIndex].id
|
||||
AppLog.d(
|
||||
"GitHugApp",
|
||||
"Level solved ${currentLevel.id}; advancing to next incomplete index=$nextLevelIndex id=$nextLevelId",
|
||||
)
|
||||
scope.launch { persistProgress(updatedCompletedLevels, nextLevelId) }
|
||||
loadLevel(nextLevelIndex)
|
||||
} else {
|
||||
AppLog.d("GitHugApp", "All levels completed")
|
||||
scope.launch { persistProgress(updatedCompletedLevels, levels.lastOrNull()?.id) }
|
||||
repo = newRepo
|
||||
output = listOf("🏁 All Githug levels completed.")
|
||||
clearCommandInput()
|
||||
suppressedImeEcho = null
|
||||
}
|
||||
} else {
|
||||
AppLog.d("GitHugApp", "Staying on level=${currentLevel.id}")
|
||||
repo = newRepo
|
||||
output = newOutput
|
||||
applyRecommendedPaneWeights(persist = false)
|
||||
}
|
||||
applyCommandResult(raw, newRepo, lines, echoCommand = true)
|
||||
}
|
||||
|
||||
fun showCommandHelp() {
|
||||
@@ -395,5 +446,25 @@ fun GitHugApp() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
editorState?.let { state ->
|
||||
TextEditorDialog(
|
||||
state = state,
|
||||
onContentChange = { editorState = state.copy(content = it) },
|
||||
onSaveAsPathChange = { editorState = state.copy(saveAsPath = it) },
|
||||
onCancel = {
|
||||
output = output + "Editor closed without saving"
|
||||
editorState = null
|
||||
},
|
||||
onSave = { saveEditor(state.path) },
|
||||
onSaveAs = {
|
||||
val targetPath = state.saveAsPath.trim()
|
||||
if (targetPath.isNotEmpty()) {
|
||||
editorState = state.copy(path = targetPath, saveAsPath = targetPath)
|
||||
saveEditor(targetPath)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user