Files
LlamaCasty/Models/SessionStartDecision.cs
T
gramps 0f8647790d fix(top bar): a signed-out ON-AIR press starts sign-in instead of disabling the button
Reported: EDIT on + ON-AIR on, signed out → the button reads "Test Stream" and cannot be pressed.
Cause: the primary button bound straight to StartTestCommand, whose CanExecute needs a connection.
StartSession already routed signed-out ON-AIR to the sign-in flow; the test path bypassed it.

The route is now explicit and pure: RouteFor(kind, connected) → SignIn | Record | Live | Test. The
primary command calls SignInAsync for the SignIn route, BeginTestStream for Test, StartSession
otherwise — so the label, the action and the sign-in fallback cannot drift apart. Pinned in
SessionStartDecisionTests for both live and test, connected and not.
2026-10-30 11:17:11 -07:00

57 lines
2.0 KiB
C#

namespace ytLive.Models;
/// <summary>What the top bar's primary action button will do.</summary>
public enum SessionStartKind
{
Record,
Live,
Test,
}
/// <summary>Creator ruling (2026-10-30): the primary button is context-sensitive, so the separate
/// TEST button is gone.
///
/// <list type="bullet">
/// <item>EDIT off + ON-AIR armed → Go Live (the livestream message)</item>
/// <item>EDIT on + ON-AIR armed → Test Stream (the test-livestream message) — a dry run you
/// cannot leak, because every broadcast is private pre-v1 anyway</item>
/// <item>REC armed → Start Recording, whatever EDIT says (there is no test recording)</item>
/// </list>
///
/// <para>Pure so the whole matrix is testable without a window.</para></summary>
public static class SessionStartDecision
{
public static SessionStartKind For(bool recordArmed, bool onAirArmed, bool editing)
{
// Neither pill armed still starts something: local recording needs no account, and the
// no-dead-ends rule forbids an inert primary button.
if (recordArmed || !onAirArmed) return SessionStartKind.Record;
return editing ? SessionStartKind.Test : SessionStartKind.Live;
}
/// <summary>What pressing the button actually does, given whether YouTube is connected.
/// A signed-out ON-AIR press must start the SIGN-IN flow, not sit there disabled — a dead
/// primary button is the dead end the design principle forbids (creator, 2026-10-30).</summary>
public enum Route
{
SignIn,
Record,
Live,
Test,
}
public static Route RouteFor(SessionStartKind kind, bool connected) => kind switch
{
SessionStartKind.Record => Route.Record,
SessionStartKind.Test => connected ? Route.Test : Route.SignIn,
_ => connected ? Route.Live : Route.SignIn,
};
public static string LabelFor(SessionStartKind kind) => kind switch
{
SessionStartKind.Record => "Start Recording",
SessionStartKind.Test => "Test Stream",
_ => "Go Live",
};
}