switched to new way

This commit is contained in:
Boki 2026-02-13 01:12:51 -05:00
parent f22d182c8f
commit 4a65c8e17b
96 changed files with 4991 additions and 10025 deletions

View file

@ -0,0 +1,329 @@
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:Poe2Trade.Ui.ViewModels"
x:Class="Poe2Trade.Ui.Views.MainWindow"
x:DataType="vm:MainWindowViewModel"
Title="POE2 Trade Bot"
Width="960" Height="720"
Background="#0d1117">
<DockPanel Margin="12">
<!-- STATUS HEADER -->
<Border DockPanel.Dock="Top" Padding="12" Margin="0,0,0,8"
Background="#161b22" BorderBrush="#30363d"
BorderThickness="1" CornerRadius="8">
<Grid ColumnDefinitions="Auto,*,Auto">
<!-- Status dot + text -->
<StackPanel Grid.Column="0" Orientation="Horizontal" Spacing="8"
VerticalAlignment="Center">
<Ellipse Width="10" Height="10"
Fill="{Binding State, Converter={StaticResource StatusDotBrush}}" />
<TextBlock Text="{Binding State}" FontWeight="SemiBold"
Foreground="#e6edf3" VerticalAlignment="Center" />
</StackPanel>
<!-- Stats cards -->
<StackPanel Grid.Column="1" Orientation="Horizontal" Spacing="16"
HorizontalAlignment="Center">
<Border Background="#21262d" CornerRadius="6" Padding="16,8">
<StackPanel HorizontalAlignment="Center">
<TextBlock Text="{Binding ActiveLinksCount}"
FontSize="20" FontWeight="Bold" Foreground="#58a6ff"
HorizontalAlignment="Center" />
<TextBlock Text="ACTIVE LINKS" FontSize="10" Foreground="#8b949e"
HorizontalAlignment="Center" />
</StackPanel>
</Border>
<Border Background="#21262d" CornerRadius="6" Padding="16,8">
<StackPanel HorizontalAlignment="Center">
<TextBlock Text="{Binding TradesCompleted}"
FontSize="20" FontWeight="Bold" Foreground="#3fb950"
HorizontalAlignment="Center" />
<TextBlock Text="TRADES DONE" FontSize="10" Foreground="#8b949e"
HorizontalAlignment="Center" />
</StackPanel>
</Border>
<Border Background="#21262d" CornerRadius="6" Padding="16,8">
<StackPanel HorizontalAlignment="Center">
<TextBlock Text="{Binding TradesFailed}"
FontSize="20" FontWeight="Bold" Foreground="#f85149"
HorizontalAlignment="Center" />
<TextBlock Text="FAILED" FontSize="10" Foreground="#8b949e"
HorizontalAlignment="Center" />
</StackPanel>
</Border>
</StackPanel>
<!-- Controls -->
<StackPanel Grid.Column="2" Orientation="Horizontal" Spacing="8">
<Button Content="Start" Command="{Binding StartCommand}" />
<Button Content="{Binding PauseButtonText}" Command="{Binding PauseCommand}" />
</StackPanel>
</Grid>
</Border>
<!-- TABBED CONTENT -->
<TabControl>
<!-- ========== MAIN TAB ========== -->
<TabItem Header="Main">
<Grid RowDefinitions="Auto,*" Margin="0,8,0,0">
<!-- Inventory Grid (12x5) -->
<Border Grid.Row="0" Background="#161b22" BorderBrush="#30363d"
BorderThickness="1" CornerRadius="8" Padding="10" Margin="0,0,0,8">
<DockPanel>
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Margin="0,0,0,6">
<TextBlock Text="INVENTORY" FontSize="11" FontWeight="SemiBold"
Foreground="#8b949e" />
<TextBlock Text="{Binding InventoryFreeCells, StringFormat='{}{0}/60 free'}"
FontSize="11" Foreground="#8b949e" Margin="12,0,0,0" />
</StackPanel>
<ItemsControl ItemsSource="{Binding InventoryCells}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="12" Rows="5" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="vm:CellState">
<Border Margin="1" CornerRadius="2" Height="22"
Background="{Binding IsOccupied, Converter={StaticResource OccupiedBrush}}"
BorderBrush="#3fb950" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DockPanel>
</Border>
<!-- Links + Logs split -->
<Grid Grid.Row="1" ColumnDefinitions="350,*">
<!-- Left: Trade Links -->
<Border Grid.Column="0" Background="#161b22" BorderBrush="#30363d"
BorderThickness="1" CornerRadius="8" Padding="10" Margin="0,0,8,0">
<DockPanel>
<TextBlock DockPanel.Dock="Top" Text="TRADE LINKS"
FontSize="11" FontWeight="SemiBold" Foreground="#8b949e"
Margin="0,0,0,8" />
<!-- Add link form -->
<StackPanel DockPanel.Dock="Top" Spacing="6" Margin="0,0,0,8">
<TextBox Text="{Binding NewLinkName}" Watermark="Name (optional)" />
<TextBox Text="{Binding NewUrl}" Watermark="Paste trade URL..." />
<StackPanel Orientation="Horizontal" Spacing="6">
<ComboBox ItemsSource="{x:Static vm:MainWindowViewModel.LinkModes}"
SelectedItem="{Binding NewLinkMode}" Width="100" />
<Button Content="Add" Command="{Binding AddLinkCommand}" />
</StackPanel>
</StackPanel>
<!-- Links list -->
<ScrollViewer>
<ItemsControl ItemsSource="{Binding Links}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Margin="0,2" Padding="8" Background="#21262d"
CornerRadius="4"
Opacity="{Binding Active, Converter={StaticResource ActiveOpacity}}">
<DockPanel>
<Button DockPanel.Dock="Right" Content="X" FontSize="10"
VerticalAlignment="Center"
Command="{Binding $parent[ItemsControl].((vm:MainWindowViewModel)DataContext).RemoveLinkCommand}"
CommandParameter="{Binding Id}" />
<CheckBox DockPanel.Dock="Left"
IsChecked="{Binding Active}"
Margin="0,0,8,0" VerticalAlignment="Center" />
<StackPanel>
<StackPanel Orientation="Horizontal" Spacing="6">
<Border Background="{Binding Mode, Converter={StaticResource ModeBrush}}"
CornerRadius="4" Padding="6,2">
<TextBlock Text="{Binding Mode}"
FontSize="10" FontWeight="Bold"
Foreground="White" />
</Border>
<TextBlock Text="{Binding Name}" FontSize="12"
FontWeight="SemiBold" Foreground="#e6edf3" />
</StackPanel>
<TextBlock Text="{Binding Label}" FontSize="10"
Foreground="#8b949e" TextTrimming="CharacterEllipsis" />
</StackPanel>
</DockPanel>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</DockPanel>
</Border>
<!-- Right: Logs -->
<Border Grid.Column="1" Background="#161b22" BorderBrush="#30363d"
BorderThickness="1" CornerRadius="8" Padding="10">
<DockPanel>
<TextBlock DockPanel.Dock="Top" Text="ACTIVITY LOG"
FontSize="11" FontWeight="SemiBold" Foreground="#8b949e"
Margin="0,0,0,8" />
<ListBox ItemsSource="{Binding Logs}" x:Name="LogList"
Background="Transparent" BorderThickness="0">
<ListBox.ItemTemplate>
<DataTemplate x:DataType="vm:LogEntry">
<StackPanel Orientation="Horizontal" Spacing="8">
<TextBlock Text="{Binding Time}" Foreground="#484f58"
FontSize="11" FontFamily="Consolas" />
<TextBlock Text="{Binding Message}" FontSize="11"
FontFamily="Consolas" TextWrapping="Wrap"
Foreground="{Binding Level, Converter={StaticResource LogLevelBrush}}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</DockPanel>
</Border>
</Grid>
</Grid>
</TabItem>
<!-- ========== DEBUG TAB ========== -->
<TabItem Header="Debug">
<ScrollViewer DataContext="{Binding DebugVm}" Margin="0,8,0,0">
<StackPanel Spacing="12" Margin="8" x:DataType="vm:DebugViewModel">
<!-- Row 1: Quick actions -->
<Border Background="#161b22" BorderBrush="#30363d" BorderThickness="1"
CornerRadius="8" Padding="12">
<StackPanel Spacing="8">
<TextBlock Text="QUICK ACTIONS" FontSize="11" FontWeight="SemiBold"
Foreground="#8b949e" />
<StackPanel Orientation="Horizontal" Spacing="8">
<Button Content="Screenshot" Command="{Binding TakeScreenshotCommand}" />
<Button Content="OCR Screen" Command="{Binding RunOcrCommand}" />
<Button Content="Go Hideout" Command="{Binding GoHideoutCommand}" />
</StackPanel>
<StackPanel Orientation="Horizontal" Spacing="8">
<Button Content="ANGE" Command="{Binding ClickAngeCommand}" />
<Button Content="STASH" Command="{Binding ClickStashCommand}" />
<Button Content="SALVAGE" Command="{Binding ClickSalvageCommand}" />
</StackPanel>
</StackPanel>
</Border>
<!-- Row 2: Find text -->
<Border Background="#161b22" BorderBrush="#30363d" BorderThickness="1"
CornerRadius="8" Padding="12">
<StackPanel Spacing="8">
<TextBlock Text="FIND TEXT" FontSize="11" FontWeight="SemiBold"
Foreground="#8b949e" />
<StackPanel Orientation="Horizontal" Spacing="8">
<TextBox Text="{Binding FindText}" Watermark="Text to find..."
Width="300" />
<Button Content="Find" Command="{Binding FindTextOnScreenCommand}" />
<Button Content="Find &amp; Click" Command="{Binding FindAndClickCommand}" />
</StackPanel>
</StackPanel>
</Border>
<!-- Row 3: Grid scan -->
<Border Background="#161b22" BorderBrush="#30363d" BorderThickness="1"
CornerRadius="8" Padding="12">
<StackPanel Spacing="8">
<TextBlock Text="GRID SCAN" FontSize="11" FontWeight="SemiBold"
Foreground="#8b949e" />
<StackPanel Orientation="Horizontal" Spacing="8">
<ComboBox ItemsSource="{Binding GridLayoutNames}"
SelectedItem="{Binding SelectedGridLayout}" Width="160" />
<Button Content="Scan" Command="{Binding ScanGridCommand}" />
</StackPanel>
</StackPanel>
</Border>
<!-- Row 4: Click At -->
<Border Background="#161b22" BorderBrush="#30363d" BorderThickness="1"
CornerRadius="8" Padding="12">
<StackPanel Spacing="8">
<TextBlock Text="CLICK AT POSITION" FontSize="11" FontWeight="SemiBold"
Foreground="#8b949e" />
<StackPanel Orientation="Horizontal" Spacing="8">
<NumericUpDown Value="{Binding ClickX}" Watermark="X"
Width="100" Minimum="0" Maximum="2560" />
<NumericUpDown Value="{Binding ClickY}" Watermark="Y"
Width="100" Minimum="0" Maximum="1440" />
<Button Content="Click" Command="{Binding ClickAtCommand}" />
</StackPanel>
</StackPanel>
</Border>
<!-- Debug result output -->
<Border Background="#161b22" BorderBrush="#30363d" BorderThickness="1"
CornerRadius="8" Padding="12" MinHeight="60">
<StackPanel>
<TextBlock Text="OUTPUT" FontSize="11" FontWeight="SemiBold"
Foreground="#8b949e" Margin="0,0,0,6" />
<TextBlock Text="{Binding DebugResult}" FontFamily="Consolas"
FontSize="11" Foreground="#e6edf3" TextWrapping="Wrap" />
</StackPanel>
</Border>
</StackPanel>
</ScrollViewer>
</TabItem>
<!-- ========== SETTINGS TAB ========== -->
<TabItem Header="Settings">
<ScrollViewer DataContext="{Binding SettingsVm}" Margin="0,8,0,0">
<StackPanel Spacing="12" Margin="8" MaxWidth="600"
x:DataType="vm:SettingsViewModel">
<Border Background="#161b22" BorderBrush="#30363d" BorderThickness="1"
CornerRadius="8" Padding="16">
<StackPanel Spacing="12">
<TextBlock Text="GENERAL SETTINGS" FontSize="11" FontWeight="SemiBold"
Foreground="#8b949e" />
<StackPanel Spacing="4">
<TextBlock Text="POE2 Client.txt Path" FontSize="11" Foreground="#8b949e" />
<TextBox Text="{Binding Poe2LogPath}" />
</StackPanel>
<StackPanel Spacing="4">
<TextBlock Text="Window Title" FontSize="11" Foreground="#8b949e" />
<TextBox Text="{Binding WindowTitle}" />
</StackPanel>
<Grid ColumnDefinitions="*,*" RowDefinitions="Auto,Auto">
<StackPanel Grid.Row="0" Grid.Column="0" Spacing="4" Margin="0,0,6,8">
<TextBlock Text="Travel Timeout (ms)" FontSize="11" Foreground="#8b949e" />
<NumericUpDown Value="{Binding TravelTimeoutMs}" Minimum="1000"
Maximum="60000" Increment="1000" />
</StackPanel>
<StackPanel Grid.Row="0" Grid.Column="1" Spacing="4" Margin="6,0,0,8">
<TextBlock Text="Stash Scan Timeout (ms)" FontSize="11" Foreground="#8b949e" />
<NumericUpDown Value="{Binding StashScanTimeoutMs}" Minimum="1000"
Maximum="60000" Increment="1000" />
</StackPanel>
<StackPanel Grid.Row="1" Grid.Column="0" Spacing="4" Margin="0,0,6,0">
<TextBlock Text="Wait for More Items (ms)" FontSize="11" Foreground="#8b949e" />
<NumericUpDown Value="{Binding WaitForMoreItemsMs}" Minimum="1000"
Maximum="120000" Increment="1000" />
</StackPanel>
<StackPanel Grid.Row="1" Grid.Column="1" Spacing="4" Margin="6,0,0,0">
<TextBlock Text="Delay Between Trades (ms)" FontSize="11" Foreground="#8b949e" />
<NumericUpDown Value="{Binding BetweenTradesDelayMs}" Minimum="0"
Maximum="60000" Increment="1000" />
</StackPanel>
</Grid>
<StackPanel Orientation="Horizontal" Spacing="8" Margin="0,4,0,0">
<Button Content="Save Settings" Command="{Binding SaveSettingsCommand}" />
<TextBlock Text="Saved!" Foreground="#3fb950" VerticalAlignment="Center"
IsVisible="{Binding IsSaved}" FontWeight="SemiBold" />
</StackPanel>
</StackPanel>
</Border>
</StackPanel>
</ScrollViewer>
</TabItem>
</TabControl>
</DockPanel>
</Window>

