Misc Changes

This commit is contained in:
Joe Tretter
2026-05-06 20:44:34 -05:00
parent 5c7c7ad29d
commit 5727022baf
7 changed files with 451 additions and 110 deletions

View File

@@ -16,9 +16,16 @@ import androidx.compose.foundation.text.selection.SelectionContainer
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.TextField
import androidx.compose.material3.TextFieldDefaults
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
@@ -38,6 +45,29 @@ fun ManPageDialog(
) {
val horizontalScrollState = rememberScrollState()
val verticalScrollState = rememberScrollState()
var searchQuery by remember(state.content) { mutableStateOf("") }
var selectedMatch by remember(state.content) { mutableStateOf(0) }
val contentLines = remember(state.content) { state.content.lines() }
val matches = remember(searchQuery, contentLines) {
if (searchQuery.isBlank()) {
emptyList()
} else {
contentLines.mapIndexedNotNull { index, line ->
index.takeIf { line.contains(searchQuery, ignoreCase = true) }
}
}
}
val matchCount = matches.size
val currentMatchNumber = if (matchCount == 0) 0 else selectedMatch + 1
LaunchedEffect(searchQuery, matchCount) {
selectedMatch = selectedMatch.coerceIn(0, (matchCount - 1).coerceAtLeast(0))
}
LaunchedEffect(selectedMatch, matches) {
val lineIndex = matches.getOrNull(selectedMatch) ?: return@LaunchedEffect
verticalScrollState.animateScrollTo((lineIndex * 18).coerceAtMost(verticalScrollState.maxValue))
}
Dialog(onDismissRequest = onClose) {
Surface(
@@ -71,6 +101,59 @@ fun ManPageDialog(
Text("Close")
}
}
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(8.dp),
) {
TextField(
value = searchQuery,
onValueChange = {
searchQuery = it
selectedMatch = 0
},
modifier = Modifier.weight(1f),
singleLine = true,
placeholder = { Text("Search") },
colors = TextFieldDefaults.colors(
focusedTextColor = TextPrimary,
unfocusedTextColor = TextPrimary,
focusedContainerColor = PanelSecondary,
unfocusedContainerColor = PanelSecondary,
focusedIndicatorColor = Accent,
unfocusedIndicatorColor = TextMuted,
cursorColor = Accent,
),
)
Button(
onClick = {
if (matchCount > 0) selectedMatch = (selectedMatch - 1 + matchCount) % matchCount
},
enabled = matchCount > 0,
colors = ButtonDefaults.buttonColors(
containerColor = PanelSecondary,
contentColor = TextPrimary,
),
) {
Text("Prev")
}
Button(
onClick = {
if (matchCount > 0) selectedMatch = (selectedMatch + 1) % matchCount
},
enabled = matchCount > 0,
colors = ButtonDefaults.buttonColors(
containerColor = PanelSecondary,
contentColor = TextPrimary,
),
) {
Text("Next")
}
}
Text(
text = "$currentMatchNumber/$matchCount",
color = TextSecondary,
fontSize = 12.sp,
)
Text(
text = "git ${state.topic}",
color = TextPrimary,