Creator: "even if it's not visible, we want to avoid polling." ScoreboardEnabled is the layer's master switch in the properties panel. Off means two things: - the strip frame is null in every scene (per-scene eye toggles stay independent), and - the cadence policy returns None at every phase — a scoreboard nobody can see must not spend quota. The switch is persisted (Scoreboard.Enabled), because one that resets would quietly resume polling. The polling gate is ScoreboardPollsEnabled: master switch AND at least one scene with a visible scoreboard — so hiding it in all five scenes also stops the polls. Guards: ScoreboardCadenceTests adds the switch off across live/test/recording; ScoreboardProperties pins the checkbox and the VM surface.
53 lines
1.9 KiB
C#
53 lines
1.9 KiB
C#
using System;
|
|
|
|
namespace ytLive.Models;
|
|
|
|
/// <summary>What kind of session the app is in, for polling decisions.</summary>
|
|
public enum SessionPhase
|
|
{
|
|
Idle,
|
|
Live,
|
|
Test,
|
|
Recording,
|
|
}
|
|
|
|
/// <summary>Which channel figures a poll should fetch.</summary>
|
|
public enum ScoreboardPoll
|
|
{
|
|
None,
|
|
SubscribersOnly,
|
|
Both,
|
|
}
|
|
|
|
/// <summary>Polling policy for the scoreboard's two channel figures (creator ruling 2026-10-30).
|
|
///
|
|
/// <para>Analytics answers in DAYS, and test/record sessions have no public audience — so querying
|
|
/// watch hours then is pure waste. Subscriber count is cheap (one quota unit) and moves during any
|
|
/// session, so it polls whenever the app is working. Idle means silent.</para></summary>
|
|
public static class ScoreboardCadence
|
|
{
|
|
public static readonly TimeSpan AnalyticsInterval = TimeSpan.FromMinutes(30);
|
|
public static readonly TimeSpan SubscriberInterval = TimeSpan.FromSeconds(60);
|
|
|
|
/// <summary><paramref name="enabled"/> is the layer's master switch. Off means NOTHING is
|
|
/// polled, whatever the session is doing — a hidden scoreboard has no reason to spend quota
|
|
/// (creator ruling 2026-10-30).</summary>
|
|
public static ScoreboardPoll Due(SessionPhase phase, DateTime lastAnalyticsUtc, DateTime lastSubscriberUtc,
|
|
DateTime nowUtc, bool enabled = true)
|
|
{
|
|
if (!enabled) return ScoreboardPoll.None;
|
|
if (phase == SessionPhase.Idle) return ScoreboardPoll.None;
|
|
|
|
var analyticsDue = phase == SessionPhase.Live && nowUtc - lastAnalyticsUtc >= AnalyticsInterval;
|
|
var subscribersDue = nowUtc - lastSubscriberUtc >= SubscriberInterval;
|
|
|
|
return (analyticsDue, subscribersDue) switch
|
|
{
|
|
(true, true) => ScoreboardPoll.Both,
|
|
(true, false) => ScoreboardPoll.None, // analytics alone is not a poll kind
|
|
(false, true) => ScoreboardPoll.SubscribersOnly,
|
|
_ => ScoreboardPoll.None,
|
|
};
|
|
}
|
|
}
|