Refactoring gestione sessione e persistenza impostazioni

Introdotto `SessionService` per centralizzare la gestione della
sessione utente, migliorando la separazione delle responsabilità
e la testabilità. Risolto il problema del caricamento del cookie
di autenticazione all'avvio e garantita la persistenza delle
checkbox di esportazione (`IncludeMetadata`, `RemoveAfterExport`,
`OverwriteExisting`).

Ottimizzata la gestione della barra degli indirizzi del browser
con aggiornamenti locali immediati. Applicato il pattern "Load ?
Modify ? Save" per il salvataggio delle impostazioni, migliorando
la simmetria e la leggibilità del codice. Logging centralizzato
e semplificato per eventi rilevanti.

Aggiornata la documentazione per riflettere i cambiamenti e
verificati i test per garantire il corretto funzionamento.
This commit is contained in:
2025-11-24 12:00:13 +01:00
parent ee67bedc31
commit 62d5cebf9c
22 changed files with 5244 additions and 299 deletions
+117 -28
View File
@@ -4,6 +4,7 @@ using System.Threading.Tasks;
using System.Windows;
using AutoBidder.Models;
using AutoBidder.ViewModels;
using AutoBidder.Utilities;
namespace AutoBidder
{
@@ -63,7 +64,28 @@ namespace AutoBidder
// CARICA IMPOSTAZIONI PREDEFINITE SALVATE
var settings = Utilities.SettingsManager.Load();
// Crea model con valori dalle impostazioni salvate - ASTA STOPPATA ALL'INIZIO
// ? NUOVO: Determina stato iniziale dalla configurazione
bool isActive = false;
bool isPaused = false;
switch (settings.DefaultNewAuctionState)
{
case "Active":
isActive = true;
isPaused = false;
break;
case "Paused":
isActive = true;
isPaused = true;
break;
case "Stopped":
default:
isActive = false;
isPaused = false;
break;
}
// Crea model con valori dalle impostazioni salvate e stato configurato
var auction = new AuctionInfo
{
AuctionId = auctionId,
@@ -71,8 +93,8 @@ namespace AutoBidder
OriginalUrl = originalUrl,
BidBeforeDeadlineMs = settings.DefaultBidBeforeDeadlineMs,
CheckAuctionOpenBeforeBid = settings.DefaultCheckAuctionOpenBeforeBid,
IsActive = false, // STOPPATA
IsPaused = false
IsActive = isActive,
IsPaused = isPaused
};
// Aggiungi al monitor
@@ -87,11 +109,20 @@ namespace AutoBidder
};
_auctionViewModels.Add(vm);
// ? NUOVO: Auto-start del monitoraggio se l'asta è attiva e il monitoraggio è fermo
if (isActive && !_isAutomationActive)
{
_auctionMonitor.Start();
_isAutomationActive = true;
Log($"[AUTO-START] Monitoraggio avviato automaticamente per nuova asta: {vm.Name}", LogLevel.Info);
}
SaveAuctions();
UpdateTotalCount();
UpdateGlobalControlButtons(); // Aggiorna stato pulsanti globali
UpdateGlobalControlButtons();
Log($"[ADD] Asta aggiunta con defaults: Anticipo={settings.DefaultBidBeforeDeadlineMs}ms, MinPrice=€{settings.DefaultMinPrice:F2}, MaxPrice=€{settings.DefaultMaxPrice:F2}, MaxClicks={settings.DefaultMaxClicks}", Utilities.LogLevel.Info);
var stateText = isActive ? (isPaused ? "Paused" : "Active") : "Stopped";
Log($"[ADD] Asta aggiunta con stato={stateText}, Anticipo={settings.DefaultBidBeforeDeadlineMs}ms", Utilities.LogLevel.Info);
}
catch (Exception ex)
{
@@ -130,10 +161,10 @@ namespace AutoBidder
{
using var httpClient = new System.Net.Http.HttpClient();
var html = await httpClient.GetStringAsync(url);
var match = System.Text.RegularExpressions.Regex.Match(html, @"<title>([^<]+)</title>");
if (match.Success)
var match2 = System.Text.RegularExpressions.Regex.Match(html, @"<title>([^<]+)</title>");
if (match2.Success)
{
name = System.Net.WebUtility.HtmlDecode(match.Groups[1].Value.Trim().Replace(" - Bidoo", ""));
name = System.Net.WebUtility.HtmlDecode(match2.Groups[1].Value.Trim().Replace(" - Bidoo", ""));
}
}
catch { }
@@ -141,7 +172,28 @@ namespace AutoBidder
// CARICA IMPOSTAZIONI PREDEFINITE SALVATE
var settings = Utilities.SettingsManager.Load();
// Crea model con valori dalle impostazioni salvate - ASTA STOPPATA ALL'INIZIO
// ? NUOVO: Determina stato iniziale dalla configurazione
bool isActive = false;
bool isPaused = false;
switch (settings.DefaultNewAuctionState)
{
case "Active":
isActive = true;
isPaused = false;
break;
case "Paused":
isActive = true;
isPaused = true;
break;
case "Stopped":
default:
isActive = false;
isPaused = false;
break;
}
// Crea model con valori dalle impostazioni salvate e stato configurato
var auction = new AuctionInfo
{
AuctionId = auctionId,
@@ -149,8 +201,8 @@ namespace AutoBidder
OriginalUrl = url,
BidBeforeDeadlineMs = settings.DefaultBidBeforeDeadlineMs,
CheckAuctionOpenBeforeBid = settings.DefaultCheckAuctionOpenBeforeBid,
IsActive = false, // STOPPATA
IsPaused = false
IsActive = isActive,
IsPaused = isPaused
};
// Aggiungi al monitor
@@ -165,11 +217,20 @@ namespace AutoBidder
};
_auctionViewModels.Add(vm);
// ? NUOVO: Auto-start del monitoraggio se l'asta è attiva e il monitoraggio è fermo
if (isActive && !_isAutomationActive)
{
_auctionMonitor.Start();
_isAutomationActive = true;
Log($"[AUTO-START] Monitoraggio avviato automaticamente per nuova asta: {vm.Name}", LogLevel.Info);
}
SaveAuctions();
UpdateTotalCount();
UpdateGlobalControlButtons(); // Aggiorna stato pulsanti globali
UpdateGlobalControlButtons();
Log($"[ADD] Asta aggiunta con defaults: Anticipo={settings.DefaultBidBeforeDeadlineMs}ms", Utilities.LogLevel.Info);
var stateText = isActive ? (isPaused ? "Paused" : "Active") : "Stopped";
Log($"[ADD] Asta aggiunta con stato={stateText}, Anticipo={settings.DefaultBidBeforeDeadlineMs}ms", Utilities.LogLevel.Info);
}
catch (Exception ex)
{
@@ -195,6 +256,10 @@ namespace AutoBidder
{
try
{
// ? Carica impostazioni per determinare lo stato iniziale delle aste
var settings = Utilities.SettingsManager.Load();
var loadState = settings.DefaultStartAuctionsOnLoad; // "Active", "Paused", "Stopped"
var auctions = Utilities.PersistenceManager.LoadAuctions();
foreach (var auction in auctions)
{
@@ -204,34 +269,58 @@ namespace AutoBidder
// Decode HTML entities
try { auction.Name = System.Net.WebUtility.HtmlDecode(auction.Name ?? string.Empty); } catch { }
// ? Applica stato iniziale configurato dall'utente
switch (loadState)
{
case "Active":
auction.IsActive = true;
auction.IsPaused = false;
break;
case "Paused":
auction.IsActive = true;
auction.IsPaused = true;
break;
case "Stopped":
default:
auction.IsActive = false;
auction.IsPaused = false;
break;
}
_auctionMonitor.AddAuction(auction);
var vm = new AuctionViewModel(auction);
_auctionViewModels.Add(vm);
}
// ? FIX: Avvia monitoraggio se ci sono aste in stato Active O Paused
// (Paused = IsActive=true ma IsPaused=true, quindi vanno monitorate)
bool hasActiveOrPausedAuctions = auctions.Any(a => a.IsActive);
// On startup treat persisted auctions as stopped
foreach (var vm in _auctionViewModels)
if (hasActiveOrPausedAuctions && auctions.Count > 0)
{
vm.IsActive = false;
vm.IsPaused = false;
_auctionMonitor.Start();
_isAutomationActive = true;
if (loadState == "Active")
{
Log($"[AUTO-START] Monitoraggio avviato automaticamente per {auctions.Count} aste caricate in stato attivo", LogLevel.Info);
}
else if (loadState == "Paused")
{
Log($"[AUTO-START] Monitoraggio avviato automaticamente per {auctions.Count} aste caricate in pausa", LogLevel.Info);
}
}
UpdateTotalCount();
UpdateGlobalControlButtons(); // Aggiorna stato pulsanti dopo caricamento
if (auctions.Count > 0)
{
Log($"[OK] Caricate {auctions.Count} aste salvate");
}
LoadSavedSession();
UpdateGlobalControlButtons();
Log($"[LOAD] {auctions.Count} aste caricate con stato iniziale: {loadState}", LogLevel.Info);
}
catch (Exception ex)
{
Log($"[ERRORE] Errore caricamento aste: {ex.Message}");
Log($"[ERRORE] Caricamento aste: {ex.Message}", LogLevel.Error);
}
}
/// <summary>
/// Aggiorna i dettagli dell'asta selezionata nel pannello Info Prodotto
/// </summary>