feat(alerts): TASK 43 — native events & alerts (six unique animations) + chat parity
Replace the external StreamElements feed with NATIVE YouTube events per the creator's 2026-09-23 question. Chat parity half: - YouTubeChatService decodes ALL SIX liveChat/messages event types into ChatMessage.Kind (superChat/superSticker/newSponsor/membershipGifting/ giftMembershipReceived/memberMilestoneChat) — the four formerly-empty overlay rows are real now — and re-arms its one-shot poll on the server's pollingIntervalMillis (streamList connection semantics; clamp 1000-6000ms, maxResults=2000). ParsePage internal static seam + ChatPage record for deterministic tests; optional HttpClient ctor seam kept; InjectSimulatedMessage (TASK 41) preserved. Alerts half (creator rulings: one celebration zone, six UNIQUE animations, no menus/polls, sub mention = chat row only, NO viewer count): - New SourceType.AlertBox 'Stream Alerts' (one per layout, CanAddAlerts gate mirroring chat; idle = transparent). - AlertRenderer: six distinct branded animations (SuperChat slide-up/shine/ count-up, SuperSticker scale-pop, NewMember drop-in/flash, MemberGift slide-left/ chip-fan, GiftReceived confetti, MemberMilestone rise/growth-bar), every card drawing the 'made with LlamaCasty!' brand line. - AlertOverlayLayer: true component (Commit-G pattern) — queue (cap 10, drop tail never stall), 33ms UI ticker, cache-first RenderFrame + UpdatePreview, Advance(double) as the deterministic test clock; ChatEventKind.None rows never enqueue. - Wired: resolver RenderAlertBox, _alertLayer ctor + dispose, LoadLayout previews, Add menu item (Controls/LeftPanel.xaml), TestSessionViewModel sims tagged (member->NewMember, superchat->SuperChat). Good Dog ONE integration test: AlertLayerTests (RealApp STA, real WPF raster) — ParsePage classifies all six kinds + cadence fields; None rows enqueue nothing; six events play pairwise-distinct moving frames then drain to null. Gate: clean build 0 warnings; full suite 316/317, the one failure (LayerReorderPersistenceTests.RealMouseDrag) repros on the clean tree — the known environmental class (real-mouse-drag no-ops with a game/fullscreen window focused). References (OBS/overlay ecosystem): - streamList semantics: https://developers.google.com/youtube/v3/live/docs/liveChatMessages/streamList - OBS alert-box pattern (designated celebration zone, idle transparent): creator-chosen model
This commit is contained in:
@@ -184,7 +184,9 @@ public sealed class TestSessionViewModel : ViewModelBase
|
||||
|
||||
/// <summary>Subscriptions aren't chat events on YouTube, so a "subscriber" row
|
||||
/// is a plain text-shaped message carrying the count — honest: the chat overlay
|
||||
/// shows it as a regular row, which is exactly what a sub looks like in chat.</summary>
|
||||
/// shows it as a regular row, which is exactly what a sub looks like in chat.
|
||||
/// It carries <see cref="ChatEventKind.None"/> on purpose: no alert animation
|
||||
/// fires for free subs — the chat mention is the announcement (creator ruling).</summary>
|
||||
private ChatMessage SimulatedSubscriber()
|
||||
{
|
||||
var author = NextViewer();
|
||||
@@ -197,6 +199,7 @@ public sealed class TestSessionViewModel : ViewModelBase
|
||||
var message = NewSimulated(author, $"🎉 {author} became a member!");
|
||||
message.IsMember = true;
|
||||
message.MembershipLevel = "New member";
|
||||
message.Kind = ChatEventKind.NewMember;
|
||||
return message;
|
||||
}
|
||||
|
||||
@@ -207,6 +210,8 @@ public sealed class TestSessionViewModel : ViewModelBase
|
||||
message.IsSuperChat = true;
|
||||
message.SuperChatAmount = 5.00;
|
||||
message.SuperChatCurrency = "$";
|
||||
message.SuperChatDisplayString = "$5.00";
|
||||
message.Kind = ChatEventKind.SuperChat;
|
||||
return message;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user