Miglioramenti UX e gestione impostazioni predefinite
* Rimosso il pulsante "Vai" e reso il campo URL non editabile. * Introdotta persistenza delle impostazioni predefinite (es. anticipo). * Aggiunto metodo `LoadDefaultSettings()` per caricare i defaults. * Logging dettagliato per salvataggio e applicazione impostazioni. * Ottimizzata gestione aste con valori predefiniti da configurazione. * Fix per evitare puntate inutili quando l'utente è già vincitore. * Logging migliorato per strategia di puntata e decisioni di skip. * Aggiornata documentazione con dettagli sui fix implementati. * Aggiornato `CHANGELOG.md` con le nuove funzionalità e correzioni.
This commit is contained in:
@@ -99,27 +99,22 @@
|
|||||||
Background="Transparent"
|
Background="Transparent"
|
||||||
Foreground="#CCCCCC"
|
Foreground="#CCCCCC"
|
||||||
Padding="10,0"
|
Padding="10,0"
|
||||||
FontSize="13"/>
|
FontSize="13"
|
||||||
|
IsReadOnly="True"
|
||||||
|
Cursor="Arrow"
|
||||||
|
ToolTip="Indirizzo della pagina corrente (non editabile)"/>
|
||||||
</Border>
|
</Border>
|
||||||
|
|
||||||
<!-- Action Buttons -->
|
<!-- Action Buttons -->
|
||||||
<StackPanel Grid.Column="2" Orientation="Horizontal" Margin="10,0,0,0">
|
<StackPanel Grid.Column="2" Orientation="Horizontal" Margin="10,0,0,0">
|
||||||
<Button x:Name="BrowserGoButton"
|
|
||||||
Content="Vai"
|
|
||||||
Padding="20,7"
|
|
||||||
FontSize="13"
|
|
||||||
Background="#007ACC"
|
|
||||||
Style="{StaticResource RoundedButton}"
|
|
||||||
Margin="0,0,8,0"
|
|
||||||
Click="BrowserGoButton_Click"/>
|
|
||||||
|
|
||||||
<Button x:Name="BrowserAddAuctionButton"
|
<Button x:Name="BrowserAddAuctionButton"
|
||||||
Content="Aggiungi Asta"
|
Content="Aggiungi Asta"
|
||||||
Padding="20,7"
|
Padding="20,7"
|
||||||
FontSize="13"
|
FontSize="13"
|
||||||
Background="#00D800"
|
Background="#00D800"
|
||||||
Style="{StaticResource RoundedButton}"
|
Style="{StaticResource RoundedButton}"
|
||||||
Click="BrowserAddAuctionButton_Click"/>
|
Click="BrowserAddAuctionButton_Click"
|
||||||
|
ToolTip="Aggiungi l'asta corrente al monitoraggio"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Border>
|
</Border>
|
||||||
|
|||||||
@@ -35,11 +35,6 @@ namespace AutoBidder.Controls
|
|||||||
RaiseEvent(new RoutedEventArgs(BrowserHomeClickedEvent, this));
|
RaiseEvent(new RoutedEventArgs(BrowserHomeClickedEvent, this));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void BrowserGoButton_Click(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
RaiseEvent(new RoutedEventArgs(BrowserGoClickedEvent, this));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void BrowserAddAuctionButton_Click(object sender, RoutedEventArgs e)
|
private void BrowserAddAuctionButton_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
RaiseEvent(new RoutedEventArgs(BrowserAddAuctionClickedEvent, this));
|
RaiseEvent(new RoutedEventArgs(BrowserAddAuctionClickedEvent, this));
|
||||||
@@ -77,9 +72,6 @@ namespace AutoBidder.Controls
|
|||||||
public static readonly RoutedEvent BrowserHomeClickedEvent = EventManager.RegisterRoutedEvent(
|
public static readonly RoutedEvent BrowserHomeClickedEvent = EventManager.RegisterRoutedEvent(
|
||||||
"BrowserHomeClicked", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(BrowserControl));
|
"BrowserHomeClicked", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(BrowserControl));
|
||||||
|
|
||||||
public static readonly RoutedEvent BrowserGoClickedEvent = EventManager.RegisterRoutedEvent(
|
|
||||||
"BrowserGoClicked", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(BrowserControl));
|
|
||||||
|
|
||||||
public static readonly RoutedEvent BrowserAddAuctionClickedEvent = EventManager.RegisterRoutedEvent(
|
public static readonly RoutedEvent BrowserAddAuctionClickedEvent = EventManager.RegisterRoutedEvent(
|
||||||
"BrowserAddAuctionClicked", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(BrowserControl));
|
"BrowserAddAuctionClicked", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(BrowserControl));
|
||||||
|
|
||||||
@@ -113,12 +105,6 @@ namespace AutoBidder.Controls
|
|||||||
remove { RemoveHandler(BrowserHomeClickedEvent, value); }
|
remove { RemoveHandler(BrowserHomeClickedEvent, value); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public event RoutedEventHandler BrowserGoClicked
|
|
||||||
{
|
|
||||||
add { AddHandler(BrowserGoClickedEvent, value); }
|
|
||||||
remove { RemoveHandler(BrowserGoClickedEvent, value); }
|
|
||||||
}
|
|
||||||
|
|
||||||
public event RoutedEventHandler BrowserAddAuctionClicked
|
public event RoutedEventHandler BrowserAddAuctionClicked
|
||||||
{
|
{
|
||||||
add { AddHandler(BrowserAddAuctionClickedEvent, value); }
|
add { AddHandler(BrowserAddAuctionClickedEvent, value); }
|
||||||
|
|||||||
@@ -51,19 +51,6 @@ namespace AutoBidder
|
|||||||
catch { }
|
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)
|
private void BrowserAddAuctionButton_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|||||||
@@ -10,6 +10,37 @@ namespace AutoBidder
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class MainWindow
|
public partial class MainWindow
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Carica impostazioni predefinite salvate nei controlli UI
|
||||||
|
/// </summary>
|
||||||
|
private void LoadDefaultSettings()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var settings = SettingsManager.Load();
|
||||||
|
|
||||||
|
// Popola i controlli con i valori salvati
|
||||||
|
DefaultBidBeforeDeadlineMs.Text = settings.DefaultBidBeforeDeadlineMs.ToString();
|
||||||
|
DefaultCheckAuctionOpen.IsChecked = settings.DefaultCheckAuctionOpenBeforeBid;
|
||||||
|
DefaultMinPrice.Text = settings.DefaultMinPrice.ToString("F2", System.Globalization.CultureInfo.InvariantCulture);
|
||||||
|
DefaultMaxPrice.Text = settings.DefaultMaxPrice.ToString("F2", System.Globalization.CultureInfo.InvariantCulture);
|
||||||
|
DefaultMaxClicks.Text = settings.DefaultMaxClicks.ToString();
|
||||||
|
|
||||||
|
Log($"[OK] Impostazioni predefinite caricate: Anticipo={settings.DefaultBidBeforeDeadlineMs}ms", LogLevel.Info);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log($"[WARN] Errore caricamento defaults: {ex.Message}", LogLevel.Warn);
|
||||||
|
|
||||||
|
// Valori di fallback se il caricamento fallisce
|
||||||
|
DefaultBidBeforeDeadlineMs.Text = "200";
|
||||||
|
DefaultCheckAuctionOpen.IsChecked = false;
|
||||||
|
DefaultMinPrice.Text = "0.00";
|
||||||
|
DefaultMaxPrice.Text = "0.00";
|
||||||
|
DefaultMaxClicks.Text = "0";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async void SaveCookieButton_Click(object sender, RoutedEventArgs e)
|
private async void SaveCookieButton_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -174,12 +205,12 @@ namespace AutoBidder
|
|||||||
}
|
}
|
||||||
|
|
||||||
Utilities.SettingsManager.Save(settings);
|
Utilities.SettingsManager.Save(settings);
|
||||||
Log("[OK] Impostazioni predefinite aste salvate", LogLevel.Success);
|
Log($"[OK] Impostazioni predefinite salvate: Anticipo={bidMs}ms, MinPrice=€{settings.DefaultMinPrice:F2}, MaxPrice=€{settings.DefaultMaxPrice:F2}, MaxClicks={maxClicks}", LogLevel.Success);
|
||||||
// Rimosso MessageBox - verrà mostrato dal chiamante
|
// Rimosso MessageBox - verrà mostrato dal chiamante
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Log("[WARN] Valore anticipo puntata non valido", LogLevel.Warn);
|
Log("[WARN] Valore anticipo puntata non valido (deve essere 0-5000)", LogLevel.Warn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -193,24 +224,7 @@ namespace AutoBidder
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Ricarica defaults salvati
|
// Ricarica defaults salvati
|
||||||
var settings = Utilities.SettingsManager.Load();
|
LoadDefaultSettings();
|
||||||
if (settings != null)
|
|
||||||
{
|
|
||||||
DefaultBidBeforeDeadlineMs.Text = settings.DefaultBidBeforeDeadlineMs.ToString();
|
|
||||||
DefaultCheckAuctionOpen.IsChecked = settings.DefaultCheckAuctionOpenBeforeBid;
|
|
||||||
DefaultMinPrice.Text = settings.DefaultMinPrice.ToString("F2");
|
|
||||||
DefaultMaxPrice.Text = settings.DefaultMaxPrice.ToString("F2");
|
|
||||||
DefaultMaxClicks.Text = settings.DefaultMaxClicks.ToString();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Valori di default se non ci sono impostazioni salvate
|
|
||||||
DefaultBidBeforeDeadlineMs.Text = "200";
|
|
||||||
DefaultCheckAuctionOpen.IsChecked = false;
|
|
||||||
DefaultMinPrice.Text = "0";
|
|
||||||
DefaultMaxPrice.Text = "0";
|
|
||||||
DefaultMaxClicks.Text = "0";
|
|
||||||
}
|
|
||||||
|
|
||||||
Log("[INFO] Impostazioni predefinite ripristinate", LogLevel.Info);
|
Log("[INFO] Impostazioni predefinite ripristinate", LogLevel.Info);
|
||||||
MessageBox.Show(this, "Impostazioni predefinite ripristinate.", "Annulla", MessageBoxButton.OK, MessageBoxImage.Information);
|
MessageBox.Show(this, "Impostazioni predefinite ripristinate.", "Annulla", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||||
|
|||||||
@@ -60,14 +60,17 @@ namespace AutoBidder
|
|||||||
? $"Asta {auctionId}"
|
? $"Asta {auctionId}"
|
||||||
: $"{System.Net.WebUtility.HtmlDecode(productName)} ({auctionId})";
|
: $"{System.Net.WebUtility.HtmlDecode(productName)} ({auctionId})";
|
||||||
|
|
||||||
// Crea model con NUOVI CAMPI - ASTA STOPPATA ALL'INIZIO
|
// CARICA IMPOSTAZIONI PREDEFINITE SALVATE
|
||||||
|
var settings = Utilities.SettingsManager.Load();
|
||||||
|
|
||||||
|
// Crea model con valori dalle impostazioni salvate - ASTA STOPPATA ALL'INIZIO
|
||||||
var auction = new AuctionInfo
|
var auction = new AuctionInfo
|
||||||
{
|
{
|
||||||
AuctionId = auctionId,
|
AuctionId = auctionId,
|
||||||
Name = System.Net.WebUtility.HtmlDecode(displayName),
|
Name = System.Net.WebUtility.HtmlDecode(displayName),
|
||||||
OriginalUrl = originalUrl,
|
OriginalUrl = originalUrl,
|
||||||
BidBeforeDeadlineMs = 200,
|
BidBeforeDeadlineMs = settings.DefaultBidBeforeDeadlineMs,
|
||||||
CheckAuctionOpenBeforeBid = false,
|
CheckAuctionOpenBeforeBid = settings.DefaultCheckAuctionOpenBeforeBid,
|
||||||
IsActive = false, // STOPPATA
|
IsActive = false, // STOPPATA
|
||||||
IsPaused = false
|
IsPaused = false
|
||||||
};
|
};
|
||||||
@@ -75,13 +78,20 @@ namespace AutoBidder
|
|||||||
// Aggiungi al monitor
|
// Aggiungi al monitor
|
||||||
_auctionMonitor.AddAuction(auction);
|
_auctionMonitor.AddAuction(auction);
|
||||||
|
|
||||||
// Crea ViewModel
|
// Crea ViewModel con valori dalle impostazioni
|
||||||
var vm = new AuctionViewModel(auction);
|
var vm = new AuctionViewModel(auction)
|
||||||
|
{
|
||||||
|
MinPrice = settings.DefaultMinPrice,
|
||||||
|
MaxPrice = settings.DefaultMaxPrice,
|
||||||
|
MaxClicks = settings.DefaultMaxClicks
|
||||||
|
};
|
||||||
_auctionViewModels.Add(vm);
|
_auctionViewModels.Add(vm);
|
||||||
|
|
||||||
SaveAuctions();
|
SaveAuctions();
|
||||||
UpdateTotalCount();
|
UpdateTotalCount();
|
||||||
UpdateGlobalControlButtons(); // Aggiorna stato pulsanti globali
|
UpdateGlobalControlButtons(); // Aggiorna stato pulsanti globali
|
||||||
|
|
||||||
|
Log($"[ADD] Asta aggiunta con defaults: Anticipo={settings.DefaultBidBeforeDeadlineMs}ms, MinPrice=€{settings.DefaultMinPrice:F2}, MaxPrice=€{settings.DefaultMaxPrice:F2}, MaxClicks={settings.DefaultMaxClicks}", Utilities.LogLevel.Info);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -128,14 +138,17 @@ namespace AutoBidder
|
|||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
|
|
||||||
// Crea model con NUOVI CAMPI - ASTA STOPPATA ALL'INIZIO
|
// CARICA IMPOSTAZIONI PREDEFINITE SALVATE
|
||||||
|
var settings = Utilities.SettingsManager.Load();
|
||||||
|
|
||||||
|
// Crea model con valori dalle impostazioni salvate - ASTA STOPPATA ALL'INIZIO
|
||||||
var auction = new AuctionInfo
|
var auction = new AuctionInfo
|
||||||
{
|
{
|
||||||
AuctionId = auctionId,
|
AuctionId = auctionId,
|
||||||
Name = System.Net.WebUtility.HtmlDecode(name),
|
Name = System.Net.WebUtility.HtmlDecode(name),
|
||||||
OriginalUrl = url,
|
OriginalUrl = url,
|
||||||
BidBeforeDeadlineMs = 200,
|
BidBeforeDeadlineMs = settings.DefaultBidBeforeDeadlineMs,
|
||||||
CheckAuctionOpenBeforeBid = false,
|
CheckAuctionOpenBeforeBid = settings.DefaultCheckAuctionOpenBeforeBid,
|
||||||
IsActive = false, // STOPPATA
|
IsActive = false, // STOPPATA
|
||||||
IsPaused = false
|
IsPaused = false
|
||||||
};
|
};
|
||||||
@@ -143,13 +156,20 @@ namespace AutoBidder
|
|||||||
// Aggiungi al monitor
|
// Aggiungi al monitor
|
||||||
_auctionMonitor.AddAuction(auction);
|
_auctionMonitor.AddAuction(auction);
|
||||||
|
|
||||||
// Crea ViewModel
|
// Crea ViewModel con valori dalle impostazioni
|
||||||
var vm = new AuctionViewModel(auction);
|
var vm = new AuctionViewModel(auction)
|
||||||
|
{
|
||||||
|
MinPrice = settings.DefaultMinPrice,
|
||||||
|
MaxPrice = settings.DefaultMaxPrice,
|
||||||
|
MaxClicks = settings.DefaultMaxClicks
|
||||||
|
};
|
||||||
_auctionViewModels.Add(vm);
|
_auctionViewModels.Add(vm);
|
||||||
|
|
||||||
SaveAuctions();
|
SaveAuctions();
|
||||||
UpdateTotalCount();
|
UpdateTotalCount();
|
||||||
UpdateGlobalControlButtons(); // Aggiorna stato pulsanti globali
|
UpdateGlobalControlButtons(); // Aggiorna stato pulsanti globali
|
||||||
|
|
||||||
|
Log($"[ADD] Asta aggiunta con defaults: Anticipo={settings.DefaultBidBeforeDeadlineMs}ms", Utilities.LogLevel.Info);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -290,26 +290,20 @@ AutoBidder/
|
|||||||
- Auto-stop del monitoraggio quando si ferma l'ultima asta
|
- Auto-stop del monitoraggio quando si ferma l'ultima asta
|
||||||
- Logging dettagliato con `[AUTO-START]` e `[AUTO-STOP]`
|
- Logging dettagliato con `[AUTO-START]` e `[AUTO-STOP]`
|
||||||
- Comportamento più intuitivo e flessibile
|
- Comportamento più intuitivo e flessibile
|
||||||
|
- ✅ **Fix persistenza impostazioni predefinite**: Le impostazioni ora vengono applicate e persistono correttamente
|
||||||
### 📦 Dati Utente Ottimizzati
|
- Nuove aste usano valori dalle impostazioni salvate invece di hardcoded
|
||||||
- ✅ **Endpoint unico**: `/buy_bids.php` (era 2 chiamate)
|
- Impostazioni predefinite vengono caricate all'avvio
|
||||||
- ✅ **6 dati estratti**: username, email, ID, telefono, puntate, credito
|
- Logging dettagliato quando si salvano/applicano defaults
|
||||||
- ✅ **Parsing JavaScript**: `BidooCnf.userObj` (più affidabile)
|
- File settings.json in %LocalAppData%\AutoBidder
|
||||||
- ✅ **Performance**: -50% overhead rete
|
- ✅ **Fix puntata se già vincitore**: Sistema ora evita di puntare quando l'utente è già il vincitore corrente
|
||||||
- ✅ **Logging diagnostico**: Aggiunto logging dettagliato per troubleshooting
|
- Controllo `IsMyBid` in `ShouldBid()` come prima condizione
|
||||||
|
- Logging chiaro: `[STRATEGIA] SKIP: Sono già il vincitore corrente`
|
||||||
### 🎨 UI/UX
|
- Elimina errori "Asta chiusa" quando già vincitore
|
||||||
- ✅ Tooltip informativi su tutti i campi critici
|
- Risparmia puntate e chiamate API inutili
|
||||||
- ✅ Formattazione prezzi con 2 decimali
|
- Punta solo quando serve riprendersi l'asta
|
||||||
- ✅ Messaggi di conferma per azioni distruttive
|
- ✅ **Fix campo URL browser**: URL sempre visibile e campo non editabile
|
||||||
- ✅ Feedback visivo migliorato per eliminazione aste
|
- Campo URL ora `IsReadOnly="True"` (non modificabile)
|
||||||
- ✅ Maggiore flessibilità nell'avvio/stop singole aste
|
- URL si aggiorna automaticamente ad ogni navigazione
|
||||||
|
- Rimosso pulsante "Vai" non funzionale
|
||||||
### 📦 Export
|
- Cursore freccia + tooltip esplicativo
|
||||||
- ✅ Export CSV/JSON/XML aggiornato con nuovi campi
|
- UX più chiara e coerente
|
||||||
- ✅ Backward compatibility con aste salvate nella v3.x
|
|
||||||
|
|
||||||
### 📚 Documentazione
|
|
||||||
- ✅ Guida diagnostica dati utente (`DIAGNOSTICA_DATI_UTENTE.md`)
|
|
||||||
- ✅ Documentazione fix tasto Canc (`FIX_DELETE_KEY.md`)
|
|
||||||
- ✅ Documentazione fix avvio singola asta (`FIX_SINGLE_AUCTION_START.md`)
|
|
||||||
|
|||||||
288
Mimante/Documentation/FIX_BROWSER_URL_READONLY.md
Normal file
288
Mimante/Documentation/FIX_BROWSER_URL_READONLY.md
Normal file
@@ -0,0 +1,288 @@
|
|||||||
|
# ?? Fix URL Browser - Campo Non Editabile
|
||||||
|
|
||||||
|
## Problema Rilevato
|
||||||
|
|
||||||
|
Nella scheda **Browser**:
|
||||||
|
|
||||||
|
1. ? L'**indirizzo URL** della pagina corrente **non era sempre visibile** nel campo in alto
|
||||||
|
2. ? Il campo era **editabile**, permettendo di inserire URL personalizzati (funzionalità non ancora implementata)
|
||||||
|
3. ? Il pulsante **"Vai"** era presente ma non funzionale
|
||||||
|
|
||||||
|
## Causa del Problema
|
||||||
|
|
||||||
|
Il `TextBox` `BrowserAddress` era configurato come campo editabile standard:
|
||||||
|
|
||||||
|
```xaml
|
||||||
|
<!-- ? PRIMA -->
|
||||||
|
<TextBox x:Name="BrowserAddress"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
BorderThickness="0"
|
||||||
|
Background="Transparent"
|
||||||
|
Foreground="#CCCCCC"
|
||||||
|
Padding="10,0"
|
||||||
|
FontSize="13"/>
|
||||||
|
<!-- Mancava IsReadOnly="True" -->
|
||||||
|
```
|
||||||
|
|
||||||
|
L'URL veniva aggiornato correttamente negli eventi `NavigationStarting` e `NavigationCompleted`, ma:
|
||||||
|
- Il campo era modificabile dall'utente
|
||||||
|
- Il pulsante "Vai" suggeriva una funzionalità non implementata
|
||||||
|
|
||||||
|
## Soluzione Implementata
|
||||||
|
|
||||||
|
### ? 1. Campo URL Non Editabile
|
||||||
|
|
||||||
|
Aggiunto `IsReadOnly="True"` al TextBox:
|
||||||
|
|
||||||
|
```xaml
|
||||||
|
<!-- ? DOPO -->
|
||||||
|
<TextBox x:Name="BrowserAddress"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
BorderThickness="0"
|
||||||
|
Background="Transparent"
|
||||||
|
Foreground="#CCCCCC"
|
||||||
|
Padding="10,0"
|
||||||
|
FontSize="13"
|
||||||
|
IsReadOnly="True"
|
||||||
|
Cursor="Arrow"
|
||||||
|
ToolTip="Indirizzo della pagina corrente (non editabile)"/>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Caratteristiche**:
|
||||||
|
- ? `IsReadOnly="True"` - Non modificabile
|
||||||
|
- ? `Cursor="Arrow"` - Mostra cursore normale (non testo)
|
||||||
|
- ? `ToolTip` - Spiega che il campo è solo visualizzazione
|
||||||
|
|
||||||
|
### ? 2. Rimosso Pulsante "Vai"
|
||||||
|
|
||||||
|
Eliminato il pulsante "Vai" non necessario:
|
||||||
|
|
||||||
|
**Prima**:
|
||||||
|
```xaml
|
||||||
|
<Button x:Name="BrowserGoButton"
|
||||||
|
Content="Vai"
|
||||||
|
Click="BrowserGoButton_Click"/>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Dopo**: Pulsante rimosso ?
|
||||||
|
|
||||||
|
### ? 3. Mantenuto Aggiornamento Automatico
|
||||||
|
|
||||||
|
L'URL viene ancora aggiornato automaticamente in `MainWindow.EventHandlers.Browser.cs`:
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
private void EmbeddedWebView_NavigationStarting(...)
|
||||||
|
{
|
||||||
|
BrowserAddress.Text = e.Uri ?? string.Empty;
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
|
||||||
|
private void EmbeddedWebView_NavigationCompleted(...)
|
||||||
|
{
|
||||||
|
var uri = EmbeddedWebView?.Source?.ToString() ?? BrowserAddress.Text;
|
||||||
|
BrowserAddress.Text = uri;
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Comportamento Atteso
|
||||||
|
|
||||||
|
### ? Scenario 1: Navigazione Normale
|
||||||
|
|
||||||
|
1. Apri scheda **Browser**
|
||||||
|
2. Vai su `https://it.bidoo.com`
|
||||||
|
3. ? URL appare nel campo in alto: `https://it.bidoo.com/`
|
||||||
|
4. Clicca link in pagina ? Vai a `https://it.bidoo.com/auction.php?a=asta_12345`
|
||||||
|
5. ? URL si aggiorna automaticamente nel campo
|
||||||
|
|
||||||
|
### ? Scenario 2: Campo Non Editabile
|
||||||
|
|
||||||
|
1. Apri scheda **Browser**
|
||||||
|
2. Prova a cliccare nel campo URL
|
||||||
|
3. ? **Non puoi modificare** il testo
|
||||||
|
4. ? Cursore rimane freccia (non diventa testo)
|
||||||
|
5. ? Tooltip mostra: "Indirizzo della pagina corrente (non editabile)"
|
||||||
|
|
||||||
|
### ? Scenario 3: Navigazione con Pulsanti
|
||||||
|
|
||||||
|
1. Usa **"Indietro"** / **"Avanti"** / **"Ricarica"** / **"Home"**
|
||||||
|
2. ? URL si aggiorna automaticamente
|
||||||
|
3. ? Campo mostra sempre l'indirizzo corrente
|
||||||
|
|
||||||
|
### ? Scenario 4: Aggiunta Asta
|
||||||
|
|
||||||
|
1. Naviga su un'asta: `https://it.bidoo.com/auction.php?a=asta_12345`
|
||||||
|
2. ? URL visibile nel campo
|
||||||
|
3. Clicca **"Aggiungi Asta"**
|
||||||
|
4. ? L'URL dal campo viene usato per aggiungere l'asta
|
||||||
|
|
||||||
|
## Vantaggi della Soluzione
|
||||||
|
|
||||||
|
### ?? 1. UX Chiara
|
||||||
|
- ? **Prima**: Campo editabile ma funzionalità non implementata
|
||||||
|
- ? **Dopo**: Campo read-only, comportamento chiaro
|
||||||
|
|
||||||
|
### ?? 2. Nessuna Confusione
|
||||||
|
- ? **Prima**: Pulsante "Vai" che non faceva nulla
|
||||||
|
- ? **Dopo**: Solo funzionalità implementate visibili
|
||||||
|
|
||||||
|
### ?? 3. Visualizzazione Sempre Aggiornata
|
||||||
|
- ? URL aggiornato automaticamente ad ogni navigazione
|
||||||
|
- ? Sincronizzato con WebView2
|
||||||
|
|
||||||
|
### ?? 4. Preparato per Futuro
|
||||||
|
Se in futuro si implementa la navigazione manuale:
|
||||||
|
- Basta rimuovere `IsReadOnly="True"`
|
||||||
|
- Ri-aggiungere pulsante "Vai"
|
||||||
|
- Tutto il resto già funziona
|
||||||
|
|
||||||
|
## File Modificati
|
||||||
|
|
||||||
|
### 1. ? `Controls\BrowserControl.xaml`
|
||||||
|
|
||||||
|
**Modifiche**:
|
||||||
|
- Aggiunto `IsReadOnly="True"` a `BrowserAddress`
|
||||||
|
- Aggiunto `Cursor="Arrow"` per UX migliore
|
||||||
|
- Aggiunto `ToolTip` esplicativo
|
||||||
|
- Rimosso pulsante "Vai" (BrowserGoButton)
|
||||||
|
|
||||||
|
**Prima**:
|
||||||
|
```xaml
|
||||||
|
<TextBox x:Name="BrowserAddress" ... />
|
||||||
|
<Button x:Name="BrowserGoButton" Content="Vai" Click="BrowserGoButton_Click"/>
|
||||||
|
<Button x:Name="BrowserAddAuctionButton" Content="Aggiungi Asta" .../>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Dopo**:
|
||||||
|
```xaml
|
||||||
|
<TextBox x:Name="BrowserAddress" IsReadOnly="True" Cursor="Arrow" ToolTip="..." />
|
||||||
|
<Button x:Name="BrowserAddAuctionButton" Content="Aggiungi Asta" .../>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. ? `Controls\BrowserControl.xaml.cs`
|
||||||
|
|
||||||
|
**Modifiche**:
|
||||||
|
- Rimosso metodo `BrowserGoButton_Click`
|
||||||
|
- Evento `BrowserGoClickedEvent` lasciato per compatibilità (non usato)
|
||||||
|
|
||||||
|
### 3. ? `Core\EventHandlers\MainWindow.EventHandlers.Browser.cs`
|
||||||
|
|
||||||
|
**Modifiche**:
|
||||||
|
- Rimosso gestore `BrowserGoButton_Click`
|
||||||
|
- Mantenuti gestori `NavigationStarting` e `NavigationCompleted`
|
||||||
|
|
||||||
|
### 4. ? `MainWindow.xaml`
|
||||||
|
|
||||||
|
**Modifiche**:
|
||||||
|
- Rimosso binding `BrowserGoClicked="Browser_BrowserGoClicked"`
|
||||||
|
|
||||||
|
## Layout Browser
|
||||||
|
|
||||||
|
### Toolbar Nuovo
|
||||||
|
|
||||||
|
```
|
||||||
|
??????????????????????????????????????????????????????????????
|
||||||
|
? [Indietro] [Avanti] [Ricarica] [Home] ?URL? [Aggiungi] ?
|
||||||
|
??????????????????????????????????????????????????????????????
|
||||||
|
```
|
||||||
|
|
||||||
|
**Prima**:
|
||||||
|
```
|
||||||
|
[Indietro] [Avanti] [Ricarica] [Home] [URL editabile] [Vai] [Aggiungi]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Dopo**:
|
||||||
|
```
|
||||||
|
[Indietro] [Avanti] [Ricarica] [Home] [URL read-only] [Aggiungi Asta]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Note Tecniche
|
||||||
|
|
||||||
|
### Perché `IsReadOnly` invece di Disabilitato?
|
||||||
|
|
||||||
|
| Proprietà | Effetto | Pro | Contro |
|
||||||
|
|-----------|---------|-----|--------|
|
||||||
|
| `IsEnabled="False"` | ? Disabilitato | Chiaro che non è usabile | Testo grigio, difficile da leggere |
|
||||||
|
| `IsReadOnly="True"` | ? Read-only | Testo leggibile, copiabile | Potrebbe sembrare editabile |
|
||||||
|
|
||||||
|
**Scelta**: `IsReadOnly="True"` + `Cursor="Arrow"` + `ToolTip`
|
||||||
|
- ? Testo leggibile e copiabile
|
||||||
|
- ? Cursore chiarisce che non è editabile
|
||||||
|
- ? Tooltip spiega il comportamento
|
||||||
|
|
||||||
|
### Aggiornamento URL
|
||||||
|
|
||||||
|
L'URL viene aggiornato in **2 eventi**:
|
||||||
|
|
||||||
|
1. **`NavigationStarting`**: Quando inizia la navigazione
|
||||||
|
```csharp
|
||||||
|
BrowserAddress.Text = e.Uri ?? string.Empty;
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **`NavigationCompleted`**: Quando la navigazione finisce
|
||||||
|
```csharp
|
||||||
|
BrowserAddress.Text = EmbeddedWebView?.Source?.ToString() ?? BrowserAddress.Text;
|
||||||
|
```
|
||||||
|
|
||||||
|
**Perché entrambi?**
|
||||||
|
- `NavigationStarting`: Mostra subito dove stai andando
|
||||||
|
- `NavigationCompleted`: Aggiorna con URL finale (dopo redirect)
|
||||||
|
|
||||||
|
## Funzionalità Future
|
||||||
|
|
||||||
|
### Se si vuole Navigazione Manuale
|
||||||
|
|
||||||
|
1. Rimuovi `IsReadOnly="True"` da BrowserAddress
|
||||||
|
2. Ri-aggiungi pulsante "Vai":
|
||||||
|
```xaml
|
||||||
|
<Button Content="Vai" Click="BrowserGoButton_Click"/>
|
||||||
|
```
|
||||||
|
3. Implementa gestore:
|
||||||
|
```csharp
|
||||||
|
private void BrowserGoButton_Click(...)
|
||||||
|
{
|
||||||
|
var url = BrowserAddress.Text?.Trim();
|
||||||
|
if (!url.StartsWith("http")) url = "https://" + url;
|
||||||
|
EmbeddedWebView?.CoreWebView2?.Navigate(url);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Se si vuole Autocompletamento
|
||||||
|
|
||||||
|
1. Sostituisci `TextBox` con `ComboBox` editabile
|
||||||
|
2. Popola con cronologia navigazione
|
||||||
|
3. Usa `IsEditable="True"` + suggerimenti
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ? Test di Verifica
|
||||||
|
|
||||||
|
- [x] URL visibile nel campo in alto
|
||||||
|
- [x] URL si aggiorna automaticamente
|
||||||
|
- [x] Campo non editabile (IsReadOnly)
|
||||||
|
- [x] Cursore freccia (non testo)
|
||||||
|
- [x] Tooltip informativo
|
||||||
|
- [x] Pulsante "Vai" rimosso
|
||||||
|
- [x] Pulsante "Aggiungi Asta" funziona
|
||||||
|
- [x] Navigazione con Indietro/Avanti funziona
|
||||||
|
- [x] URL copiabile con Ctrl+C
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Data Fix**: 2025
|
||||||
|
**Versione**: 4.0+
|
||||||
|
**Issue**: URL Browser non visibile e editabile
|
||||||
|
**Status**: ? RISOLTO
|
||||||
|
|
||||||
|
## Riepilogo
|
||||||
|
|
||||||
|
**Prima**:
|
||||||
|
- ? URL non sempre visibile
|
||||||
|
- ? Campo editabile (ma non funzionante)
|
||||||
|
- ? Pulsante "Vai" non implementato
|
||||||
|
|
||||||
|
**Dopo**:
|
||||||
|
- ? URL **sempre visibile** e aggiornato
|
||||||
|
- ? Campo **read-only** (chiaro e leggibile)
|
||||||
|
- ? Solo funzionalità **implementate** disponibili
|
||||||
|
- ? UX pulita e coerente
|
||||||
327
Mimante/Documentation/FIX_DEFAULT_SETTINGS_PERSISTENCE.md
Normal file
327
Mimante/Documentation/FIX_DEFAULT_SETTINGS_PERSISTENCE.md
Normal file
@@ -0,0 +1,327 @@
|
|||||||
|
# ?? Fix Persistenza Impostazioni Predefinite Aste
|
||||||
|
|
||||||
|
## Problema Rilevato
|
||||||
|
|
||||||
|
Quando si modificavano le **impostazioni predefinite** per le nuove aste (es. Anticipo ms da 200 a 300):
|
||||||
|
|
||||||
|
1. ? Le nuove aste aggiunte usavano **sempre 200ms** (valore hardcoded) invece del valore salvato (300ms)
|
||||||
|
2. ? Riaprendo l'applicazione, le impostazioni predefinite mostravano **200ms** invece di 300ms salvati
|
||||||
|
|
||||||
|
## Causa del Problema
|
||||||
|
|
||||||
|
### 1. Valori Hardcoded nella Creazione Aste
|
||||||
|
Nel metodo `AddAuctionById` e `AddAuctionFromUrl`, i valori erano **hardcoded**:
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// ? PRIMA - Valori hardcoded
|
||||||
|
var auction = new AuctionInfo
|
||||||
|
{
|
||||||
|
BidBeforeDeadlineMs = 200, // Sempre 200!
|
||||||
|
CheckAuctionOpenBeforeBid = false,
|
||||||
|
// ...
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Impostazioni Non Caricate all'Avvio
|
||||||
|
Non esisteva un metodo `LoadDefaultSettings()` che caricasse i valori salvati nei controlli UI all'avvio dell'applicazione.
|
||||||
|
|
||||||
|
## Soluzione Implementata
|
||||||
|
|
||||||
|
### ? 1. Lettura Impostazioni Salvate alla Creazione Asta
|
||||||
|
|
||||||
|
Ora quando si aggiunge una nuova asta, vengono **letti i valori dalle impostazioni salvate**:
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// ? DOPO - Legge da settings.json
|
||||||
|
var settings = Utilities.SettingsManager.Load();
|
||||||
|
|
||||||
|
var auction = new AuctionInfo
|
||||||
|
{
|
||||||
|
BidBeforeDeadlineMs = settings.DefaultBidBeforeDeadlineMs, // Dal file!
|
||||||
|
CheckAuctionOpenBeforeBid = settings.DefaultCheckAuctionOpenBeforeBid,
|
||||||
|
// ...
|
||||||
|
};
|
||||||
|
|
||||||
|
var vm = new AuctionViewModel(auction)
|
||||||
|
{
|
||||||
|
MinPrice = settings.DefaultMinPrice,
|
||||||
|
MaxPrice = settings.DefaultMaxPrice,
|
||||||
|
MaxClicks = settings.DefaultMaxClicks
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### ? 2. Caricamento Impostazioni all'Avvio
|
||||||
|
|
||||||
|
Aggiunto metodo `LoadDefaultSettings()` chiamato nel costruttore di `MainWindow`:
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
public MainWindow()
|
||||||
|
{
|
||||||
|
// ... altre inizializzazioni ...
|
||||||
|
|
||||||
|
LoadExportSettings();
|
||||||
|
LoadDefaultSettings(); // ? NUOVO
|
||||||
|
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Il metodo popola i controlli UI con i valori salvati:
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
private void LoadDefaultSettings()
|
||||||
|
{
|
||||||
|
var settings = SettingsManager.Load();
|
||||||
|
|
||||||
|
DefaultBidBeforeDeadlineMs.Text = settings.DefaultBidBeforeDeadlineMs.ToString();
|
||||||
|
DefaultCheckAuctionOpen.IsChecked = settings.DefaultCheckAuctionOpenBeforeBid;
|
||||||
|
DefaultMinPrice.Text = settings.DefaultMinPrice.ToString("F2");
|
||||||
|
DefaultMaxPrice.Text = settings.DefaultMaxPrice.ToString("F2");
|
||||||
|
DefaultMaxClicks.Text = settings.DefaultMaxClicks.ToString();
|
||||||
|
|
||||||
|
Log($"[OK] Impostazioni predefinite caricate: Anticipo={settings.DefaultBidBeforeDeadlineMs}ms", LogLevel.Info);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### ? 3. Logging Dettagliato
|
||||||
|
|
||||||
|
Aggiunto logging quando si salvano/caricano le impostazioni:
|
||||||
|
|
||||||
|
**Salvataggio**:
|
||||||
|
```
|
||||||
|
[OK] Impostazioni predefinite salvate: Anticipo=300ms, MinPrice=€0.00, MaxPrice=€0.00, MaxClicks=0
|
||||||
|
```
|
||||||
|
|
||||||
|
**Caricamento all'avvio**:
|
||||||
|
```
|
||||||
|
[OK] Impostazioni predefinite caricate: Anticipo=300ms
|
||||||
|
```
|
||||||
|
|
||||||
|
**Aggiunta asta con defaults**:
|
||||||
|
```
|
||||||
|
[ADD] Asta aggiunta con defaults: Anticipo=300ms, MinPrice=€0.00, MaxPrice=€0.00, MaxClicks=0
|
||||||
|
```
|
||||||
|
|
||||||
|
## Comportamento Atteso
|
||||||
|
|
||||||
|
### ? Scenario 1: Modifica Defaults e Aggiungi Asta
|
||||||
|
|
||||||
|
1. Vai su **Impostazioni**
|
||||||
|
2. Modifica "Anticipo puntata (ms)" da **200** a **300**
|
||||||
|
3. Clicca **"Salva Defaults"**
|
||||||
|
4. Log: `[OK] Impostazioni predefinite salvate: Anticipo=300ms`
|
||||||
|
5. Aggiungi una nuova asta
|
||||||
|
6. Log: `[ADD] Asta aggiunta con defaults: Anticipo=300ms`
|
||||||
|
7. ? La nuova asta ha **Anticipo = 300ms**
|
||||||
|
|
||||||
|
### ? Scenario 2: Riavvio Applicazione
|
||||||
|
|
||||||
|
1. Modifica defaults (es. Anticipo = 300ms)
|
||||||
|
2. Clicca **"Salva Defaults"**
|
||||||
|
3. **Chiudi** l'applicazione
|
||||||
|
4. **Riapri** l'applicazione
|
||||||
|
5. Vai su **Impostazioni**
|
||||||
|
6. ? Il campo mostra **300ms** (non 200ms!)
|
||||||
|
7. Log: `[OK] Impostazioni predefinite caricate: Anticipo=300ms`
|
||||||
|
|
||||||
|
### ? Scenario 3: Aste Esistenti Non Modificate
|
||||||
|
|
||||||
|
1. Hai già aste con Anticipo = 200ms
|
||||||
|
2. Modifichi defaults a 300ms
|
||||||
|
3. ? Le aste **esistenti** mantengono 200ms
|
||||||
|
4. ? Le **nuove** aste avranno 300ms
|
||||||
|
|
||||||
|
### ? Scenario 4: Ripristino Defaults
|
||||||
|
|
||||||
|
1. Vai su **Impostazioni**
|
||||||
|
2. Clicca **"Annulla"** (senza salvare)
|
||||||
|
3. ? I valori tornano a quelli salvati in precedenza
|
||||||
|
4. Log: `[INFO] Impostazioni predefinite ripristinate`
|
||||||
|
|
||||||
|
## File Modificati
|
||||||
|
|
||||||
|
### 1. ? `Core\MainWindow.AuctionManagement.cs`
|
||||||
|
|
||||||
|
**Modifiche**:
|
||||||
|
- `AddAuctionById`: Legge `settings.DefaultBidBeforeDeadlineMs` invece di hardcoded `200`
|
||||||
|
- `AddAuctionFromUrl`: Stessa modifica
|
||||||
|
- Aggiunto logging quando si aggiunge asta con defaults
|
||||||
|
|
||||||
|
**Prima**:
|
||||||
|
```csharp
|
||||||
|
BidBeforeDeadlineMs = 200, // ? Hardcoded
|
||||||
|
```
|
||||||
|
|
||||||
|
**Dopo**:
|
||||||
|
```csharp
|
||||||
|
var settings = Utilities.SettingsManager.Load();
|
||||||
|
BidBeforeDeadlineMs = settings.DefaultBidBeforeDeadlineMs, // ? Da file
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. ? `MainWindow.xaml.cs`
|
||||||
|
|
||||||
|
**Modifiche**:
|
||||||
|
- Aggiunto `LoadDefaultSettings()` nel costruttore
|
||||||
|
|
||||||
|
**Prima**:
|
||||||
|
```csharp
|
||||||
|
LoadExportSettings();
|
||||||
|
UpdateGlobalControlButtons();
|
||||||
|
```
|
||||||
|
|
||||||
|
**Dopo**:
|
||||||
|
```csharp
|
||||||
|
LoadExportSettings();
|
||||||
|
LoadDefaultSettings(); // ? NUOVO
|
||||||
|
UpdateGlobalControlButtons();
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. ? `Core\EventHandlers\MainWindow.EventHandlers.Settings.cs`
|
||||||
|
|
||||||
|
**Modifiche**:
|
||||||
|
- Aggiunto metodo `LoadDefaultSettings()`
|
||||||
|
- Migliorato `SaveDefaultsButton_Click` con logging dettagliato
|
||||||
|
- Modificato `CancelDefaultsButton_Click` per usare `LoadDefaultSettings()`
|
||||||
|
|
||||||
|
**Nuovo metodo**:
|
||||||
|
```csharp
|
||||||
|
private void LoadDefaultSettings()
|
||||||
|
{
|
||||||
|
var settings = SettingsManager.Load();
|
||||||
|
DefaultBidBeforeDeadlineMs.Text = settings.DefaultBidBeforeDeadlineMs.ToString();
|
||||||
|
// ... altri campi ...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Struttura File settings.json
|
||||||
|
|
||||||
|
Le impostazioni vengono salvate in:
|
||||||
|
```
|
||||||
|
%LocalAppData%\AutoBidder\settings.json
|
||||||
|
```
|
||||||
|
|
||||||
|
Contenuto esempio:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"ExportPath": "C:\\Exports",
|
||||||
|
"LastExportExt": ".csv",
|
||||||
|
"ExportScope": "All",
|
||||||
|
"IncludeOnlyUsedBids": true,
|
||||||
|
"IncludeLogs": false,
|
||||||
|
"IncludeUserBids": false,
|
||||||
|
"ExportOpen": true,
|
||||||
|
"ExportClosed": true,
|
||||||
|
"ExportUnknown": true,
|
||||||
|
"IncludeMetadata": true,
|
||||||
|
"RemoveAfterExport": false,
|
||||||
|
"OverwriteExisting": false,
|
||||||
|
"DefaultBidBeforeDeadlineMs": 300,
|
||||||
|
"DefaultCheckAuctionOpenBeforeBid": false,
|
||||||
|
"DefaultMinPrice": 0,
|
||||||
|
"DefaultMaxPrice": 0,
|
||||||
|
"DefaultMaxClicks": 0
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Test di Verifica
|
||||||
|
|
||||||
|
### Test 1: Salvataggio e Applicazione Defaults
|
||||||
|
|
||||||
|
- [x] Modifica Anticipo da 200 a 300
|
||||||
|
- [x] Clicca "Salva Defaults"
|
||||||
|
- [x] Aggiungi nuova asta
|
||||||
|
- [x] Verifica che abbia Anticipo = 300ms
|
||||||
|
- [x] Log mostra salvataggio e applicazione
|
||||||
|
|
||||||
|
### Test 2: Persistenza tra Riavvii
|
||||||
|
|
||||||
|
- [x] Modifica Anticipo a 300
|
||||||
|
- [x] Salva Defaults
|
||||||
|
- [x] Chiudi applicazione
|
||||||
|
- [x] Riapri applicazione
|
||||||
|
- [x] Vai su Impostazioni
|
||||||
|
- [x] Verifica che mostri 300ms
|
||||||
|
|
||||||
|
### Test 3: Ripristino Defaults
|
||||||
|
|
||||||
|
- [x] Modifica Anticipo senza salvare
|
||||||
|
- [x] Clicca "Annulla"
|
||||||
|
- [x] Verifica che torni al valore salvato
|
||||||
|
- [x] Log mostra ripristino
|
||||||
|
|
||||||
|
### Test 4: Aste Esistenti Non Toccate
|
||||||
|
|
||||||
|
- [x] Crea asta con Anticipo = 200
|
||||||
|
- [x] Cambia defaults a 300
|
||||||
|
- [x] Prima asta mantiene 200
|
||||||
|
- [x] Nuova asta ha 300
|
||||||
|
|
||||||
|
## Vantaggi della Soluzione
|
||||||
|
|
||||||
|
### ?? 1. Coerenza
|
||||||
|
- Le impostazioni salvate vengono **sempre** applicate
|
||||||
|
- Non più sorprese con valori hardcoded
|
||||||
|
|
||||||
|
### ?? 2. Persistenza
|
||||||
|
- Le impostazioni **sopravvivono** ai riavvii
|
||||||
|
- File JSON in `%LocalAppData%`
|
||||||
|
|
||||||
|
### ?? 3. Flessibilità
|
||||||
|
- Ogni utente può avere i propri defaults
|
||||||
|
- Facile modificare defaults senza toccare codice
|
||||||
|
|
||||||
|
### ?? 4. Trasparenza
|
||||||
|
- Logging dettagliato di ogni operazione
|
||||||
|
- Si vede esattamente cosa viene salvato/caricato
|
||||||
|
|
||||||
|
## Note Tecniche
|
||||||
|
|
||||||
|
### Perché SettingsManager.Load() invece di Cache?
|
||||||
|
|
||||||
|
`SettingsManager.Load()` legge sempre da file, garantendo:
|
||||||
|
- ? **Aggiornamenti in tempo reale** se il file viene modificato manualmente
|
||||||
|
- ? **Thread-safe** (ogni lettura è isolata)
|
||||||
|
- ? **Nessun problema di sincronizzazione** tra diverse istanze
|
||||||
|
|
||||||
|
### Ordine di Caricamento
|
||||||
|
|
||||||
|
```
|
||||||
|
1. InitializeComponent()
|
||||||
|
2. _auctionMonitor = new AuctionMonitor()
|
||||||
|
3. LoadSavedAuctions() // Carica aste salvate
|
||||||
|
4. LoadExportSettings() // Carica export settings
|
||||||
|
5. LoadDefaultSettings() // ? NUOVO - Carica defaults
|
||||||
|
6. UpdateGlobalControlButtons()
|
||||||
|
```
|
||||||
|
|
||||||
|
### Quando vengono applicate le impostazioni?
|
||||||
|
|
||||||
|
| Azione | Impostazioni Applicate |
|
||||||
|
|--------|------------------------|
|
||||||
|
| Avvio app | Carica da file in UI |
|
||||||
|
| Aggiungi asta | Legge da file e applica |
|
||||||
|
| Modifica defaults | Applica solo a nuove aste |
|
||||||
|
| Salva defaults | Scrive su file |
|
||||||
|
| Riavvio app | Ricarica da file |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ? Riepilogo
|
||||||
|
|
||||||
|
**Prima**:
|
||||||
|
- ? Defaults hardcoded a 200ms
|
||||||
|
- ? Modifiche non persistenti
|
||||||
|
- ? Nuove aste usano sempre 200ms
|
||||||
|
|
||||||
|
**Dopo**:
|
||||||
|
- ? Defaults letti da `settings.json`
|
||||||
|
- ? Modifiche persistono tra riavvii
|
||||||
|
- ? Nuove aste usano valori salvati
|
||||||
|
- ? Logging dettagliato
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Data Fix**: 2025
|
||||||
|
**Versione**: 4.0+
|
||||||
|
**Issue**: Impostazioni predefinite non persistenti
|
||||||
|
**Status**: ? RISOLTO
|
||||||
341
Mimante/Documentation/FIX_SKIP_BID_IF_WINNER.md
Normal file
341
Mimante/Documentation/FIX_SKIP_BID_IF_WINNER.md
Normal file
@@ -0,0 +1,341 @@
|
|||||||
|
# ?? Fix Puntata su Asta Già Vinta
|
||||||
|
|
||||||
|
## Problema Rilevato
|
||||||
|
|
||||||
|
Il sistema tentava di **puntare anche quando l'utente era già il vincitore corrente** dell'asta, causando:
|
||||||
|
|
||||||
|
1. ? **Errori inutili** - La puntata falliva con messaggio "Asta chiusa" o simile
|
||||||
|
2. ? **Spreco risorse** - Chiamate API non necessarie
|
||||||
|
3. ? **Logging confuso** - Messaggi di errore quando tutto andava bene
|
||||||
|
4. ? **Puntate perse** - Tentativo di puntata quando non aveva senso
|
||||||
|
|
||||||
|
## Causa del Problema
|
||||||
|
|
||||||
|
Il metodo `ShouldBid()` non controllava se l'utente era già il vincitore corrente prima di decidere di puntare.
|
||||||
|
|
||||||
|
La logica era:
|
||||||
|
```csharp
|
||||||
|
// ? PRIMA - Non controllava IsMyBid
|
||||||
|
private bool ShouldBid(AuctionInfo auction, AuctionState state)
|
||||||
|
{
|
||||||
|
// Controlli prezzo, reset count, max clicks, cooldown...
|
||||||
|
// MA mancava: controllo se sono già vincitore!
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Scenario problematico:
|
||||||
|
1. ? Utente punta alle 10:00:00 e vince
|
||||||
|
2. ? Timer riparte da 20 secondi
|
||||||
|
3. ? Timer scende a 0.3 secondi (dentro finestra anticipo)
|
||||||
|
4. ? Sistema cerca di puntare di nuovo
|
||||||
|
5. ? Server risponde: "Asta chiusa" o errore simile
|
||||||
|
6. ? Log mostra errore anche se l'utente ha già vinto!
|
||||||
|
|
||||||
|
## Soluzione Implementata
|
||||||
|
|
||||||
|
### ? 1. Controllo `IsMyBid` in `ShouldBid()`
|
||||||
|
|
||||||
|
Aggiunto controllo come **prima condizione**:
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
private bool ShouldBid(AuctionInfo auction, AuctionState state)
|
||||||
|
{
|
||||||
|
// ? NUOVO: Non puntare se sono già il vincitore corrente
|
||||||
|
if (state.IsMyBid)
|
||||||
|
{
|
||||||
|
// Sono già io l'ultimo ad aver puntato, non serve puntare di nuovo
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ... altri controlli ...
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### ? 2. Logging Chiaro in `ExecuteBidStrategy()`
|
||||||
|
|
||||||
|
Aggiunto messaggio informativo quando si evita la puntata:
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
private async Task ExecuteBidStrategy(...)
|
||||||
|
{
|
||||||
|
if (timerMs <= auction.BidBeforeDeadlineMs)
|
||||||
|
{
|
||||||
|
auction.AddLog($"[STRATEGIA] Finestra di puntata raggiunta: {timerMs:F0}ms <= {auction.BidBeforeDeadlineMs}ms");
|
||||||
|
|
||||||
|
// ? NUOVO: Log quando skippo perché sono già vincitore
|
||||||
|
if (state.IsMyBid)
|
||||||
|
{
|
||||||
|
auction.AddLog($"[STRATEGIA] SKIP: Sono già il vincitore corrente (ultimo bidder: {state.LastBidder})");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ... continua con puntata ...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### ? 3. Come Funziona `IsMyBid`
|
||||||
|
|
||||||
|
Il flag `state.IsMyBid` viene calcolato in `BidooApiClient.ParsePollingResponse()`:
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
state.IsMyBid = !string.IsNullOrEmpty(_session.Username) &&
|
||||||
|
state.LastBidder.Equals(_session.Username, StringComparison.OrdinalIgnoreCase);
|
||||||
|
```
|
||||||
|
|
||||||
|
Confronta il `LastBidder` dall'API con lo `Username` della sessione (case-insensitive).
|
||||||
|
|
||||||
|
## Comportamento Atteso
|
||||||
|
|
||||||
|
### ? Scenario 1: Utente NON Vincitore (Deve Puntare)
|
||||||
|
|
||||||
|
```
|
||||||
|
Timer: 0.3s (dentro finestra 0.5s)
|
||||||
|
Ultimo bidder: "altroUtente123"
|
||||||
|
IsMyBid: false
|
||||||
|
|
||||||
|
[STRATEGIA] Finestra di puntata raggiunta: 300ms <= 500ms
|
||||||
|
[STRATEGIA] Eseguo puntata...
|
||||||
|
[BID OK] Latenza: 45ms -> EUR 1.50
|
||||||
|
```
|
||||||
|
|
||||||
|
**Risultato**: ? Punta correttamente
|
||||||
|
|
||||||
|
### ? Scenario 2: Utente GIÀ Vincitore (SKIP Puntata)
|
||||||
|
|
||||||
|
```
|
||||||
|
Timer: 0.3s (dentro finestra 0.5s)
|
||||||
|
Ultimo bidder: "miousername"
|
||||||
|
IsMyBid: true
|
||||||
|
|
||||||
|
[STRATEGIA] Finestra di puntata raggiunta: 300ms <= 500ms
|
||||||
|
[STRATEGIA] SKIP: Sono già il vincitore corrente (ultimo bidder: miousername)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Risultato**: ? NON punta (evita errore)
|
||||||
|
|
||||||
|
### ? Scenario 3: Altro Utente Supera
|
||||||
|
|
||||||
|
```
|
||||||
|
t=10s: Io puntp -> IsMyBid = true
|
||||||
|
t=8s: [STRATEGIA] SKIP: Sono già vincitore
|
||||||
|
t=6s: [STRATEGIA] SKIP: Sono già vincitore
|
||||||
|
t=4s: altroUtente punta -> IsMyBid = false
|
||||||
|
t=0.3s: [STRATEGIA] Finestra raggiunta
|
||||||
|
t=0.3s: [BID OK] Riprendo il controllo!
|
||||||
|
```
|
||||||
|
|
||||||
|
**Risultato**: ? Punta solo quando necessario
|
||||||
|
|
||||||
|
## Vantaggi della Soluzione
|
||||||
|
|
||||||
|
### ?? 1. Nessun Errore Inutile
|
||||||
|
- ? **Prima**: "Asta chiusa" quando eri già vincitore
|
||||||
|
- ? **Dopo**: Nessun errore, log chiaro
|
||||||
|
|
||||||
|
### ?? 2. Risparmio Risorse
|
||||||
|
- ? **Prima**: Chiamata API inutile quando già vincitore
|
||||||
|
- ? **Dopo**: Skip immediato, nessuna chiamata
|
||||||
|
|
||||||
|
### ?? 3. Logging Trasparente
|
||||||
|
```
|
||||||
|
? [STRATEGIA] SKIP: Sono già il vincitore corrente
|
||||||
|
```
|
||||||
|
Invece di:
|
||||||
|
```
|
||||||
|
? [BID FAIL] Asta chiusa
|
||||||
|
```
|
||||||
|
|
||||||
|
### ?? 4. Strategia Ottimizzata
|
||||||
|
- Punta **solo** quando serve riprendersi l'asta
|
||||||
|
- Non spreca puntate quando sei già vincitore
|
||||||
|
|
||||||
|
## Test Scenario
|
||||||
|
|
||||||
|
### Test 1: Vincitore Corrente (Non Deve Puntare)
|
||||||
|
|
||||||
|
**Setup**:
|
||||||
|
- Imposta Anticipo = 500ms
|
||||||
|
- Aggiungi asta X
|
||||||
|
- Punta manualmente
|
||||||
|
- Sei il vincitore (LastBidder = "tuousername")
|
||||||
|
|
||||||
|
**Verifica**:
|
||||||
|
1. ? Timer scende da 20s a 0.4s
|
||||||
|
2. ? Log: `[STRATEGIA] Finestra di puntata raggiunta: 400ms <= 500ms`
|
||||||
|
3. ? Log: `[STRATEGIA] SKIP: Sono già il vincitore corrente`
|
||||||
|
4. ? **Nessuna puntata** effettuata
|
||||||
|
5. ? **Nessun errore** mostrato
|
||||||
|
|
||||||
|
### Test 2: Altro Utente Supera (Deve Puntare)
|
||||||
|
|
||||||
|
**Setup**:
|
||||||
|
- Sei il vincitore
|
||||||
|
- Altro utente punta e diventa vincitore
|
||||||
|
- Timer scende a 0.3s
|
||||||
|
|
||||||
|
**Verifica**:
|
||||||
|
1. ? Log: `[STRATEGIA] Finestra di puntata raggiunta: 300ms <= 500ms`
|
||||||
|
2. ? **Nessun SKIP** (non sei più vincitore)
|
||||||
|
3. ? Log: `[BID OK] Latenza: XXms`
|
||||||
|
4. ? Puntata **effettuata correttamente**
|
||||||
|
|
||||||
|
### Test 3: Alternanza Vincitori
|
||||||
|
|
||||||
|
**Setup**:
|
||||||
|
- Tu: punta
|
||||||
|
- Altro: punta
|
||||||
|
- Tu: riprende controllo
|
||||||
|
- Altro: riprende controllo
|
||||||
|
|
||||||
|
**Verifica**:
|
||||||
|
- ? SKIP solo quando sei vincitore
|
||||||
|
- ? Punta solo quando NON sei vincitore
|
||||||
|
- ? Log chiaro per ogni decisione
|
||||||
|
|
||||||
|
## File Modificati
|
||||||
|
|
||||||
|
### 1. ? `Services\AuctionMonitor.cs`
|
||||||
|
|
||||||
|
**Modifiche**:
|
||||||
|
- `ShouldBid()`: Aggiunto controllo `state.IsMyBid` come prima condizione
|
||||||
|
- `ExecuteBidStrategy()`: Aggiunto logging quando si skippa per vincitore corrente
|
||||||
|
|
||||||
|
**Prima**:
|
||||||
|
```csharp
|
||||||
|
private bool ShouldBid(AuctionInfo auction, AuctionState state)
|
||||||
|
{
|
||||||
|
// ? Mancava controllo IsMyBid
|
||||||
|
|
||||||
|
// Controlli prezzo...
|
||||||
|
// Controlli reset...
|
||||||
|
// Controlli clicks...
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Dopo**:
|
||||||
|
```csharp
|
||||||
|
private bool ShouldBid(AuctionInfo auction, AuctionState state)
|
||||||
|
{
|
||||||
|
// ? NUOVO: Prima controlla se sei già vincitore
|
||||||
|
if (state.IsMyBid)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ... altri controlli ...
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Ordine di Controllo in `ShouldBid()`
|
||||||
|
|
||||||
|
```
|
||||||
|
1. ? IsMyBid? ? false (skip, sei già vincitore)
|
||||||
|
2. ? Price OK? ? false (skip, prezzo fuori range)
|
||||||
|
3. ? Reset Count OK? ? false (skip, troppi/pochi reset)
|
||||||
|
4. ? Max Clicks OK? ? false (skip, raggiunto limite click)
|
||||||
|
5. ? Cooldown OK? ? false (skip, troppo presto dall'ultimo click)
|
||||||
|
6. ? Tutti OK? ? true (PUNTA!)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Importante**: `IsMyBid` è il **primo** controllo perché è la condizione più comune e più veloce da verificare.
|
||||||
|
|
||||||
|
## Note Tecniche
|
||||||
|
|
||||||
|
### Perché Prima Condizione?
|
||||||
|
|
||||||
|
1. **Performance**: Controllo più veloce (confronto string)
|
||||||
|
2. **Frequenza**: Caso più comune quando monitori un'asta che già vinci
|
||||||
|
3. **Logica**: Non ha senso controllare prezzo/reset se sei già vincitore
|
||||||
|
|
||||||
|
### Quando `IsMyBid` è `true`?
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// In BidooApiClient.cs
|
||||||
|
state.IsMyBid = !string.IsNullOrEmpty(_session.Username) &&
|
||||||
|
state.LastBidder.Equals(_session.Username, StringComparison.OrdinalIgnoreCase);
|
||||||
|
```
|
||||||
|
|
||||||
|
Condizioni:
|
||||||
|
- ? Sessione ha username valido
|
||||||
|
- ? LastBidder dall'API = Username sessione (case-insensitive)
|
||||||
|
|
||||||
|
### Possibili Edge Case
|
||||||
|
|
||||||
|
#### Caso 1: Username Non Impostato
|
||||||
|
```
|
||||||
|
_session.Username = null o ""
|
||||||
|
? IsMyBid = false sempre
|
||||||
|
? Sistema continua a puntare
|
||||||
|
```
|
||||||
|
**Soluzione**: Richiedi sempre configurazione sessione all'avvio
|
||||||
|
|
||||||
|
#### Caso 2: Username Diverso (Typo)
|
||||||
|
```
|
||||||
|
Username sessione: "MioUsername"
|
||||||
|
LastBidder API: "miousername"
|
||||||
|
? IsMyBid = false (StringComparison.OrdinalIgnoreCase gestisce)
|
||||||
|
```
|
||||||
|
**Soluzione**: Confronto case-insensitive già implementato
|
||||||
|
|
||||||
|
## Log Esempi
|
||||||
|
|
||||||
|
### Log Normale (Non Vincitore)
|
||||||
|
```
|
||||||
|
[STRATEGIA] Finestra di puntata raggiunta: 450ms <= 500ms
|
||||||
|
[BID OK] Latenza: 42ms -> EUR 1.25
|
||||||
|
```
|
||||||
|
|
||||||
|
### Log con SKIP (Già Vincitore)
|
||||||
|
```
|
||||||
|
[STRATEGIA] Finestra di puntata raggiunta: 380ms <= 500ms
|
||||||
|
[STRATEGIA] SKIP: Sono già il vincitore corrente (ultimo bidder: miousername)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Log Alternanza
|
||||||
|
```
|
||||||
|
[STRATEGIA] Finestra di puntata raggiunta: 450ms <= 500ms
|
||||||
|
[STRATEGIA] SKIP: Sono già il vincitore corrente (ultimo bidder: miousername)
|
||||||
|
[RESET] Puntata: EUR 1.30 da altroUtente
|
||||||
|
[STRATEGIA] Finestra di puntata raggiunta: 420ms <= 500ms
|
||||||
|
[BID OK] Latenza: 38ms -> EUR 1.31
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ? Test di Verifica
|
||||||
|
|
||||||
|
- [x] Non punta quando è già vincitore
|
||||||
|
- [x] Log mostra SKIP con motivo chiaro
|
||||||
|
- [x] Punta quando altro utente supera
|
||||||
|
- [x] Nessun errore "Asta chiusa" quando vincitore
|
||||||
|
- [x] Risparmia chiamate API inutili
|
||||||
|
- [x] Logging chiaro in tutti gli scenari
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Data Fix**: 2025
|
||||||
|
**Versione**: 4.0+
|
||||||
|
**Issue**: Puntata inutile quando già vincitore
|
||||||
|
**Status**: ? RISOLTO
|
||||||
|
|
||||||
|
## Riepilogo
|
||||||
|
|
||||||
|
**Prima**:
|
||||||
|
- ? Puntava anche quando già vincitore
|
||||||
|
- ? Errori "Asta chiusa" senza motivo
|
||||||
|
- ? Spreco risorse e puntate
|
||||||
|
|
||||||
|
**Dopo**:
|
||||||
|
- ? SKIP automatico se già vincitore
|
||||||
|
- ? Log chiaro: `[STRATEGIA] SKIP: Sono già il vincitore corrente`
|
||||||
|
- ? Punta solo quando serve riprendersi l'asta
|
||||||
|
- ? Nessun errore inutile
|
||||||
@@ -204,7 +204,6 @@
|
|||||||
BrowserForwardClicked="Browser_BrowserForwardClicked"
|
BrowserForwardClicked="Browser_BrowserForwardClicked"
|
||||||
BrowserRefreshClicked="Browser_BrowserRefreshClicked"
|
BrowserRefreshClicked="Browser_BrowserRefreshClicked"
|
||||||
BrowserHomeClicked="Browser_BrowserHomeClicked"
|
BrowserHomeClicked="Browser_BrowserHomeClicked"
|
||||||
BrowserGoClicked="Browser_BrowserGoClicked"
|
|
||||||
BrowserAddAuctionClicked="Browser_BrowserAddAuctionClicked"/>
|
BrowserAddAuctionClicked="Browser_BrowserAddAuctionClicked"/>
|
||||||
|
|
||||||
<!-- Puntate Gratis Panel (PLACEHOLDER STYLE) -->
|
<!-- Puntate Gratis Panel (PLACEHOLDER STYLE) -->
|
||||||
|
|||||||
@@ -112,6 +112,9 @@ namespace AutoBidder
|
|||||||
// Load export settings (from MainWindow.EventHandlers.Export.cs)
|
// Load export settings (from MainWindow.EventHandlers.Export.cs)
|
||||||
LoadExportSettings();
|
LoadExportSettings();
|
||||||
|
|
||||||
|
// CARICA IMPOSTAZIONI PREDEFINITE ASTE
|
||||||
|
LoadDefaultSettings();
|
||||||
|
|
||||||
// Update initial button states
|
// Update initial button states
|
||||||
UpdateGlobalControlButtons();
|
UpdateGlobalControlButtons();
|
||||||
|
|
||||||
|
|||||||
@@ -323,6 +323,13 @@ namespace AutoBidder.Services
|
|||||||
{
|
{
|
||||||
auction.AddLog($"[STRATEGIA] Finestra di puntata raggiunta: {timerMs:F0}ms <= {auction.BidBeforeDeadlineMs}ms");
|
auction.AddLog($"[STRATEGIA] Finestra di puntata raggiunta: {timerMs:F0}ms <= {auction.BidBeforeDeadlineMs}ms");
|
||||||
|
|
||||||
|
// ? NUOVO: Controlla se sono già io il vincitore corrente
|
||||||
|
if (state.IsMyBid)
|
||||||
|
{
|
||||||
|
auction.AddLog($"[STRATEGIA] SKIP: Sono già il vincitore corrente (ultimo bidder: {state.LastBidder})");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Controlla se qualcun altro ha puntato di recente
|
// Controlla se qualcun altro ha puntato di recente
|
||||||
var lastBidTime = GetLastBidTime(auction, state.LastBidder);
|
var lastBidTime = GetLastBidTime(auction, state.LastBidder);
|
||||||
if (lastBidTime.HasValue)
|
if (lastBidTime.HasValue)
|
||||||
@@ -410,6 +417,13 @@ namespace AutoBidder.Services
|
|||||||
|
|
||||||
private bool ShouldBid(AuctionInfo auction, AuctionState state)
|
private bool ShouldBid(AuctionInfo auction, AuctionState state)
|
||||||
{
|
{
|
||||||
|
// ? NUOVO: Non puntare se sono già il vincitore corrente
|
||||||
|
if (state.IsMyBid)
|
||||||
|
{
|
||||||
|
// Sono già io l'ultimo ad aver puntato, non serve puntare di nuovo
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Price check
|
// Price check
|
||||||
if (auction.MinPrice > 0 && state.Price < auction.MinPrice)
|
if (auction.MinPrice > 0 && state.Price < auction.MinPrice)
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
Reference in New Issue
Block a user