View file

@ -0,0 +1,69 @@
using System.Collections.Specialized;
using Avalonia;
using Avalonia.Controls;
using Poe2Trade.Core;
using Poe2Trade.Ui.ViewModels;
namespace Poe2Trade.Ui.Views;
public partial class MainWindow : Window
{
private ConfigStore? _store;
public MainWindow()
{
InitializeComponent();
}
public void SetConfigStore(ConfigStore store)
{
_store = store;
var s = store.Settings;
if (s.WindowWidth.HasValue && s.WindowHeight.HasValue)
{
Width = s.WindowWidth.Value;
Height = s.WindowHeight.Value;
}
if (s.WindowX.HasValue && s.WindowY.HasValue)
{
Position = new PixelPoint((int)s.WindowX.Value, (int)s.WindowY.Value);
WindowStartupLocation = WindowStartupLocation.Manual;
}
else
{
WindowStartupLocation = WindowStartupLocation.CenterScreen;
}
}
protected override void OnDataContextChanged(EventArgs e)
{
base.OnDataContextChanged(e);
if (DataContext is MainWindowViewModel vm)
{
vm.Logs.CollectionChanged += (_, args) =>
{
if (args.Action == NotifyCollectionChangedAction.Add)
{
var logList = this.FindControl<ListBox>("LogList");
if (logList != null && vm.Logs.Count > 0)
logList.ScrollIntoView(vm.Logs[^1]);
}
};
}
}
protected override void OnClosing(WindowClosingEventArgs e)
{
if (_store != null)
{
_store.UpdateSettings(s =>
{
s.WindowX = Position.X;
s.WindowY = Position.Y;
s.WindowWidth = Width;
s.WindowHeight = Height;
});
}
base.OnClosing(e);
}
}