feat(ui): remove a queued interactive message with a ✕

Queued rows are now QueuedMessageViewModel (Text + RemoveCommand); each shows a
✕ (Icon.WinClose) that calls RemoveQueuedInteractiveMessageAsync(taskId, text).
The worker re-broadcasts the queue, rebuilding the strip without the removed
message. Adds session.composer.unqueue (en/de).
This commit is contained in:
Mika Kuns
2026-06-26 11:19:47 +02:00
parent fd1e38fb7f
commit afe7218b7c
6 changed files with 80 additions and 18 deletions

View File

@@ -70,7 +70,7 @@ public sealed partial class TaskMonitorViewModel : ViewModelBase, IDisposable
private const string RoadblockMarker = "Roadblocks reported during the run:";
public ObservableCollection<string> QueuedMessages { get; } = new();
public ObservableCollection<QueuedMessageViewModel> QueuedMessages { get; } = new();
public bool HasQueuedMessages => QueuedMessages.Count > 0;
// Captured handler delegates for disposal
@@ -181,7 +181,15 @@ public sealed partial class TaskMonitorViewModel : ViewModelBase, IDisposable
{
if (taskId != _subscribedTaskId) return;
QueuedMessages.Clear();
foreach (var m in pending) QueuedMessages.Add(m);
foreach (var m in pending)
{
var text = m;
QueuedMessages.Add(new QueuedMessageViewModel
{
Text = text,
RemoveCommand = new CommunityToolkit.Mvvm.Input.RelayCommand(() => _ = RemoveQueuedAsync(text)),
});
}
OnPropertyChanged(nameof(HasQueuedMessages));
};
_worker.InteractiveQueueChangedEvent += _onInteractiveQueueChanged;
@@ -234,6 +242,12 @@ public sealed partial class TaskMonitorViewModel : ViewModelBase, IDisposable
await _worker.InterruptInteractiveSessionAsync(_subscribedTaskId);
}
private async System.Threading.Tasks.Task RemoveQueuedAsync(string text)
{
if (!string.IsNullOrEmpty(_subscribedTaskId))
await _worker.RemoveQueuedInteractiveMessageAsync(_subscribedTaskId, text);
}
private void ClearPendingQuestion()
{
PendingQuestionId = null;
@@ -515,3 +529,9 @@ public sealed partial class TaskMonitorViewModel : ViewModelBase, IDisposable
_worker.InteractiveMessageSentEvent -= _onInteractiveMessageSent;
}
}
public sealed class QueuedMessageViewModel
{
public required string Text { get; init; }
public required System.Windows.Input.ICommand RemoveCommand { get; init; }
}

View File

@@ -276,19 +276,30 @@
Foreground="{DynamicResource TextMuteBrush}" />
<ItemsControl ItemsSource="{Binding Monitor.QueuedMessages}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Spacing="6">
<TextBlock Text=""
<DataTemplate x:DataType="vm:QueuedMessageViewModel">
<Grid ColumnDefinitions="Auto,*,Auto" Margin="0,1">
<TextBlock Grid.Column="0"
Text="⧗"
Foreground="{DynamicResource TextMuteBrush}"
FontFamily="{StaticResource MonoFont}"
FontSize="{StaticResource FontSizeMono}"
VerticalAlignment="Center" />
<TextBlock Text="{Binding}"
VerticalAlignment="Center"
Margin="0,0,6,0" />
<TextBlock Grid.Column="1"
Text="{Binding Text}"
Foreground="{DynamicResource TextDimBrush}"
FontFamily="{StaticResource MonoFont}"
FontSize="{StaticResource FontSizeMono}"
TextTrimming="CharacterEllipsis" />
</StackPanel>
TextTrimming="CharacterEllipsis"
VerticalAlignment="Center" />
<Button Grid.Column="2"
Classes="title-ctrl"
Command="{Binding RemoveCommand}"
ToolTip.Tip="{loc:Tr session.composer.unqueue}"
Margin="4,0,0,0">
<PathIcon Data="{StaticResource Icon.WinClose}" Width="8" Height="8"/>
</Button>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>

View File

@@ -64,19 +64,30 @@
Foreground="{DynamicResource TextMuteBrush}" />
<ItemsControl ItemsSource="{Binding #Root.QueuedMessages}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Spacing="6">
<TextBlock Text=""
<DataTemplate x:DataType="vm:QueuedMessageViewModel">
<Grid ColumnDefinitions="Auto,*,Auto" Margin="0,1">
<TextBlock Grid.Column="0"
Text="⧗"
Foreground="{DynamicResource TextMuteBrush}"
FontFamily="{StaticResource MonoFont}"
FontSize="{StaticResource FontSizeMono}"
VerticalAlignment="Center" />
<TextBlock Text="{Binding}"
VerticalAlignment="Center"
Margin="0,0,6,0" />
<TextBlock Grid.Column="1"
Text="{Binding Text}"
Foreground="{DynamicResource TextDimBrush}"
FontFamily="{StaticResource MonoFont}"
FontSize="{StaticResource FontSizeMono}"
TextTrimming="CharacterEllipsis" />
</StackPanel>
TextTrimming="CharacterEllipsis"
VerticalAlignment="Center" />
<Button Grid.Column="2"
Classes="title-ctrl"
Command="{Binding RemoveCommand}"
ToolTip.Tip="{loc:Tr session.composer.unqueue}"
Margin="4,0,0,0">
<PathIcon Data="{StaticResource Icon.WinClose}" Width="8" Height="8"/>
</Button>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>