Files
Mimante/Mimante/Documentation/FIX_UI_UPDATE_AFTER_BID.md
Alberto Balbo 4bfcf147b4 Miglioramenti UI e gestione puntate server
- Implementato focus automatico sulla riga successiva dopo la
  cancellazione di un'asta, con scrolling e reset focus.
- Utilizzo dei dati ufficiali del server per il conteggio
  delle puntate residue e usate su asta, con fallback manuale.
- Corretto il parsing dei campi della risposta server
  (campo 2: puntate residue, campo 5: puntate usate).
- Risolto il mancato aggiornamento immediato della UI
  (colonna "Clicks" e banner "Puntate residue").
- Aggiunto logging dettagliato per il parsing della risposta
  server e il debugging di eventuali problemi.
- Documentate le modifiche in file dedicati con scenari di
  test e istruzioni per il troubleshooting.
2025-11-20 23:01:53 +01:00

13 KiB

?? Fix Aggiornamento UI Contatori Puntate

?? Problema Rilevato

Dopo una puntata riuscita:

  • ? La colonna "Clicks" nella griglia mostra 0 invece del numero corretto
  • ? Il banner "Puntate residue" in alto non si aggiorna immediatamente
  • ? L'aggiornamento avviene solo dopo 5-10 minuti (timer automatico)

Screenshot del Problema

  • Clicks: mostra 0 anche dopo puntata
  • Puntate: mostra 48 (non aggiornato dopo puntata)

?? Analisi del Problema

Problema 1: RefreshCounters() non sul Thread UI

RefreshCounters() veniva chiamato dal thread worker invece che dal thread UI, quindi la UI non si aggiornava.

// ? PRIMA - thread worker
vm.RefreshCounters();

Problema 2: Banner Aggiornato Solo dai Timer

Il banner delle puntate residue veniva aggiornato solo dai timer (ogni 5-10 minuti), non immediatamente dopo la puntata.

Problema 3: Parsing Risposta Server Poco Chiaro

Il parsing della risposta non aveva logging dettagliato, quindi era impossibile capire se i dati arrivavano correttamente.


? Soluzioni Implementate

1?? Aggiunto Logging Dettagliato per Debugging

File: Services/BidooApiClient.cs

Ora quando punti, il log mostra esattamente cosa restituisce il server:

if (responseText.StartsWith("ok", StringComparison.OrdinalIgnoreCase))
{
    result.Success = true;
    var parts = responseText.Split('|');
    
    // Log della risposta completa per debugging
    Log($"[BID PARSE] Risposta completa: {responseText}", auctionId);
    Log($"[BID PARSE] Numero totale campi: {parts.Length}", auctionId);
    
    // ? FORMATO RISPOSTA BIDOO: 9 campi
    // Campo 1 (indice 0): "ok"
    // Campo 2 (indice 1): Puntate residue totali
    // Campo 5 (indice 4): Puntate usate su questa asta
    
    // Campo 2 (indice 1): Puntate residue totali
    if (parts.Length > 1)
    {
        Log($"[BID PARSE] Campo 2 (indice 1) - Remaining bids: '{parts[1]}'", auctionId);
        if (int.TryParse(parts[1], out var remaining))
        {
            result.RemainingBids = remaining;
            _session.RemainingBids = remaining;
            Log($"[BID SUCCESS] ? Puntate residue totali: {remaining}", auctionId);
        }
        else
        {
            Log($"[BID PARSE WARN] ?? Impossibile parsare campo 2", auctionId);
        }
    }
    
    // Campo 5 (indice 4): Puntate usate su questa asta
    if (parts.Length > 4)
    {
        Log($"[BID PARSE] Campo 5 (indice 4) - Bids used: '{parts[4]}'", auctionId);
        if (int.TryParse(parts[4], out var usedOnAuction))
        {
            result.BidsUsedOnThisAuction = usedOnAuction;
            Log($"[BID SUCCESS] ? Puntate usate su questa asta: {usedOnAuction}", auctionId);
        }
        else
        {
            Log($"[BID PARSE WARN] ?? Impossibile parsare campo 5", auctionId);
        }
    }
    
    // Log tutti i campi per debugging completo
    Log($"[BID PARSE DEBUG] Tutti i campi della risposta:", auctionId);
    for (int i = 0; i < parts.Length; i++)
    {
        Log($"  Campo {i+1} (indice {i}): '{parts[i]}'", auctionId);
    }
}

