feat(topbar): the action follows the armed output; Test is an explicit ask again
Unit C (creator ruling 2026-11-12). - Local MP4: one button, "Start Recording". - YouTube: "Private Test Stream" beside "Review & Go Live", the latter with the primary face because it is the default ask. - Running: "End Live Stream" (or "End Test" for a test run, "Stop Recording" for a local one). The behavioural change underneath: SessionStartDecision.For no longer takes `editing`. Since 2026-10-30 EDIT silently chose test-vs-real, which meant the same button did two different things depending on a toggle three inches away. With Test as its own button that inference has no job, so For() now reads only the armed output and ON-AIR always means the real livestream. That supersedes the 2026-10-30 ruling; SessionStartDecisionTests is rewritten to pin the new matrix rather than the old one. A signed-out press still starts the sign-in flow instead of sitting dead (no-dead-ends), unchanged from before — now stated in one place, the two new commands, instead of inside a route table. 680 pass, 0 warnings. Scope justification: Assets/starting-background.jpg is outside this unit — the creator's replacement art, still awaiting their visual check.
This commit is contained in:
@@ -35,11 +35,33 @@ public partial class MainViewModel
|
||||
/// running — a live session cannot change its output, so its switch is not offered.</summary>
|
||||
public bool ShowOutputStage => IsOutputWorld && IsOffline && !IsRecording;
|
||||
|
||||
/// <summary>The action the armed output offers: recording is one button, YouTube is two — the test
|
||||
/// run and the real one are separate asks since 2026-11-12, not something inferred from EDIT.</summary>
|
||||
public bool ShowStartRecordingAction => ShowOutputStage && RecordPillOn;
|
||||
public bool ShowYouTubeStartActions => ShowOutputStage && OnAirPillOn;
|
||||
|
||||
public ICommand StartRecordingCommand { get; private set; } = null!;
|
||||
public ICommand TestStreamCommand { get; private set; } = null!;
|
||||
public ICommand GoLiveCommand { get; private set; } = null!;
|
||||
|
||||
public ICommand EnterBuildWorldCommand { get; private set; } = null!;
|
||||
public ICommand EnterOutputWorldCommand { get; private set; } = null!;
|
||||
|
||||
private void InitializeWorldCommands()
|
||||
{
|
||||
StartRecordingCommand = new RelayCommand(_ => BeginRecordOnly(), _ => ShowStartRecordingAction);
|
||||
// A signed-out press starts the sign-in flow instead of sitting dead (no-dead-ends rule).
|
||||
TestStreamCommand = new RelayCommand(_ =>
|
||||
{
|
||||
if (!IsConnected) { _ = SignInAsync(); return; }
|
||||
BeginTestStream();
|
||||
}, _ => ShowYouTubeStartActions);
|
||||
GoLiveCommand = new RelayCommand(_ =>
|
||||
{
|
||||
if (!IsConnected) { _ = SignInAsync(); return; }
|
||||
StartSession();
|
||||
}, _ => ShowYouTubeStartActions);
|
||||
|
||||
EnterBuildWorldCommand = new RelayCommand(_ => EnterWorld(BarWorld.Build));
|
||||
EnterOutputWorldCommand = new RelayCommand(_ => EnterWorld(BarWorld.Output));
|
||||
}
|
||||
@@ -54,5 +76,7 @@ public partial class MainViewModel
|
||||
OnPropertyChanged(nameof(IsOutputWorld));
|
||||
EditingActive = world == BarWorld.Build;
|
||||
OnPropertyChanged(nameof(ShowOutputStage));
|
||||
OnPropertyChanged(nameof(ShowStartRecordingAction));
|
||||
OnPropertyChanged(nameof(ShowYouTubeStartActions));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user