Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
877d59bb26 | ||
|
|
8a69e740ee | ||
|
|
d4f284d829 | ||
|
|
0ed83be9eb |
+65
-37
@@ -15,7 +15,8 @@
|
|||||||
<SolidColorBrush x:Key="SurfaceBrush" Color="#FAFAFA" po:Freeze="False"/>
|
<SolidColorBrush x:Key="SurfaceBrush" Color="#FAFAFA" po:Freeze="False"/>
|
||||||
<SolidColorBrush x:Key="BannerBgBrush" Color="#E8F2FB" po:Freeze="False"/>
|
<SolidColorBrush x:Key="BannerBgBrush" Color="#E8F2FB" po:Freeze="False"/>
|
||||||
<SolidColorBrush x:Key="BannerBorderBrush" Color="#B3D6F5" po:Freeze="False"/>
|
<SolidColorBrush x:Key="BannerBorderBrush" Color="#B3D6F5" po:Freeze="False"/>
|
||||||
<SolidColorBrush x:Key="HoverBrush" Color="#EBEBEB" po:Freeze="False"/>
|
<SolidColorBrush x:Key="HoverBrush" Color="#EBEBEB" po:Freeze="False"/>
|
||||||
|
<SolidColorBrush x:Key="PressedBrush" Color="#D6D6D6" po:Freeze="False"/>
|
||||||
<SolidColorBrush x:Key="BadgeBrush" Color="#F0F0F0" po:Freeze="False"/>
|
<SolidColorBrush x:Key="BadgeBrush" Color="#F0F0F0" po:Freeze="False"/>
|
||||||
|
|
||||||
<Style x:Key="HeaderText" TargetType="TextBlock">
|
<Style x:Key="HeaderText" TargetType="TextBlock">
|
||||||
@@ -26,27 +27,31 @@
|
|||||||
</Style>
|
</Style>
|
||||||
|
|
||||||
<Style x:Key="PrimaryButton" TargetType="Button">
|
<Style x:Key="PrimaryButton" TargetType="Button">
|
||||||
<Setter Property="Background" Value="{DynamicResource BlueBrush}"/>
|
<Setter Property="Background" Value="{DynamicResource BlueBrush}"/>
|
||||||
<Setter Property="Foreground" Value="White"/>
|
<Setter Property="Foreground" Value="White"/>
|
||||||
<Setter Property="BorderThickness" Value="0"/>
|
<Setter Property="BorderThickness" Value="0"/>
|
||||||
<Setter Property="Padding" Value="14,6"/>
|
<Setter Property="Padding" Value="14,6"/>
|
||||||
<Setter Property="FontSize" Value="12"/>
|
<Setter Property="FontSize" Value="12"/>
|
||||||
<Setter Property="FontWeight" Value="SemiBold"/>
|
<Setter Property="FontWeight" Value="SemiBold"/>
|
||||||
<Setter Property="FontFamily" Value="Segoe UI"/>
|
<Setter Property="FontFamily" Value="Segoe UI"/>
|
||||||
<Setter Property="Cursor" Value="Hand"/>
|
<Setter Property="Cursor" Value="Hand"/>
|
||||||
|
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
|
||||||
<Setter Property="Template">
|
<Setter Property="Template">
|
||||||
<Setter.Value>
|
<Setter.Value>
|
||||||
<ControlTemplate TargetType="Button">
|
<ControlTemplate TargetType="Button">
|
||||||
<Border Background="{TemplateBinding Background}" CornerRadius="4"
|
<Border x:Name="Bd" Background="{TemplateBinding Background}"
|
||||||
Padding="{TemplateBinding Padding}">
|
CornerRadius="4" Padding="{TemplateBinding Padding}">
|
||||||
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||||
</Border>
|
</Border>
|
||||||
<ControlTemplate.Triggers>
|
<ControlTemplate.Triggers>
|
||||||
<Trigger Property="IsMouseOver" Value="True">
|
<Trigger Property="IsMouseOver" Value="True">
|
||||||
<Setter Property="Background" Value="#106EBE"/>
|
<Setter TargetName="Bd" Property="Background" Value="#106EBE"/>
|
||||||
|
</Trigger>
|
||||||
|
<Trigger Property="IsPressed" Value="True">
|
||||||
|
<Setter TargetName="Bd" Property="Background" Value="#005A9E"/>
|
||||||
</Trigger>
|
</Trigger>
|
||||||
<Trigger Property="IsEnabled" Value="False">
|
<Trigger Property="IsEnabled" Value="False">
|
||||||
<Setter Property="Background" Value="#BDBDBD"/>
|
<Setter TargetName="Bd" Property="Background" Value="#BDBDBD"/>
|
||||||
</Trigger>
|
</Trigger>
|
||||||
</ControlTemplate.Triggers>
|
</ControlTemplate.Triggers>
|
||||||
</ControlTemplate>
|
</ControlTemplate>
|
||||||
@@ -55,18 +60,20 @@
|
|||||||
</Style>
|
</Style>
|
||||||
|
|
||||||
<Style x:Key="SmallButton" TargetType="Button">
|
<Style x:Key="SmallButton" TargetType="Button">
|
||||||
<Setter Property="Background" Value="{DynamicResource ButtonBrush}"/>
|
<Setter Property="Background" Value="{DynamicResource ButtonBrush}"/>
|
||||||
<Setter Property="BorderBrush" Value="{DynamicResource BorderBrush}"/>
|
<Setter Property="BorderBrush" Value="{DynamicResource BorderBrush}"/>
|
||||||
<Setter Property="BorderThickness" Value="1"/>
|
<Setter Property="BorderThickness" Value="1"/>
|
||||||
<Setter Property="Foreground" Value="{DynamicResource TextBrush}"/>
|
<Setter Property="Foreground" Value="{DynamicResource TextBrush}"/>
|
||||||
<Setter Property="Padding" Value="10,4"/>
|
<Setter Property="Padding" Value="10,4"/>
|
||||||
<Setter Property="FontSize" Value="12"/>
|
<Setter Property="FontSize" Value="12"/>
|
||||||
<Setter Property="FontFamily" Value="Segoe UI"/>
|
<Setter Property="FontFamily" Value="Segoe UI"/>
|
||||||
<Setter Property="Cursor" Value="Hand"/>
|
<Setter Property="Cursor" Value="Hand"/>
|
||||||
|
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
|
||||||
<Setter Property="Template">
|
<Setter Property="Template">
|
||||||
<Setter.Value>
|
<Setter.Value>
|
||||||
<ControlTemplate TargetType="Button">
|
<ControlTemplate TargetType="Button">
|
||||||
<Border Background="{TemplateBinding Background}"
|
<Border x:Name="Bd"
|
||||||
|
Background="{TemplateBinding Background}"
|
||||||
BorderBrush="{TemplateBinding BorderBrush}"
|
BorderBrush="{TemplateBinding BorderBrush}"
|
||||||
BorderThickness="{TemplateBinding BorderThickness}"
|
BorderThickness="{TemplateBinding BorderThickness}"
|
||||||
CornerRadius="4" Padding="{TemplateBinding Padding}">
|
CornerRadius="4" Padding="{TemplateBinding Padding}">
|
||||||
@@ -74,7 +81,10 @@
|
|||||||
</Border>
|
</Border>
|
||||||
<ControlTemplate.Triggers>
|
<ControlTemplate.Triggers>
|
||||||
<Trigger Property="IsMouseOver" Value="True">
|
<Trigger Property="IsMouseOver" Value="True">
|
||||||
<Setter Property="Background" Value="{DynamicResource HoverBrush}"/>
|
<Setter TargetName="Bd" Property="Background" Value="{DynamicResource HoverBrush}"/>
|
||||||
|
</Trigger>
|
||||||
|
<Trigger Property="IsPressed" Value="True">
|
||||||
|
<Setter TargetName="Bd" Property="Background" Value="{DynamicResource PressedBrush}"/>
|
||||||
</Trigger>
|
</Trigger>
|
||||||
</ControlTemplate.Triggers>
|
</ControlTemplate.Triggers>
|
||||||
</ControlTemplate>
|
</ControlTemplate>
|
||||||
@@ -83,18 +93,19 @@
|
|||||||
</Style>
|
</Style>
|
||||||
|
|
||||||
<Style TargetType="ComboBox">
|
<Style TargetType="ComboBox">
|
||||||
<Setter Property="FontFamily" Value="Segoe UI"/>
|
<Setter Property="FontFamily" Value="Segoe UI"/>
|
||||||
<Setter Property="FontSize" Value="12"/>
|
<Setter Property="FontSize" Value="12"/>
|
||||||
<Setter Property="Background" Value="{DynamicResource CardBrush}"/>
|
<Setter Property="Background" Value="{DynamicResource CardBrush}"/>
|
||||||
<Setter Property="Foreground" Value="{DynamicResource TextBrush}"/>
|
<Setter Property="Foreground" Value="{DynamicResource TextBrush}"/>
|
||||||
<Setter Property="BorderBrush" Value="{DynamicResource BorderBrush}"/>
|
<Setter Property="BorderBrush" Value="{DynamicResource BorderBrush}"/>
|
||||||
<Setter Property="BorderThickness" Value="1"/>
|
<Setter Property="BorderThickness" Value="1"/>
|
||||||
<Setter Property="Padding" Value="8,4"/>
|
<Setter Property="Padding" Value="8,4"/>
|
||||||
|
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
|
||||||
<Setter Property="Template">
|
<Setter Property="Template">
|
||||||
<Setter.Value>
|
<Setter.Value>
|
||||||
<ControlTemplate TargetType="ComboBox">
|
<ControlTemplate TargetType="ComboBox">
|
||||||
<Grid>
|
<Grid>
|
||||||
<Border x:Name="Border"
|
<Border x:Name="Bd"
|
||||||
Background="{TemplateBinding Background}"
|
Background="{TemplateBinding Background}"
|
||||||
BorderBrush="{TemplateBinding BorderBrush}"
|
BorderBrush="{TemplateBinding BorderBrush}"
|
||||||
BorderThickness="{TemplateBinding BorderThickness}"
|
BorderThickness="{TemplateBinding BorderThickness}"
|
||||||
@@ -106,14 +117,21 @@
|
|||||||
ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
|
ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
|
||||||
Margin="{TemplateBinding Padding}"
|
Margin="{TemplateBinding Padding}"
|
||||||
VerticalAlignment="Center" HorizontalAlignment="Left"/>
|
VerticalAlignment="Center" HorizontalAlignment="Left"/>
|
||||||
<TextBlock Text="▾" FontSize="10"
|
<TextBlock Text="▾" FontSize="10"
|
||||||
Foreground="{DynamicResource SecondaryBrush}"
|
Foreground="{DynamicResource SecondaryBrush}"
|
||||||
HorizontalAlignment="Right" VerticalAlignment="Center"
|
HorizontalAlignment="Right" VerticalAlignment="Center"
|
||||||
Margin="0,0,8,0" IsHitTestVisible="False"/>
|
Margin="0,0,8,0" IsHitTestVisible="False"/>
|
||||||
|
<!-- Fully transparent toggle — no system chrome bleeds through -->
|
||||||
<ToggleButton Focusable="False" ClickMode="Press"
|
<ToggleButton Focusable="False" ClickMode="Press"
|
||||||
|
FocusVisualStyle="{x:Null}"
|
||||||
IsChecked="{Binding IsDropDownOpen, Mode=TwoWay,
|
IsChecked="{Binding IsDropDownOpen, Mode=TwoWay,
|
||||||
RelativeSource={RelativeSource TemplatedParent}}"
|
RelativeSource={RelativeSource TemplatedParent}}">
|
||||||
Background="Transparent" BorderThickness="0"/>
|
<ToggleButton.Template>
|
||||||
|
<ControlTemplate TargetType="ToggleButton">
|
||||||
|
<Border Background="Transparent"/>
|
||||||
|
</ControlTemplate>
|
||||||
|
</ToggleButton.Template>
|
||||||
|
</ToggleButton>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Border>
|
</Border>
|
||||||
<Popup x:Name="Popup" Placement="Bottom"
|
<Popup x:Name="Popup" Placement="Bottom"
|
||||||
@@ -132,15 +150,21 @@
|
|||||||
</Border>
|
</Border>
|
||||||
</Popup>
|
</Popup>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
<ControlTemplate.Triggers>
|
||||||
|
<Trigger Property="IsMouseOver" Value="True">
|
||||||
|
<Setter TargetName="Bd" Property="Background" Value="{DynamicResource HoverBrush}"/>
|
||||||
|
</Trigger>
|
||||||
|
</ControlTemplate.Triggers>
|
||||||
</ControlTemplate>
|
</ControlTemplate>
|
||||||
</Setter.Value>
|
</Setter.Value>
|
||||||
</Setter>
|
</Setter>
|
||||||
<Setter Property="ItemContainerStyle">
|
<Setter Property="ItemContainerStyle">
|
||||||
<Setter.Value>
|
<Setter.Value>
|
||||||
<Style TargetType="ComboBoxItem">
|
<Style TargetType="ComboBoxItem">
|
||||||
<Setter Property="Foreground" Value="{DynamicResource TextBrush}"/>
|
<Setter Property="Foreground" Value="{DynamicResource TextBrush}"/>
|
||||||
<Setter Property="Background" Value="{DynamicResource CardBrush}"/>
|
<Setter Property="Background" Value="{DynamicResource CardBrush}"/>
|
||||||
<Setter Property="Padding" Value="10,5"/>
|
<Setter Property="Padding" Value="10,5"/>
|
||||||
|
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
|
||||||
<Setter Property="Template">
|
<Setter Property="Template">
|
||||||
<Setter.Value>
|
<Setter.Value>
|
||||||
<ControlTemplate TargetType="ComboBoxItem">
|
<ControlTemplate TargetType="ComboBoxItem">
|
||||||
@@ -154,6 +178,10 @@
|
|||||||
<Setter TargetName="Bd" Property="Background"
|
<Setter TargetName="Bd" Property="Background"
|
||||||
Value="{DynamicResource HoverBrush}"/>
|
Value="{DynamicResource HoverBrush}"/>
|
||||||
</Trigger>
|
</Trigger>
|
||||||
|
<Trigger Property="IsSelected" Value="True">
|
||||||
|
<Setter TargetName="Bd" Property="Background"
|
||||||
|
Value="{DynamicResource HoverBrush}"/>
|
||||||
|
</Trigger>
|
||||||
</ControlTemplate.Triggers>
|
</ControlTemplate.Triggers>
|
||||||
</ControlTemplate>
|
</ControlTemplate>
|
||||||
</Setter.Value>
|
</Setter.Value>
|
||||||
|
|||||||
+11
-16
@@ -33,7 +33,7 @@ public partial class PopupWindow : Window
|
|||||||
VM.PropertyChanged += (_, e) => Dispatcher.InvokeAsync(() => OnVmChanged(e.PropertyName));
|
VM.PropertyChanged += (_, e) => Dispatcher.InvokeAsync(() => OnVmChanged(e.PropertyName));
|
||||||
Updater.PropertyChanged += (_, e) => Dispatcher.InvokeAsync(() => OnUpdaterChanged(e.PropertyName));
|
Updater.PropertyChanged += (_, e) => Dispatcher.InvokeAsync(() => OnUpdaterChanged(e.PropertyName));
|
||||||
|
|
||||||
_clockTimer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(5) };
|
_clockTimer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1) };
|
||||||
_clockTimer.Tick += (_, _) => UpdateFooter();
|
_clockTimer.Tick += (_, _) => UpdateFooter();
|
||||||
_clockTimer.Start();
|
_clockTimer.Start();
|
||||||
|
|
||||||
@@ -97,7 +97,7 @@ public partial class PopupWindow : Window
|
|||||||
badgeStack.Children.Add(usageBadge);
|
badgeStack.Children.Add(usageBadge);
|
||||||
|
|
||||||
var nameStack = new StackPanel { Orientation = Orientation.Horizontal, VerticalAlignment = VerticalAlignment.Center };
|
var nameStack = new StackPanel { Orientation = Orientation.Horizontal, VerticalAlignment = VerticalAlignment.Center };
|
||||||
nameStack.Children.Add(new TextBlock { Text = "✦", FontSize = 11, Foreground = accent, VerticalAlignment = VerticalAlignment.Center });
|
nameStack.Children.Add(new TextBlock { Text = "✶", FontSize = 11, Foreground = accent, VerticalAlignment = VerticalAlignment.Center });
|
||||||
nameStack.Children.Add(new TextBlock { Text = "Claude", FontSize = 13, FontWeight = FontWeights.SemiBold,
|
nameStack.Children.Add(new TextBlock { Text = "Claude", FontSize = 13, FontWeight = FontWeights.SemiBold,
|
||||||
Foreground = text, Margin = new Thickness(6, 0, 0, 0), VerticalAlignment = VerticalAlignment.Center });
|
Foreground = text, Margin = new Thickness(6, 0, 0, 0), VerticalAlignment = VerticalAlignment.Center });
|
||||||
nameStack.Children.Add(new TextBlock { Text = $"· {VM.PlanLabel}", FontSize = 11,
|
nameStack.Children.Add(new TextBlock { Text = $"· {VM.PlanLabel}", FontSize = 11,
|
||||||
@@ -166,17 +166,10 @@ public partial class PopupWindow : Window
|
|||||||
timeRow.Children.Add(timeLeft);
|
timeRow.Children.Add(timeLeft);
|
||||||
timeRow.Children.Add(timeRight);
|
timeRow.Children.Add(timeRight);
|
||||||
|
|
||||||
var sparkline = new SparklineControl
|
|
||||||
{
|
|
||||||
Height = 28, Margin = new Thickness(0, 8, 0, 0), LineColor = Color.FromRgb(0xF9, 0x73, 0x16),
|
|
||||||
Data = limit.BurnHistory.Count > 0 ? limit.BurnHistory : null,
|
|
||||||
};
|
|
||||||
|
|
||||||
var infoPanel = new StackPanel { VerticalAlignment = VerticalAlignment.Center };
|
var infoPanel = new StackPanel { VerticalAlignment = VerticalAlignment.Center };
|
||||||
infoPanel.Children.Add(headerRow);
|
infoPanel.Children.Add(headerRow);
|
||||||
infoPanel.Children.Add(progress);
|
infoPanel.Children.Add(progress);
|
||||||
infoPanel.Children.Add(timeRow);
|
infoPanel.Children.Add(timeRow);
|
||||||
infoPanel.Children.Add(sparkline);
|
|
||||||
|
|
||||||
var cardGrid = new Grid { Margin = new Thickness(16, 12, 16, 12) };
|
var cardGrid = new Grid { Margin = new Thickness(16, 12, 16, 12) };
|
||||||
cardGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
|
cardGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
|
||||||
@@ -215,7 +208,6 @@ public partial class PopupWindow : Window
|
|||||||
var secondary = (SolidColorBrush)Application.Current.Resources["SecondaryBrush"];
|
var secondary = (SolidColorBrush)Application.Current.Resources["SecondaryBrush"];
|
||||||
var border = (SolidColorBrush)Application.Current.Resources["BorderBrush"];
|
var border = (SolidColorBrush)Application.Current.Resources["BorderBrush"];
|
||||||
|
|
||||||
// Stats row inside the card (mirrors macOS layout without the Claude icon/header)
|
|
||||||
var statsRow = new Grid { Margin = new Thickness(12, 10, 12, 6) };
|
var statsRow = new Grid { Margin = new Thickness(12, 10, 12, 6) };
|
||||||
statsRow.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
|
statsRow.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
|
||||||
statsRow.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
|
statsRow.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
|
||||||
@@ -280,7 +272,6 @@ public partial class PopupWindow : Window
|
|||||||
var prepaid = VM.Prepaid;
|
var prepaid = VM.Prepaid;
|
||||||
var currency = VM.ExtraUsage?.Currency ?? overage?.Currency ?? "$";
|
var currency = VM.ExtraUsage?.Currency ?? overage?.Currency ?? "$";
|
||||||
|
|
||||||
// All credit values from the API are in cents — divide by 100.
|
|
||||||
var spent = (overage?.UsedCredits / 100.0) ?? (VM.ExtraUsage?.UsedCredits / 100.0) ?? 0;
|
var spent = (overage?.UsedCredits / 100.0) ?? (VM.ExtraUsage?.UsedCredits / 100.0) ?? 0;
|
||||||
var limit = (overage?.MonthlyCreditLimit / 100.0) ?? (VM.ExtraUsage?.MonthlyLimit / 100.0) ?? 0;
|
var limit = (overage?.MonthlyCreditLimit / 100.0) ?? (VM.ExtraUsage?.MonthlyLimit / 100.0) ?? 0;
|
||||||
var balance = (prepaid?.Amount / 100.0) ?? 0;
|
var balance = (prepaid?.Amount / 100.0) ?? 0;
|
||||||
@@ -403,8 +394,14 @@ public partial class PopupWindow : Window
|
|||||||
if (VM.LastUpdated.HasValue)
|
if (VM.LastUpdated.HasValue)
|
||||||
{
|
{
|
||||||
var diff = DateTime.Now - VM.LastUpdated.Value;
|
var diff = DateTime.Now - VM.LastUpdated.Value;
|
||||||
LastUpdatedText.Text = diff.TotalSeconds < 10 ? "Updated just now"
|
string age;
|
||||||
: $"Updated {(int)diff.TotalSeconds}s ago";
|
if (diff.TotalSeconds < 10)
|
||||||
|
age = "just now";
|
||||||
|
else if (diff.TotalMinutes < 1)
|
||||||
|
age = $"{(int)diff.TotalSeconds} sec ago";
|
||||||
|
else
|
||||||
|
age = $"{(int)diff.TotalMinutes} min, {diff.Seconds} sec ago";
|
||||||
|
LastUpdatedText.Text = $"Updated {age}";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -431,11 +428,9 @@ public partial class PopupWindow : Window
|
|||||||
BetaToggle.IsChecked = Updater.BetaChannel;
|
BetaToggle.IsChecked = Updater.BetaChannel;
|
||||||
UpdateAboutSection();
|
UpdateAboutSection();
|
||||||
|
|
||||||
// Populate ComboBox with ComboBoxItem — DisplayMemberPath doesn't bind reliably
|
|
||||||
// on ValueTuple at runtime so we build items explicitly.
|
|
||||||
RefreshPicker.SelectionChanged -= RefreshPicker_Changed;
|
RefreshPicker.SelectionChanged -= RefreshPicker_Changed;
|
||||||
RefreshPicker.Items.Clear();
|
RefreshPicker.Items.Clear();
|
||||||
int selectIdx = 1; // default: 2 min
|
int selectIdx = 1;
|
||||||
for (int i = 0; i < RefreshIntervals.Length; i++)
|
for (int i = 0; i < RefreshIntervals.Length; i++)
|
||||||
{
|
{
|
||||||
var (label, seconds) = RefreshIntervals[i];
|
var (label, seconds) = RefreshIntervals[i];
|
||||||
|
|||||||
Reference in New Issue
Block a user