2?? Aggiunto Metodo per Aggiornare Banner Immediatamente

File: Core/MainWindow.UserInfo.cs

Nuovo metodo UpdateRemainingBidsDisplay() per aggiornare il banner senza aspettare i timer:

/// <summary>
/// Aggiorna immediatamente il banner delle puntate residue (chiamato dopo ogni puntata)
/// </summary>
public void UpdateRemainingBidsDisplay()
{
    try
    {
        var session = _auctionMonitor.GetSession();
        if (session != null && session.RemainingBids > 0)
        {
            RemainingBidsText.Text = session.RemainingBids.ToString();
            Log($"[BANNER UPDATE] Puntate residue aggiornate: {session.RemainingBids}", LogLevel.Info);
        }
    }
    catch (Exception ex)
    {
        Log($"[ERROR] Errore aggiornamento banner: {ex.Message}", LogLevel.Error);
    }
}

3?? Aggiornamento Banner dopo Puntata Manuale

File: Core/MainWindow.Commands.cs

Ora ExecuteGridBidAsync chiama UpdateRemainingBidsDisplay() e RefreshCounters() sul thread UI:

private async Task ExecuteGridBidAsync(AuctionViewModel? vm)
{
    if (vm == null) return;
    try
    {
        Log($"[BID] Puntata manuale richiesta su: {vm.Name}", LogLevel.Info);
        var result = await _auctionMonitor.PlaceManualBidAsync(vm.AuctionInfo);
        
        // Aggiorna dati puntate da risposta server per puntata manuale
        if (result.Success)
        {
            if (result.RemainingBids.HasValue)
            {
                vm.AuctionInfo.RemainingBids = result.RemainingBids.Value;
                
                // ? NUOVO: Aggiorna immediatamente il banner in alto - SUL THREAD UI
                Dispatcher.Invoke(() => UpdateRemainingBidsDisplay());
            }
            if (result.BidsUsedOnThisAuction.HasValue)
            {
                vm.AuctionInfo.BidsUsedOnThisAuction = result.BidsUsedOnThisAuction.Value;
            }
            
            // ? NUOVO: Notifica aggiornamento contatori - SUL THREAD UI
            Dispatcher.Invoke(() => vm.RefreshCounters());
            
            Log($"[OK] Puntata manuale su {vm.Name}: {result.LatencyMs}ms", LogLevel.Success);
        }
        else
        {
            Log($"[FAIL] Puntata manuale su {vm.Name}: {result.Error}", LogLevel.Error);
        }
    }
    catch (System.Exception ex)
    {
        Log($"[ERRORE] Puntata manuale: {ex.Message}", LogLevel.Error);
    }
}

4?? Aggiornamento Banner dopo Puntata Automatica

File: MainWindow.xaml.cs

Modificato AuctionMonitor_OnBidExecuted per aggiornare anche il banner:

private void AuctionMonitor_OnBidExecuted(AuctionInfo auction, BidResult result)
{
    Dispatcher.BeginInvoke(() =>
    {
        var vm = _auctionViewModels.FirstOrDefault(a => a.AuctionId == auction.AuctionId);
        if (vm != null)
        {
            vm.RefreshCounters();

            if (result.Success)
            {
                // ? NUOVO: Aggiorna il banner delle puntate residue dopo puntata automatica
                if (result.RemainingBids.HasValue)
                {
                    UpdateRemainingBidsDisplay();
                }
                
                Log($"[OK] Click su {auction.Name}: {result.LatencyMs}ms {result.Response}", LogLevel.Success);
            }
            else
            {
                Log($"[FAIL] Click fallito su {auction.Name}: {result.Error}", LogLevel.Error);
            }
        }
    });
}

?? Comportamento Corretto

