feat(ui): left-panel alert stack — licence indicator pinned on top, events LIFO below

Creator design (2026-11-05). A stack of red rows at the top of the left panel, above both mode grids
so it shows while editing and while live, pushing the panel's content down.

- Row 1 is the **Steam licence indicator** and nothing displaces it. It reads as status, not a
  warning: "Entitlement 30 fps · Maximum 60 fps", both numbers derived from QualityOptions and
  HasProOutput. While higher tiers are unavailable it shows a **pin** (standing indicator, no close
  control); once ownership is verified the pin becomes a **close control** and the dismissal is
  persisted (`Steam.LicenceIndicatorDismissed`), permanent while ownership holds. Losing ownership
  restores it as pinned — a change of state, not a preference. Click → About.
- **Event rows stack beneath, newest first**, one row per episode (an episode advancing its state
  updates its own row rather than adding another). Each is dismissible. Click → the Logs tab opens
  with that event's sequence range painted red (`HighlightedLogFrom/To` + `LogInRangeConverter`; two
  numbers rather than a collection because the log list is virtualised and realised rows do not
  re-evaluate on membership changes).
- Replaces the old red panel under the quality picker, which is removed.
- The Steam diagnostic text loses "Contact the creator or support" for a neutral
  "Steam licensing is not configured in this build."

Tests: `AttentionAlertStackTests` — pinned first with the status text; owned → closable and the close
survives a reload but ownership loss restores it pinned; pinned cannot be dismissed; event rows LIFO
with in-place episode updates; clicking an event opens Logs and sets its range. AboutHub + Entitlement
tests updated for the removed panel and the new wording. FAST gate: 532 passed, 0 failed, 0 warnings.
This commit is contained in:
2026-11-05 11:41:59 -08:00
parent adf9883ae9
commit a80108dd96
15 changed files with 501 additions and 49 deletions
+7 -4
View File
@@ -96,10 +96,13 @@ public sealed class AboutHubTests
var lockedTier = vm.QualityOptions.First(option => option.Fps == 60);
Assert.Same(freeTier, vm.SelectedQuality);
var errorPanel = (Border)window.FindName("EntitlementErrorPanel");
var errorText = (TextBlock)window.FindName("EntitlementErrorText");
Assert.Equal(Visibility.Visible, errorPanel.Visibility);
Assert.Contains("Open Steam, sign in", errorText.Text);
// The old red panel under the quality picker is gone (2026-11-05): the licence state
// lives in the left panel's alert stack now, as a pinned status indicator.
Assert.Null(window.FindName("EntitlementErrorPanel"));
var licenceRow = vm.AttentionAlerts.Single(alert => alert.Label == "STEAM LICENCE");
Assert.True(licenceRow.IsPinned);
Assert.Contains("Entitlement 30 fps", licenceRow.Text);
Assert.Contains("Maximum 60 fps", licenceRow.Text);
var picker = (ComboBox)window.FindName("QualityPicker");
Assert.True(vm.CanChangeQuality);