From 2b60dd62c9e7044fec5445fcbee3a69c25b03770 Mon Sep 17 00:00:00 2001 From: frizat Date: Sun, 4 Oct 2026 22:02:32 -0500 Subject: [PATCH] Hide the field graphic when ESPN reports no possession Between plays (kickoff after a score, timeouts) ESPN sends a situation with no possession and a stale yardLine; the card drew a ball and an away-team arrow from it. No possessor now means no situation, so the field graphic hides until the next play (NFL and CFB share this DTO). Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01DAWjtJgXaMYbzZXYJjTEYs --- Client.React/CHANGELOG.md | 1 + Server.UnitTests/LiveGameDtoTests.cs | 14 ++++++++++++++ Shared/Models/Data/Dtos/LiveGameDto.cs | 9 ++++++--- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/Client.React/CHANGELOG.md b/Client.React/CHANGELOG.md index 81b1053b..ff2b4d19 100644 --- a/Client.React/CHANGELOG.md +++ b/Client.React/CHANGELOG.md @@ -6,6 +6,7 @@ Format: `## ` release headings and single-line `- ` bullets only — no bold, li ## 2026-10-04 +- Fixed: right after a score or during a timeout, live game cards showed the ball at a stale spot with a possession arrow even though nobody had the ball — the field graphic now hides until the next play - Improved: live covering/bloody alerts now come as one notification per team that lists each of your leagues and how many picked it there (e.g. "Alpha: your pick + 1 other") instead of a separate notification per league - Changed: the NFL and college apps now each have their own notification settings, and each app only gets its own sport's alerts — turn on push in the NFL app for NFL alerts and in the college app for college alerts (your existing settings were copied to both) - Fixed: NFL notifications also arrived on the college app (and vice versa) when both were installed — each app now only gets its own sport's alerts diff --git a/Server.UnitTests/LiveGameDtoTests.cs b/Server.UnitTests/LiveGameDtoTests.cs index 67d19906..d5366bd5 100644 --- a/Server.UnitTests/LiveGameDtoTests.cs +++ b/Server.UnitTests/LiveGameDtoTests.cs @@ -111,6 +111,20 @@ public void FromCompetition_SituationIsNull_WhenCompetitionHasNoSituation() Assert.Null(dto.Situation); } + // Between plays — kickoff after a score, timeouts, end of quarter — ESPN sends a situation with + // no possession (and a stale yardLine). Showing a ball and an arrow then is wrong (owner report: + // DET@CAR right after a CAR field goal), so no possession means no field graphic at all. + [Fact] + public void FromCompetition_SituationIsNull_WhenEspnReportsNoPossession() + { + var competition = BuildCompetition(possessionId: null); + competition.Situation = new EspnSitutation { Possession = null, YardLine = 35, Down = -1, IsRedZone = true }; + + var dto = LiveGameDto.FromCompetition(competition); + + Assert.Null(dto.Situation); + } + // ── IsRedZone ───────────────────────────────────────────────────────────── [Fact] diff --git a/Shared/Models/Data/Dtos/LiveGameDto.cs b/Shared/Models/Data/Dtos/LiveGameDto.cs index d909be90..abcf7386 100644 --- a/Shared/Models/Data/Dtos/LiveGameDto.cs +++ b/Shared/Models/Data/Dtos/LiveGameDto.cs @@ -48,16 +48,19 @@ public class GameSituationDto public bool IsRedZone { get; set; } public string DownDistanceText { get; set; } = string.Empty; - internal static GameSituationDto FromSituation(EspnSitutation situation, Competitor home, Competitor away) + // Null when nobody has the ball (kickoff after a score, timeouts, end of quarter) — ESPN still + // sends a situation then, with a stale yardLine, and drawing a ball + arrow from it is wrong. + internal static GameSituationDto? FromSituation(EspnSitutation situation, Competitor home, Competitor away) { var possessor = situation.Possession == home.Id ? home : situation.Possession == away.Id ? away : null; + if (possessor is null) return null; return new GameSituationDto { - PossessionTeam = possessor?.Team.Abbreviation, - IsHomePossession = possessor?.HomeAway == HomeAway.Home, + PossessionTeam = possessor.Team.Abbreviation, + IsHomePossession = possessor.HomeAway == HomeAway.Home, YardLine = situation.YardLine, Down = situation.Down, Distance = situation.Distance,