? Scenario: Puntata Manuale

Azioni:

  1. Clicchi "Punta" nella griglia
  2. Server risponde: ok|47|xxx|xxx|1|xxx|xxx|xxx|xxx (9 campi)

Risultato Atteso:

  • ?? Colonna "Clicks": aggiornata immediatamente da 0 ? 1
  • ?? Banner "Puntate": aggiornato immediatamente da 48 ? 47
  • ?? Log dettagliato:
    [BID PARSE] Risposta completa: ok|47|xxx|xxx|1|xxx|xxx|xxx|xxx
    [BID PARSE] Numero totale campi: 9
    [BID PARSE] Campo 2 (indice 1) - Remaining bids: '47'
    [BID SUCCESS] ? Puntate residue totali: 47
    [BID PARSE] Campo 5 (indice 4) - Bids used: '1'
    [BID SUCCESS] ? Puntate usate su questa asta: 1
    [BID PARSE DEBUG] Tutti i campi della risposta:
      Campo 1 (indice 0): 'ok'
      Campo 2 (indice 1): '47'
      Campo 3 (indice 2): 'xxx'
      Campo 4 (indice 3): 'xxx'
      Campo 5 (indice 4): '1'
      Campo 6 (indice 5): 'xxx'
      Campo 7 (indice 6): 'xxx'
      Campo 8 (indice 7): 'xxx'
      Campo 9 (indice 8): 'xxx'
    [BANNER UPDATE] Puntate residue aggiornate: 47
    [OK] Puntata manuale su Balenciaga Collana: 45ms
    

? Scenario: Puntata Automatica

Azioni:

  1. Strategia punta automaticamente
  2. Server risponde: ok|46|xxx|xxx|2|xxx|xxx|xxx|xxx (9 campi)

Risultato Atteso:

  • ?? Colonna "Clicks": aggiornata automaticamente 1 ? 2
  • ?? Banner "Puntate": aggiornato automaticamente 47 ? 46
  • ?? Log dettagliato (come sopra)

?? Log di Debugging

Cosa Cercare nei Log

Dopo una puntata, cerca nel log questi messaggi:

[BID PARSE] Risposta completa: ok|XX|xxx|xxx|X|xxx|xxx|xxx|xxx
[BID PARSE] Numero totale campi: 9
[BID PARSE] Campo 2 (indice 1) - Remaining bids: 'XX'
[BID SUCCESS] ? Puntate residue totali: XX
[BID PARSE] Campo 5 (indice 4) - Bids used: 'X'
[BID SUCCESS] ? Puntate usate su questa asta: X
[BID PARSE DEBUG] Tutti i campi della risposta:
  Campo 1 (indice 0): 'ok'
  Campo 2 (indice 1): 'XX'
  Campo 3 (indice 2): 'xxx'
  Campo 4 (indice 3): 'xxx'
  Campo 5 (indice 4): 'X'
  ...
[BANNER UPDATE] Puntate residue aggiornate: XX

Se Vedi Questi Messaggi = Problema Risolto ?

Se vedi:

  • [BID PARSE] Numero totale campi: 9 ?
  • [BID PARSE] Campo 2 (indice 1) - Remaining bids: 'XX' ?
  • [BID SUCCESS] ? Puntate residue totali: XX ?
  • [BID PARSE] Campo 5 (indice 4) - Bids used: 'X' ?
  • [BID SUCCESS] ? Puntate usate su questa asta: X ?
  • [BANNER UPDATE] Puntate residue aggiornate: XX ?

Significa che:

  • ? Il server restituisce i dati correttamente
  • ? Il parsing legge i campi giusti (campo 2 e campo 5)
  • ? Il banner viene aggiornato
  • ? La colonna "Clicks" si aggiorna

Se Vedi Questi Warning = Problema con Risposta Server ??

Se vedi:

  • [BID PARSE] Numero totale campi: X (dove X ? 9) ??
  • [BID PARSE ERROR] ? Risposta non ha campo 2 ??
  • [BID PARSE ERROR] ? Risposta non ha campo 5 ??
  • [BID PARSE WARN] ?? Impossibile parsare campo X ??

