Aggiunto limite configurabile storia puntate
Introdotta la possibilità di configurare un limite massimo di puntate visualizzabili nella scheda "Storia Puntate" tramite l'interfaccia utente. La nuova proprietà `MaxBidHistoryEntries` è stata aggiunta alle impostazioni e salvata in modo persistente. - Aggiunti controlli UI per configurare il limite. - Implementata persistenza della lista `RecentBids` con serializzazione JSON. - Introdotto il metodo `MergeBidHistory` per unire puntate evitando duplicati e mantenendo ordine cronologico decrescente. - Sincronizzate le statistiche utenti (`BidderStats`) con la lista `RecentBids`. - Ripristinata la proprietà `IsMyBid` al caricamento delle aste salvate. - Ottimizzate le performance con `HashSet` per deduplicazione e limite configurabile. - Creato il file `FIX_BID_HISTORY_PERSISTENCE.md` per documentare il problema e la soluzione. - Garantita compatibilità retroattiva con aste salvate. Questi aggiornamenti migliorano la gestione, la visualizzazione e la persistenza della storia delle puntate, offrendo un'esperienza utente più robusta e intuitiva.
This commit is contained in:
@@ -249,10 +249,10 @@ namespace AutoBidder.Services
|
||||
|
||||
auction.PollingLatencyMs = state.PollingLatencyMs;
|
||||
|
||||
// ? NUOVO: Aggiorna storia puntate da API
|
||||
// ? AGGIORNATO: Aggiorna storia puntate mantenendo quelle vecchie
|
||||
if (state.RecentBidsHistory != null && state.RecentBidsHistory.Count > 0)
|
||||
{
|
||||
auction.RecentBids = state.RecentBidsHistory;
|
||||
MergeBidHistory(auction, state.RecentBidsHistory);
|
||||
}
|
||||
|
||||
if (state.Status == AuctionStatus.EndedWon ||
|
||||
@@ -563,6 +563,146 @@ namespace AutoBidder.Services
|
||||
return lastEntry?.Timer ?? 999;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unisce la storia puntate ricevuta dall'API con quella esistente,
|
||||
/// mantenendo le puntate più vecchie e aggiungendo solo le nuove.
|
||||
/// Le puntate sono ordinate con le più RECENTI in CIMA.
|
||||
/// </summary>
|
||||
private void MergeBidHistory(AuctionInfo auction, List<BidHistoryEntry> newBids)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Carica impostazioni per limite massimo
|
||||
var settings = Utilities.SettingsManager.Load();
|
||||
var maxEntries = settings?.MaxBidHistoryEntries ?? 20;
|
||||
|
||||
// Se la lista esistente è vuota, semplicemente copia le nuove
|
||||
if (auction.RecentBids.Count == 0)
|
||||
{
|
||||
auction.RecentBids = newBids.ToList();
|
||||
|
||||
// Ordina per timestamp DECRESCENTE (più recenti in cima)
|
||||
auction.RecentBids = auction.RecentBids
|
||||
.OrderByDescending(b => b.Timestamp)
|
||||
.ToList();
|
||||
|
||||
// Limita se necessario
|
||||
if (maxEntries > 0 && auction.RecentBids.Count > maxEntries)
|
||||
{
|
||||
auction.RecentBids = auction.RecentBids
|
||||
.Take(maxEntries)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
// Aggiorna statistiche bidder basandosi su RecentBids
|
||||
UpdateBidderStatsFromRecentBids(auction);
|
||||
return;
|
||||
}
|
||||
|
||||
// Crea un HashSet delle puntate esistenti per ricerca veloce
|
||||
// Usiamo una chiave composta: timestamp + username + price per identificare univocamente una puntata
|
||||
var existingBidsKeys = new HashSet<string>(
|
||||
auction.RecentBids.Select(b => $"{b.Timestamp}_{b.Username}_{b.Price:F2}")
|
||||
);
|
||||
|
||||
// Aggiungi solo le puntate nuove (non duplicate)
|
||||
var bidsToAdd = newBids
|
||||
.Where(b => !existingBidsKeys.Contains($"{b.Timestamp}_{b.Username}_{b.Price:F2}"))
|
||||
.ToList();
|
||||
|
||||
if (bidsToAdd.Count > 0)
|
||||
{
|
||||
auction.RecentBids.AddRange(bidsToAdd);
|
||||
|
||||
// Ordina per timestamp DECRESCENTE (più recenti in cima)
|
||||
auction.RecentBids = auction.RecentBids
|
||||
.OrderByDescending(b => b.Timestamp)
|
||||
.ToList();
|
||||
|
||||
// Limita al numero massimo di puntate (mantieni le più recenti = prime della lista)
|
||||
if (maxEntries > 0 && auction.RecentBids.Count > maxEntries)
|
||||
{
|
||||
auction.RecentBids = auction.RecentBids
|
||||
.Take(maxEntries)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
// Aggiorna statistiche bidder basandosi su RecentBids
|
||||
UpdateBidderStatsFromRecentBids(auction);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
auction.AddLog($"[WARN] Errore merge storia puntate: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Aggiorna le statistiche dei bidder basandosi sulla lista RecentBids (fonte ufficiale).
|
||||
/// Raggruppa le puntate per utente e conta il numero di puntate per ciascuno.
|
||||
/// </summary>
|
||||
private void UpdateBidderStatsFromRecentBids(AuctionInfo auction)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Raggruppa puntate per username
|
||||
var bidsByUser = auction.RecentBids
|
||||
.GroupBy(b => b.Username, StringComparer.OrdinalIgnoreCase)
|
||||
.ToDictionary(
|
||||
g => g.Key,
|
||||
g => new
|
||||
{
|
||||
Count = g.Count(),
|
||||
LastBidTime = DateTimeOffset.FromUnixTimeSeconds(g.Max(b => b.Timestamp)).DateTime
|
||||
},
|
||||
StringComparer.OrdinalIgnoreCase
|
||||
);
|
||||
|
||||
// Aggiorna o crea BidderInfo per ogni utente
|
||||
foreach (var kvp in bidsByUser)
|
||||
{
|
||||
var username = kvp.Key;
|
||||
var stats = kvp.Value;
|
||||
|
||||
if (!auction.BidderStats.ContainsKey(username))
|
||||
{
|
||||
auction.BidderStats[username] = new BidderInfo
|
||||
{
|
||||
Username = username,
|
||||
BidCount = stats.Count,
|
||||
LastBidTime = stats.LastBidTime
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
// Aggiorna statistiche esistenti
|
||||
var existing = auction.BidderStats[username];
|
||||
existing.BidCount = stats.Count;
|
||||
existing.LastBidTime = stats.LastBidTime;
|
||||
}
|
||||
}
|
||||
|
||||
// Rimuovi bidder che non sono più in RecentBids
|
||||
var usersInRecentBids = new HashSet<string>(
|
||||
auction.RecentBids.Select(b => b.Username),
|
||||
StringComparer.OrdinalIgnoreCase
|
||||
);
|
||||
|
||||
var usersToRemove = auction.BidderStats.Keys
|
||||
.Where(u => !usersInRecentBids.Contains(u))
|
||||
.ToList();
|
||||
|
||||
foreach (var user in usersToRemove)
|
||||
{
|
||||
auction.BidderStats.Remove(user);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
auction.AddLog($"[WARN] Errore aggiornamento statistiche bidder: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Stop();
|
||||
|
||||
@@ -344,11 +344,19 @@ namespace AutoBidder.Services
|
||||
if (!int.TryParse(currentPriceStr, out var currentPriceIndex))
|
||||
return null;
|
||||
|
||||
// 📊 NUOVO: Carica impostazione limite visualizzazione puntate
|
||||
var settings = Utilities.SettingsManager.Load();
|
||||
var maxEntries = settings?.MaxBidHistoryEntries ?? 20; // Default 20 se non impostato
|
||||
|
||||
foreach (var record in records)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(record))
|
||||
continue;
|
||||
|
||||
// 📊 Limita il numero di puntate basandosi sulle impostazioni
|
||||
if (maxEntries > 0 && entries.Count >= maxEntries)
|
||||
break;
|
||||
|
||||
var parts = record.Split(';');
|
||||
if (parts.Length < 4)
|
||||
continue;
|
||||
|
||||
Reference in New Issue
Block a user