Auto-commit after successful build: update app gameplay/UI, improve build setup

Changed files:\napp/build.gradle.kts
app/src/main/java/com/kawomi/githugandroid/GitHugApp.kt
This commit is contained in:
Joe Tretter
2026-04-23 16:10:18 -05:00
parent 09e4bba1a4
commit 1ea5e1d2b2
2 changed files with 54 additions and 32 deletions

View File

@@ -11,8 +11,8 @@ android {
applicationId = "com.kawomi.githugandroid" applicationId = "com.kawomi.githugandroid"
minSdk = 26 minSdk = 26
targetSdk = 34 targetSdk = 34
versionCode = 30 versionCode = 32
versionName = "0.1.29" versionName = "0.1.31"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true vectorDrawables.useSupportLibrary = true

View File

@@ -252,10 +252,14 @@ fun GitHugApp() {
transform = { layout -> transform = { layout ->
layout.copy( layout.copy(
weights = layout.weights + recommendedPaneWeights( weights = layout.weights + recommendedPaneWeights(
level = currentLevel, heights = recommendedPaneHeights(
levelCount = levels.size, level = currentLevel,
outputLineCount = output.size, levelCount = levels.size,
screenHeightDp = screenHeightDp, outputLineCount = output.size,
screenHeightDp = screenHeightDp,
suggestionsVisible = activeExerciseDetail == ExerciseDetailPanel.SUGGESTIONS,
visibleHint = visibleHint,
),
) )
) )
}, },
@@ -263,16 +267,20 @@ fun GitHugApp() {
) )
} }
val recommendedWeights = recommendedPaneWeights( val recommendedHeights = recommendedPaneHeights(
level = currentLevel, level = currentLevel,
levelCount = levels.size, levelCount = levels.size,
outputLineCount = output.size, outputLineCount = output.size,
screenHeightDp = screenHeightDp, screenHeightDp = screenHeightDp,
suggestionsVisible = activeExerciseDetail == ExerciseDetailPanel.SUGGESTIONS,
visibleHint = visibleHint,
)
val recommendedWeights = recommendedPaneWeights(
heights = recommendedHeights,
) )
val workspaceHeight = recommendedWorkspaceHeight( val workspaceHeight = recommendedWorkspaceHeight(
paneLayout = paneLayout, paneLayout = paneLayout,
recommendedWeights = recommendedWeights, recommendedHeights = recommendedHeights,
screenHeightDp = screenHeightDp,
) )
fun resetCurrentLevel(message: String = "Level reset.") { fun resetCurrentLevel(message: String = "Level reset.") {
@@ -301,10 +309,14 @@ fun GitHugApp() {
historyDraft = "" historyDraft = ""
paneLayout = paneLayout.copy( paneLayout = paneLayout.copy(
weights = paneLayout.weights + recommendedPaneWeights( weights = paneLayout.weights + recommendedPaneWeights(
level = levels[index], heights = recommendedPaneHeights(
levelCount = levels.size, level = levels[index],
outputLineCount = 1, levelCount = levels.size,
screenHeightDp = screenHeightDp, outputLineCount = 1,
screenHeightDp = screenHeightDp,
suggestionsVisible = false,
visibleHint = null,
),
) )
) )
} }
@@ -457,12 +469,17 @@ fun GitHugApp() {
suggestionsExpanded = activeExerciseDetail == ExerciseDetailPanel.SUGGESTIONS, suggestionsExpanded = activeExerciseDetail == ExerciseDetailPanel.SUGGESTIONS,
onToggleSuggestions = { onToggleSuggestions = {
activeExerciseDetail = if (activeExerciseDetail == ExerciseDetailPanel.SUGGESTIONS) null else ExerciseDetailPanel.SUGGESTIONS activeExerciseDetail = if (activeExerciseDetail == ExerciseDetailPanel.SUGGESTIONS) null else ExerciseDetailPanel.SUGGESTIONS
if (activeExerciseDetail == ExerciseDetailPanel.SUGGESTIONS) {
visibleHint = null
}
applyRecommendedPaneWeights(persist = false)
}, },
onHint = { onHint = {
val hint = currentLevel.hints.getOrNull(hintIndex) ?: "No more hints for this level." val hint = currentLevel.hints.getOrNull(hintIndex) ?: "No more hints for this level."
visibleHint = hint visibleHint = hint
activeExerciseDetail = ExerciseDetailPanel.HINT activeExerciseDetail = ExerciseDetailPanel.HINT
hintIndex = (hintIndex + 1).coerceAtMost(currentLevel.hints.size) hintIndex = (hintIndex + 1).coerceAtMost(currentLevel.hints.size)
applyRecommendedPaneWeights(persist = false)
}, },
onReset = { resetCurrentLevel() }, onReset = { resetCurrentLevel() },
) )
@@ -1193,44 +1210,49 @@ private fun resizePanes(
) )
} }
private fun recommendedPaneWeights( private fun recommendedPaneHeights(
level: Level, level: Level,
levelCount: Int, levelCount: Int,
outputLineCount: Int, outputLineCount: Int,
screenHeightDp: Int, screenHeightDp: Int,
): Map<PaneId, Float> { suggestionsVisible: Boolean,
visibleHint: String?,
): Map<PaneId, Int> {
val screenHeight = screenHeightDp.coerceAtLeast(560) val screenHeight = screenHeightDp.coerceAtLeast(560)
val levelsHeight = (56 + levelCount * 44).coerceAtMost((screenHeight * 0.35f).toInt()) val levelsHeight = (56 + levelCount * 44).coerceAtLeast(160)
val descriptionLines = (level.description.length / 42).coerceAtLeast(2) + 2 val descriptionLines = (level.description.length / 42).coerceAtLeast(2) + 2
val suggestionsLines = level.commandSuggestions.size val suggestionsLines = if (suggestionsVisible) level.commandSuggestions.size + 1 else 0
val exerciseHeight = (120 + descriptionLines * 24 + suggestionsLines * 22).coerceAtLeast(180) val hintLines = visibleHint?.let { (it.length / 42).coerceAtLeast(1) + 1 } ?: 0
val terminalHeight = (120 + outputLineCount.coerceAtLeast(1) * 20).coerceAtMost((screenHeight * 0.7f).toInt()) val exerciseHeight = (120 + descriptionLines * 24 + suggestionsLines * 22 + hintLines * 22).coerceAtLeast(180)
val terminalHeight = (170 + outputLineCount.coerceAtLeast(1) * 20).coerceAtMost((screenHeight * 0.7f).toInt())
val visualHeight = (screenHeight * 0.24f).toInt().coerceAtLeast(170) val visualHeight = (screenHeight * 0.24f).toInt().coerceAtLeast(170)
fun weightFor(height: Int): Float = (height.toFloat() / screenHeight.toFloat()).coerceAtLeast(0.6f)
return mapOf( return mapOf(
PaneId.EXERCISE to weightFor(exerciseHeight), PaneId.EXERCISE to exerciseHeight,
PaneId.TERMINAL to weightFor(terminalHeight), PaneId.TERMINAL to terminalHeight,
PaneId.VISUAL to weightFor(visualHeight), PaneId.VISUAL to visualHeight,
PaneId.LEVELS to weightFor(levelsHeight), PaneId.LEVELS to levelsHeight,
) )
} }
private fun recommendedPaneWeights(
heights: Map<PaneId, Int>,
): Map<PaneId, Float> {
fun weightFor(height: Int): Float = (height / 180f).coerceAtLeast(0.6f)
return heights.mapValues { (_, height) -> weightFor(height) }
}
private fun recommendedWorkspaceHeight( private fun recommendedWorkspaceHeight(
paneLayout: PaneLayout, paneLayout: PaneLayout,
recommendedWeights: Map<PaneId, Float>, recommendedHeights: Map<PaneId, Int>,
screenHeightDp: Int,
): androidx.compose.ui.unit.Dp { ): androidx.compose.ui.unit.Dp {
val screenHeight = screenHeightDp.coerceAtLeast(560)
val dividerHeight = 18 * (paneLayout.order.size - 1) val dividerHeight = 18 * (paneLayout.order.size - 1)
val collapsedPaneHeight = 44 * paneLayout.collapsed.size val collapsedPaneHeight = 44 * paneLayout.collapsed.size
val expandedHeight = paneLayout.order val expandedHeight = paneLayout.order
.filterNot { it in paneLayout.collapsed } .filterNot { it in paneLayout.collapsed }
.sumOf { pane -> .sumOf { pane -> recommendedHeights[pane] ?: 0 }
(recommendedWeights[pane] ?: 1f * screenHeight).toInt() return (expandedHeight + dividerHeight + collapsedPaneHeight).dp
}
return (expandedHeight + dividerHeight + collapsedPaneHeight).coerceAtLeast(screenHeight / 2).dp
} }
private fun commonPrefix(values: List<String>): String { private fun commonPrefix(values: List<String>): String {