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:
@@ -11,8 +11,8 @@ android {
|
|||||||
applicationId = "com.kawomi.githugandroid"
|
applicationId = "com.kawomi.githugandroid"
|
||||||
minSdk = 26
|
minSdk = 26
|
||||||
targetSdk = 34
|
targetSdk = 34
|
||||||
versionCode = 22
|
versionCode = 24
|
||||||
versionName = "0.1.21"
|
versionName = "0.1.23"
|
||||||
|
|
||||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||||
vectorDrawables.useSupportLibrary = true
|
vectorDrawables.useSupportLibrary = true
|
||||||
|
|||||||
@@ -38,8 +38,6 @@ import androidx.compose.material3.MaterialTheme
|
|||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.material3.Surface
|
import androidx.compose.material3.Surface
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TextField
|
|
||||||
import androidx.compose.material3.TextFieldDefaults
|
|
||||||
import androidx.compose.material3.TextButton
|
import androidx.compose.material3.TextButton
|
||||||
import androidx.compose.material3.darkColorScheme
|
import androidx.compose.material3.darkColorScheme
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
@@ -205,7 +203,7 @@ fun GitHugApp() {
|
|||||||
val persistedPaneLayout by paneLayoutStore.layoutFlow.collectAsState(initial = defaultPaneLayout())
|
val persistedPaneLayout by paneLayoutStore.layoutFlow.collectAsState(initial = defaultPaneLayout())
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
val screenScrollState = rememberScrollState()
|
val screenScrollState = rememberScrollState()
|
||||||
val workspaceHeight = (configuration.screenHeightDp.dp * 0.72f).coerceAtLeast(420.dp)
|
val workspaceHeight = (configuration.screenHeightDp.dp * 1.05f).coerceAtLeast(560.dp)
|
||||||
|
|
||||||
var paneLayout by remember { mutableStateOf(defaultPaneLayout()) }
|
var paneLayout by remember { mutableStateOf(defaultPaneLayout()) }
|
||||||
var currentLevelIndex by remember { mutableStateOf(0) }
|
var currentLevelIndex by remember { mutableStateOf(0) }
|
||||||
@@ -225,11 +223,13 @@ fun GitHugApp() {
|
|||||||
paneLayout = persistedPaneLayout
|
paneLayout = persistedPaneLayout
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updatePaneLayout(transform: (PaneLayout) -> PaneLayout) {
|
fun updatePaneLayout(transform: (PaneLayout) -> PaneLayout, persist: Boolean = true) {
|
||||||
val updated = transform(paneLayout)
|
val updated = transform(paneLayout)
|
||||||
paneLayout = updated
|
paneLayout = updated
|
||||||
|
if (persist) {
|
||||||
scope.launch { paneLayoutStore.save(updated) }
|
scope.launch { paneLayoutStore.save(updated) }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun clearCommandInput(recreateField: Boolean = false) {
|
fun clearCommandInput(recreateField: Boolean = false) {
|
||||||
commandInput = TextFieldValue(text = "", selection = TextRange.Zero)
|
commandInput = TextFieldValue(text = "", selection = TextRange.Zero)
|
||||||
@@ -380,17 +380,20 @@ fun GitHugApp() {
|
|||||||
.height(workspaceHeight),
|
.height(workspaceHeight),
|
||||||
paneLayout = paneLayout,
|
paneLayout = paneLayout,
|
||||||
onMovePane = { paneId, delta ->
|
onMovePane = { paneId, delta ->
|
||||||
updatePaneLayout { layout -> movePane(layout, paneId, delta) }
|
updatePaneLayout(transform = { layout -> movePane(layout, paneId, delta) })
|
||||||
},
|
},
|
||||||
onTogglePane = { paneId ->
|
onTogglePane = { paneId ->
|
||||||
updatePaneLayout { layout ->
|
updatePaneLayout(transform = { layout ->
|
||||||
val collapsed = layout.collapsed.toMutableSet()
|
val collapsed = layout.collapsed.toMutableSet()
|
||||||
if (!collapsed.add(paneId)) collapsed.remove(paneId)
|
if (!collapsed.add(paneId)) collapsed.remove(paneId)
|
||||||
layout.copy(collapsed = collapsed)
|
layout.copy(collapsed = collapsed)
|
||||||
}
|
})
|
||||||
},
|
},
|
||||||
onResize = { upper, lower, dragFraction ->
|
onResize = { upper, lower, dragFraction ->
|
||||||
updatePaneLayout { layout -> resizePanes(layout, upper, lower, dragFraction) }
|
updatePaneLayout(transform = { layout -> resizePanes(layout, upper, lower, dragFraction) }, persist = false)
|
||||||
|
},
|
||||||
|
onResizeFinished = {
|
||||||
|
scope.launch { paneLayoutStore.save(paneLayout) }
|
||||||
},
|
},
|
||||||
levelsContent = {
|
levelsContent = {
|
||||||
LevelsPane(levels, currentLevelIndex, completedLevels) { index -> loadLevel(index) }
|
LevelsPane(levels, currentLevelIndex, completedLevels) { index -> loadLevel(index) }
|
||||||
@@ -470,6 +473,7 @@ private fun PaneWorkspace(
|
|||||||
onMovePane: (PaneId, Int) -> Unit,
|
onMovePane: (PaneId, Int) -> Unit,
|
||||||
onTogglePane: (PaneId) -> Unit,
|
onTogglePane: (PaneId) -> Unit,
|
||||||
onResize: (PaneId, PaneId, Float) -> Unit,
|
onResize: (PaneId, PaneId, Float) -> Unit,
|
||||||
|
onResizeFinished: () -> Unit,
|
||||||
levelsContent: @Composable () -> Unit,
|
levelsContent: @Composable () -> Unit,
|
||||||
visualContent: @Composable () -> Unit,
|
visualContent: @Composable () -> Unit,
|
||||||
exerciseContent: @Composable () -> Unit,
|
exerciseContent: @Composable () -> Unit,
|
||||||
@@ -523,6 +527,7 @@ private fun PaneWorkspace(
|
|||||||
val fraction = deltaPx / (heightBasis * 4f)
|
val fraction = deltaPx / (heightBasis * 4f)
|
||||||
onResize(upper, lower, fraction)
|
onResize(upper, lower, fraction)
|
||||||
},
|
},
|
||||||
|
onDragFinished = onResizeFinished,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -643,6 +648,7 @@ private fun HeaderActionButton(
|
|||||||
private fun PaneDivider(
|
private fun PaneDivider(
|
||||||
enabled: Boolean,
|
enabled: Boolean,
|
||||||
onDrag: (Float) -> Unit,
|
onDrag: (Float) -> Unit,
|
||||||
|
onDragFinished: () -> Unit,
|
||||||
) {
|
) {
|
||||||
val dragState = rememberDraggableState { delta ->
|
val dragState = rememberDraggableState { delta ->
|
||||||
if (enabled) onDrag(delta)
|
if (enabled) onDrag(delta)
|
||||||
@@ -656,6 +662,7 @@ private fun PaneDivider(
|
|||||||
state = dragState,
|
state = dragState,
|
||||||
orientation = Orientation.Vertical,
|
orientation = Orientation.Vertical,
|
||||||
enabled = enabled,
|
enabled = enabled,
|
||||||
|
onDragStopped = { onDragFinished() },
|
||||||
),
|
),
|
||||||
contentAlignment = Alignment.Center,
|
contentAlignment = Alignment.Center,
|
||||||
) {
|
) {
|
||||||
@@ -665,6 +672,13 @@ private fun PaneDivider(
|
|||||||
.height(1.dp)
|
.height(1.dp)
|
||||||
.background(if (enabled) Accent.copy(alpha = 0.45f) else PanelTertiary),
|
.background(if (enabled) Accent.copy(alpha = 0.45f) else PanelTertiary),
|
||||||
)
|
)
|
||||||
|
Text(
|
||||||
|
text = "↕",
|
||||||
|
color = if (enabled) Accent else TextMuted,
|
||||||
|
modifier = Modifier.align(Alignment.CenterStart).padding(start = 28.dp),
|
||||||
|
fontSize = 12.sp,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -855,6 +869,7 @@ private fun TerminalPane(
|
|||||||
val horizontalScroll = rememberScrollState()
|
val horizontalScroll = rememberScrollState()
|
||||||
val outputVerticalScroll = rememberScrollState()
|
val outputVerticalScroll = rememberScrollState()
|
||||||
val terminalMinWidth = 640.dp
|
val terminalMinWidth = 640.dp
|
||||||
|
val scope = rememberCoroutineScope()
|
||||||
|
|
||||||
LaunchedEffect(inputFieldVersion) {
|
LaunchedEffect(inputFieldVersion) {
|
||||||
if (inputFieldVersion == 0) return@LaunchedEffect
|
if (inputFieldVersion == 0) return@LaunchedEffect
|
||||||
@@ -886,7 +901,6 @@ private fun TerminalPane(
|
|||||||
.widthIn(min = terminalMinWidth),
|
.widthIn(min = terminalMinWidth),
|
||||||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||||
) {
|
) {
|
||||||
Text("Terminal", color = TextPrimary, fontWeight = FontWeight.Bold)
|
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.weight(1f)
|
.weight(1f)
|
||||||
@@ -929,36 +943,41 @@ private fun TerminalPane(
|
|||||||
fontWeight = FontWeight.Bold,
|
fontWeight = FontWeight.Bold,
|
||||||
)
|
)
|
||||||
key(inputFieldVersion) {
|
key(inputFieldVersion) {
|
||||||
TextField(
|
BasicTextField(
|
||||||
value = commandInput,
|
value = commandInput,
|
||||||
onValueChange = onValueChange,
|
onValueChange = onValueChange,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.weight(1f)
|
.weight(1f)
|
||||||
.focusRequester(focusRequester)
|
.focusRequester(focusRequester)
|
||||||
|
.bringIntoViewRequester(bringIntoViewRequester)
|
||||||
.onFocusChanged { state ->
|
.onFocusChanged { state ->
|
||||||
if (state.isFocused) {
|
if (state.isFocused) {
|
||||||
keyboardController?.show()
|
keyboardController?.show()
|
||||||
|
scope.launch {
|
||||||
|
delay(150)
|
||||||
|
bringIntoViewRequester.bringIntoView()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
singleLine = true,
|
singleLine = true,
|
||||||
textStyle = TextStyle(color = TextPrimary, fontFamily = FontFamily.Monospace),
|
textStyle = TextStyle(color = TextPrimary, fontFamily = FontFamily.Monospace),
|
||||||
colors = TextFieldDefaults.colors(
|
cursorBrush = SolidColor(Accent),
|
||||||
focusedContainerColor = Color.Transparent,
|
|
||||||
unfocusedContainerColor = Color.Transparent,
|
|
||||||
disabledContainerColor = Color.Transparent,
|
|
||||||
cursorColor = Accent,
|
|
||||||
focusedIndicatorColor = Color.Transparent,
|
|
||||||
unfocusedIndicatorColor = Color.Transparent,
|
|
||||||
disabledIndicatorColor = Color.Transparent,
|
|
||||||
focusedTextColor = TextPrimary,
|
|
||||||
unfocusedTextColor = TextPrimary,
|
|
||||||
),
|
|
||||||
keyboardOptions = KeyboardOptions(
|
keyboardOptions = KeyboardOptions(
|
||||||
autoCorrect = false,
|
autoCorrect = false,
|
||||||
keyboardType = KeyboardType.Ascii,
|
keyboardType = KeyboardType.Ascii,
|
||||||
imeAction = ImeAction.Done,
|
imeAction = ImeAction.Done,
|
||||||
),
|
),
|
||||||
keyboardActions = KeyboardActions(onDone = { submitCommand() }),
|
keyboardActions = KeyboardActions(onDone = { submitCommand() }),
|
||||||
|
decorationBox = { innerTextField ->
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(vertical = 8.dp),
|
||||||
|
contentAlignment = Alignment.CenterStart,
|
||||||
|
) {
|
||||||
|
innerTextField()
|
||||||
|
}
|
||||||
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user