Significa che:

  • ?? Il server non restituisce 9 campi come previsto
  • ?? I campi sono in posizioni diverse
  • ?? Il formato risposta è cambiato

?? Come Testare

Test 1: Puntata Manuale con Log Abilitati

  1. Apri l'applicazione
  2. Aggiungi un'asta
  3. Guarda il banner in alto - nota le puntate residue (es. 48)
  4. Clicca "Punta" nella griglia
  5. Controlla il log - devi vedere i messaggi [BID PARSE]
  6. Verifica:
    • ? Colonna "Clicks" aggiornata immediatamente
    • ? Banner "Puntate" decrementato (es. 48 ? 47)
    • ? Log mostra parsing dettagliato

Test 2: Puntata Automatica

  1. Configura strategia (Anticipo = 200ms)
  2. Avvia l'asta
  3. Aspetta che punti automaticamente
  4. Verifica (come sopra)

Test 3: Puntate Multiple

  1. Punta 3 volte manualmente
  2. Verifica che ad ogni puntata:
    • Clicks: 0 ? 1 ? 2 ? 3
    • Puntate: 48 ? 47 ? 46 ? 45

?? Troubleshooting

Problema: Clicks Rimane a 0

Possibili cause:

  1. Il server non restituisce il campo "bids used" nella risposta
  2. Il campo è in una posizione diversa

Soluzione: Guarda il log [BID PARSE] e verifica:

  • Quanti campi ha la risposta?
  • Quale campo contiene il contatore?
  • Potrebbe servire modificare gli indici del parsing

Problema: Banner Non Si Aggiorna

Possibili cause:

  1. Il server non restituisce "remaining bids"
  2. UpdateRemainingBidsDisplay() non viene chiamato

Soluzione: Cerca nel log:

  • [BANNER UPDATE] Puntate residue aggiornate ?
  • Se non c'è, il metodo non viene chiamato
  • Se c'è ma il banner non cambia, problema UI binding

Problema: Log Non Mostra [BID PARSE]

Possibile causa: La puntata fallisce prima del parsing

Soluzione: Cerca errori prima di [BID PARSE]:

  • [BID ERROR] - puntata fallita
  • [BID EXCEPTION] - errore durante chiamata

?? File Modificati

File Modifiche
Services/BidooApiClient.cs ?? Aggiunto logging dettagliato parsing risposta
Core/MainWindow.UserInfo.cs ? Aggiunto metodo UpdateRemainingBidsDisplay()
Core/MainWindow.Commands.cs ?? Chiamata UpdateRemainingBidsDisplay() e RefreshCounters() su UI thread
MainWindow.xaml.cs ?? Aggiornamento banner in AuctionMonitor_OnBidExecuted

? Checklist Test

Prima di Chiudere Issue

  • Puntata manuale aggiorna colonna "Clicks" immediatamente
  • Puntata manuale aggiorna banner "Puntate" immediatamente
  • Puntata automatica aggiorna colonna "Clicks"
  • Puntata automatica aggiorna banner "Puntate"
  • Log mostra [BID PARSE] con tutti i campi
  • Log mostra [BID SUCCESS] Puntate residue totali: XX
  • Log mostra [BID SUCCESS] Puntate usate su questa asta: X
  • Log mostra [BANNER UPDATE] Puntate residue aggiornate: XX
  • Nessun errore/warning nel parsing
  • Build compila senza errori

Data Fix: 2025
Versione: 4.1+
Issue: UI non aggiorna contatori dopo puntata
Status: ? RISOLTO


Prima:

  • ? Colonna "Clicks" mostra sempre 0
  • ? Banner aggiornato solo dopo 5-10 minuti
  • ? Nessun logging dettagliato
  • ? RefreshCounters() su thread sbagliato

Dopo:

  • ? Colonna "Clicks" aggiornata immediatamente
  • ? Banner aggiornato immediatamente
  • ? Log dettagliato per debugging
  • ? RefreshCounters() sul thread UI corretto
  • ? UpdateRemainingBidsDisplay() chiamato dopo ogni puntata