Implement conditional autoscroll in log monitor

Improves the user experience in the monitor tab by making the log output autoscroll conditional.

Autoscrolling is now disabled when the user selects a log entry other than the last one, allowing them to inspect previous output without interruption. Selecting the last item in the list re-enables autoscrolling.
This commit is contained in:
rbalsleyMSFT
2025-07-14 17:56:51 -07:00
parent 315f0f3858
commit ca84f4dfea
2 changed files with 40 additions and 2 deletions
+14 -1
View File
@@ -120,9 +120,10 @@ $script:uiState.Controls.btnRun.Add_Click({
# Switch to Monitor Tab # Switch to Monitor Tab
$script:uiState.Controls.MainTabControl.SelectedItem = $script:uiState.Controls.MonitorTab $script:uiState.Controls.MainTabControl.SelectedItem = $script:uiState.Controls.MonitorTab
# Clear previous log data # Clear previous log data and reset autoscroll
if ($null -ne $script:uiState.Data.logData) { if ($null -ne $script:uiState.Data.logData) {
$script:uiState.Data.logData.Clear() $script:uiState.Data.logData.Clear()
$script:uiState.Flags.autoScrollLog = $true
} }
$progressBar = $script:uiState.Controls.pbOverallProgress $progressBar = $script:uiState.Controls.pbOverallProgress
@@ -201,7 +202,10 @@ $script:uiState.Controls.btnRun.Add_Click({
while ($null -ne ($line = $script:uiState.Data.logStreamReader.ReadLine())) { while ($null -ne ($line = $script:uiState.Data.logStreamReader.ReadLine())) {
# Add the full line to the log view first to maintain consistency # Add the full line to the log view first to maintain consistency
$script:uiState.Data.logData.Add($line) $script:uiState.Data.logData.Add($line)
if ($script:uiState.Flags.autoScrollLog) {
$script:uiState.Controls.lstLogOutput.ScrollIntoView($line) $script:uiState.Controls.lstLogOutput.ScrollIntoView($line)
$script:uiState.Controls.lstLogOutput.SelectedIndex = $script:uiState.Controls.lstLogOutput.Items.Count - 1
}
# Now, check if it's a progress line and update the UI accordingly # Now, check if it's a progress line and update the UI accordingly
if ($line -match '\[PROGRESS\] (\d{1,3}) \| (.*)') { if ($line -match '\[PROGRESS\] (\d{1,3}) \| (.*)') {
@@ -234,9 +238,11 @@ $script:uiState.Controls.btnRun.Add_Click({
# Final read of the log stream # Final read of the log stream
if ($null -ne $script:uiState.Data.logStreamReader) { if ($null -ne $script:uiState.Data.logStreamReader) {
$lastLine = $null
while ($null -ne ($line = $script:uiState.Data.logStreamReader.ReadLine())) { while ($null -ne ($line = $script:uiState.Data.logStreamReader.ReadLine())) {
# Add the full line to the log view first # Add the full line to the log view first
$script:uiState.Data.logData.Add($line) $script:uiState.Data.logData.Add($line)
$lastLine = $line
# Now, check if it's a progress line and update the UI accordingly # Now, check if it's a progress line and update the UI accordingly
if ($line -match '\[PROGRESS\] (\d{1,3}) \| (.*)') { if ($line -match '\[PROGRESS\] (\d{1,3}) \| (.*)') {
@@ -247,6 +253,13 @@ $script:uiState.Controls.btnRun.Add_Click({
$script:uiState.Controls.txtStatus.Text = $message $script:uiState.Controls.txtStatus.Text = $message
} }
} }
# After the final read, scroll to the last line if autoscroll is enabled
if ($script:uiState.Flags.autoScrollLog -and $null -ne $lastLine) {
$script:uiState.Controls.lstLogOutput.ScrollIntoView($lastLine)
$script:uiState.Controls.lstLogOutput.SelectedIndex = $script:uiState.Controls.lstLogOutput.Items.Count - 1
}
$script:uiState.Data.logStreamReader.Close() $script:uiState.Data.logStreamReader.Close()
$script:uiState.Data.logStreamReader.Dispose() $script:uiState.Data.logStreamReader.Dispose()
$script:uiState.Data.logStreamReader = $null $script:uiState.Data.logStreamReader = $null
@@ -778,5 +778,30 @@ function Register-EventHandlers {
$keyEventArgs.Handled = $true $keyEventArgs.Handled = $true
} }
}) })
$State.Controls.lstLogOutput.Add_SelectionChanged({
param($eventSource, $selectionChangedEventArgs)
$listBox = $eventSource
$window = [System.Windows.Window]::GetWindow($listBox)
if ($null -eq $window) { return }
$localState = $window.Tag
# If nothing is selected or the list is empty, do nothing.
if ($listBox.SelectedIndex -eq -1 -or $listBox.Items.Count -eq 0) {
return
}
# Check if the last item is selected
$isLastItemSelected = ($listBox.SelectedIndex -eq ($listBox.Items.Count - 1))
# Update the flag
$localState.Flags.autoScrollLog = $isLastItemSelected
if ($isLastItemSelected) {
WriteLog "Monitor tab autoscroll enabled (last item selected)."
}
else {
WriteLog "Monitor tab autoscroll disabled (user selected item #$($listBox.SelectedIndex))."
}
})
} }
Export-ModuleMember -Function * Export-ModuleMember -Function *