- System tray icon with connection status - Exec approval dialogs with queue and timeout - Settings persistence to JSON (%LOCALAPPDATA%\Clawdbot) - Auto-start on login via Windows Registry - Notification sounds for approvals and connection events - WebView2 Control UI embedding - 23 unit tests passing - Build scripts and Inno Setup installer template - Community build guide documentation Phase 0: Protocol models, WebSocket client, logging Phase 1: Tray icon, exec approval dialogs, Control UI Phase 2: Settings, auto-start, sounds, settings UI
213 lines
9.9 KiB
XML
213 lines
9.9 KiB
XML
<Window x:Class="Clawdbot.Windows.ExecApprovalDialog"
|
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
Title="Clawdbot - Command Approval"
|
|
Width="500"
|
|
Height="400"
|
|
MinWidth="400"
|
|
MinHeight="300"
|
|
WindowStartupLocation="CenterScreen"
|
|
WindowStyle="SingleBorderWindow"
|
|
ResizeMode="CanResize"
|
|
Topmost="True"
|
|
ShowInTaskbar="True"
|
|
Background="{StaticResource BackgroundDarkBrush}">
|
|
|
|
<Window.Resources>
|
|
<Style x:Key="SectionTitleStyle" TargetType="TextBlock">
|
|
<Setter Property="FontWeight" Value="SemiBold"/>
|
|
<Setter Property="FontSize" Value="13"/>
|
|
<Setter Property="Foreground" Value="{StaticResource TextPrimaryBrush}"/>
|
|
<Setter Property="Margin" Value="0,0,0,4"/>
|
|
</Style>
|
|
|
|
<Style x:Key="DetailLabelStyle" TargetType="TextBlock">
|
|
<Setter Property="FontSize" Value="12"/>
|
|
<Setter Property="Foreground" Value="{StaticResource TextSecondaryBrush}"/>
|
|
</Style>
|
|
|
|
<Style x:Key="DetailValueStyle" TargetType="TextBlock">
|
|
<Setter Property="FontSize" Value="12"/>
|
|
<Setter Property="Foreground" Value="{StaticResource TextPrimaryBrush}"/>
|
|
<Setter Property="TextTrimming" Value="CharacterEllipsis"/>
|
|
</Style>
|
|
|
|
<Style x:Key="CommandBoxStyle" TargetType="TextBox">
|
|
<Setter Property="IsReadOnly" Value="True"/>
|
|
<Setter Property="FontFamily" Value="Consolas, Courier New"/>
|
|
<Setter Property="FontSize" Value="12"/>
|
|
<Setter Property="Background" Value="#1A1A1A"/>
|
|
<Setter Property="Foreground" Value="#E0E0E0"/>
|
|
<Setter Property="BorderBrush" Value="#3A3A3A"/>
|
|
<Setter Property="BorderThickness" Value="1"/>
|
|
<Setter Property="Padding" Value="8"/>
|
|
<Setter Property="TextWrapping" Value="Wrap"/>
|
|
<Setter Property="VerticalScrollBarVisibility" Value="Auto"/>
|
|
</Style>
|
|
|
|
<Style x:Key="ActionButtonStyle" TargetType="Button">
|
|
<Setter Property="MinWidth" Value="100"/>
|
|
<Setter Property="Height" Value="32"/>
|
|
<Setter Property="Padding" Value="16,0"/>
|
|
<Setter Property="FontSize" Value="13"/>
|
|
<Setter Property="Cursor" Value="Hand"/>
|
|
</Style>
|
|
|
|
<Style x:Key="AllowOnceButtonStyle" TargetType="Button" BasedOn="{StaticResource ActionButtonStyle}">
|
|
<Setter Property="Background" Value="#4CAF50"/>
|
|
<Setter Property="Foreground" Value="White"/>
|
|
<Setter Property="BorderThickness" Value="0"/>
|
|
<Setter Property="Template">
|
|
<Setter.Value>
|
|
<ControlTemplate TargetType="Button">
|
|
<Border Background="{TemplateBinding Background}"
|
|
CornerRadius="4"
|
|
Padding="{TemplateBinding Padding}">
|
|
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
|
</Border>
|
|
<ControlTemplate.Triggers>
|
|
<Trigger Property="IsMouseOver" Value="True">
|
|
<Setter Property="Background" Value="#66BB6A"/>
|
|
</Trigger>
|
|
<Trigger Property="IsPressed" Value="True">
|
|
<Setter Property="Background" Value="#388E3C"/>
|
|
</Trigger>
|
|
</ControlTemplate.Triggers>
|
|
</ControlTemplate>
|
|
</Setter.Value>
|
|
</Setter>
|
|
</Style>
|
|
|
|
<Style x:Key="AllowAlwaysButtonStyle" TargetType="Button" BasedOn="{StaticResource ActionButtonStyle}">
|
|
<Setter Property="Background" Value="#2196F3"/>
|
|
<Setter Property="Foreground" Value="White"/>
|
|
<Setter Property="BorderThickness" Value="0"/>
|
|
<Setter Property="Template">
|
|
<Setter.Value>
|
|
<ControlTemplate TargetType="Button">
|
|
<Border Background="{TemplateBinding Background}"
|
|
CornerRadius="4"
|
|
Padding="{TemplateBinding Padding}">
|
|
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
|
</Border>
|
|
<ControlTemplate.Triggers>
|
|
<Trigger Property="IsMouseOver" Value="True">
|
|
<Setter Property="Background" Value="#42A5F5"/>
|
|
</Trigger>
|
|
<Trigger Property="IsPressed" Value="True">
|
|
<Setter Property="Background" Value="#1976D2"/>
|
|
</Trigger>
|
|
</ControlTemplate.Triggers>
|
|
</ControlTemplate>
|
|
</Setter.Value>
|
|
</Setter>
|
|
</Style>
|
|
|
|
<Style x:Key="DenyButtonStyle" TargetType="Button" BasedOn="{StaticResource ActionButtonStyle}">
|
|
<Setter Property="Background" Value="#F44336"/>
|
|
<Setter Property="Foreground" Value="White"/>
|
|
<Setter Property="BorderThickness" Value="0"/>
|
|
<Setter Property="Template">
|
|
<Setter.Value>
|
|
<ControlTemplate TargetType="Button">
|
|
<Border Background="{TemplateBinding Background}"
|
|
CornerRadius="4"
|
|
Padding="{TemplateBinding Padding}">
|
|
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
|
</Border>
|
|
<ControlTemplate.Triggers>
|
|
<Trigger Property="IsMouseOver" Value="True">
|
|
<Setter Property="Background" Value="#EF5350"/>
|
|
</Trigger>
|
|
<Trigger Property="IsPressed" Value="True">
|
|
<Setter Property="Background" Value="#D32F2F"/>
|
|
</Trigger>
|
|
</ControlTemplate.Triggers>
|
|
</ControlTemplate>
|
|
</Setter.Value>
|
|
</Setter>
|
|
</Style>
|
|
</Window.Resources>
|
|
|
|
<Grid Margin="20">
|
|
<Grid.RowDefinitions>
|
|
<RowDefinition Height="Auto"/>
|
|
<RowDefinition Height="Auto"/>
|
|
<RowDefinition Height="*"/>
|
|
<RowDefinition Height="Auto"/>
|
|
<RowDefinition Height="Auto"/>
|
|
<RowDefinition Height="Auto"/>
|
|
</Grid.RowDefinitions>
|
|
|
|
<!-- Header -->
|
|
<StackPanel Grid.Row="0" Margin="0,0,0,16">
|
|
<TextBlock Text="⚠️ Allow this command?"
|
|
FontSize="18"
|
|
FontWeight="Bold"
|
|
Foreground="{StaticResource TextPrimaryBrush}"/>
|
|
<TextBlock Text="Review the command details before allowing execution."
|
|
FontSize="12"
|
|
Foreground="{StaticResource TextSecondaryBrush}"
|
|
Margin="0,4,0,0"/>
|
|
</StackPanel>
|
|
|
|
<!-- Command Section -->
|
|
<StackPanel Grid.Row="1" Margin="0,0,0,12">
|
|
<TextBlock Text="Command" Style="{StaticResource SectionTitleStyle}"/>
|
|
<TextBox x:Name="CommandTextBox"
|
|
Style="{StaticResource CommandBoxStyle}"
|
|
MaxHeight="100"/>
|
|
</StackPanel>
|
|
|
|
<!-- Context Section -->
|
|
<StackPanel Grid.Row="2" Margin="0,0,0,12">
|
|
<TextBlock Text="Context" Style="{StaticResource SectionTitleStyle}"/>
|
|
<Border Background="#1A1A1A" BorderBrush="#3A3A3A" BorderThickness="1" CornerRadius="4" Padding="12">
|
|
<StackPanel x:Name="ContextPanel">
|
|
<!-- Context details will be added programmatically -->
|
|
</StackPanel>
|
|
</Border>
|
|
</StackPanel>
|
|
|
|
<!-- Timer -->
|
|
<StackPanel Grid.Row="3" Orientation="Horizontal" HorizontalAlignment="Left" Margin="0,0,0,12">
|
|
<TextBlock Text="⏱️ " FontSize="12" Foreground="{StaticResource TextSecondaryBrush}"/>
|
|
<TextBlock x:Name="TimerText"
|
|
Text="Expires in --:--"
|
|
FontSize="12"
|
|
Foreground="{StaticResource TextSecondaryBrush}"/>
|
|
</StackPanel>
|
|
|
|
<!-- Footer Note -->
|
|
<TextBlock Grid.Row="4"
|
|
Text="This command will run on this machine."
|
|
FontSize="11"
|
|
Foreground="{StaticResource TextSecondaryBrush}"
|
|
Margin="0,0,0,16"/>
|
|
|
|
<!-- Action Buttons -->
|
|
<StackPanel Grid.Row="5"
|
|
Orientation="Horizontal"
|
|
HorizontalAlignment="Right">
|
|
<Button x:Name="DenyButton"
|
|
Content="Don't Allow"
|
|
Style="{StaticResource DenyButtonStyle}"
|
|
Click="DenyButton_Click"
|
|
Margin="0,0,12,0"
|
|
ToolTip="Press Escape to deny"/>
|
|
<Button x:Name="AllowAlwaysButton"
|
|
Content="Always Allow"
|
|
Style="{StaticResource AllowAlwaysButtonStyle}"
|
|
Click="AllowAlwaysButton_Click"
|
|
Margin="0,0,12,0"
|
|
ToolTip="Add to allowlist and run"/>
|
|
<Button x:Name="AllowOnceButton"
|
|
Content="Allow Once"
|
|
Style="{StaticResource AllowOnceButtonStyle}"
|
|
Click="AllowOnceButton_Click"
|
|
IsDefault="True"
|
|
ToolTip="Press Enter to allow once"/>
|
|
</StackPanel>
|
|
</Grid>
|
|
</Window>
|