Aggiornamento alla versione 4.0.0
- Aggiunta dipendenza per WebView2 per integrare un browser. - Introdotto layout a schede (TabControl) per organizzare le funzionalità. - Aggiunto browser WebView2 per navigazione e aggiunta aste. - Implementata gestione delle impostazioni di esportazione (CSV, JSON, XML). - Aggiunta funzionalità di caricamento e analisi delle aste chiuse. - Introdotta gestione dei cookie di sessione tramite la scheda "Impostazioni". - Creato controllo personalizzato `SimpleToolbar` per layout modulare. - Migliorata gestione dello stato utente e fallback per dati mancanti. - Rimossi stili e animazioni obsolete per semplificare il codice. - Salvate le impostazioni utente in un file JSON locale. - Correzioni di bug e miglioramenti di leggibilità del codice.
This commit is contained in:
@@ -23,6 +23,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.1343.22" />
|
||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26100.6584" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
16
Mimante/Controls/SimpleToolbar.xaml
Normal file
16
Mimante/Controls/SimpleToolbar.xaml
Normal file
@@ -0,0 +1,16 @@
|
||||
<UserControl x:Class="AutoBidder.Controls.SimpleToolbar"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="48" d:DesignWidth="800">
|
||||
<Grid Background="Transparent">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<ContentPresenter Content="{Binding LeftContent, RelativeSource={RelativeSource AncestorType=UserControl}}" VerticalAlignment="Center" />
|
||||
<ContentPresenter Grid.Column="1" Content="{Binding RightContent, RelativeSource={RelativeSource AncestorType=UserControl}}" VerticalAlignment="Center" />
|
||||
</Grid>
|
||||
</UserControl>
|
||||
28
Mimante/Controls/SimpleToolbar.xaml.cs
Normal file
28
Mimante/Controls/SimpleToolbar.xaml.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace AutoBidder.Controls
|
||||
{
|
||||
public partial class SimpleToolbar : UserControl
|
||||
{
|
||||
public static readonly DependencyProperty LeftContentProperty = DependencyProperty.Register("LeftContent", typeof(object), typeof(SimpleToolbar));
|
||||
public static readonly DependencyProperty RightContentProperty = DependencyProperty.Register("RightContent", typeof(object), typeof(SimpleToolbar));
|
||||
|
||||
public object? LeftContent
|
||||
{
|
||||
get => GetValue(LeftContentProperty);
|
||||
set => SetValue(LeftContentProperty, value);
|
||||
}
|
||||
|
||||
public object? RightContent
|
||||
{
|
||||
get => GetValue(RightContentProperty);
|
||||
set => SetValue(RightContentProperty, value);
|
||||
}
|
||||
|
||||
public SimpleToolbar()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
<Window x:Class="AutoBidder.Dialogs.AddAuctionSimpleDialog"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:controls="clr-namespace:AutoBidder.Controls"
|
||||
Title="Aggiungi Asta" Height="320" Width="700"
|
||||
Background="#0a0a0a" Foreground="#FFFFFF"
|
||||
WindowStartupLocation="CenterOwner"
|
||||
@@ -24,12 +25,16 @@
|
||||
Padding="8" FontSize="13" ToolTip="Inserisci uno o più URL/ID dell'asta. Separali con a capo, spazio o ';'"
|
||||
AcceptsReturn="True" TextWrapping="Wrap" VerticalScrollBarVisibility="Auto" Height="160" />
|
||||
|
||||
<StackPanel Grid.Row="3" Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,8,0,0">
|
||||
<Button x:Name="OkButton" Content="OK" Width="110" Margin="6" Padding="10,8"
|
||||
<controls:SimpleToolbar Grid.Row="3" Margin="0,8,0,0">
|
||||
<controls:SimpleToolbar.RightContent>
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
|
||||
<Button Content="OK" Width="110" Margin="6" Padding="10,8"
|
||||
Style="{StaticResource SmallButtonStyle}" Background="#00CC66" Foreground="White" Click="OkButton_Click" />
|
||||
<Button x:Name="CancelButton" Content="Annulla" Width="110" Margin="6" Padding="10,8"
|
||||
<Button Content="Annulla" Width="110" Margin="6" Padding="10,8"
|
||||
Style="{StaticResource SmallButtonStyle}" Background="#666" Foreground="White" Click="CancelButton_Click" />
|
||||
</StackPanel>
|
||||
</controls:SimpleToolbar.RightContent>
|
||||
</controls:SimpleToolbar>
|
||||
</Grid>
|
||||
</Border>
|
||||
</Window>
|
||||
@@ -1,23 +1,25 @@
|
||||
<Window x:Class="AutoBidder.MainWindow"
|
||||
<Window x:Class="AutoBidder.MainWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
Title="AutoBidder v3.0" Height="800" Width="1400"
|
||||
xmlns:wv2="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf"
|
||||
Title="AutoBidder v4.0" Height="800" Width="1400"
|
||||
Background="#0a0a0a" Foreground="#FFFFFF"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
Icon="pack://application:,,,/Icon/favicon.ico">
|
||||
Icon="pack://application:,,,/Icon/favicon.ico"
|
||||
Loaded="Window_Loaded">
|
||||
<Window.Resources>
|
||||
<!-- Stile pulsanti stile vecchia versione -->
|
||||
<Style x:Key="MainButtonStyle" TargetType="Button">
|
||||
<!-- Stili pulsanti -->
|
||||
<Style x:Key="SmallButtonStyle" TargetType="Button">
|
||||
<Setter Property="Foreground" Value="White" />
|
||||
<Setter Property="FontWeight" Value="Bold" />
|
||||
<Setter Property="FontSize" Value="14" />
|
||||
<Setter Property="FontSize" Value="12" />
|
||||
<Setter Property="BorderThickness" Value="0" />
|
||||
<Setter Property="Cursor" Value="Hand" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Button">
|
||||
<Border Background="{TemplateBinding Background}"
|
||||
CornerRadius="8"
|
||||
CornerRadius="6"
|
||||
Padding="{TemplateBinding Padding}">
|
||||
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
|
||||
</Border>
|
||||
@@ -26,7 +28,7 @@
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!-- Grid action button styles (enable/opacity based on auction state) -->
|
||||
<!-- Grid action button styles -->
|
||||
<Style x:Key="GridStartButtonStyle" TargetType="Button" BasedOn="{StaticResource SmallButtonStyle}">
|
||||
<Setter Property="IsEnabled" Value="True" />
|
||||
<Setter Property="Opacity" Value="1" />
|
||||
@@ -39,22 +41,6 @@
|
||||
<Setter Property="IsEnabled" Value="False" />
|
||||
<Setter Property="Opacity" Value="0.5" />
|
||||
</MultiDataTrigger>
|
||||
<Trigger Property="IsEnabled" Value="False">
|
||||
<Trigger.EnterActions>
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<DoubleAnimation Storyboard.TargetProperty="Opacity" To="0.5" Duration="0:0:0.15" />
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</Trigger.EnterActions>
|
||||
<Trigger.ExitActions>
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<DoubleAnimation Storyboard.TargetProperty="Opacity" To="1" Duration="0:0:0.15" />
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</Trigger.ExitActions>
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
|
||||
@@ -70,22 +56,6 @@
|
||||
<Setter Property="IsEnabled" Value="True" />
|
||||
<Setter Property="Opacity" Value="1" />
|
||||
</MultiDataTrigger>
|
||||
<Trigger Property="IsEnabled" Value="False">
|
||||
<Trigger.EnterActions>
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<DoubleAnimation Storyboard.TargetProperty="Opacity" To="0.5" Duration="0:0:0.15" />
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</Trigger.EnterActions>
|
||||
<Trigger.ExitActions>
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<DoubleAnimation Storyboard.TargetProperty="Opacity" To="1" Duration="0:0:0.15" />
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</Trigger.ExitActions>
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
|
||||
@@ -97,22 +67,6 @@
|
||||
<Setter Property="IsEnabled" Value="True" />
|
||||
<Setter Property="Opacity" Value="1" />
|
||||
</DataTrigger>
|
||||
<Trigger Property="IsEnabled" Value="False">
|
||||
<Trigger.EnterActions>
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<DoubleAnimation Storyboard.TargetProperty="Opacity" To="0.5" Duration="0:0:0.15" />
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</Trigger.EnterActions>
|
||||
<Trigger.ExitActions>
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<DoubleAnimation Storyboard.TargetProperty="Opacity" To="1" Duration="0:0:0.15" />
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</Trigger.ExitActions>
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
|
||||
@@ -128,27 +82,51 @@
|
||||
<Setter Property="IsEnabled" Value="True" />
|
||||
<Setter Property="Opacity" Value="1" />
|
||||
</MultiDataTrigger>
|
||||
<Trigger Property="IsEnabled" Value="False">
|
||||
<Trigger.EnterActions>
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<DoubleAnimation Storyboard.TargetProperty="Opacity" To="0.5" Duration="0:0:0.15" />
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</Trigger.EnterActions>
|
||||
<Trigger.ExitActions>
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<DoubleAnimation Storyboard.TargetProperty="Opacity" To="1" Duration="0:0:0.15" />
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</Trigger.ExitActions>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
|
||||
<!-- Vertical Tab Header Style -->
|
||||
<Style x:Key="VerticalTabHeaderStyle" TargetType="Border">
|
||||
<Setter Property="Background" Value="#1a1a1a" />
|
||||
<Setter Property="BorderThickness" Value="0,0,0,1" />
|
||||
<Setter Property="BorderBrush" Value="#333333" />
|
||||
<Setter Property="Padding" Value="12,16" />
|
||||
<Setter Property="Cursor" Value="Hand" />
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter Property="Background" Value="#2a2a2a" />
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
|
||||
<!-- TabControl vertical style -->
|
||||
<Style x:Key="VerticalTabControlStyle" TargetType="TabControl">
|
||||
<Setter Property="TabStripPlacement" Value="Left" />
|
||||
<Setter Property="Background" Value="#0a0a0a" />
|
||||
<Setter Property="BorderThickness" Value="0" />
|
||||
</Style>
|
||||
|
||||
</Window.Resources>
|
||||
|
||||
<Grid Margin="0" Background="#0a0a0a">
|
||||
<!-- TAB NAVIGATION (Vertical Sidebar) -->
|
||||
<TabControl x:Name="MainTabControl" Style="{StaticResource VerticalTabControlStyle}">
|
||||
|
||||
<!-- TAB 1: ASTE ATTIVE -->
|
||||
<TabItem>
|
||||
<TabItem.Header>
|
||||
<Border Style="{StaticResource VerticalTabHeaderStyle}" Width="160">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="📊" FontSize="20" Margin="0,0,12,0" />
|
||||
<StackPanel>
|
||||
<TextBlock Text="Aste Attive" FontWeight="Bold" FontSize="13" Foreground="#00CC66" />
|
||||
<TextBlock Text="Monitoraggio" FontSize="10" Foreground="#999" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</TabItem.Header>
|
||||
<TabItem.Content>
|
||||
<!-- EXISTING MAIN WINDOW CONTENT -->
|
||||
<Grid Margin="12" Background="#0a0a0a">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
@@ -186,10 +164,8 @@
|
||||
Style="{StaticResource SmallButtonStyle}"
|
||||
Background="#8B5CF6" Padding="20,10" Margin="0,0,6,0" Height="40" MinWidth="110" />
|
||||
|
||||
<!-- separator between Config and action group -->
|
||||
<Border Width="2" Height="36" Background="#333333" Margin="12,0" VerticalAlignment="Center" CornerRadius="2" />
|
||||
|
||||
<!-- Group: Start / Pause / Stop -->
|
||||
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
|
||||
<Button x:Name="StartButton" Content="Avvia Tutti" Command="{Binding StartAllCommand}" IsEnabled="False"
|
||||
Style="{StaticResource SmallButtonStyle}"
|
||||
@@ -201,24 +177,10 @@
|
||||
Style="{StaticResource SmallButtonStyle}"
|
||||
Background="#CC0000" Padding="20,10" Opacity="0.5" Height="40" MinWidth="110" />
|
||||
</StackPanel>
|
||||
|
||||
<!-- separator graphic -->
|
||||
<Border Width="2" Height="36" Background="#333333" Margin="12,0" VerticalAlignment="Center" CornerRadius="2" />
|
||||
|
||||
<!-- Group: Closed auctions + Free bids (free bids disabled for now) -->
|
||||
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
|
||||
<Button x:Name="ClosedAuctionsButton" Content="Aste Chiuse" Click="OpenClosedAuctionsButton_Click"
|
||||
Style="{StaticResource SmallButtonStyle}"
|
||||
Background="#0099FF" Padding="20,10" Margin="0,0,6,0" Height="40" MinWidth="120" />
|
||||
<Button x:Name="FreeBidsButton" Content="Puntate Gratis" IsEnabled="False" ToolTip="Funzionalita in sviluppo"
|
||||
Style="{StaticResource SmallButtonStyle}"
|
||||
Background="#666" Padding="20,10" Height="40" MinWidth="140" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<!-- Riga vuota (toolbar rimossa) -->
|
||||
<Grid Grid.Row="1" Height="0" />
|
||||
|
||||
<!-- Griglia Aste + Log -->
|
||||
@@ -237,7 +199,6 @@
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- Header con titolo e pulsanti -->
|
||||
<Grid Grid.Row="0" Margin="0,0,0,12">
|
||||
<TextBlock x:Name="MonitorateTitle" Text="Aste monitorate: 0" FontSize="14" FontWeight="Bold" Foreground="#00CC66" VerticalAlignment="Center" />
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
|
||||
@@ -267,7 +228,6 @@
|
||||
<Style TargetType="DataGridRow">
|
||||
<Setter Property="Height" Value="36" />
|
||||
<Style.Triggers>
|
||||
<!-- Colore basato sullo stato dell'asta -->
|
||||
<DataTrigger Binding="{Binding StatusDisplay}" Value="VINTA">
|
||||
<Setter Property="Background" Value="#1B5E20" />
|
||||
<Setter Property="Foreground" Value="#FFFFFF" />
|
||||
@@ -287,7 +247,6 @@
|
||||
<Setter Property="Background" Value="#424242" />
|
||||
<Setter Property="Foreground" Value="#AAAAAA" />
|
||||
</DataTrigger>
|
||||
<!-- Override quando selezionata -->
|
||||
<Trigger Property="IsSelected" Value="True">
|
||||
<Setter Property="Background" Value="#0099FF" />
|
||||
<Setter Property="Foreground" Value="White" />
|
||||
@@ -348,7 +307,7 @@
|
||||
|
||||
<GridSplitter Grid.Row="3" Height="8" HorizontalAlignment="Stretch" Background="#333333" />
|
||||
|
||||
<!-- Dettagli Asta Selezionata - 3 Pannelli Affiancati -->
|
||||
<!-- Dettagli Asta Selezionata -->
|
||||
<Border Grid.Row="4" Background="#1a1a1a" Padding="8" CornerRadius="6" BorderBrush="#333333" BorderThickness="1">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
@@ -368,18 +327,15 @@
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- Header -->
|
||||
<Grid Grid.Row="0" Margin="0,0,0,12">
|
||||
<TextBlock Text="Impostazioni" FontSize="13" FontWeight="Bold" Foreground="#00CC66" VerticalAlignment="Center" />
|
||||
</Grid>
|
||||
|
||||
<!-- Nome Asta -->
|
||||
<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto">
|
||||
<StackPanel>
|
||||
<TextBlock x:Name="SelectedAuctionName" Text="Seleziona un'asta dalla griglia"
|
||||
FontSize="12" FontWeight="SemiBold" Foreground="#FFFFFF" TextWrapping="Wrap" Margin="0,0,0,16" />
|
||||
|
||||
<!-- Link asta e pulsanti -->
|
||||
<Grid Margin="0,0,0,12">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
@@ -442,7 +398,6 @@
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
|
||||
<!-- Reset Button -->
|
||||
<Button Grid.Row="2" x:Name="ResetSettingsButton" Content="Reset Impostazioni" Click="ResetSettingsButton_Click"
|
||||
Style="{StaticResource SmallButtonStyle}" IsEnabled="False"
|
||||
Background="#666" Padding="10,8" Height="32" FontSize="11" Margin="0,8,0,0" />
|
||||
@@ -533,4 +488,303 @@
|
||||
</Grid>
|
||||
</Border>
|
||||
</Grid>
|
||||
</TabItem.Content>
|
||||
</TabItem>
|
||||
|
||||
<!-- TAB 2: BROWSER -->
|
||||
<TabItem>
|
||||
<TabItem.Header>
|
||||
<Border Style="{StaticResource VerticalTabHeaderStyle}" Width="160">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="🌐" FontSize="20" Margin="0,0,12,0" />
|
||||
<StackPanel>
|
||||
<TextBlock Text="Browser" FontWeight="Bold" FontSize="13" Foreground="#0099FF" />
|
||||
<TextBlock Text="Navigazione" FontSize="10" Foreground="#999" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</TabItem.Header>
|
||||
<TabItem.Content>
|
||||
<Grid Margin="12" Background="#0a0a0a">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- Browser Toolbar -->
|
||||
<Border Grid.Row="0" Background="#1a1a1a" Padding="12" CornerRadius="8" Margin="0,0,0,12">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- Navigation Buttons -->
|
||||
<StackPanel Grid.Column="0" Orientation="Horizontal" Margin="0,0,12,0">
|
||||
<Button x:Name="BrowserBackButton" Content="◀︎" Click="BrowserBackButton_Click"
|
||||
Style="{StaticResource SmallButtonStyle}" Background="#666"
|
||||
Padding="12,8" Margin="0,0,4,0" Height="36" MinWidth="40" />
|
||||
<Button x:Name="BrowserForwardButton" Content="▶︎" Click="BrowserForwardButton_Click"
|
||||
Style="{StaticResource SmallButtonStyle}" Background="#666"
|
||||
Padding="12,8" Margin="0,0,4,0" Height="36" MinWidth="40" />
|
||||
<Button x:Name="BrowserRefreshButton" Content="⟳" Click="BrowserRefreshButton_Click"
|
||||
Style="{StaticResource SmallButtonStyle}" Background="#666"
|
||||
Padding="12,8" Margin="0,0,4,0" Height="36" MinWidth="40" />
|
||||
<Button x:Name="BrowserHomeButton" Content="🏠" Click="BrowserHomeButton_Click"
|
||||
Style="{StaticResource SmallButtonStyle}" Background="#00CC66"
|
||||
Padding="12,8" Height="36" MinWidth="40" />
|
||||
</StackPanel>
|
||||
|
||||
<!-- Address Bar -->
|
||||
<TextBox x:Name="BrowserAddress" Grid.Column="1" Text="https://it.bidoo.com/"
|
||||
Background="#0f0f0f" Foreground="#FFFFFF"
|
||||
Padding="12,8" FontSize="13" BorderBrush="#333" BorderThickness="1"
|
||||
VerticalAlignment="Center" Margin="0,0,12,0" />
|
||||
|
||||
<!-- Action Buttons -->
|
||||
<StackPanel Grid.Column="2" Orientation="Horizontal">
|
||||
<Button x:Name="BrowserGoButton" Content="Vai" Click="BrowserGoButton_Click"
|
||||
Style="{StaticResource SmallButtonStyle}" Background="#0099FF"
|
||||
Padding="16,8" Margin="0,0,8,0" Height="36" MinWidth="70" />
|
||||
<Button x:Name="BrowserAddAuctionButton" Content="+ Aggiungi Asta" Click="BrowserAddAuctionButton_Click"
|
||||
Style="{StaticResource SmallButtonStyle}" Background="#00CC66"
|
||||
Padding="16,8" Height="36" MinWidth="140" IsEnabled="False" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<!-- WebView2 Browser -->
|
||||
<Border Grid.Row="1" Background="#0f0f0f" BorderBrush="#333333" BorderThickness="1" CornerRadius="6">
|
||||
<wv2:WebView2 x:Name="EmbeddedWebView"
|
||||
Source="https://it.bidoo.com/"
|
||||
NavigationStarting="EmbeddedWebView_NavigationStarting"
|
||||
NavigationCompleted="EmbeddedWebView_NavigationCompleted" />
|
||||
</Border>
|
||||
</Grid>
|
||||
</TabItem.Content>
|
||||
</TabItem>
|
||||
|
||||
<!-- TAB 3: PUNTATE GRATIS (DISABLED) -->
|
||||
<TabItem IsEnabled="False">
|
||||
<TabItem.Header>
|
||||
<Border Style="{StaticResource VerticalTabHeaderStyle}" Width="160" Background="#424242">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="🎁" FontSize="20" Margin="0,0,12,0" Opacity="0.5" />
|
||||
<StackPanel>
|
||||
<TextBlock Text="Puntate Gratis" FontWeight="Bold" FontSize="13" Foreground="#999" />
|
||||
<TextBlock Text="In sviluppo" FontSize="10" Foreground="#666" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</TabItem.Header>
|
||||
<TabItem.Content>
|
||||
<Grid Margin="12" Background="#0a0a0a">
|
||||
<Border Background="#1a1a1a" Padding="40" CornerRadius="8" BorderBrush="#333333" BorderThickness="1"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||
<StackPanel HorizontalAlignment="Center">
|
||||
<TextBlock Text="🎁" FontSize="60" HorizontalAlignment="Center" Margin="0,0,0,20" Opacity="0.3" />
|
||||
<TextBlock Text="Puntate Gratis" FontSize="20" FontWeight="Bold"
|
||||
Foreground="#999" HorizontalAlignment="Center" Margin="0,0,0,8" />
|
||||
<TextBlock Text="Questa funzione è attualmente in sviluppo" FontSize="14"
|
||||
Foreground="#666" HorizontalAlignment="Center" />
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Grid>
|
||||
</TabItem.Content>
|
||||
</TabItem>
|
||||
|
||||
<!-- TAB 4: DATI STATISTICI -->
|
||||
<TabItem>
|
||||
<TabItem.Header>
|
||||
<Border Style="{StaticResource VerticalTabHeaderStyle}" Width="160">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="📈" FontSize="20" Margin="0,0,12,0" />
|
||||
<StackPanel>
|
||||
<TextBlock Text="Dati Statistici" FontWeight="Bold" FontSize="13" Foreground="#FF9933" />
|
||||
<TextBlock Text="Analisi" FontSize="10" Foreground="#999" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</TabItem.Header>
|
||||
<TabItem.Content>
|
||||
<Grid Margin="12" Background="#0a0a0a">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- Header -->
|
||||
<Border Grid.Row="0" Background="#1a1a1a" Padding="12" CornerRadius="8" Margin="0,0,0,12">
|
||||
<Grid>
|
||||
<TextBlock Text="Statistiche Aste Chiuse" FontSize="18" FontWeight="Bold" Foreground="#FF9933" VerticalAlignment="Center" />
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
|
||||
<Button x:Name="LoadClosedAuctionsButton" Content="📥 Carica Aste Chiuse" Click="LoadClosedAuctionsButton_Click"
|
||||
Style="{StaticResource SmallButtonStyle}" Background="#0099FF"
|
||||
Padding="16,10" Height="40" MinWidth="180" Margin="0,0,8,0" />
|
||||
<Button x:Name="ExportStatsButton" Content="📊 Esporta Statistiche" Click="ExportStatsButton_Click"
|
||||
Style="{StaticResource SmallButtonStyle}" Background="#00CC66"
|
||||
Padding="16,10" Height="40" MinWidth="180" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<!-- Data Grid for Statistics -->
|
||||
<Border Grid.Row="1" Background="#1a1a1a" Padding="12" CornerRadius="6" BorderBrush="#333333" BorderThickness="1">
|
||||
<DataGrid x:Name="StatsDataGrid" AutoGenerateColumns="False"
|
||||
Background="#1a1a1a" Foreground="#FFFFFF"
|
||||
BorderBrush="#333333" BorderThickness="0"
|
||||
GridLinesVisibility="Horizontal" HorizontalGridLinesBrush="#333333"
|
||||
RowBackground="#1a1a1a" AlternatingRowBackground="#222222"
|
||||
IsReadOnly="True">
|
||||
<DataGrid.Resources>
|
||||
<Style TargetType="DataGridColumnHeader">
|
||||
<Setter Property="Background" Value="#2a2a2a" />
|
||||
<Setter Property="Foreground" Value="#FFFFFF" />
|
||||
<Setter Property="FontWeight" Value="Bold" />
|
||||
<Setter Property="Padding" Value="10,8" />
|
||||
<Setter Property="BorderThickness" Value="0,0,0,2" />
|
||||
<Setter Property="BorderBrush" Value="#FF9933" />
|
||||
</Style>
|
||||
<Style TargetType="DataGridRow">
|
||||
<Setter Property="Height" Value="32" />
|
||||
</Style>
|
||||
</DataGrid.Resources>
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Header="Prodotto" Binding="{Binding ProductName}" Width="2*" />
|
||||
<DataGridTextColumn Header="Prezzo Finale" Binding="{Binding FinalPrice, StringFormat='{}{0:F2}€'}" Width="120" />
|
||||
<DataGridTextColumn Header="Vincitore" Binding="{Binding Winner}" Width="150" />
|
||||
<DataGridTextColumn Header="Puntate Usate" Binding="{Binding BidsUsed}" Width="120" />
|
||||
<DataGridTextColumn Header="URL Asta" Binding="{Binding AuctionUrl}" Width="*" />
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
</Border>
|
||||
|
||||
<!-- Status Bar -->
|
||||
<Border Grid.Row="2" Background="#1a1a1a" Padding="12" CornerRadius="8" Margin="0,12,0,0">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock x:Name="StatsStatusText" Text="Nessuna statistica caricata"
|
||||
FontSize="12" Foreground="#999" VerticalAlignment="Center" />
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Grid>
|
||||
</TabItem.Content>
|
||||
</TabItem>
|
||||
|
||||
<!-- TAB 5: IMPOSTAZIONI -->
|
||||
<TabItem>
|
||||
<TabItem.Header>
|
||||
<Border Style="{StaticResource VerticalTabHeaderStyle}" Width="160">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="⚙️" FontSize="20" Margin="0,0,12,0" />
|
||||
<StackPanel>
|
||||
<TextBlock Text="Impostazioni" FontWeight="Bold" FontSize="13" Foreground="#8B5CF6" />
|
||||
<TextBlock Text="Configurazione" FontSize="10" Foreground="#999" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</TabItem.Header>
|
||||
<TabItem.Content>
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto">
|
||||
<Grid Margin="12" Background="#0a0a0a">
|
||||
<StackPanel MaxWidth="800">
|
||||
<!-- Cookie Configuration -->
|
||||
<Border Background="#1a1a1a" Padding="20" CornerRadius="8" Margin="0,0,0,16" BorderBrush="#333333" BorderThickness="1">
|
||||
<StackPanel>
|
||||
<TextBlock Text="🔧 Configurazione Cookie" FontSize="16" FontWeight="Bold" Foreground="#8B5CF6" Margin="0,0,0,16" />
|
||||
<TextBlock Text="Cookie di sessione (__stattrb):" FontSize="12" Foreground="#999" Margin="0,0,0,8" />
|
||||
<TextBox x:Name="SettingsCookieTextBox"
|
||||
Background="#0f0f0f" Foreground="#FFFFFF"
|
||||
Padding="12" FontSize="12" BorderBrush="#444" BorderThickness="1"
|
||||
TextWrapping="Wrap" MinHeight="80" Margin="0,0,0,12" />
|
||||
<TextBlock Text="➕ Inserisci il valore del cookie __stattrb dal browser"
|
||||
FontSize="11" Foreground="#666" FontStyle="Italic" Margin="0,0,0,12" />
|
||||
<Button x:Name="SaveCookieButton" Content="Salva Cookie" Click="SaveCookieButton_Click"
|
||||
Style="{StaticResource SmallButtonStyle}" Background="#8B5CF6"
|
||||
Padding="16,10" Height="40" HorizontalAlignment="Left" MinWidth="150" />
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- Export Settings -->
|
||||
<Border Background="#1a1a1a" Padding="20" CornerRadius="8" Margin="0,0,0,16" BorderBrush="#333333" BorderThickness="1">
|
||||
<StackPanel>
|
||||
<TextBlock Text="📤 Impostazioni Esportazione" FontSize="16" FontWeight="Bold" Foreground="#8B5CF6" Margin="0,0,0,16" />
|
||||
|
||||
<!-- Export Path -->
|
||||
<TextBlock Text="Percorso di esportazione:" FontSize="12" Foreground="#999" Margin="0,0,0,8" />
|
||||
<Grid Margin="0,0,0,16">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBox x:Name="ExportPathTextBox" Grid.Column="0"
|
||||
Background="#0f0f0f" Foreground="#FFFFFF"
|
||||
Padding="12" FontSize="12" BorderBrush="#444" BorderThickness="1"
|
||||
Margin="0,0,8,0" />
|
||||
<Button x:Name="ExportBrowseButton" Grid.Column="1" Content="Sfoglia..." Click="ExportBrowseButton_Click"
|
||||
Style="{StaticResource SmallButtonStyle}" Background="#666"
|
||||
Padding="16,10" Height="38" MinWidth="100" />
|
||||
</Grid>
|
||||
|
||||
<!-- File Format -->
|
||||
<TextBlock Text="Formato file:" FontSize="12" Foreground="#999" Margin="0,0,0,8" />
|
||||
<StackPanel Orientation="Horizontal" Margin="0,0,0,16">
|
||||
<RadioButton x:Name="ExtCsv" Content="CSV" Foreground="#FFFFFF" Margin="0,0,20,0" IsChecked="True" />
|
||||
<RadioButton x:Name="ExtJson" Content="JSON" Foreground="#FFFFFF" Margin="0,0,20,0" />
|
||||
<RadioButton x:Name="ExtXml" Content="XML" Foreground="#FFFFFF" />
|
||||
</StackPanel>
|
||||
|
||||
<!-- Export Scope -->
|
||||
<TextBlock Text="Aste da esportare:" FontSize="12" Foreground="#999" Margin="0,0,0,8" />
|
||||
<ComboBox x:Name="ExportScopeCombo"
|
||||
Background="#0f0f0f" Foreground="#FFFFFF"
|
||||
Padding="12,8" FontSize="12" BorderBrush="#444" BorderThickness="1"
|
||||
Margin="0,0,0,16" SelectedIndex="0">
|
||||
<ComboBoxItem Content="Tutte le aste" />
|
||||
<ComboBoxItem Content="Solo aste terminate" />
|
||||
<ComboBoxItem Content="Solo aste sconosciute" />
|
||||
</ComboBox>
|
||||
|
||||
<!-- Data to Include -->
|
||||
<TextBlock Text="Dati da includere:" FontSize="12" Foreground="#999" Margin="0,0,0,8" />
|
||||
<CheckBox x:Name="IncludeOnlyUsedBids" Content="Solo puntate usate e prezzo finale"
|
||||
Foreground="#FFFFFF" Margin="0,0,0,8" IsChecked="True" />
|
||||
<CheckBox x:Name="IncludeLogs" Content="Includi log completo"
|
||||
Foreground="#FFFFFF" Margin="0,0,0,8" />
|
||||
<CheckBox x:Name="IncludeUserBids" Content="Includi puntate singoli utenti"
|
||||
Foreground="#FFFFFF" Margin="0,0,0,16" />
|
||||
|
||||
<!-- Save/Cancel Buttons -->
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Button x:Name="SaveSettingsButton" Content="Salva Impostazioni" Click="SaveSettingsButton_Click"
|
||||
Style="{StaticResource SmallButtonStyle}" Background="#00CC66"
|
||||
Padding="16,10" Height="40" MinWidth="150" Margin="0,0,8,0" />
|
||||
<Button x:Name="CancelSettingsButton" Content="Annulla" Click="CancelSettingsButton_Click"
|
||||
Style="{StaticResource SmallButtonStyle}" Background="#666"
|
||||
Padding="16,10" Height="40" MinWidth="100" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- Progress Indicators (hidden by default) -->
|
||||
<Border x:Name="ExportProgressContainer" Background="#1a1a1a" Padding="20" CornerRadius="8"
|
||||
BorderBrush="#333333" BorderThickness="1" Visibility="Collapsed">
|
||||
<StackPanel>
|
||||
<ProgressBar x:Name="ExportProgressBar" Height="8" Margin="0,0,0,8" />
|
||||
<TextBlock x:Name="ExportProgressText" Text="Esportazione in corso..."
|
||||
FontSize="12" Foreground="#999" HorizontalAlignment="Center" />
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- Toggle Button (collapsed/hidden placeholder) -->
|
||||
<ToggleButton x:Name="ToggleTabsButton" Visibility="Collapsed"
|
||||
Checked="ToggleTabsButton_Checked" Unchecked="ToggleTabsButton_Unchecked" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</ScrollViewer>
|
||||
</TabItem.Content>
|
||||
</TabItem>
|
||||
</TabControl>
|
||||
</Grid>
|
||||
</Window>
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Text.Json;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Net;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
@@ -21,7 +28,7 @@ namespace AutoBidder
|
||||
{
|
||||
// SERVIZI CORE
|
||||
private readonly AuctionMonitor _auctionMonitor;
|
||||
private readonly ObservableCollection<AuctionViewModel> _auctionViewModels = new();
|
||||
private readonly System.Collections.ObjectModel.ObservableCollection<AuctionViewModel> _auctionViewModels = new System.Collections.ObjectModel.ObservableCollection<AuctionViewModel>();
|
||||
// UI State
|
||||
private AuctionViewModel? _selectedAuction;
|
||||
private bool _isAutomationActive = false;
|
||||
@@ -40,6 +47,9 @@ namespace AutoBidder
|
||||
private System.Windows.Threading.DispatcherTimer _userBannerTimer;
|
||||
private System.Windows.Threading.DispatcherTimer _userHtmlTimer;
|
||||
|
||||
// export cancellation
|
||||
private CancellationTokenSource? _exportCts;
|
||||
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
@@ -71,6 +81,9 @@ namespace AutoBidder
|
||||
// Carica aste salvate
|
||||
LoadSavedAuctions();
|
||||
|
||||
// Load export/settings UI
|
||||
LoadExportSettings();
|
||||
|
||||
// Ensure initial global button states (pause/stop disabled until starting)
|
||||
UpdateGlobalControlButtons();
|
||||
|
||||
@@ -1113,6 +1126,196 @@ namespace AutoBidder
|
||||
}
|
||||
}
|
||||
|
||||
// Add LoadExportSettings to initialize UI from saved settings
|
||||
private void LoadExportSettings()
|
||||
{
|
||||
try
|
||||
{
|
||||
var s = Utilities.SettingsManager.Load();
|
||||
if (s != null)
|
||||
{
|
||||
ExportPathTextBox.Text = s.ExportPath ?? string.Empty;
|
||||
if (!string.IsNullOrEmpty(s.LastExportExt))
|
||||
{
|
||||
var ext = s.LastExportExt.ToLowerInvariant();
|
||||
if (ext == ".json") ExtJson.IsChecked = true;
|
||||
else if (ext == ".xml") ExtXml.IsChecked = true;
|
||||
else ExtCsv.IsChecked = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ExtCsv.IsChecked = true;
|
||||
}
|
||||
|
||||
switch (s.ExportScope)
|
||||
{
|
||||
case "Closed": ExportScopeCombo.SelectedIndex =1; break;
|
||||
case "Unknown": ExportScopeCombo.SelectedIndex =2; break;
|
||||
default: ExportScopeCombo.SelectedIndex =0; break;
|
||||
}
|
||||
|
||||
IncludeOnlyUsedBids.IsChecked = s.IncludeOnlyUsedBids;
|
||||
IncludeLogs.IsChecked = s.IncludeLogs;
|
||||
IncludeUserBids.IsChecked = s.IncludeUserBids;
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
finally
|
||||
{
|
||||
try { ExportProgressBar.Visibility = Visibility.Collapsed; ExportProgressText.Visibility = Visibility.Collapsed; } catch { }
|
||||
}
|
||||
}
|
||||
|
||||
// Export all (simple async wrapper)
|
||||
private async void ExportAllButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
var settings = Utilities.SettingsManager.Load();
|
||||
string ext = ExtJson.IsChecked == true ? ".json" : ExtXml.IsChecked == true ? ".xml" : ".csv";
|
||||
var dlg = new Microsoft.Win32.SaveFileDialog() { FileName = "auctions_export" + ext, Filter = "CSV files|*.csv|JSON files|*.json|XML files|*.xml|All files|*.*" };
|
||||
if (dlg.ShowDialog(this) != true) return;
|
||||
var path = dlg.FileName;
|
||||
|
||||
var all = _auctionMonitor.GetAuctions();
|
||||
var selection = all.AsEnumerable();
|
||||
var scope = settings.ExportScope ?? "All";
|
||||
if (scope == "Closed") selection = selection.Where(a => !a.IsActive);
|
||||
else if (scope == "Unknown") selection = selection.Where(a => (a.BidHistory == null || a.BidHistory.Count ==0) && (a.BidderStats == null || a.BidderStats.Count ==0));
|
||||
var list = selection.ToList();
|
||||
if (list.Count ==0)
|
||||
{
|
||||
MessageBox.Show(this, "Nessuna asta da esportare.", "Esporta Aste", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
return;
|
||||
}
|
||||
|
||||
ExportProgressBar.Visibility = Visibility.Visible;
|
||||
ExportProgressText.Visibility = Visibility.Visible;
|
||||
ExportProgressText.Text = "Esportazione in corso...";
|
||||
|
||||
await Task.Run(() =>
|
||||
{
|
||||
if (path.EndsWith(".json", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var json = System.Text.Json.JsonSerializer.Serialize(list, new System.Text.Json.JsonSerializerOptions { WriteIndented = true });
|
||||
System.IO.File.WriteAllText(path, json, System.Text.Encoding.UTF8);
|
||||
}
|
||||
else if (path.EndsWith(".xml", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var doc = new XDocument(new XElement("Auctions",
|
||||
from a in list
|
||||
select new XElement("Auction",
|
||||
new XElement("AuctionId", a.AuctionId),
|
||||
new XElement("Name", a.Name),
|
||||
new XElement("OriginalUrl", a.OriginalUrl ?? string.Empty)
|
||||
)
|
||||
));
|
||||
doc.Save(path);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use existing exporter
|
||||
CsvExporter.ExportAllAuctions(list, path);
|
||||
}
|
||||
});
|
||||
|
||||
try { ExportPreferences.SaveLastExportExtension(System.IO.Path.GetExtension(path)); } catch { }
|
||||
|
||||
MessageBox.Show(this, "Esportazione completata.", "Esporta Aste", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
Log($"[EXPORT] Aste esportate -> {path}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log($"[ERRORE] Esportazione massiva: {ex.Message}");
|
||||
MessageBox.Show(this, "Errore durante esportazione: " + ex.Message, "Esporta Aste", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
finally
|
||||
{
|
||||
ExportProgressBar.Visibility = Visibility.Collapsed;
|
||||
ExportProgressText.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
}
|
||||
|
||||
// Browser handlers (simple)
|
||||
private void BrowserBackButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
try { if (EmbeddedWebView?.CoreWebView2 != null && EmbeddedWebView.CoreWebView2.CanGoBack) EmbeddedWebView.CoreWebView2.GoBack(); } catch { }
|
||||
}
|
||||
private void BrowserForwardButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
try { if (EmbeddedWebView?.CoreWebView2 != null && EmbeddedWebView.CoreWebView2.CanGoForward) EmbeddedWebView.CoreWebView2.GoForward(); } catch { }
|
||||
}
|
||||
private void BrowserRefreshButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
try { EmbeddedWebView?.Reload(); } catch { }
|
||||
}
|
||||
private void BrowserHomeButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
try { EmbeddedWebView?.CoreWebView2?.Navigate("https://it.bidoo.com/"); BrowserAddress.Text = "https://it.bidoo.com/"; } catch { }
|
||||
}
|
||||
private void BrowserGoButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
var url = BrowserAddress.Text?.Trim(); if (string.IsNullOrEmpty(url)) return; if (!url.StartsWith("http", StringComparison.OrdinalIgnoreCase)) url = "https://" + url;
|
||||
EmbeddedWebView?.CoreWebView2?.Navigate(url);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
private void BrowserAddAuctionButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
try { var url = BrowserAddress.Text?.Trim() ?? EmbeddedWebView?.Source?.ToString(); if (!string.IsNullOrEmpty(url)) _ = AddAuctionFromUrl(url); } catch { }
|
||||
}
|
||||
private void BrowserContext_AddAuction_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
try { var url = EmbeddedWebView?.Source?.ToString() ?? BrowserAddress.Text; if (!string.IsNullOrEmpty(url)) _ = AddAuctionFromUrl(url); } catch { }
|
||||
}
|
||||
private void EmbeddedWebView_NavigationStarting(object sender, Microsoft.Web.WebView2.Core.CoreWebView2NavigationStartingEventArgs e)
|
||||
{
|
||||
try { BrowserAddress.Text = e.Uri ?? string.Empty; BrowserAddAuctionButton.IsEnabled = IsValidAuctionUrl(e.Uri ?? string.Empty); } catch { }
|
||||
}
|
||||
private void EmbeddedWebView_NavigationCompleted(object sender, Microsoft.Web.WebView2.Core.CoreWebView2NavigationCompletedEventArgs e)
|
||||
{
|
||||
try { var uri = EmbeddedWebView?.Source?.ToString() ?? BrowserAddress.Text; BrowserAddress.Text = uri; BrowserAddAuctionButton.IsEnabled = IsValidAuctionUrl(uri); } catch { }
|
||||
}
|
||||
|
||||
private void ExportBrowseButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var dlg = new Microsoft.Win32.SaveFileDialog() { FileName = "export.csv", Filter = "CSV files|*.csv|All files|*.*" };
|
||||
if (dlg.ShowDialog(this) == true)
|
||||
{
|
||||
ExportPathTextBox.Text = System.IO.Path.GetDirectoryName(dlg.FileName) ?? string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
private void SaveSettingsButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
var s = new Utilities.AppSettings()
|
||||
{
|
||||
ExportPath = ExportPathTextBox.Text,
|
||||
LastExportExt = ExtJson.IsChecked == true ? ".json" : ExtXml.IsChecked == true ? ".xml" : ".csv",
|
||||
ExportScope = ExportScopeCombo.SelectedIndex ==1 ? "Closed" : ExportScopeCombo.SelectedIndex ==2 ? "Unknown" : "All",
|
||||
IncludeOnlyUsedBids = IncludeOnlyUsedBids.IsChecked == true,
|
||||
IncludeLogs = IncludeLogs.IsChecked == true,
|
||||
IncludeUserBids = IncludeUserBids.IsChecked == true
|
||||
};
|
||||
Utilities.SettingsManager.Save(s);
|
||||
ExportPreferences.SaveLastExportExtension(s.LastExportExt);
|
||||
MessageBox.Show(this, "Impostazioni salvate.", "Salva", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show(this, "Errore salvataggio impostazioni: " + ex.Message, "Errore", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private void CancelSettingsButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
LoadExportSettings();
|
||||
}
|
||||
|
||||
private enum LogLevel { Info, Warn, Error }
|
||||
|
||||
private void Log(string message, LogLevel level = LogLevel.Info)
|
||||
@@ -1170,6 +1373,8 @@ namespace AutoBidder
|
||||
base.OnClosed(e);
|
||||
}
|
||||
|
||||
// NOTE: Window_Loaded and ToggleTabsButton handlers were removed because they forced a fixed
|
||||
// width on `MainTabControl` at runtime, causing the UI to render incorrectly compared to the designer.
|
||||
|
||||
// === HANDLER BOTTONI GRIGLIA ===
|
||||
private void GridOpenAuction_Click(object sender, RoutedEventArgs e)
|
||||
@@ -1321,13 +1526,32 @@ namespace AutoBidder
|
||||
var info = await _auctionMonitor.GetUserBannerInfoAsync();
|
||||
if (info != null)
|
||||
{
|
||||
BannerAsteDaRiscattare.Text = $"{info.nAsteVinte - info.nAsteConfermate}";
|
||||
// BannerPuntateBonus.Text = $"Bonus: {info.nPuntateBonus}"; // RIMOSSO
|
||||
// Map banner info to available UI fields
|
||||
try
|
||||
{
|
||||
// Use nPuntateDaRiscattare if available as remaining bids proxy
|
||||
if (info.nPuntateDaRiscattare >0)
|
||||
{
|
||||
RemainingBidsText.Text = info.nPuntateDaRiscattare.ToString();
|
||||
}
|
||||
else if (info.nPuntateBonus >0)
|
||||
{
|
||||
RemainingBidsText.Text = info.nPuntateBonus.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
BannerAsteDaRiscattare.Text = "--";
|
||||
// BannerPuntateBonus.Text = "Bonus: --"; // RIMOSSO
|
||||
// fallback: show total won minus confirmed if meaningful
|
||||
if (info.nAsteVinte >= info.nAsteConfermate)
|
||||
RemainingBidsText.Text = (info.nAsteVinte - info.nAsteConfermate).ToString();
|
||||
else
|
||||
RemainingBidsText.Text = "--";
|
||||
}
|
||||
}
|
||||
catch { RemainingBidsText.Text = "--"; }
|
||||
}
|
||||
else
|
||||
{
|
||||
RemainingBidsText.Text = "--";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1377,7 +1601,7 @@ namespace AutoBidder
|
||||
{
|
||||
var dlg = new Microsoft.Win32.SaveFileDialog()
|
||||
{
|
||||
Filter = "CSV files|*.csv|JSON files|*.json|XML files|*.xml|All files|*.*",
|
||||
Filter = "CSV files|*.csv|JSON files|*.json|All files|*.*",
|
||||
FileName = $"auction_{_selectedAuction.AuctionId}.csv"
|
||||
};
|
||||
|
||||
@@ -1538,5 +1762,168 @@ namespace AutoBidder
|
||||
if (v == null) return string.Empty;
|
||||
return v.Replace("\"", "\"\"");
|
||||
}
|
||||
|
||||
private void OpenFreeBids_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
try { MainTabControl.SelectedIndex =1; } catch { }
|
||||
}
|
||||
|
||||
private void ExportSelectionButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ExportSelectedAuction_Click(sender, e);
|
||||
}
|
||||
|
||||
// New handlers for Statistics tab
|
||||
private async void LoadClosedAuctionsButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
StatsStatusText.Text = "Caricamento aste chiuse in corso...";
|
||||
Log("[STATS] Avvio caricamento aste chiuse...");
|
||||
|
||||
// Use the existing ClosedAuctionsScraper service
|
||||
var scraper = new Services.ClosedAuctionsScraper(null, null, (msg) => Log($"[SCRAPER] {msg}"));
|
||||
var closedUrl = "https://it.bidoo.com/closed_auctions.php";
|
||||
|
||||
var results = new System.Collections.ObjectModel.ObservableCollection<Models.ClosedAuctionRecord>();
|
||||
|
||||
await foreach (var rec in scraper.ScrapeYieldAsync(closedUrl))
|
||||
{
|
||||
// Filter out records without bids info
|
||||
if (!rec.BidsUsed.HasValue)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
results.Add(rec);
|
||||
StatsStatusText.Text = $"Caricate {results.Count} aste...";
|
||||
}
|
||||
|
||||
StatsDataGrid.ItemsSource = results;
|
||||
StatsStatusText.Text = $"Totale: {results.Count} aste caricate";
|
||||
Log($"[STATS] Caricamento completato: {results.Count} aste");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log($"[ERRORE] Caricamento statistiche: {ex.Message}", LogLevel.Error);
|
||||
StatsStatusText.Text = "Errore nel caricamento";
|
||||
MessageBox.Show($"Errore: {ex.Message}", "Errore Caricamento", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private async void ExportStatsButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
var items = StatsDataGrid.ItemsSource as System.Collections.ObjectModel.ObservableCollection<Models.ClosedAuctionRecord>;
|
||||
if (items == null || items.Count ==0)
|
||||
{
|
||||
MessageBox.Show("Nessuna statistica da esportare. Carica prima le aste chiuse.", "Info", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
return;
|
||||
}
|
||||
|
||||
var dlg = new Microsoft.Win32.SaveFileDialog()
|
||||
{
|
||||
Filter = "CSV files|*.csv|JSON files|*.json|All files|*.*",
|
||||
FileName = "closed_auctions_stats.csv"
|
||||
};
|
||||
|
||||
if (dlg.ShowDialog(this) != true) return;
|
||||
|
||||
var path = dlg.FileName;
|
||||
|
||||
await Task.Run(() =>
|
||||
{
|
||||
if (path.EndsWith(".json", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var json = System.Text.Json.JsonSerializer.Serialize(items, new System.Text.Json.JsonSerializerOptions { WriteIndented = true });
|
||||
System.IO.File.WriteAllText(path, json, System.Text.Encoding.UTF8);
|
||||
}
|
||||
else
|
||||
{
|
||||
// CSV export
|
||||
using var sw = new System.IO.StreamWriter(path, false, System.Text.Encoding.UTF8);
|
||||
sw.WriteLine("ProductName,FinalPrice,Winner,BidsUsed,AuctionUrl");
|
||||
foreach (var item in items)
|
||||
{
|
||||
sw.WriteLine($"\"{EscapeCsv(item.ProductName)}\",{item.FinalPrice:F2},\"{EscapeCsv(item.Winner)}\",{item.BidsUsed},\"{EscapeCsv(item.AuctionUrl)}\"");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
MessageBox.Show("Esportazione completata.", "Esporta Statistiche", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
Log($"[EXPORT] Statistiche esportate -> {path}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log($"[ERRORE] Esportazione statistiche: {ex.Message}", LogLevel.Error);
|
||||
MessageBox.Show($"Errore: {ex.Message}", "Errore Esportazione", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
}
|
||||
|
||||
// New handler for Settings tab
|
||||
private void SaveCookieButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
var cookieValue = SettingsCookieTextBox.Text?.Trim();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(cookieValue))
|
||||
{
|
||||
MessageBox.Show("Inserisci un valore valido per il cookie.", "Errore", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialize session with the cookie
|
||||
var cookieString = $"__stattrb={cookieValue}";
|
||||
_auctionMonitor.InitializeSessionWithCookie(cookieString, "");
|
||||
|
||||
StartButton.IsEnabled = true;
|
||||
|
||||
// Save session securely
|
||||
var session = _auctionMonitor.GetSession();
|
||||
SessionManager.SaveSession(session);
|
||||
|
||||
Log("Sessione configurata da impostazioni");
|
||||
Log("Cookie salvato in modo sicuro");
|
||||
|
||||
// Update user info
|
||||
Task.Run(async () =>
|
||||
{
|
||||
var userData = await _auctionMonitor.GetUserDataAsync();
|
||||
if (userData != null)
|
||||
{
|
||||
Dispatcher.Invoke(() =>
|
||||
{
|
||||
SetUserBanner(userData.Username, userData.RemainingBids);
|
||||
Log($"[OK] Utente: {userData.Username}, Puntate residue: {userData.RemainingBids}");
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
MessageBox.Show("Cookie salvato con successo!", "Salva Cookie", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log($"[ERRORE] Salvataggio cookie: {ex.Message}", LogLevel.Error);
|
||||
MessageBox.Show($"Errore: {ex.Message}", "Errore", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
}
|
||||
|
||||
// Add empty handlers required by XAML (no-op to avoid forcing runtime width changes)
|
||||
private void Window_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// Intentionally left empty to allow designer sizing to take precedence at runtime.
|
||||
}
|
||||
|
||||
private void ToggleTabsButton_Checked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// No runtime width adjustments to avoid layout mismatch with designer.
|
||||
}
|
||||
|
||||
private void ToggleTabsButton_Unchecked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// No runtime width adjustments to avoid layout mismatch with designer.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
46
Mimante/Utilities/SettingsManager.cs
Normal file
46
Mimante/Utilities/SettingsManager.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace AutoBidder.Utilities
|
||||
{
|
||||
internal class AppSettings
|
||||
{
|
||||
public string? ExportPath { get; set; }
|
||||
public string? LastExportExt { get; set; }
|
||||
public string ExportScope { get; set; } = "All"; // All, Closed, Unknown
|
||||
public bool IncludeOnlyUsedBids { get; set; } = true;
|
||||
public bool IncludeLogs { get; set; } = false;
|
||||
public bool IncludeUserBids { get; set; } = false;
|
||||
}
|
||||
|
||||
internal static class SettingsManager
|
||||
{
|
||||
private static readonly string _folder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "AutoBidder");
|
||||
private static readonly string _file = Path.Combine(_folder, "settings.json");
|
||||
|
||||
public static AppSettings Load()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!File.Exists(_file)) return new AppSettings();
|
||||
var txt = File.ReadAllText(_file);
|
||||
var s = JsonSerializer.Deserialize<AppSettings>(txt);
|
||||
if (s == null) return new AppSettings();
|
||||
return s;
|
||||
}
|
||||
catch { return new AppSettings(); }
|
||||
}
|
||||
|
||||
public static void Save(AppSettings settings)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!Directory.Exists(_folder)) Directory.CreateDirectory(_folder);
|
||||
var txt = JsonSerializer.Serialize(settings, new JsonSerializerOptions { WriteIndented = true });
|
||||
File.WriteAllText(_file, txt);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user