fix(go-live): the Start Stream dialog re-reads Stream Info at open

Creator went live on the Debug build while the Release build was recording and got an empty
title/description, with the Stream Info tab filled in on screen. Both processes write to the same
profile: `BroadcastForm` is loaded ONCE at startup and each keystroke persists straight to the store,
so the instance that opened the dialog was holding the form as it was when it launched — before the
other instance saved those fields. The dialog copied from that stale copy.

`CreateGoLiveDialog` (new, extracted so it can be tested without showing a window) calls
`BroadcastForm.Load()` before composing the dialog. That is what the form's own doc comment always
claimed ("startup / Go Live refresh") but the refresh was never wired. It cannot lose an edit: every
keystroke is already persisted.

The dialog also logs `Go Live dialog: title='…' description=N chars`, so the next report of "the
dialog was blank" says immediately whether the values reached the dialog or never left the store.

Test: `BroadcastPullOutTests` writes metadata through a second `LayoutStore` handle (the other
instance) after the VM has loaded and asserts the dialog carries it. 572 green, 0 warnings.
This commit is contained in:
2026-11-06 12:56:05 -08:00
parent bef818f4a1
commit b4e952fda9
2 changed files with 28 additions and 1 deletions
@@ -96,13 +96,25 @@ public partial class MainViewModel : ViewModelBase
}
}
private void BeginGoLive(bool alsoRecord)
/// <summary>Builds the Start Stream dialog's model from the Stream Info tab. Re-reads the store
/// first: the form is loaded once at startup, and a second LlamaCasty on the same profile (the dev
/// instance, or Release recording while Debug goes live) writes its edits straight to the store, so
/// this process's copy can be empty while the tab the creator filled in is not (2026-11-06).</summary>
internal GoLiveViewModel CreateGoLiveDialog()
{
BroadcastForm.Load();
var dialog = new GoLiveViewModel(() => SignInAsync(), _youtubeAuth.CurrentChannel)
{
StreamTitle = BroadcastForm.Title,
StreamDescription = BroadcastForm.Description,
};
AppLog.Write($"Go Live dialog: title='{dialog.StreamTitle}' description={dialog.StreamDescription.Length} chars");
return dialog;
}
private void BeginGoLive(bool alsoRecord)
{
var dialog = CreateGoLiveDialog();
var window = new ytLive.GoLiveWindow(dialog) { Owner = System.Windows.Application.Current.MainWindow };
if (window.ShowDialog() != true) return;
+15
View File
@@ -76,6 +76,21 @@ public sealed class BroadcastPullOutTests
vm.BroadcastForm.Load();
Assert.Equal("Hello", vm.BroadcastForm.Title);
// Go Live must read what the STORE holds, not this process's copy. Two instances share the
// real profile (Release recording while Debug goes live), and the other one's edits never
// reach this process's in-memory form — that is how the creator got an empty dialog while
// the Stream Info tab was filled in (2026-11-06).
using (var otherInstance = new LayoutStore(tempDb))
otherInstance.SaveBroadcastMetadata(new BroadcastMetadata
{
Title = "Written by the other instance",
Description = "And its description",
});
var dialog = vm.CreateGoLiveDialog();
Assert.Equal("Written by the other instance", dialog.StreamTitle);
Assert.Equal("And its description", dialog.StreamDescription);
Assert.False(vm.BroadcastForm.IsDrawerOpen);
vm.BroadcastForm.ToggleDrawerCommand.Execute(null);
Assert.True(vm.BroadcastForm.IsDrawerOpen);