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.
26 lines
1.0 KiB
C#
26 lines
1.0 KiB
C#
using System;
|
|
using System.Globalization;
|
|
using System.Windows.Data;
|
|
|
|
namespace ytLive.Helpers;
|
|
|
|
/// <summary>
|
|
/// True when a log entry's sequence falls inside the range a clicked alert points at. Two numbers
|
|
/// rather than a membership collection: the log list is virtualised, and rows that are already
|
|
/// realised do not re-evaluate when a collection changes — but they do when a bound number changes.
|
|
/// </summary>
|
|
public sealed class LogInRangeConverter : IMultiValueConverter
|
|
{
|
|
public object Convert(object[] values, Type targetType, object? parameter, CultureInfo culture)
|
|
{
|
|
if (values.Length < 3) return false;
|
|
if (values[0] is not long sequence) return false;
|
|
if (values[1] is not long from || values[2] is not long to) return false;
|
|
if (from == 0 && to == 0) return false;
|
|
return sequence >= from && sequence <= to;
|
|
}
|
|
|
|
public object[] ConvertBack(object value, Type[] targetTypes, object? parameter, CultureInfo culture)
|
|
=> throw new NotSupportedException();
|
|
}
|