- Implement ThemeManager for dynamic light/dark theme switching in the application. - Create Wait class for cancellable delays without exceptions for smoother user experience. - Introduce WatchedProductsStore to manage and persist watched products in JSON format. - Add WindowsNotifier for system notifications to inform users of important events. - Develop ProductViewModel to encapsulate product data and manage UI interactions effectively.
125 lines
4.9 KiB
C#
125 lines
4.9 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Windows;
|
|
using AutoBidder.Models;
|
|
using AutoBidder.Services;
|
|
using AutoBidder.Utilities;
|
|
using AutoBidder.ViewModels;
|
|
|
|
namespace AutoBidder
|
|
{
|
|
/// <summary>
|
|
/// Prodotti seguiti: le aste nuove dello stesso articolo entrano nel monitor da sole.
|
|
///
|
|
/// L'aggiunta qui deve essere silenziosa — succede mentre l'utente sta facendo altro,
|
|
/// quindi niente finestre di dialogo: solo righe di log.
|
|
/// </summary>
|
|
public partial class MainWindow
|
|
{
|
|
private ProductWatchService? _productWatcher;
|
|
|
|
/// <summary>Aste presenti nel monitor perché aggiunte automaticamente.</summary>
|
|
private readonly HashSet<string> _autoAddedAuctionIds = new(StringComparer.Ordinal);
|
|
|
|
private void StartProductWatcher()
|
|
{
|
|
try
|
|
{
|
|
_productWatcher = new ProductWatchService(CatalogClient)
|
|
{
|
|
CountAutoAdded = () => _autoAddedAuctionIds.Count(id =>
|
|
_auctionViewModels.Any(a => a.AuctionId == id))
|
|
};
|
|
|
|
_productWatcher.OnLog += msg => Dispatcher.BeginInvoke(() => Log(msg, LogLevel.Info));
|
|
_productWatcher.OnAuctionFound += (auction, product) =>
|
|
Dispatcher.BeginInvoke(() => AutoAddAuction(auction, product));
|
|
|
|
_productWatcher.Start();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log($"[SEGUITI] Impossibile avviare la sorveglianza: {ex.Message}", LogLevel.Error);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Aggiunge al monitor un'asta trovata dalla sorveglianza. Volutamente separata da
|
|
/// AddAuctionById: quella mostra finestre di dialogo, qui inaccettabili.
|
|
/// </summary>
|
|
private void AutoAddAuction(CatalogAuction auction, WatchedProduct product)
|
|
{
|
|
try
|
|
{
|
|
// Marcala comunque: anche se la scartiamo, non va riproposta a ogni giro.
|
|
WatchedProductsStore.MarkHandled(auction.AuctionId);
|
|
|
|
if (_auctionViewModels.Any(a => a.AuctionId == auction.AuctionId)) return;
|
|
|
|
var settings = SettingsManager.Load();
|
|
|
|
// I limiti del prodotto, dove ci sono, hanno la precedenza sui predefiniti:
|
|
// è il senso della scheda Prodotti.
|
|
var limits = ProductRuleResolver.Resolve(product, settings);
|
|
|
|
var info = new AuctionInfo
|
|
{
|
|
AuctionId = auction.AuctionId,
|
|
Name = DecodeAllHtmlEntities(auction.Name),
|
|
OriginalUrl = auction.Url,
|
|
BidBeforeDeadlineMs = settings.DefaultBidBeforeDeadlineMs,
|
|
BuyNowPrice = auction.BuyNowPrice.HasValue ? (double)auction.BuyNowPrice.Value : null,
|
|
State = limits.State
|
|
};
|
|
|
|
_auctionMonitor.AddAuction(info);
|
|
|
|
var vm = new AuctionViewModel(info)
|
|
{
|
|
MinPrice = limits.MinPrice,
|
|
MaxPrice = limits.MaxPrice,
|
|
MaxClicks = limits.MaxClicks
|
|
};
|
|
_auctionViewModels.Add(vm);
|
|
_autoAddedAuctionIds.Add(auction.AuctionId);
|
|
|
|
// Un'asta che entra in Osserva o Attiva ha bisogno del motore acceso.
|
|
if (info.State != RunState.Stopped && !_isAutomationActive)
|
|
{
|
|
_auctionMonitor.Start();
|
|
_isAutomationActive = true;
|
|
}
|
|
|
|
WatchedProductsStore.CountAutoAdd(product);
|
|
|
|
SaveAuctions();
|
|
UpdateTotalCount();
|
|
UpdateGlobalControlButtons();
|
|
RefreshMonitorHeader();
|
|
|
|
var origine = limits.FromProduct ? " — limiti del prodotto" : "";
|
|
Log($"[SEGUITI] Aggiunta automaticamente: {info.Name} ({StateLabel(product.AutoAddState ?? settings.AutoAddNewAuctionState)}){origine}",
|
|
LogLevel.Success);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log($"[SEGUITI] Aggiunta automatica non riuscita: {ex.Message}", LogLevel.Error);
|
|
}
|
|
}
|
|
|
|
/// <summary>Applica a caldo le impostazioni della sorveglianza dopo un salvataggio.</summary>
|
|
private void ApplyProductWatchSettings(AppSettings settings)
|
|
{
|
|
if (_productWatcher == null) return;
|
|
|
|
if (settings.AutoAddProductsEnabled && !_productWatcher.IsRunning) _productWatcher.Start();
|
|
else if (!settings.AutoAddProductsEnabled && _productWatcher.IsRunning) _productWatcher.Stop();
|
|
}
|
|
|
|
// L'elenco dei prodotti, con stellina e limiti, vive ora nella scheda Prodotti:
|
|
// vedi MainWindow.Products.cs. Qui restano solo l'avvio della sorveglianza e
|
|
// l'aggiunta automatica delle aste che trova.
|
|
}
|
|
}
|