feat(toast): wire ToastVariant::Warning for daily-challenge expiry
Adds the first in-engine consumer of `ToastVariant::Warning` — a 4s amber-bordered toast that fires once per daily-challenge date when the player is within 30 minutes of UTC midnight reset and hasn't yet completed today's challenge. Mirrors the v0.21.2 `ToastVariant::Error` wiring: a domain-event message (`WarningToastEvent(String)`) crosses the plugin boundary; `animation_plugin::handle_warning_toast` reads it and spawns the fire-and-forget toast. Suppression is decided by a pure helper (`compute_expiry_warning_minutes`) that's exhaustively covered by 7 unit tests + 1 in-Bevy idempotence test. After this lands, every `ToastVariant` (Info, Warning, Error, Celebration) has at least one real driver — closing the "is this enum scaffolding or load-bearing?" ambiguity that's been latent since the variant was introduced. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -22,7 +22,8 @@ use crate::card_plugin::CardEntity;
|
||||
use crate::challenge_plugin::ChallengeAdvancedEvent;
|
||||
use crate::daily_challenge_plugin::{DailyChallengeCompletedEvent, DailyGoalAnnouncementEvent};
|
||||
use crate::events::{
|
||||
AchievementUnlockedEvent, GameWonEvent, InfoToastEvent, MoveRejectedEvent, XpAwardedEvent,
|
||||
AchievementUnlockedEvent, GameWonEvent, InfoToastEvent, MoveRejectedEvent, WarningToastEvent,
|
||||
XpAwardedEvent,
|
||||
};
|
||||
use crate::game_plugin::GameMutation;
|
||||
use crate::layout::LayoutResource;
|
||||
@@ -164,6 +165,7 @@ impl Plugin for AnimationPlugin {
|
||||
.add_message::<SettingsChangedEvent>()
|
||||
.add_message::<InfoToastEvent>()
|
||||
.add_message::<MoveRejectedEvent>()
|
||||
.add_message::<WarningToastEvent>()
|
||||
.add_message::<XpAwardedEvent>()
|
||||
.init_resource::<EffectiveSlideDuration>()
|
||||
.init_resource::<ToastQueue>()
|
||||
@@ -186,6 +188,7 @@ impl Plugin for AnimationPlugin {
|
||||
handle_auto_complete_toast,
|
||||
handle_xp_awarded_toast,
|
||||
handle_move_rejected_toast,
|
||||
handle_warning_toast,
|
||||
tick_toasts,
|
||||
(enqueue_toasts, drive_toast_display).chain(),
|
||||
)
|
||||
@@ -651,6 +654,23 @@ fn handle_move_rejected_toast(
|
||||
}
|
||||
}
|
||||
|
||||
/// Spawns a 4-second amber-bordered Warning toast for every incoming
|
||||
/// [`WarningToastEvent`]. First in-engine consumer of
|
||||
/// [`ToastVariant::Warning`] — exercises the variant's amber accent and
|
||||
/// the design-system "act soon" semantic.
|
||||
///
|
||||
/// Mirrors [`handle_move_rejected_toast`] but reads a generic carrier
|
||||
/// event (not a domain-specific one) because Warning has multiple
|
||||
/// candidate drivers and the call-site knows the message wording.
|
||||
fn handle_warning_toast(
|
||||
mut commands: Commands,
|
||||
mut events: MessageReader<WarningToastEvent>,
|
||||
) {
|
||||
for ev in events.read() {
|
||||
spawn_toast(&mut commands, ev.0.clone(), 4.0, ToastVariant::Warning);
|
||||
}
|
||||
}
|
||||
|
||||
/// Ticks down `ToastTimer` on each toast and despawns it when the timer expires.
|
||||
///
|
||||
/// Skipped while the game is paused so toast countdowns freeze along with the
|
||||
|
||||
Reference in New Issue
Block a user